You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用go-git编程检测工作区未提交的变更?

用go-git检测工作区未提交变更的实现思路

go-git完全支持识别和查看工作区未提交的变更,核心是利用Worktree的两个关键方法,无需依赖用于提交间对比的Patch API:

1. 快速获取变更状态

通过Worktree.Status()方法可以直接拿到工作区所有文件的变更类型,包括新增、修改、删除、未追踪等,返回的Status结构体以文件路径为键,值包含该文件的具体状态信息。

示例代码片段:

repo, err := git.PlainOpen("/path/to/your/repo")
if err != nil {
    // 处理错误逻辑
}
wt, err := repo.Worktree()
if err != nil {
    // 处理错误逻辑
}

status, err := wt.Status()
if err != nil {
    // 处理错误逻辑
}

// 遍历所有变更条目
for filePath, entry := range status {
    switch entry.Status {
    case git.Added:
        fmt.Printf("新增文件:%s\n", filePath)
    case git.Modified:
        fmt.Printf("修改文件:%s\n", filePath)
    case git.Deleted:
        fmt.Printf("删除文件:%s\n", filePath)
    case git.Untracked:
        fmt.Printf("未追踪文件:%s\n", filePath)
    // 按需处理重命名、复制等其他状态
    }
}

2. 获取详细Diff补丁内容

如果需要查看文件的具体修改内容(类似git diff的输出),可以用Worktree.Diff()方法,通过指定基准树(比如HEAD)和目标(工作区)来生成完整的补丁信息。

示例代码片段:

// 获取HEAD对应的提交树
headRef, err := repo.Head()
if err != nil {
    // 处理错误逻辑
}
headCommit, err := repo.CommitObject(headRef.Hash())
if err != nil {
    // 处理错误逻辑
}
headTree, err := headCommit.Tree()
if err != nil {
    // 处理错误逻辑
}

// 生成工作区与HEAD的diff
diff, err := wt.Diff(&git.DiffOptions{
    From: headTree,
    To:   nil, // nil代表使用当前工作区内容
})
if err != nil {
    // 处理错误逻辑
}

// 输出具体变更内容
for _, patch := range diff {
    fmt.Println(patch.String())
}

额外注意事项

  • 新初始化的仓库(无任何提交)不存在HEAD,需提前判断该场景避免报错
  • 若要检测暂存区(已git add但未commit)的变更,可将DiffOptions的Cached参数设为true,此时To会指向暂存区内容
  • Status()方法还会检测文件权限变更、符号链接变更等细节,可通过entry.WorktreeFile获取更多文件元信息

内容的提问来源于stack exchange,提问作者Durval Carvalho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 22:36:20