.
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user