重生之我在 Vibe Coding 时代当程序员:第五课,AI 写代码这么快,我为什么还要学 Git
上节课我把 Drum Kit 项目交给了 Claude Code,让它当员工接手。它真的进了项目目录、读代码、改文件、加功能、修 bug,一个 session 跑完,项目从空壳变成能用的鼓机。但跑通的那一刻我冒出一个新问题:如果它改坏了怎么办?如果改了一半我想回去看上一版怎么办?如果我和它同时在改同一个文件,又怎么办? 这节课老师没继续讲 AI,反而把我们拉回到 2005 年发明的、看起来跟 AI 完全没关系的一个工具——Git。
从一个叫 lk_ai 的文件夹说起
我这学期的课程项目都堆在 lk_ai/ 这个目录里。
第一课的生日贺卡、第二课的 3D 小世界、第三课的 Foodiez 落地页、第四课的 Drum Kit……每节课一个子目录,文件夹整整齐齐。打开任何一个子目录,里面是当前能跑的最新版本。
听起来挺好。但老师让我们盯着这个目录想三个问题:
- 如果我手贱把
index.html改坏了,怎么回到昨天那一版?——答案是没办法,因为我电脑里只有"现在这一版"。 - 如果我想和同学一起开发这个项目,怎么办?——答案是只能拷贝整个文件夹给他,他改完再发回来,我手动合并。一来一回两个小时没了。
- 如果我硬盘坏了,这个目录怎么办?——答案是一起没了。
这就是一个单机版项目目录的真实样貌:没有版本概念、没有协作能力、没有任何"工程化"的保护。
老师把这三个痛点合起来概括了一句话:
单机版本不好协作,多版本不好保存,硬盘一坏就什么都没了。
这三件事,都是 Git 要解决的。
Git 是什么:一台时间机器,外加一份分布式档案
如果只用两句话讲明白 Git:
- Git 是一台时间机器:它不只保存"现在",它保存"每一次按下保存键的瞬间"。每一个版本都是一张可以读回去的快照。
- Git 是分布式的:每个人的电脑上都是一份完整的仓库,中央仓库(GitHub / Gitee / GitLab)只是大家约定的"汇合点"。
这两个能力合在一起就解决了上面三个痛点:
| 痛点 | Git 的回答 |
|---|---|
| 文件改坏了想回退 | 任意一次 commit 都能读回 |
| 多人协作 | 每个人有完整副本 + 中央仓库做同步 |
| 硬盘坏了文件丢了 | 网络上还有一份完整的 |
这件事的关键在"分布式"这三个字。它跟我们常见的"一切都存在云端"的中心化设计不一样:每一台开发机本身就是一份完整档案,中央仓库不是"唯一真相",只是"大家约好的同步点"。
git init:给一个普通目录装上"版本控制"
要让 lk_ai/ 从"单机版"升级成"带版本控制的仓库",只需要一句话:
git init
这条命令做的事就一件:在当前目录下生成一个隐藏文件夹 .git/。
lk_ai/
├── .git/ ← Git 的"档案柜"
├── ai/
├── git/
└── readme.md
.git/ 是 Git 的"档案柜",所有版本、所有快照、所有历史都存在里面。这个文件夹默认是隐藏的:
- Windows:默认看不见,得去文件资源管理器里勾"显示隐藏文件";或者在命令行里用
ls -Force - Mac / Linux:用
ls -all - 推荐做法:在项目目录上右键 →
Git Bash Here,开一个最简版的 Linux 终端
为什么 Git 要把它隐藏起来?其实理由很简单:
版本文件不能被随意更改,防止恶意或失误导致的修改。
.git/ 是仓库的灵魂,你手动碰它一下,仓库就废了。所以 Git 默认把它藏起来——你只能通过 git add、git commit 这种Git 自己提供的命令去和它交互,不能用资源管理器直接拖文件进去。
这一步等于在你的项目上正式开启了"时间记录"功能。
git add 和 git commit:为什么要分两步走
装好仓库之后,下一个最常用的动作是把改动存进仓库。这件事 Git 把它拆成了两步:
git add readme.md # 第一步:放进暂存区(stage)
git commit -m "写完 readme" # 第二步:从暂存区入库
我第一次学的时候很疑惑:为什么不一步到位?为什么要先 add 再 commit?
老师在课堂上回答了这个问题,我把他的话原样记了下来:
完成某个功能时才有必要存档。
举个例子。我现在要给一个项目加"登录功能"。这件事不是改一个文件就完事的——
login.html要加表单结构common.css要加表单样式login.js要加提交逻辑
这三个文件逻辑上属于同一个功能。它们应该被作为"一次完整的存档"放进仓库。
如果 Git 没有暂存区,每改一个文件就直接 commit 一次,仓库的提交记录会变成:
* 改了 login.html
* 改了 common.css
* 改了 login.js
——三条记录讲一件事,记录碎得不行。
而有了暂存区之后,工作流变成:
git add login.html # 攒着
git add common.css # 继续攒
git add login.js # 攒齐了
git commit -m "添加登录功能" # 一次性入库
仓库里只留下一条干净的记录:"添加登录功能"。
所以 Git 的设计原则是:
- add 多次(积累一个完整功能的所有改动)
- commit 一次(完成时一次性存档)
我心里给暂存区起了个外号:出厂前的质检台。改动先攒在台子上,攒够一个完整功能再"装箱出货",进入仓库。仓库提交记录的清晰与整洁,全靠这个质检台。
git status:任何关键时刻,先按一下
这是老师反复强调的一句话,我决定原样抄下来当原则用:
任何关键时刻,先 git status。
为什么?因为 Git 一个文件可能处于很多种状态:
| 状态 | 含义 |
|---|---|
| untracked | Git 还不认识它(新建文件) |
| modified | Git 认识,但你改过没 add |
| staged / to be committed | 在暂存区,等着 commit |
| committed | 已经入库 |
这四个状态串成一条链,是一个文件从"野生"到"入档"的完整旅程。
光靠脑子记你现在每个文件在哪一格,根本记不过来。但 git status 一句话就能把"现在仓库长什么样"摆给你看:
- 哪些文件 Git 还不认识
- 哪些文件改了还没 add
- 哪些文件在暂存区等着 commit
- 当前在哪个分支
- 跟远程仓库差多少
所以"关键时刻先 status"不是规矩,是自我保护。在你准备 commit、准备 push、准备切分支、准备让 AI 改文件之前,多按一下 git status,你就永远不会"我是谁、我在哪、我刚干了啥"。
git branch 和 git remote:协作的两个入口
Git 真正强大的不是单机的时间机器,是多机协作。这一节没讲很深,但两个概念先记住:
git branch # 查看当前在哪条分支上
git remote # 查看远程仓库是谁
分支(branch) 是平行宇宙:同一个项目可以同时存在多个版本,互不干扰。主线在 main,你想试个新想法不影响主线,就开一条 feature/login 分支去玩,玩坏了直接删掉,主线毫发无伤。
远程仓库(remote) 是约定的集合点:你在本地写代码,写够一个 commit 推(push)到远程,其他人从远程拉(pull)下来,大家在中央仓库汇合。
把这两个概念翻译回办公场景:
每个员工有一份完整的项目档案在本地,中央服务器只是大家约定的"共享白板"。
这跟很多人想象中"代码都在云上,本地只是一个客户端"是相反的设计。Git 的世界里,真相不在中央,真相在每个人的机器里。这才是"分布式"三个字真正的分量。
真正让我重新认识 Git 的,是 AI
讲完命令之后,老师把我们拉回 Vibe Coding 的语境,丢了一句话:
AI 写代码越快,你越需要 Git。
我一开始没明白。Git 不是 2005 年的东西吗?跟 AI 有什么关系?
老师让我对比一下"以前写代码"和"现在让 AI 写代码"两种节奏:
| 以前(自己写) | 现在(让 cc 写) | |
|---|---|---|
| 一次改动量 | 几十行 | 几百行甚至几千行 |
| 改的速度 | 慢,能边写边想 | 快,几秒钟一个文件 |
| 出错时你的反应时间 | 充分 | 几乎为零 |
| "我能看清每一行吗" | 能 | 看不过来 |
以前我自己写代码,慢,错也慢。一天写 100 行,错也就 5 行,bug 出来当时就发现。
现在 AI 一个 prompt 改 500 行。你来不及看每一行就回车了。那"如果改错了怎么办"这个问题,比以前严重了 10 倍。
Git 提供的能力刚好对症:事前快照 + 任意回滚。
我现在的工作流变成了这样:
- 让 cc 改代码之前:先
git status看一下当前状态干不干净(没有"忘了 commit 的旧改动"混进来) - 让 cc 干活之前:先 commit 一个"安全点"
- 让 cc 改完之后:先看 diff,再决定要不要再 commit
- 一旦觉得它改坏了:一键回到上一个安全点
这套流程的核心思路是:把 AI 的每一次介入,包成一个独立的 commit。AI 不再是"自由地在我代码上涂改",而是"在两个 commit 之间,操作一段被夹起来的版本"。改好了,留下;改坏了,撤销。
Git 在 AI 时代变成了"撤销键"——不是 Ctrl+Z 撤销一行的那种小撤销,是一键撤销 AI 整轮介入的大撤销。
这件事让 Git 这门技能在 Vibe Coding 时代的价值反而变高了,而不是变低。以前 Git 是"团队协作的工具",现在它额外承担了一个角色:人和 AI 之间的安全栅栏。
这节课我学到了什么
- Git 是一台时间机器,不只是个备份工具。 它保存的不是"现在",而是"每一次按下保存键的瞬间"。每个 commit 都是一个可以读回的存档点。
- add 和 commit 分两步,是为了让"一次提交 = 一个完整功能"。 暂存区是出厂前的质检台,攒够一个完整功能再发版。仓库提交记录的清晰与整洁,全靠这条纪律。
- 任何关键时刻,先
git status。 Git 状态多、容易混,但只要敢按 status,你就永远不会"我是谁、我在哪、我刚干了啥"。 - 分布式 = 每个人都有完整档案,中央仓库只是共享白板。 真相不在云上,真相在每个人的机器里——这才是 Git 跟传统中心化版本控制最不一样的地方。
- AI 写得越快,Git 越重要。 AI 一次性改几百行,你来不及一行行看。Git 的"事前快照、任意回滚"在 Vibe Coding 时代不是"程序员的好习惯",是一道必备的安全栅栏。把 AI 的每次介入包成一个独立 commit,改好了留下,改坏了撤销。
从第一课讲怎么写 prompt,到这节课讲怎么管版本,我的工具箱在一格一格地补完。AI 替我写代码越多,我越意识到一件事:程序员真正的工作不是"敲键盘",是"做决定"。决定 prompt 怎么写、决定项目怎么搭、决定哪一版要保留、决定改坏了从哪个点退回去。Git 给的其实不是命令,而是一种"做决定的底气"。你知道哪怕全错了,也能退回上一个安全点重来。
下一课,继续往下挖。
本文思考来自吴恩达 DeepLearning.ai 课程:AI for Everyone。