This commit is contained in:
Adam Majer
2024-07-15 19:19:34 +02:00
parent 3c4f1d103c
commit fb8e5d5e03
3 changed files with 112 additions and 33 deletions

View File

@@ -251,12 +251,26 @@ type tree_entry struct {
name string
mode int
hash string
size int
}
type tree struct {
items []tree_entry
}
func (t *tree_entry) isSubmodule() bool {
return (t.mode & 0170000) == 0160000
}
func (t *tree_entry) isTree() bool {
return (t.mode & 0170000) == 0040000
}
func (t *tree_entry) isBlob() bool {
return !t.isTree() && !t.isSubmodule()
}
func parseGitMsg(data <-chan byte) (gitMsg, error) {
var id []byte = make([]byte, 64)
var msgType []byte = make([]byte, 16)
@@ -295,7 +309,7 @@ func parseGitMsg(data <-chan byte) (gitMsg, error) {
if c >= '0' && c <= '9' {
size = size*10 + (int(c) - '0')
} else {
return gitMsg{}, errors.New("Invalid character during commit size parse")
return gitMsg{}, fmt.Errorf("Invalid character during object size parse: '%c'", c)
}
}
@@ -366,31 +380,65 @@ func parseGitCommit(data <-chan byte) (commit, error) {
return c, err
}
func parseTreeEntry(data <-chan byte) (tree_entry, error) {
func parseTreeEntry(data <-chan byte, hashLen int) (tree_entry, error) {
var e tree_entry
for c:=<-data; c != ' '; c=<-data {
e.mode = e.mode * 8 + (c - '0')
for c := <-data; c != ' '; c = <-data {
e.mode = e.mode*8 + int(c-'0')
e.size++
}
for c:=<-data; c != '\x00'; c=<-data {
e.name = append(e.name, c)
e.size++
name := make([]byte, 0, 128)
for c := <-data; c != '\x00'; c = <-data {
name = append(name, c)
e.size++
}
e.size++
e.name = string(name)
const hexBinToAscii = "0123456789abcdef"
hash := make([]byte, 0, hashLen*2)
for range hashLen {
c := <-data
hash = append(hash, hexBinToAscii[((c&0xF0)>>4)], hexBinToAscii[c&0xF])
}
e.hash = string(hash)
e.size += hashLen
return e, nil
}
func parseGitTree(data <-chan byte) (tree, error) {
return tree{}, nil
hdr, err := parseGitMsg(data)
if err != nil {
return tree{}, err
}
// max capacity to length of hash
t := tree{items: make([]tree_entry, 0, hdr.size/len(hdr.hash))}
for parsedLen := 0; parsedLen+1 < hdr.size; {
entry, err := parseTreeEntry(data, len(hdr.hash)/2)
if err != nil {
return tree{}, nil
}
t.items = append(t.items, entry)
parsedLen += entry.size
}
return t, nil
}
func (e *RequestHandler) GitSubmoduleCommitId(cwd, packageName, headId string) (string, bool) {
func (e *RequestHandler) GitSubmoduleCommitId(cwd, packageName, commitId string) (string, bool) {
if e.Error != nil {
return "", false
}
data_in, data_out := ChanIO{make(chan byte, 256)}, ChanIO{make(chan byte, 70)}
var commitId string
var subCommitId string
var foundLock sync.Mutex
foundLock.Lock()
@@ -399,7 +447,8 @@ func (e *RequestHandler) GitSubmoduleCommitId(cwd, packageName, headId string) (
defer foundLock.Unlock()
defer close(data_out.ch)
data_out.Write([]byte("HEAD\n"))
data_out.Write([]byte(commitId))
data_out.ch <- '\x00'
c, err := parseGitCommit(data_in.ch)
if err != nil {
e.Error = err
@@ -407,7 +456,7 @@ func (e *RequestHandler) GitSubmoduleCommitId(cwd, packageName, headId string) (
return
}
data_out.Write([]byte(c.Tree))
data_out.ch <- '\n'
data_out.ch <- '\x00'
tree, err := parseGitTree(data_in.ch)
if err != nil {
@@ -417,8 +466,8 @@ func (e *RequestHandler) GitSubmoduleCommitId(cwd, packageName, headId string) (
}
for _, te := range tree.items {
if te.name == packageName {
commitId = te.hash
if te.name == packageName && te.isSubmodule() {
subCommitId = te.hash
return
}
}
@@ -431,5 +480,5 @@ func (e *RequestHandler) GitSubmoduleCommitId(cwd, packageName, headId string) (
e.Log("command run: %v", cmd.Run())
foundLock.Lock()
return commitId, len(commitId) == len(headId)
return subCommitId, len(subCommitId) == len(commitId)
}