2016-02-12 67 views
0

我正在嘗試使用pure go解包git pack file。我能找到的唯一lib是github.com/jbrukh/ggit/api -> parse,但我很難弄清楚它應該如何工作。 基本上我需要的是提供包文件的主體並獲取git對象(我假設它使用zlib進行壓縮)。我嘗試了幾種方法,包括分叉和嘗試使用私有函數,但沒有成功(即它恐慌)。如何用Go解包git pack文件?

package main 

import(

    log "github.com/golang/glog" 
    "io/ioutil" 
    "bytes" 
    "bufio" 
    "flag" 
    "os" 
    "github.com/jbrukh/ggit/api/parse" 
) 

func main(){ 
    flag.Parse() 
    defer log.Flush() 
    packPath := "/Users/user/go/src/gopath/test_pack_no_header" 
    b, err := ioutil.ReadFile(packPath) 
    if err !=nil{ 
     panic(err) 
    } 
    sha := "9eabf5b536662000f79978c4d1b6e4eff5c8d785" 

    reader := bufio.NewReader(bytes.NewBuffer(b)) 
    openner := func()(*os.File, error){ 
     return os.Open(packPath) 
    } 
    po := parse.NewPackIdxParser(reader, openner, sha) 
    if err !=nil{ 
     log.Error(err) 
     return 
    } 
    pack := po.ParsePack() 
    log.Error("oo is %s", pack) 

} 

恐慌:

go run main.go -logtostderr 
panic: expected string: �tOc 

goroutine 1 [running]: 
github.com/jbrukh/ggit/util.PanicErrf(0x1d4b30, 0x13, 0xc8200537d8, 0x1, 0x1) 
    /Users/user/go/src/github.com/jbrukh/ggit/util/data_parser.go:72 +0x63 
github.com/jbrukh/ggit/util.(*DataParser).ConsumeString(0xc820086380, 0x1b3910, 0x4) 
    /Users/user/go/src/github.com/jbrukh/ggit/util/data_parser.go:226 +0x1a5 
github.com/jbrukh/ggit/api/parse.(*packIdxParser).parseIdx(0xc820053ed0, 0xc820053ba0) 
    /Users/user/go/src/github.com/jbrukh/ggit/api/parse/pack.go:320 +0x66 
github.com/jbrukh/ggit/api/parse.(*packIdxParser).ParsePack(0xc820053ed0, 0xc820086380) 
    /Users/user/go/src/github.com/jbrukh/ggit/api/parse/pack.go:400 +0x4e 
main.main() 
    /Users/user/go/src/gopath/tools/main.go:33 +0x450 
exit status 2 
exit status 1 
2016-02-12 16:28:16.322504062 +0200 EET 

注:我需要解壓只包文件,並在嘗試上面的例子我沒有IDX文件。

+0

張貼恐慌。 – OneOfOne

+0

恐慌貼:完成! –

+0

另請參閱https://github.com/libgit2/git2go – elithrar

回答

0

爲了什麼值得我用蠻力的方法結束了。不是一個強大的解決方案,但它適用於我需要的東西(解碼已知對象類型的包文件)。

package main 

import(
    "compress/zlib" 
    log "github.com/golang/glog" 
    "io/ioutil" 
    "bytes" 
    "flag" 
    "io" 
) 

func main(){ 
    flag.Parse() 
    defer log.Flush() 
    packPath := "/Users/usr/test_pack_no_header" 
    b, err := ioutil.ReadFile(packPath) 
    if err !=nil{ 
     panic(err) 
    } 
    buf := bytes.NewBuffer(b) 

    i := 0 
    for { 
     decoded, err := readObjectRaw(bytes.NewBuffer(buf.Bytes())) 
     if err ==nil{ 
      log.Errorf("i %v, decoded is %s", i, decoded) 
      //return 
     } 
     if _, err = buf.ReadByte(); err == io.EOF{ 
      log.Errorf("EOF") 
      return 
     } 
     i++ 
    } 

} 


func readObjectRaw(reader io.Reader)([]byte, error){ 
    r, err := zlib.NewReader(reader) 
    if err !=nil{ 
     //log.Error(err) 
     return nil, err 
    } 
    defer r.Close() 
    def := bytes.NewBuffer(nil) 
    _, err = io.Copy(def, r) 
    if err !=nil{ 
     //log.Errorf("%v bytes copied, err %v", i, err) 
     return nil, err 
    } 
    return def.Bytes(), nil 
}