第 07 篇

与编程智能体协作时如何使用 Git

Simon Willison 介绍如何用自然语言让编程智能体操作 Git,涵盖提交、同步、冲突处理、代码恢复、二分定位缺陷和重写历史。

Hex4C59 6 分钟阅读 更新于 2026-10-14

译文信息

本文为非官方中文译文,依据提供的原文正文翻译,并按系列目录补入小节标题。正文中的「我」及智能体能力、Git 操作可撤销性等判断均指原作者。命令、路径和提示词用于说明原文做法,译者未执行这些操作。

Git 是与编程智能体协作的重要工具。把代码纳入版本控制,让我们能够记录代码随时间发生的变化,查明错误,并撤销错误改动。各种编程智能体都熟悉 Git 的功能,包括基础操作和高级操作。

正因为它们如此熟练,我们自己使用 Git 时也可以尝试更多做法。我们不必记住每项 Git 操作的具体方法,但只要知道它能做什么,就能充分利用它的各项能力。

Git 基础知识 #

每个 Git 项目都保存在一个仓库(repository)中。仓库是磁盘上的一个文件夹,能够跟踪其中的文件变化。这些变化记录在提交(commit)里。每个提交包含一个或多个文件的一组改动、时间戳、描述改动的提交信息,以及记录是谁做出改动的作者信息。

Git 支持分支(branch),让你能够相互独立地开发和试验不同的改动。准备好后,便可以通过不同的方式,把这些分支合并回主分支。

Git 仓库可以克隆到另一台计算机上。克隆副本既包含当前文件,也包含它们完整的变更历史。因此,开发者或编程智能体可以在不产生额外网络流量的情况下浏览和探索这些历史,查阅历史的成本几乎为零。

Git 仓库可以只保存在自己的计算机上,但 Git 也支持把仓库发布到公开或私有的远端(remote),以便协作和备份。GitHub 是最常用的远端托管平台。不过,Git 是开源软件,任何支持 Git 协议的计算机或服务都可以托管远端仓库。

核心概念与提示词 #

编程智能体都很熟悉 Git 术语。下面这些提示词,应该对任何一种编程智能体都适用。

在这里新建一个 Git 仓库。

这会把智能体当前工作的文件夹变成 Git 仓库。它很可能会运行 git init 命令。即使你只说「repo」,智能体也会理解为 Git 仓库。

提交这些改动。

创建一个新的 Git 提交,记录智能体做出的改动。它通常会使用 git commit -m "commit message" 命令。

把 username/repo 添加为 GitHub 远端。

这应该会为仓库配置 GitHub 远端。你需要先通过 github.com/new 创建一个新仓库,并配置好计算机与 GitHub 的连接。

审查今天做出的改动。

也可以说「最近的改动」或「最后三个提交」。

这是开始一个新的编程智能体会话的好方法。让智能体查看最近的改动,会促使它运行 git log,迅速把你最近的工作细节载入上下文,包括修改过的代码,以及描述这些改动的提交信息。

用这种方式为会话提供初始背景后,你就可以直接讨论这些代码:提出进一步的修复建议、询问它如何工作,或者提出基于此前工作的下一项改动。

整合 main 的最新改动。

在主分支上使用这条提示词,可以从远端仓库获取其他人贡献的改动;在其他分支上使用,则可以整合 main 上的最新改动。

整合改动有多种方式,包括合并(merge)、变基(rebase)、压缩合并(squash)和快进(fast-forward)。如果记不清它们的细节,也没关系:

讨论整合 main 改动的几种方案。

智能体很擅长解释不同合并策略的优缺点。Git 中的操作总能撤销,因此尝试新做法的风险很小。

帮我把这团 Git 乱麻理清楚。

我使用这条通用提示词的频率高得出乎意料!这是最近的一个例子:智能体帮我修复了一次因合并冲突而失败的 cherry-pick,也就是把指定提交应用到当前分支的操作。

有很多事情会让 Git 状态变得混乱。常见的情况是拉取或变基操作出现合并冲突,或者只是把不该加入的东西放进了 Git 暂存区。

过去,理清这些状况往往是使用 Git 时最困难、最耗时的部分。现在不一样了!编程智能体能够处理极其复杂的合并冲突,分析新代码的意图,判断哪些内容应该保留,以及如何组合相互冲突的改动。如果你的代码有自动化测试——而且它应该有——智能体还可以在最终完成合并之前,确保测试通过。

找回我那段用于……的代码。

如果丢失的代码以前提交过,或者用 git stash 暂存过,智能体很可能可以帮你找回来。

Git 有一种称为 reflog 的机制,用于记录引用的变动。它往往能留下尚未进入长期保留分支的代码线索。智能体可以搜索这些记录,也可以搜索其他分支。

只要告诉它们要找什么,然后看它们深入查找即可。

使用 git bisect 找出这个缺陷是在哪次改动中引入的:……

git bisect 是 Git 最强大的调试工具之一,但它的学习门槛相对较高,常常让开发者望而却步。

进行 bisect 操作时,你需要给 Git 提供一个测试条件,以及由起点和终点提交确定的范围。随后,Git 会通过二分查找,找出最早导致测试条件失败的提交。

这能够高效地回答「最初是什么引发了这个缺陷」。唯一的麻烦,是需要把判断缺陷的测试写成 git bisect 可以执行的形式。

编程智能体可以替你完成这些准备工作。这样,git bisect 就从一个偶尔使用的工具,变成了只要你想了解软件过去的行为,就随时可以用上的工具。

重写历史 #

接下来,聊聊有趣的高级用法。

Git 仓库的提交历史并非不可更改。毕竟,这些数据只是藏在磁盘上 .git/ 隐藏目录里的文件,而 Git 本身就提供了修改历史的工具。

不要把 Git 历史看成一份永远不能改动的事实记录。可以把它看成经过精心编排的故事,用来讲述软件项目如何一步步发展。

这个故事是辅助未来开发的工具。有时,永久记录错误和后来放弃的方向会有帮助,但仓库作者也可以像编辑一样,决定保留什么,以及怎样记录这段历史最合适。

编程智能体非常擅长使用 Git 的高级历史重写功能。

撤销或重写提交 #

撤销最后一个提交。

提交代码后又后悔,是很常见的事。比如,你发现提交里包含了一个原本不想加入的文件。对应的 Git 命令是 git reset --soft HEAD~1。我一直记不住这个命令,而现在也不必记了!

从最后一个提交中移除 uv.lock。

你也可以对提交做更精细的调整,比如重写提交,只从中移除一个文件。

把最后三个提交合并成一个,并写一条更好的提交信息。

智能体可以重写提交信息,也可以把多个提交合并成一个。

我发现,前沿模型通常很会写提交信息。我过去坚持亲自写,但如今已经接受,它们写出的质量一般足够好,而且往往比我自己写的还好。

从旧仓库中提取代码,创建新仓库 #

我经常使用的一项技巧,是把代码从较大的仓库中提取出来,放进一个新仓库,同时保留这些代码的关键历史。

一个常见的例子是提取代码库。我可能已经在某个项目里写了一些类和函数,后来才意识到,把它们做成独立、可复用的代码库更合适。

在 /tmp/distance-functions 新建一个仓库,把这里的 lib/distance_functions.py 模块做成一个 Python 库。为新仓库构建相似的提交历史,并复制原有的作者和提交日期。

过去,这类操作复杂到大多数开发者宁可新建一个副本,与原来的提交历史脱离。现在,我们不必再满足于这种做法了!

一起讨论

选中正文中的文字,可以针对这段内容发起讨论。

正在读取讨论…

在 GitHub 查看与管理讨论 ↗

文章讨论