让 AI 改代码,最怕的不是改错,是改错了回不去。版本管理就是给项目“存档”:打 Boss 前存一下,打输了读档重来。有了它,你才敢让 AI 大胆试。
最常用的工具叫 Git。你不用背命令,大部分时候对 AI 说一句话就行;但要知道每句话背后发生了什么,这样 AI 做错时你拦得住。
先记住一个边界:Git 只管你交给它的代码和文档。数据库里的数据、线上平台的配置、密钥,它都不管,也不该管。
遇到什么,先读哪一节
- 从没用过 Git,想马上开始新手三招
- 看不懂 AI 回复里的 commit、branch七个概念
- 每做完一件事怎么存日常循环
- 改坏了,想回去改坏了怎么恢复
- 推送失败、提示冲突同步与冲突
- 想同时试两个方向,或让几个 AI 并行干活分支与工作区
- 要把项目交给别人或上线一个版本给别人一份能复现的版本
- 不小心把密钥存进去了密钥误提交怎么办
- 想看完整的来回过程三个示例
- 想知道自己算不算会了四关自测
前四节是新手必读;从“同步与冲突”开始是进阶,新手可以先跳过,用到再回来。
全书一图
每一格都能点,直接跳到那一节。
1新手三招:存档、看改动、回到上个存档
读完你能:
- 让 AI 帮你存档、看改动、回到上个存档
什么时候用第一次接触 Git,或者项目里还没有 Git。
还没用过 Git?先说说“复制文件夹”
很多人的第一套版本管理是这样的:做完一步,把整个项目文件夹复制一份,改名叫“项目-导航做完了”“项目-最终版”“项目-真的最终版”。这很正常,也确实救过急。
但它很快会出问题:文件夹越来越多,分不清哪份能用;每份都带着几百兆的依赖包;密钥文件跟着到处复制;想知道两份之间改了什么,只能靠眼睛比。
Git 做的是同一件事,只是更聪明:只记录变化,每次存档附一句说明,随时能对比、能回去。第一次设置,交给 AI:
我的项目在 ,还没用过 Git。请帮我初始化 Git 并做第一次存档。 先检查这个文件夹是不是已经在某个 Git 仓库里,如果是就告诉我,别重复初始化。 再创建 .gitignore,排除依赖包、构建产物、.env 和其他密钥文件,把排除清单给我看。 我确认后再存第一个档,说明写“项目初始版本”,最后告诉我存了哪些文件。
把方括号里的内容换成你的情况
AI 大致会执行下面这些命令。.gitignore 是一张“别管这些文件”的清单,要在第一次存档之前建好:已经被存进去的文件,之后再写进清单也不会自动移除。Git 官方文档:gitignore
# 在项目文件夹的终端里运行
git init # 在当前文件夹建一个 Git 仓库(多出一个隐藏的 .git 文件夹)
git status # 查看有哪些文件会被收录,只读
git add . # 把当前文件夹里没被 .gitignore 排除的文件放进“待存档”
git commit -m "项目初始版本" # 正式存档git add . 会收录当前文件夹下的所有文件,所以一定先看过 git status 和 .gitignore,确认里面没有密钥和依赖包。Pro Git:获取 Git 仓库
第一次存档如果提示“Author identity unknown”(请告诉我你是谁),让 AI 带你设置一次用户名和邮箱,以后不用再设:
# 在终端运行一次即可;只写入 Git 的配置,不改项目文件
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"第一招:存个档
做完一件事、检查过能用,就存一次。存档说明写人话:“修好手机上登录按钮错位”,比“fix bug”有用得多。
刚才 我检查过了,能用。请帮我存个档:先告诉我改了哪些文件, 只收录和这件事有关的,说明写“”,存完告诉我存档编号。
把方括号里的内容换成你的情况
# 在项目文件夹的终端里运行
git status # 看哪些文件变了,只读
git add src/Login.jsx src/login.css # 只把这次相关的文件放进“待存档”
git commit -m "修好手机上登录按钮错位" # 存档,生成一个存档编号(commit)会发生什么:Git 记下这几个文件此刻的样子和你的说明。文件本身不变,你照常继续改。
做到这样算完成git log --oneline -1 里多了一条说明清楚的存档,git status 里没有这件事相关的未存档改动。
第二招:看看改了啥
AI 改完一轮,或者你隔天回来,先看看和上个存档比动了哪里,尤其是 AI 有没有“顺手”改了你没让它改的地方。
帮我看看现在和上个存档比改了什么:哪些文件变了,每个文件大概改了什么。 有我没要求改的地方请单独指出来。先别存档,也别改文件。
# 在项目文件夹的终端里运行,全部只读,不改任何文件
git status # 哪些文件变了
git diff # 还没放进“待存档”的具体改动
git log --oneline -5 # 最近 5 个存档的编号和说明git diff 只显示还没 add 的改动;已经 add 的要用 git diff --staged 看。Pro Git:记录每次更新
做到这样算完成你能说出这次改了哪几个文件、各改了什么,并且知道有没有多出来的改动。
第三招:回到上个存档
改坏了、还没存档,想让项目回到上个存档的样子。新手的默认做法是先收起来,不要直接扔掉,万一里面有想要的,还能拿回来。
刚才的改动把 弄坏了,还没存档。请帮我把项目回到上个存档的样子, 但先把现在的改动收起来别扔,告诉我以后怎么拿回来。执行前先说会影响哪些文件,等我确认。
把方括号里的内容换成你的情况
# 在项目文件夹的终端里运行
git stash push -u -m "改坏的尝试" # 把所有未存档改动(含新建文件)收起来,项目回到上个存档
git stash list # 查看收起来的记录,只读
git stash pop # 以后想拿回来时运行:把最近收起的改动放回项目会发生什么:文件恢复成上个存档的样子,你的改动暂存在一边。-u 让新建的文件也一起收起,不加的话新文件会留在原地。收起来只是临时存放,重要的东西还是要正式存档。Git 官方文档:git-stash
做到这样算完成项目按上个存档的样子正常运行;git stash list 里能看到“改坏的尝试”。
2七个概念
读完你能:
- 分清工作区、暂存区、提交、分支和远程
什么时候用AI 的回复里出现 commit、branch、remote,你不确定它在说什么。
| 概念 | 大白话 | 容易误会的地方 |
|---|---|---|
| 仓库 repository | 装着项目全部存档历史的地方 | 就是项目里那个隐藏的 .git 文件夹,别手动改它 |
| 工作区 working tree | 你正在编辑的那些文件 | 没存档的改动不在历史里,丢了就找不回来 |
| 暂存区 staging area | “这次准备存进去的东西” | add 只是放进来,还没存档 |
| 提交 commit | 一次存档,带编号和说明 | 只存在你电脑上,推送了才有备份 |
| 分支 branch | 一条独立的存档线,指向最新那次存档 | 不是复制一整份文件夹,也不会隔离数据库 |
| 远程 remote | 放在 GitHub 等网站上的那份仓库 | 本地和远程要手动同步,不会自动一致 |
| 标签 tag | 给某次存档起个好记的名字,如 v1.0 | 打了标签不等于测试过或已上线 |
Git 里的分支只是一个指向某次存档、会随新存档往前移动的“指针”,所以开分支很轻,不会复制文件。Pro Git:分支简介
AI 刚才的回复里提到了 。请结合我现在这个项目的状态,用一两句大白话解释它, 再告诉我这一步会不会改动我的文件。先解释,不要执行任何命令。
把方括号里的内容换成你的情况
做到这样算完成看到这七个词,你能说出它们各指什么,也知道哪些操作只在你电脑上发生。
3日常循环
读完你能:
- 按“拉取、修改、检查、存档、推送”走完一轮
什么时候用每一次让 AI 做一件事的前后。
怎么做每做一件事,走一遍这个圈:
| 步骤 | 做什么 | 对 AI 说 |
|---|---|---|
| 开始前 | 看一眼有没有没存档的改动;多人合作先同步 | “开始前帮我看看有没有没存档的改动” |
| 改 | 一次只让 AI 做一件事 | “这次只改 [功能],别动其他文件” |
| 检查 | 自己按用户操作走一遍 | —— |
| 看改动 | 确认没有多余修改、没有密钥 | “帮我看看改了哪些文件” |
| 存档 | 只收这件事相关的文件,写清说明 | “帮我存个档,说明写 [……]” |
| 推送 | 需要备份或给别人看时推到远程 | “把存档推到远程仓库” |
几个习惯:
- 一件事一个存档。一次存档里混着新功能、修 bug、改样式,出问题时很难只退掉其中一个。
- 让 AI 大改之前先存档。这是你的安全网。
- 存档前看一眼改动。AI 有时会顺手改别的文件,或把测试用的密钥写进代码。
- 推送才有备份。存档只在你电脑上,电脑坏了就没了。
帮我为 存个档。先列出改动的文件,只收录这件事相关的, 不要收录 .env 或含密钥的文件。说明写清“改了什么、为什么”。 存完告诉我存档编号,以及还有哪些改动没存。
把方括号里的内容换成你的情况
做到这样算完成一件事对应一个存档,说明能看懂;需要备份的已经推送到远程。
4改坏了怎么恢复
读完你能:
- 按改坏的情况选对恢复方式,不丢有用的改动
什么时候用AI 改完之后项目坏了,或者你想退回某个旧版本。
怎么做先回答两个问题再选方法:改坏的东西存档了没有?存档推送(分享给别人)了没有?
| 情况 | 推荐做法 | 会发生什么 | 注意 |
|---|---|---|---|
| 没存档,整体不要了 | git stash push -u |
改动收到一边,项目回到上个存档 | 新手默认,还能拿回来 |
| 没存档,只想让一个文件回到上个存档 | git restore 文件 |
该文件的未存档改动被丢弃 | 丢了找不回,确定不要再用 |
| 文件误放进“待存档” | git restore --staged 文件 |
从待存档里拿出来,内容保留 | 安全 |
| 想看看某个旧存档里的文件 | git show 存档编号:文件路径 |
只显示,不改任何东西 | 安全 |
| 想把某个文件恢复成旧存档的内容 | git restore --source=存档编号 文件 |
覆盖该文件当前内容 | 当前改动要先存档或收起 |
| 某次存档有问题,已经推送 | git revert 存档编号 |
新增一个“反向”存档抵消它,历史保留 | 要求当前没有未存档改动 |
| 最近一次存档还没推送,想重新整理 | git reset --soft HEAD~1 |
撤掉这个存档,改动保留在“待存档” | 只用于没推送的存档 |
| 线上网站坏了 | 在部署平台重新部署上一个正常版本 | 用户看到的版本退回 | 改过数据库结构的,先确认旧版本能读新数据 |
新手按表格从上往下找,通常前三行就够用。
为什么不推荐 git reset --hard:它会把工作区和待存档全部强制改成目标存档的样子,所有没存档的改动直接消失,还可能覆盖没被 Git 管理的文件。AI 有时会顺手用它,看到了请先拦下。Git 官方文档:git-reset
restore 也不是安全按钮:git restore 文件 会用上个存档覆盖这个文件,本地改动就没了。Pro Git:撤消操作
revert 和 reset 的区别:revert 是新写一个存档把错误抵消掉,历史完整,已经推送、别人可能已拿到的存档用它;reset 是把分支指针挪回去,适合只在你电脑上、还没推送的存档。git-revert、git-restore
真的误删了存档:git reflog 会列出最近分支指针去过的位置,很多“丢了”的存档还能从这里找回。发现后先别再做其他操作,把 reflog 输出交给 AI 一起看。
我想撤销 ,保留 。先别执行,告诉我: 这个改动存档了没有、推送了没有、你打算用什么方法、会影响哪些文件。 优先用不丢东西、不改写已推送历史的方法,等我确认再做。做完我会按 验证一遍。
把方括号里的内容换成你的情况
做到这样算完成自己走一遍原来的操作,功能恢复正常,而且想留下的改动没丢。Git 命令成功只说明文件变了,不代表功能恢复了;代码退回旧版,数据库也不会自动退回。
以下是进阶内容,新手可以先跳过:一个人在一台电脑上做项目时,前四节已经够用。开始用远程仓库、和别人合作、同时开几个方向或准备上线时,再回来读。
5同步与冲突
读完你能:
- 推送被拒时先看远程多了什么,再合并
什么时候用推送被拒绝、提示有冲突,或者要拿别人(或另一台电脑)推上来的改动。
怎么做先看清楚远程多了什么,再合进来。三个动作:
git fetch:把远程的新存档拿下来看看,不动你的文件。git pull:拿下来并合进你当前的分支。具体是合并还是变基,取决于你的设置;两边都有新存档时,Git 可能要你选择怎么合。git-pullgit push:把你的新存档推上去。默认只推分支,不推标签。git-push
推送被拒(提示 rejected、non-fast-forward),意思通常是远程有你还没拿到的新存档。正确顺序是:先 git fetch 拿下来只看不合,弄清远程多了哪些存档,再合并,合好检查过再推。不是加 --force 强推,强推会让远程丢掉别人的存档。
冲突是两边改了同一处,Git 不知道留哪个。文件里会出现这样的标记:
<<<<<<< HEAD 你这边的内容 ======= 对方的内容 >>>>>>> 对方分支名
处理冲突不是“选我的还是选他的”。先弄明白两边各想解决什么,能都保留就都保留;删掉三行标记,检查功能正常,再 git add 这个文件表示已解决,最后存档。Pro Git:遇到冲突时的合并
请先获取远程的新存档但不要合并,告诉我远程和本地各多了哪些存档,等我看过再合并。 有冲突的话,先解释两边各改了什么、想解决什么,尽量保留两边的有效改动, 合完帮我检查 。不要全选某一边,也不要强推。
把方括号里的内容换成你的情况
做到这样算完成文件里没有冲突标记,功能检查通过,推送成功,远程和本地的最新存档一致。
6分支与工作区:并行做事
读完你能:
- 用分支或工作区同时做两件事,互不干扰
什么时候用想试一个新方向又怕弄坏主线,或者想让几个 AI 同时干活。
分支:想试一个新方向又怕弄坏主线,就开一个分支。试成了合回去,没试成直接放弃,主线毫发无损。
# 在项目文件夹的终端里运行
git switch -c try-new-nav # 新建并切换到 try-new-nav 分支,文件暂时不变
git switch main # 切回主线;文件会变成主线上的样子切换分支会改变你看到的文件,所以切之前先存档或收起改动。分支名和文件夹名建议用英文和短横线,部署平台的预览地址和一些工具对中文名支持不好。
工作区(worktree):同一个文件夹同一时间只能在一个分支上。想让两个 AI 同时干活,或者边修 bug 边做新功能,就给每个任务一个独立的文件夹,它们共享同一份存档历史。同一个分支默认不能在两个工作区同时打开,这正好防止两边互相覆盖。git-worktree
# 在项目文件夹的终端里运行;会在旁边新建一个文件夹 ../myapp-search,并新建分支 search
git worktree add ../myapp-search -b search多人或多个 AI 并行时,提前说好:
| 事项 | 约定 |
|---|---|
| 起点 | 从同一个确认过的存档开始 |
| 文件 | 每个任务负责哪些文件;共用的接口只由一方改 |
| 运行 | 不同端口、不同的测试数据库,别共用一份可写数据 |
| 合并顺序 | 先合底层(接口、数据结构),再合用它的功能;每合一个检查一次 |
“合并时没有冲突”不等于“合在一起能用”,合完一定要跑一遍相关功能。
我想让 和 并行做。请给它们各开一个工作区和分支, 列出各自负责的文件、共用的接口、各用哪个端口和测试数据库。 先完成 再合并另一个,每合一次帮我检查 。
把方括号里的内容换成你的情况
做到这样算完成两条线各自完成并检查过;合并后主线功能完整,没有互相覆盖的改动。
7给别人一份能复现的版本
读完你能:
- 给一个版本打标签,让别人能复现它
什么时候用交作业、给客户演示、准备上线。
怎么做交作业、给客户演示、准备上线时,要给出一个“别人拿到就能跑起来、跑出来和你一样”的版本。
打标签:给这次存档起个名字。正式版本用带说明的标签;标签不会随 git push 自动上传,要单独推。git-tag
# 在项目文件夹的终端里运行
git tag -a v1.0 -m "第一次课堂演示版本" # 给当前存档打标签,不改文件
git push origin v1.0 # 把这个标签推到远程已经推出去的标签不要挪到别的存档上;要修正就打一个新的,比如 v1.0.1。
随版本记下这些:
- 存档编号和标签名
- 运行环境(比如 Node 版本)和依赖锁文件(如
package-lock.json)是否一并提交 - 启动步骤,从拿到代码到打开页面
- 需要哪些环境变量(只写名字,不写值)
- 数据库结构版本和演示数据从哪来(用假数据,不用真实用户数据)
- 你实际检查过什么、结果如何;没检查的写“未检查”
我要把 的当前版本交给 。请确认没有未存档的改动, 给当前存档打标签 并推送。再写一份说明:运行环境、启动步骤、 需要的环境变量名(不写值)、数据怎么准备。然后在一个新文件夹里从头跑一遍,告诉我结果。
把方括号里的内容换成你的情况
做到这样算完成别人按说明在新文件夹里从头跑起来,看到的和你一样;标签在远程可以看到。
8密钥误提交怎么办
读完你能:
- 密钥误提交后按顺序作废、移出、清理历史
什么时候用发现 API 密钥、数据库密码被存进了 Git,尤其是已经推到了远程。
怎么做按这个顺序处理:
- 先作废或更换这把密钥。去发放密钥的平台把它停用,生成一把新的。这是最重要的一步:光删文件、再存个档、甚至删掉仓库重建,都挡不住已经泄露的密钥被使用。GitHub Docs:处理泄露的密钥
- 把密钥从代码里移出去。改成从环境变量读取,把
.env写进.gitignore,再用git rm --cached .env让 Git 不再管理它(文件还留在你电脑上)。 - 再考虑清理历史。旧存档里仍然有这把密钥。清理历史需要专门工具(GitHub 推荐 git-filter-repo),会改写所有存档编号,合作者必须重新拉取或克隆,否则一推送密钥又回来了。密钥已经作废的话,这一步可以和合作者商量后再做。GitHub Docs:从仓库中删除敏感数据
- 检查有没有被用过。去平台看看这段时间的调用记录和账单。
我不小心把 存进了 Git, 推送到远程。 第一步我会先去平台作废它。请帮我:把代码改成从环境变量读取, 把 .env 加入 .gitignore 并让 Git 停止管理它。清理历史先别做, 告诉我需要做什么、会影响谁,等我确认。密钥的值不要写进回复里。
把方括号里的内容换成你的情况
做到这样算完成旧密钥已经作废,新密钥只存在环境变量或平台设置里;git status 不再显示 .env;平台的调用记录里没有异常。
预防比补救便宜:密钥不要贴给 AI,不要写进代码,不要提交进代码仓库;每次存档前看一眼改动。
9三个示例
以下是教学示例,展示一次完整的来回。
示例一:AI 大改后首页白屏
- 现象:让 AI 重做导航后,首页一片空白,改动还没存档。
- 先保住现场:“先把现在的改动收起来别扔,项目回到上个存档,告诉我影响哪些文件,等我确认。”(
git stash push -u -m "重做导航") - 验证:首页恢复正常,确认问题出在这次改动里。
- 取回有用的部分:
git stash show -p看收起的改动,让 AI 只把导航样式那一部分重新做进来。 - 做到这样算完成:首页正常,新导航的有用部分保留,并存成一个新存档;
git stash drop清掉那条记录。
示例二:推送被拒绝
- 现象:
git push提示 rejected,远程有你本地没有的存档(你在另一台电脑上推过)。 - 先看不合:“先获取远程更新但不合并,告诉我远程多了哪些存档。”(
git fetch后git log --oneline main..origin/main) - 合并:确认后合并;出现冲突时,让 AI 先解释两边各改了什么,保留两边的有效改动。
- 验证:本地把相关功能跑一遍。
- 做到这样算完成:推送成功,
git status显示和远程一致,没有用--force。
示例三:.env 已经推到了远程
- 现象:在远程仓库页面看到了
.env文件。 - 第一步:去发放密钥的平台作废旧密钥,生成新的。
- 移出代码:“把 .env 加进 .gitignore,用 git rm --cached 让 Git 停止管理它,文件留在我电脑上。”然后存档、推送。
- 检查:去平台看这段时间的调用记录和账单。
- 做到这样算完成:旧密钥失效,新密钥只在环境变量里,远程最新版本里没有
.env;是否清理历史,和合作者商量后再决定。
10四关自测:怎样算会用了
| 关卡 | 你要做到 | 过关标准 |
|---|---|---|
| 第一关:存得准 | 改了三个文件,其中只有两个属于这次任务 | 只把这两个存进档,说明写清楚 |
| 第二关:退得对 | 分别说出同一个 bug 在“没存档”“存档了没推送”“已推送”时怎么撤 | 三种情况用了不同方法,都没丢别的改动 |
| 第三关:分得开 | 开一个分支或工作区试新方向,再回到主线 | 主线没受影响,试验的改动也还在 |
| 第四关:说得清 | 说出 Git 存档、数据库备份、线上部署各自保护什么 | 不把 Git 当成“什么都能恢复” |
四关都过了,你就可以放心让 AI 大胆改:因为你知道,怎么都回得去。
练一练:改写这三句话
先自己改一遍,再点开参考改法对照。
把这句话改清楚:“帮我保存一下代码。”
看参考改法
改法我刚把首页改好了,先帮我看一下有哪些文件改动,确认没有 .env 这类密钥文件,然后存一次档,说明写“首页加了搜索框”,存完告诉我存档编号。
差别说清了存什么、先检查什么、存档说明,以及怎么确认存好了。
把这句话改清楚:“改坏了,帮我回到之前。”
看参考改法
改法我改完登录页后网站打不开了,改动还没推送。先帮我把现在的改动暂存起来,回到上一个能用的存档,确认网站能打开后,再告诉我怎么取回刚才有用的部分。
差别补上了是否推送过、要保留什么,以及回去之后怎么验证。
把这句话改清楚:“推不上去,帮我强推一下。”
看参考改法
改法我推送时被拒绝了,提示远程有我本地没有的存档。先帮我获取远程的更新但不合并,告诉我远程多了什么,再合并;有冲突就停下来给我看,不要强制推送。
差别拒绝了强推,改为先看清远程变化、再安全合并。