如何将 Git 用于编码智能体工作流¶
原文标题:Using Git with coding agents 原文链接:https://simonwillison.net/guides/agentic-engineering-patterns/using-git-with-coding-agents/ 原文作者:Simon Willison 访问日期:2026-03-25 原文发布日期:2026-03-21 原文最后修改:2026-03-23 译文版本:v0.1
译文说明¶
本文为 Simon Willison《Agentic Engineering Patterns》系列中《Using Git with coding agents》的示范中文版。本文沿用本项目既定术语约定,将 Coding Agent 统一译为“编码智能体”,将 repository 统一处理为“仓库”,并继续保留 Git 命令、参数、路径、提交引用和子命令原文,例如 git commit、git rebase、git cherry-pick、git bisect、git stash、reflog、.git/ 与 HEAD。标题采用“如何将 Git 用于编码智能体工作流”,强调重点不只是 Git 本身,而是 Git 与编码智能体协作时的整套工程实践。
正文¶
Git 是与编码智能体协作时的一项关键工具。把代码放进版本控制里,能让我们记录代码随时间发生的变化,也能调查并撤销任何错误。所有编码智能体都很擅长使用 Git 的能力,不管是基础功能还是高级功能。
正因为它们有这种熟练度,我们自己也可以把 Git 用得更有野心一点。我们不需要把用 Git 做事的“具体步骤”全背下来,但只要始终知道 Git 有哪些可能性,就能把它整套能力都用起来。
Git 基础¶
每一个 Git 项目,都存在于一个 repository 里——也就是磁盘上的一个文件夹,它可以追踪其中各个文件发生的变化。这些变化会被记录为 commits:它们是带有时间戳的一组文件改动,附带一条描述这些改动的 commit message,以及记录是谁做出这次改动的 author 信息。
Git 支持 branches。分支让你可以彼此独立地构建和试验新的改动。等这些改动准备好之后,就可以再把它们用不同方式 merged 回主分支。
Git 仓库可以被 cloned 到另一台机器上,而克隆下来的内容不只是当前文件,还包括完整的历史记录。这意味着开发者——或者编码智能体——都可以直接浏览和探索这些历史,而不需要额外网络流量,所以“下潜翻历史”这件事几乎是零成本的。
Git 仓库可以只存在于你自己的机器上,但 Git 本身就是为协作和备份而设计的:你可以把它发布到一个 remote 上,而这个 remote 可以是公开的,也可以是私有的。GitHub 是这类 remote 最常见的托管地点,但 Git 本身是开源软件;只要某台机器或某项服务支持 Git 协议,就都可以托管这种 remote。
核心概念与 Prompt¶
编码智能体对 Git 术语都有很深的理解。下面这些 Prompt,几乎对任何一款编码智能体都适用。
初始化仓库¶
如果你想把当前文件夹变成一个 Git 仓库,可以让智能体去做这件事——它多半会运行 git init。如果你只说一句 “repo”,智能体一般也会默认你指的是 Git repository。
提交改动¶
你也可以让它创建一个新的 Git commit,把刚才做出的改动记录下来——通常会用到 git commit -m "commit message"。
配置 GitHub¶
你还可以让它把当前仓库配置到 GitHub 上。这一步通常要求你先去 github.com/new 创建一个新的 repo,然后把你的机器配置成可以和 GitHub 通信。
查看最近历史¶
你也可以直接说 “recent changes” 或 “last three commits”。
这是开启一轮全新编码智能体会话的极佳方式。告诉智能体去查看最近改动,它通常就会运行 git log,并立刻把你最近在做什么的上下文加载进来——既包括代码本身的改动,也包括描述这些改动的 commit messages。
像这样给一轮会话“预热”,会让你可以直接接着讨论那段代码:继续提额外修复、问它这段代码是怎么工作的,或者提出建立在前面基础之上的下一步修改。
拉取 main 上的最新改动¶
你可以在主分支上运行这一类指令,从 remote 获取其他人最新提交的内容;或者在某个分支里运行它,把 main 上的最新变化并进来。
把当前分支合入 main¶
合并改动有很多方法,包括 merge、rebase、squash 或 fast-forward。如果你一时记不清这些细节,也没关系。
智能体很擅长解释不同合并策略各自的优缺点,而且 Git 里的很多操作本来就总是可以撤销,所以尝试一些新做法的风险其实很低。
修复合并冲突¶
这是一个出乎意料地通用、而且我自己经常会用到的 Prompt。这里有一个最近的例子:我有一次 cherry-pick 因为 merge conflict 失败了,它替我把问题收拾干净了。
Git 有很多种把自己搞乱的方式:比如一次 pull 或 rebase 最后撞进了 merge conflict,又或者只是把不该加进去的东西塞进了 Git 的 staging 环境里。
以前,要把这些乱局拆开理顺,往往是使用 Git 时最困难、也最耗时的部分。现在不一样了。编码智能体可以穿过那些极其绕的 merge conflicts,一边推断新代码原本的意图,一边判断哪些内容应该保留、冲突改动又应该怎样组合。如果你的代码有自动化测试——而且它本来就应该有——那智能体还可以在最终完成这次合并之前,确保测试全部通过。
我把代码弄丢了,帮我找回来¶
如果你丢掉了一段正在写的代码,但它之前已经 commit 过,或者至少曾经用 git stash 存过一次,智能体大概率能帮你找回来。
Git 有一个叫 reflog 的机制,它往往能捕捉到那些还没落到永久分支上的代码痕迹。智能体可以去搜这个 reflog,也可以顺着其他分支一起找。
你只要告诉它该找什么,然后看它一头扎进历史里去翻就行。
用 Git bisect 找出这个 bug 是从什么时候引入的¶
Git bisect 是 Git 武器库里最强大的调试工具之一,但它的学习曲线也相对更陡,这让很多开发者始终没有真正把它用起来。
当你运行一次 bisect 操作时,你需要先告诉 Git 一个测试条件,再给出开始和结束的 commit 范围。然后 Git 会执行二分搜索,找出最早那个会让测试条件失败的 commit。
这可以非常高效地回答“到底是哪一次改动最先引入了这个 bug”这个问题。它唯一的缺点在于:你得先把这个 bug 的测试写成 Git bisect 能执行的形式。
编码智能体可以替你处理这层样板工作。这样一来,Git bisect 就不再只是一个偶尔才会想起的工具,而会变成只要你对软件的历史行为产生好奇,就随时可以调用的武器。
重写历史¶
下面来聊点真正有意思的高级玩法。
Git 仓库的 commit history 并不是固定不变的。毕竟这些数据说到底也只是磁盘上的文件——都藏在那个隐藏的 .git/ 目录里——而 Git 自己就提供了一整套可以修改历史的工具。
不要把 Git 历史理解成“真实发生过什么”的永久记录;更好的理解方式,是把它看成一段经过刻意编排的叙事,用来描述这个软件项目是怎样一步步走到今天的。
而这段叙事,本身就是帮助未来继续开发的一种工具。把错误、走偏的方向以及后来取消的尝试永久记下来,有时候当然有用;但仓库作者同样也可以做出带编辑性质的判断:哪些内容值得保留,以及怎样记录这段历史才最有帮助。
编码智能体非常擅长使用 Git 的这些高级历史重写能力。
撤销或重写提交¶
写完代码、commit 之后又后悔,这种事太常见了。比如你忽然发现,这次提交里混进了一个本来不该包含的文件。对应的 Git 食谱是 git reset --soft HEAD~1。这个命令我以前一直记不住,而现在我也不需要再记住它了。
你还可以对提交做更细粒度的手术。比如,你可以重写一次提交,只把其中某一个文件移除掉。
智能体也可以替你改写 commit messages,或者把多个 commits 合并成一个整体。
我发现,前沿模型在 commit messages 上通常都挺有品味。我以前坚持这些一定要自己写,但现在我已经接受:它们给出的质量通常已经足够好,而且很多时候甚至比我自己写得还好。
从旧仓库的零散部分搭出一个新仓库¶
有一个技巧我自己相当常用:从一个更大的仓库里,把一部分代码提取出来,放进一个新的仓库,同时尽量保留那部分代码关键的历史。
一个很常见的例子,就是做 library extraction。你可能一开始把一些类和函数直接写在某个项目里,后来才发现,把它们抽出来做成一个独立、可复用的代码库,其实更合理。
这种操作以前复杂到一个程度:多数开发者最后会干脆复制一份全新的代码,把它和旧的 commit history 彻底切断。现在我们已经不必再接受这种妥协了。