如何识别 git 次提交之间更改了哪些文件

How to identify which files have changed between git commits

我们如何使用 go-git 生成类似于 git diff --name-only commit1 commit2 的两次提交之间更改的所有文件的列表?

对于上下文,我们有一个 git monorepo,它包含一个根 go.mod 文件但包含多个 Go 应用程序。当开发人员将提交推送到分支时,我们希望获得在两次 git 提交 (git diff --name-only) 之间更改的所有文件的列表,并将其过滤到应用程序目录列表​​中,同时排除一些目录.我们的最终目标是我们可以只构建、部署和测试在我们的 monorepo 中发生变化的应用程序。我们有一个 bash script similar to this one from shippable 可以执行此操作,但我们想使用 pure go and go-git.

似乎 change.Files() 只给出了带有 to.Name 的文件的名称,没有存储库中的路径,但是 change.toString() 给出了完整路径。

所以如果你想使用Tree.Diff,你必须得到这样的路径:

func getChangeName(change *object.Change) string {
        var empty = object.ChangeEntry{}
        if change.From != empty {
            return change.From.Name
        }

        return change.To.Name
}

因此,看起来您可以根据需要选择 Tree.DiffPatch.Stats

    currentTree, err := commit.Tree()
    CheckIfError(err)

    prevTree, err := prevCommit.Tree()
    CheckIfError(err)

    patch, err := currentTree.Patch(prevTree)
    CheckIfError(err)
    fmt.Println("----- Patch Stats ------")

    var changedFiles []string
    for _, fileStat := range patch.Stats() {
        fmt.Println(fileStat.Name)
        changedFiles = append(changedFiles,fileStat.Name)
    }

    changes, err := currentTree.Diff(prevTree)
    CheckIfError(err)
    fmt.Println("----- Changes -----")
    for _, change := range changes {
        // Ignore deleted files
        action, err := change.Action()
        CheckIfError(err)
        if action == merkletrie.Delete {
            //fmt.Println("Skipping delete")
            continue
        }
        // Get list of involved files
        name := getChangeName(change)
        fmt.Println(name)
    }

Patch.Stats 将跳过二进制文件,其中 Tree.Diff 让您忽略删除。