如何使用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
相关产品推荐
相关产品推荐

