go - git2go Patch() 仅返回第一个文件的差异

标签 go libgit2

我试图配置rb-gateway (用 Go 编写的简单代理,支持 ReviewBoard 的自定义存储库)。 git2go 是从 next 分支与 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版本go1.4.2 linux/amd64 git版本1.8.3.1 libgit2 和 git2go 最新 Linux 3.10.0-327.4.5.el7.x86_64(CentOS)

最佳答案

您需要发布所有必要的元素来重现您的问题: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 <<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="650104130c014b150c0017060025080a1f4b060a08" rel="noreferrer noopener nofollow">[email protected]</a>>
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)
+   }
+}
$

关于go - git2go Patch() 仅返回第一个文件的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35101616/

相关文章:

c - libgit2 git_checkout_head 和 GIT_CHECKOUT_SAFE 对工作目录没有任何作用

pointers - 显式定义变量地址(在 Go 中)

go - 使用 Go reflect 实例化一个新的 obj 并在接口(interface)中输入 assert

git - "Invalid description in FETCH_HEAD"在 Visual Studio 中 pull/同步

git2go : Listing files with the latest committer and commit date

c++ - 使用 libgit2 进行 git pull merge commit (cpp)

http - Golang : http server leaving open goroutines

go - 从路径列表中删除最长的公共(public)前缀

ajax - 如何在 GAE GO 中实现 AJAX

c - libgit2 如何成功提交文件?