代码提交与版本保存
了解 Git 的工作区、暂存区与提交机制。每当一个功能调试正常,让 AI 及时创建提交保存代码快照,后续改出问题时就能随时安全恢复。
这门课程会学习什么
这门课面向借助 AI Agent 开发网页或软件的初学者。整个流程从保存一个正常运行的功能开始,逐步经历检查代码改动、新建分支尝试新想法、合并代码与解决冲突,再到把项目同步到 GitHub 远程协作与撤销反悔。我们不需要在黑盒终端里手动敲击复杂的命令,而是学会用自然语言把需求准确地告诉 AI Agent,并掌握看懂它返回状态与底层动作的能力。
课程中的所有操作都以自然语言对话为主。我们要学会判断 Agent 改了哪些文件、记录了哪个版本,以及有没有上传到远程。
- 存版本第 1–2 章
- 管分支第 3–4 章
- 协远程第 5–6 章
整门课程分为存版本、管分支与协远程三个阶段。我们将通过一个实际项目,从本地记录第一份代码快照开始,逐步掌握分支管理与多人远程协作。
有了 AI,为什么还需要 Git
借助 AI 编写或修改代码时,我们经常会遇到这样的情况:原本运行正常的登录功能,只是让 AI 调整一下按钮样式,它却在改动样式的同时误改了提交逻辑。此时如果只对 AI 说“改回去”,它未必能准确找回原本的代码。
如果在调整样式之前,我们已经用 Git 记录了正常的版本,就能清楚看到这次修改究竟改变了哪些文件和代码行,并且可以选定已记录的内容来恢复。
Git 是版本管理工具,用来记录和比较项目文件的版本,并在需要时恢复已记录的内容。 一个人做项目也用得上:验证好一个小功能,就留下一个提交;下一次尝试失败时,不必靠记忆让 AI 重写。
平时我们习惯把前后版本叫做 V1、V2,但 Git 并不会自动按这种序号命名,而是用一串唯一的哈希值来标识每次提交,并附带一行修改说明。另外,Git 不会自动保存每一次敲击键盘的编辑;只有执行过提交的文件,之后才能找回。至于数据库里的订单记录、第三方的云端配置等,并不包含在代码快照里。
改动前可以对 Agent 说:“登录功能现在测试能用了。先检查当前改动,帮我把已验证的代码提交保存一下,确认提交完成再去调整样式。”需要恢复时,要明确目标版本和文件范围,第六章会区分几种恢复方式。
Git 和 GitHub 有什么区别
是安装在电脑上的软件。本地查看差异、创建提交和恢复已记录文件,都可以在没有 GitHub 账号、没有网络的情况下完成。安装 Git 也不会自动把项目上传到云端。
GitHub 是云端的代码托管与协作平台。你可以把本地仓库的提交推送到 GitHub;有读取权限的人可以克隆或拉取它,团队还可以围绕分支发起 Pull Request、审查改动。GitHub 上新建仓库也不会自动得到你电脑里的文件。
- 我的电脑 · Gitcommit 留在本地仓库;执行 push,才把提交传到下一站。
- 云端 · GitHub保存已推送的提交;有读取权限的同事可用 clone 获取仓库。
- 同事电脑 · Git得到独立的本地副本;以后按需拉取远程更新,再继续修改。
Git 本身也支持远程协作,GitHub 是常见的托管选择,并非唯一选择。只在本机 commit 后,同事不会自动收到更新;还要完成远程关联、认证和 push,具体操作在第五章。需要回查定义时,见 GitHub 官方的 Git 与 GitHub 说明。
怎样安装 Git,确认它能用
我们可以直接在有本机操作能力的 AI Agent 对话框里说:
“帮我检查这台电脑有没有安装 Git。如果没有,按我的系统完成安装;安装完成后运行 git --version,把版本号告诉我。”
Agent 会在后台检查系统环境并完成配置。我们只需要核对它的回复中是否包含以 git version 开头的版本信息(例如 git version 2.39.5),这就说明当前环境已经能正常找到 Git。
如果 Agent 提示命令未找到,可以让它进一步检查系统的命令搜索路径;普通聊天窗口如果不能直接操作电脑,也可以按 Agent 提供的安装说明完成系统对应的安装程序。安装 Git 与登录 GitHub 是两件事,此时不需要先登录账号。
怎样让当前项目开始使用 Git
Git 安装到电脑后,不会自动对每个文件夹做版本管理。先在编辑器中打开要长期维护的项目根目录,例如项目目录 my-project,确认左侧文件列表里是该项目的源文件。不要在整个桌面或用户目录里初始化。
我们直接对 Agent 这样表达:
“帮我初始化这个项目的 Git。先确认当前目录是否已经是仓库;如果不是才初始化,初始分支用 main。暂时不要提交或推送,完成后告诉我仓库根目录、分支和文件状态。”
了解 Agent 的底层操作:
- Agent 首先会运行
git status检查现状;如果已属于仓库,便不会重复初始化。 - 如果确认不是仓库,Agent 底层会执行
git init -b main。这里的-b main指定了初始分支名为 main。 - 初始化完成后,Agent 会反馈当前状态:显示
On branch main、No commits yet,未被忽略的新文件会列在Untracked files下,含义是“仓库已建立,但还没有产生任何提交快照”。
- 未初始化已有网页文件,但没有仓库。status:not a git repository。下一步:git init -b main。
- 已初始化 · 0 次提交新增 .git;status:On branch main / No commits yet。接下来检查文件、add,再 commit。
- 完成首次提交 · 1 次提交log 中出现哈希与说明。若全部待记录内容已提交且没有其他变化,status 显示 working tree clean。
初始化只为当前项目建立版本管理记录,不改动网页代码,不创建 GitHub 仓库,也不会自动生成第一次提交。如果是通过 clone 下载的已有仓库,通常已经包含这些记录,直接让 Agent 检查状态即可。
初始化后多出来的 .git,里面存了什么
按上面的初始化方式,项目根目录会多一个隐藏的 .git 文件夹。在编辑器或系统文件管理器中开启“显示隐藏文件”就能看到它。它不只是配置文件夹,还保存了本项目的全部版本管理数据与快照历史。
- src/components/LoginForm.tsx:当前登录表单
- src/styles.css:当前样式
- 普通保存更新这些文件,不会自动生成提交
- objects:文件内容、目录快照与提交对象
- refs / HEAD:分支记录与当前检出位置
- index:暂存区记录
- config / logs:仓库设置与引用移动记录
图中列的是常见存储位置:objects 保存文件内容、目录快照和提交记录等对象;refs 记录分支等引用,HEAD 标明当前检出位置;index 保存暂存区记录,config 保存本仓库设置,logs 可记录引用的移动。它们随操作逐步产生,刚 init 时并不一定全部存在,也还没有任何已提交版本。
我们日常编写和修改的是网页源文件,.git 目录则由 Git 命令自动维护。千万不要把它当作临时缓存删掉:只保存在本机、尚未推送到远程的历史记录都会因此丢失。在第六章介绍的独立工作目录中,.git 也可能是一个指向实际存储位置的引用文件。平时我们只需要知道它负责存盘,不需要手动修改其内部文件。
第一次提交前,怎样设置作者身份
在第一次创建提交之前,我们还需要完成一项基础设置:作者身份配置(git config)。许多初学者在第一次尝试保存版本时,终端会弹出一行拦截提示:Author identity unknown: Please tell me who you are。这是因为 Git 的每一份提交快照都必须明确记录责任人。如果此前从未设置过身份,Git 就不知道在提交记录中该署上谁的名字。
你可以直接对 Agent 说:
“帮我配置一下当前项目的 Git 提交身份,名字用‘你的名字’,邮箱用‘你的邮箱@example.com’。配置完成后查询一下确认结果。”
Agent 底层会执行对应的设置命令:
- 设置作者名字:
git config user.name "你的名字" - 设置作者邮箱:
git config user.email "你的邮箱@example.com"
完成后 Agent 会通过查询命令核对结果。如果希望它们成为所有项目的默认配置,可以告诉 Agent 加上全局设置(--global)。这里设置的是提交的作者签名,不是 GitHub 登录密码。
文件在 Git 里的四个区域
在借助 AI 编写项目时,我们通常会打开一个像 Cursor、VS Code 或 Windsurf 这样的软件,这类软件被称为代码编辑器。编辑器的界面一般包含三个主要部分:左侧是项目文件列表,展示当前目录包含哪些文件;中间是代码编辑窗口,像记事本一样展示并修改具体文件的内容;侧边则是我们与 AI Agent 对话的窗口。
当我们让 AI 生成代码,或者自己手动修改了几行内容后,按快捷键(Ctrl+S 或 Cmd+S)保存文件,改动只是写进了电脑硬盘上的普通文件里,这就像在文档软件里保存了一次修改。很多初学者的误区在于,以为文件保存了,Git 就自动记录了历史。事实并非如此:普通的保存操作只是覆盖了本地磁盘上的上一版文字;如果不经过 Git 的专门记录,Git 就不能据此恢复刚才的状态;编辑器自己的本地历史或备份是另外的机制。
- 文件内容直接被最新一次编辑覆盖
- 如果 AI 误改原有逻辑,上一版内容直接丢失
- 没有版本编号,不能回到历史状态
- git add:挑选改好的文件,登记到待提交清单
- git commit:生成带有唯一哈希值的版本快照
- 后续即使代码改乱,也能随时按编号完整找回
把日常保存与 Git 记录区分开来,我们可以把它们看作两道分工明确的工序:日常保存只负责更新当前磁盘文件,随时可能被下一次编辑覆盖;而 Git 的记录流程则是在这之上建立一套独立的存档系统。
在 的运行机制中,文件主要在四个区域之间流动:
第一是工作区(Working Tree)。在物理层面,工作区就是我们电脑硬盘上的真实项目文件夹(例如桌面上建好的项目目录)。我们在编辑器左侧文件列表看到的、在中间窗口正在阅读和修改的,以及在电脑文件管理器里能点开的项目文件,都在这里;隐藏的 .git 则保存 Git 的管理数据。这里就像我们的日常工作台,我们和 AI 可以随时修改或测试代码。
第二是暂存区(Staging Area / Index)。它记录准备进入下一次提交的文件内容,相当于一份待提交的清单。执行 git add 时,Git 保存的是文件当时的内容,而不只是勾选文件名。例如登录按钮先写成“登录”,add 后又改成“登录中”,普通 git commit 记录的仍是“登录”。想提交后来的文字,需要再次 add;同一个文件也可以只有部分改动进入暂存区。
第三是本地仓库(Local Repository)。本地仓库保存本机已经记录的项目版本。当我们在项目根目录初始化 Git 时,电脑中会生成一个隐藏的 .git 文件夹,本地仓库就存放在这里。确认暂存内容正确后,执行 git commit,Git 就会按暂存区记录生成项目快照,并保存修改说明。只要对应提交还在仓库中,就能恢复那次记录的文件内容;这不包含未提交的后续编辑。
第四是远程仓库(Remote Repository)。远程仓库是放在另一台机器上的仓库,例如托管在 GitHub 上的项目仓库。通过推送操作(git push),我们把本地仓库里的提交记录上传到云端。推送成功的提交可以从远程取回,团队成员也能据此同步进度;仅存在本机、尚未推送的提交不在这份远程副本里。
src/components/LoginForm.tsx+ 本地修改src/components/LoginForm.tsxc7d8e9fsrc/components/LoginForm.tsxorigin 上的 mainc7d8e9f无论是敲击命令行(例如 git add 和 git commit),还是在编辑器的图形界面上点击按钮,或者直接对 AI Agent 说一句话让它处理,底层都是在推动文件在这四个区域之间流转。理清了四个区域的分工,我们就能清楚知道改动目前停留在哪一步,知道恢复时有哪些已记录的版本可用。
提交不是文件拷贝,而是一棵快照树
很多初学者在没有接触版本控制前,习惯用复制文件夹的方式做备份,例如给目录命名为“项目最终版”、“项目最终版2”。这种做法不仅占用大量磁盘空间,而且无法看清两次修改之间到底改了哪几行代码。
的机制与手动复制完全不同。每次普通提交,Git 都会根据暂存区记录生成整个已纳入版本管理的文件树快照;未跟踪、被忽略或尚未暂存的新改动不会自动进入它。如果某个文件在这次提交中没有被修改,Git 不会重复保存该文件,而是直接引用上一次的记录;如果文件被修改了,Git 则记录修改后的新对象。
平时我们习惯按 V1、V2 称呼前后版本,但在团队多人协作或分支同时推进时,单纯靠序号很容易发生重名混乱。Git 对提交对象计算 ,为每一次提交生成一个全局唯一的标识码;c7d8e9f 这样的短值是便于阅读的缩写。提交对象记录文件树、作者、说明、时间和父提交引用(可理解为 )。所以即使文件内容相同,作者、时间或父提交改变,也可能得到不同的提交哈希。普通提交有一个父提交,首个提交没有,后面会看到拥有两个父提交的合并。
0f1e2d3a1b2c3dc7d8e9fmainHEAD ➔每个提交引用一份已记录的文件树。文件名仅列本次改动,反向箭头指向父提交。
做一次可以核对的提交
下面以项目中刚刚在浏览器里验证通过的登录功能为例。功能测试正常后,我们不需要自己去翻找具体改动了哪几个代码文件,更不需要手动编写技术提交说明,直接用自然的口语对 Agent 提出提交要求即可:
“刚才测试登录功能没问题了。帮我把这次登录功能的改动提交一下,不要混入未完成的临时文件。提交说明你根据改动帮我起一个简明的就行,提交完成后告诉我改了哪些文件。”
了解 Agent 在底层为我们完成的步骤:
- 首先检查分支状态与现有改动(对应
git status),找出与登录功能相关的改动文件(如LoginForm.tsx与validation.ts),排查是否存在未完成的临时文件。 - 审查登录功能文件的改动范围(对应
git diff)。 - 将目标文件当前的内容登记到暂存区(对应
git add)。 - 再次核对暂存清单(对应
git diff --cached),确认准备提交的内容准确无误。 - 根据改动自动生成规范的提交说明(例如
feat: 完成登录表单与字段验证),生成提交快照(对应git commit -m)。 - 最后向我们汇报提交完成并列出改动的文件列表。
判断一下:add 后又改了按钮文字,但没有再次 add,这次 commit 会记录哪版? 是 add 时的文字。新的编辑还留在工作区,不会因为文件名已被选中就自动提交。
常见任务怎样向 Agent 表达
我们不需要死记硬背具体的参数命令。在借助 AI 开发时,清楚说明业务意图和范围即可,同时了解底层命令能帮我们看懂 Agent 的操作:
- 想了解当前仓库情况:对 Agent 说“查看当前分支和文件状态,并列出最近五次提交说明”(底层对应
git status与git log -5 --oneline)。 - 想审查 AI 改动了什么:对 Agent 说“检查这次未暂存和已暂存的代码差异,告诉我改了哪些行”(底层对应
git diff与git diff --cached,第二章展开)。 - 想尝试新功能:对 Agent 说“基于当前的 main 分支新建 feature/cart 分支并切换过去”(底层对应
git switch -c,第三章展开)。 - 想合并或同步代码:对 Agent 明确指定要合并的分支名称,或要求拉取远程更新(第四、五章展开)。
- 想撤销或暂停工作:对 Agent 准确说出要放弃或保留的文件范围(第六章展开)。
commit 是本地记录,push 才是向远程发送提交;日常保存文件不等于这两步中的任何一步。
怎样向 AI Agent 描述提交需求
借助 AI 写代码时,我们通常不清楚底层具体改动了哪几个代码文件,更不需要自己去苦思冥想规范的提交说明,这些工作 AI 都能自动处理。
但如果我们只对 AI 简单说一句“帮我提交一下代码”,AI 可能会把调试时产生的临时日志、未完成的代码甚至本地配置文件一起提交上去。
因此,向 AI 提出提交要求时,最自然也最稳妥的方式是把重心放在业务功能和边界约束上:
- 说明刚测完的功能:告诉 AI 哪个功能在界面上已经验证通过,只提交该功能相关的改动;
- 提醒隔离无关文件:明确要求 AI 检查工作区,不要混入未完成的临时文件或调试日志;
- 让 AI 自动生成说明并汇报:让 AI 根据改动内容自动拟定一句简明的提交说明,并在提交完成后告知具体修改了哪些文件。
刚才测试登录功能没问题了。帮我把这次登录功能的改动提交一下,不要混入未完成的临时文件。提交说明你根据改动帮我起一个简明的就行,提交完成后告诉我改了哪些文件。
示例结果:已完成提交,说明为「feat: 完成登录表单与字段验证」。本次提交包含 2 个改动文件(LoginForm.tsx 和 validation.ts);工作区中未完成的 debug.log 已保留未提交。
对话中的回复只是格式示例。实际验收要看已提交的差异和剩余文件状态,不能只看 Agent 说“已完成”。
本章总结:理解区域流转,规范存盘要求
在这一章中,我们梳理了 Git 中文件的四个区域,明确了提交快照的数据结构,并掌握了如何向 AI 描述提交需求。在本地验证通过一个独立的小功能后,及时让 AI 创建一个说明完整的 Commit,是保证项目能够随时恢复到稳定状态的基础。在下一章中,我们会学习如何使用 Diff 检查 AI 修改的代码,并通过忽略规则过滤不需要的文件。