git2go Patch()仅返回第一个文件的diff

时间:2016-01-30 12:10:21

标签: go libgit2

我正在尝试配置rb-gateway(用Go编写的简单代理,它支持ReviewBoard的自定义存储库)。 git2go是从下一个分支与 libgit2 一起构建的。 在diff的生成补丁期间出现问题。下面的代码仅返回第一个文件更改。

package main

import (
    "github.com/libgit2/git2go"
    "log"
)

func main() {
    gitRepo, err := git.OpenRepository("repo_path")
    if err != nil {
        log.Fatal(err)
    }

    commitOid, err := git.NewOid("commit_id_sha1")
    if err != nil {
        log.Fatal(err)
    }

    commit, err := gitRepo.LookupCommit(commitOid)
    if err != nil {
        log.Fatal(err)
    }

    commitTree, err := commit.Tree()
    if err != nil {
        log.Fatal(err)
    }

    options, err := git.DefaultDiffOptions()
    if err != nil {
        log.Fatal(err)
    }

    // Specifying full patch indices.
    options.IdAbbrev = 40

    var parentTree *git.Tree
    if commit.ParentCount() > 0 {
        parentTree, err = commit.Parent(0).Tree()
        if err != nil {
            log.Fatal(err)
         }
    }

    gitDiff, err := gitRepo.DiffTreeToTree(parentTree, commitTree, &options)
    if err != nil {
         log.Fatal(err)
    }

    patch, err := gitDiff.Patch(0)
    if err != nil {
        log.Fatal(err)
    }

    patchString, err := patch.String()
    if err != nil {
         log.Fatal(err)
    }

    log.Printf("%s", patchString)

    patch.Free()
}

环境: go version go1.4.2 linux/amd64 git version 1.8.3.1 libgit2 and git2go latest Linux 3.10.0-327.4.5.el7.x86_64 (CentOS)

1 个答案:

答案 0 :(得分:2)

您需要发布所有必要的元素来重现您的问题:How to create a Minimal, Complete, and Verifiable example。这包括输入和预期输出。

例如,以可重现的形式,在提交中显示所有文件补丁差异:

patchdiffs.go

package main

import (
    "github.com/libgit2/git2go"
    "log"
)

/*
github.com/libgit2/git2go
commit 80cf533fe4e48ddfab3015d9570f2833951c1dea
Author: David Pierce <david.pierce@moz.com>
Date:   Sat Sep 26 15:37:48 2015 -0700

    Config#LookupString uses git_buf to load value

 config.go      |  8 +++++---
 config_test.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 3 deletions(-)
*/

func main() {
    // After go get -v github.com/libgit2/git2go
    // path to git2go repository in your $GOPATH
    repoPath := `/home/peter/gopath/src/github.com/libgit2/git2go`
    gitRepo, err := git.OpenRepository(repoPath)
    if err != nil {
        log.Fatal(err)
    }
    // commit SHA-1 checksum
    commitID := `80cf533fe4e48ddfab3015d9570f2833951c1dea`
    commitOid, err := git.NewOid(commitID)
    if err != nil {
        log.Fatal(err)
    }
    commit, err := gitRepo.LookupCommit(commitOid)
    if err != nil {
        log.Fatal(err)
    }
    commitTree, err := commit.Tree()
    if err != nil {
        log.Fatal(err)
    }
    options, err := git.DefaultDiffOptions()
    if err != nil {
        log.Fatal(err)
    }
    options.IdAbbrev = 40
    var parentTree *git.Tree
    if commit.ParentCount() > 0 {
        parentTree, err = commit.Parent(0).Tree()
        if err != nil {
            log.Fatal(err)
        }
    }
    gitDiff, err := gitRepo.DiffTreeToTree(parentTree, commitTree, &options)
    if err != nil {
        log.Fatal(err)
    }

    // Show all file patch diffs in a commit.
    numDeltas, err := gitDiff.NumDeltas()
    if err != nil {
        log.Fatal(err)
    }
    for d := 0; d < numDeltas; d++ {
        patch, err := gitDiff.Patch(d)
        if err != nil {
            log.Fatal(err)
        }
        patchString, err := patch.String()
        if err != nil {
            log.Fatal(err)
        }
        log.Printf("\n%s", patchString)
        patch.Free()
    }
}

输出:

$ go run patchdiffs.go
2016/01/30 18:35:44 
diff --git a/config.go b/config.go
index 9d25e3571de22b4121d66bb88949d0e292f1a836..c4c40281abb85a861ba1bf760011e2990cf151b3 100644
--- a/config.go
+++ b/config.go
@@ -115,18 +115,20 @@ func (c *Config) LookupInt64(name string) (int64, error) {
 }

 func (c *Config) LookupString(name string) (string, error) {
-   var ptr *C.char
    cname := C.CString(name)
    defer C.free(unsafe.Pointer(cname))

+   valBuf := C.git_buf{}
+
    runtime.LockOSThread()
    defer runtime.UnlockOSThread()

-   if ret := C.git_config_get_string(&ptr, c.ptr, cname); ret < 0 {
+   if ret := C.git_config_get_string_buf(&valBuf, c.ptr, cname); ret < 0 {
        return "", MakeGitError(ret)
    }
+   defer C.git_buf_free(&valBuf)

-   return C.GoString(ptr), nil
+   return C.GoString(valBuf.ptr), nil
 }

 func (c *Config) LookupBool(name string) (bool, error) {
2016/01/30 18:35:44 
diff --git a/config_test.go b/config_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..e4a2c1f310f1beb9bcb70be50320c53e22417e2a
--- /dev/null
+++ b/config_test.go
@@ -0,0 +1,58 @@
+package git
+
+import (
+   "os"
+   "testing"
+)
+
+func setupConfig() (*Config, error) {
+   var (
+       c   *Config
+       err error
+       p   string
+   )
+
+   p, err = ConfigFindGlobal()
+   if err != nil {
+       return nil, err
+   }
+
+   c, err = OpenOndisk(nil, p)
+   if err != nil {
+       return nil, err
+   }
+
+   c.SetString("foo.bar", "baz")
+
+   return c, err
+}
+
+func cleanupConfig() {
+   os.Remove(tempConfig)
+}
+
+func TestConfigLookupString(t *testing.T) {
+   var (
+       err error
+       val string
+       c   *Config
+   )
+
+   c, err = setupConfig()
+   defer cleanupConfig()
+   if err != nil {
+       t.Errorf("Setup error: '%v'. Expected none\n", err)
+       t.FailNow()
+   }
+   defer c.Free()
+
+   val, err = c.LookupString("foo.bar")
+   if err != nil {
+       t.Errorf("Got error: '%v', expected none\n", err)
+       t.FailNow()
+   }
+
+   if val != "baz" {
+       t.Errorf("Got '%s', expected 'bar'\n", val)
+   }
+}
$