Vibe Coding 不写 Git,等于悬崖边飙车
前言
很多同学用 Git 只会 add → commit → push,一旦出了问题就开始慌:"我刚才的代码去哪了?"
尤其是 git reset --hard 和 git reset --soft,听起来都是"回退",但效果天差地别。今天我们就从 Git 的三大区域出发,用实际例子把它们彻底讲清楚。
更关键的是------在当下 Vibe Coding(氛围编程) 浪潮中,为什么说 Git 不是"锦上添花",而是你的生命线?
💡 本文会教你一个大多数人不知道的安全回退策略:用
--soft三步渐进式回退 ,让你永远不用再为--hard丢代码而后悔。
一、先搞懂 Git 的三大区域
Git 的所有操作,本质上都是在三个区域之间搬数据:
scss
┌─────────────┐ git add ┌─────────────┐ git commit ┌─────────────┐
│ 工作区 │ ──────────► │ 暂存区 │ ──────────► │ 本地仓库 │
│ (Workspace) │ │ (Staging) │ │ (Repository) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
你编辑文件的地方 git add 后的快照 git commit 后的历史
(你肉眼看到的文件) (.git/index) (.git/objects)
| 区域 | 是什么 | 你能看到吗 | 怎么查看 |
|---|---|---|---|
| 工作区 | 你电脑上的文件目录 | ✅ 直接看到 | 直接打开文件夹 |
| 暂存区 | git add 后的快照 |
❌ 不直观 | git diff --cached |
| 本地仓库 | git commit 后的历史 |
❌ 不直观 | git log / git show |
二、git reset --soft:只动仓库,其他原封不动
一句话总结
--soft只回退本地仓库的 HEAD 指针 ,工作区和暂存区的修改全部保留。
影响范围
makefile
工作区: ✅ 保持不变(你的代码还在)
暂存区: ✅ 保持不变(之前 add 的还在)
本地仓库: 🔄 回退到指定版本
实战例子
假设你有这样的提交历史:
bash
git log --oneline
# abc1234 第三次提交:添加了登录功能
# def5678 第二次提交:添加了首页
# 9990000 第一次提交:初始化项目
现在你觉得"第三次提交"应该和"第二次提交"合并成一个 commit,执行:
bash
git reset --soft HEAD~1
结果:
bash
git status
# Changes to be committed:
# modified: login.js ← 还在暂存区!没有丢!
# modified: auth.js ← 还在暂存区!
HEAD 指针回到了 def5678,但你写的 login.js 和 auth.js 的修改完好无损地待在暂存区。你可以重新组织 commit:
bash
git commit -m "第二次提交:添加首页和登录功能"
典型使用场景
- 修改上一次 commit 的信息 :
git reset --soft HEAD~1→ 重新 commit - 把多个 commit 合并成一个:回退 N 步,然后一次性提交
- 重新组织提交内容:拆分或合并变更
三、git reset --hard:三大区域全部回退
一句话总结
--hard回退本地仓库、暂存区、工作区 全部三个区域,所有未提交的修改彻底丢失。
影响范围
makefile
工作区: 🔄 回退到指定版本(你的代码修改被丢弃!)
暂存区: 🔄 回退到指定版本(add 的内容被清空!)
本地仓库: 🔄 回退到指定版本
实战例子
同样的提交历史:
bash
git log --oneline
# abc1234 第三次提交:添加了登录功能
# def5678 第二次提交:添加了首页
# 9990000 第一次提交:初始化项目
你觉得第三次提交写得不好,想彻底回退到第二次提交,连登录功能都不要了:
bash
git reset --hard def5678
结果:
bash
git log --oneline
# def5678 第二次提交:添加了首页
# 9990000 第一次提交:初始化项目
# abc1234 消失了!login.js 的代码也没了!
bash
git status
# nothing to commit, working tree clean ← 干干净净,所有修改消失
⚡ 注意:如果只想丢弃工作区的修改(不回退 commit),可以用
git restore .。--hard的真正威力在于连 commit 历史都一起回退。
⚠️ 致命提醒
--hard 是不可逆的(至少对工作区而言)。执行前请三思!
但如果只是误操作了 commit,还有救:
bash
git reflog # 查看所有操作记录
git reset --hard abc1234 # 找回丢失的 commit
注意:
reflog只能找回 commit 记录 ,工作区中从未 commit 过的修改,--hard丢掉就真的没了。
四、从 --soft 到 --hard:三步渐进式回退
这是很多人忽略的一个关键认知:--soft 和 --hard 不是两个孤立的命令,而是同一条回退链上的不同档位。
你可以把 --soft 理解为"安全模式"------先回退,再决定要不要继续丢弃。整个过程可以分三步走,每一步你都有机会停下来:
完整流程演示
假设当前状态:你刚提交了第三次 commit,但觉得写得不好,想回退。
bash
git log --oneline
# abc1234 第三次提交:添加了登录功能(写得不好)
# def5678 第二次提交:添加了首页
# 9990000 第一次提交:初始化项目
第一步:git reset --soft HEAD~1 ------ 只动仓库
bash
git reset --soft HEAD~1
makefile
本地仓库: HEAD → def5678 ← 回退了
暂存区: login.js 的修改还在 ← 没动
工作区: login.js 的修改还在 ← 没动
💡 此时你还能看到 login.js 的代码,它就在暂存区里
如果后悔了,直接 git commit 就能回到 abc1234
第二步:git restore --staged . ------ 再清暂存区(可选)
bash
# 将暂存区的文件移回工作区(等同于旧写法 git reset HEAD)
git restore --staged .
makefile
本地仓库: HEAD → def5678 ← 没变
暂存区: login.js 被移出暂存区 ← 清空了
工作区: login.js 的修改还在 ← 没动
💡 代码从暂存区"掉"回了工作区,你可以用 git status 看到
文件变成了 "Changes not staged for commit" 状态
如果后悔了,git add . 就能回到上一步
第三步:git restore . ------ 最后清工作区(可选)
bash
git restore .
makefile
本地仓库: HEAD → def5678 ← 没变
暂存区: 空 ← 没变
工作区: login.js 的修改被丢弃 ← 清空了
💥 到这一步,效果就和 git reset --hard 完全一样了
代码彻底消失,不可恢复(对未 commit 的内容而言)
一图看懂渐进过程
sql
第一步 第二步 第三步
--soft HEAD~1 restore --staged . git restore .
┌────────────┐ ┌────────────┐ ┌────────────┐
本地仓库 HEAD │ ✕ 回退 │ │ - 不变 │ │ - 不变 │
├────────────┤ ├────────────┤ ├────────────┤
暂存区 │ ✓ 保留 │ │ ✕ 清空 │ │ - 不变 │
├────────────┤ ├────────────┤ ├────────────┤
工作区 │ ✓ 保留 │ │ ✓ 保留 │ │ ✕ 丢弃 │
└────────────┘ └────────────┘ └────────────┘
│ │ │
└─── 可以停 ────┴─── 可以停 ────┴── 到底了
随时 commit 随时 add
为什么推荐这种方式?
| 对比 | 直接 --hard |
渐进式 --soft → --mixed → restore |
|---|---|---|
| 安全性 | 🔴 一步到位,梭哈赌命 | 🟢 分步执行,每步可撤 |
| 可逆性 | ❌ 工作区修改直接没了 | ✅ 每一步都能反悔 |
| 灵活性 | 😐 要么全要,要么全丢 | 😎 可以选择性保留部分修改 |
| 适合场景 | 确定要全部丢弃 | 不确定要不要丢、想先看看 |
💡 实战建议 :养成习惯,默认用
--soft。先回退 commit,看看暂存区里有什么,再决定要不要继续清。--hard是最后的核武器,只在你 100% 确定时使用。
五、三种模式对比总览
除了 --soft 和 --hard,还有一个中间态:--mixed(不加参数时的默认模式)。它回退仓库 + 暂存区,但保留工作区的修改。三者对比如下:
| 模式 | 本地仓库 | 暂存区 | 工作区 | 危险程度 |
|---|---|---|---|---|
--soft |
🔄 回退 | ✅ 不变 | ✅ 不变 | 🟢 安全 |
--mixed(默认) |
🔄 回退 | 🔄 回退 | ✅ 不变 | 🟡 中等 |
--hard |
🔄 回退 | 🔄 回退 | 🔄 回退 | 🔴 危险 |
markdown
soft mixed hard
本地仓库 HEAD ✕ ✕ ✕
暂存区 ✓ ✕ ✕
工作区 ✓ ✓ ✕
✓ = 保留 ✕ = 回退(修改丢失)
六、补充:你还会用到的几个命令
bash
# 将暂存区的文件移回工作区(取消 add)
git restore --staged readme.md
# 丢弃工作区的修改(恢复到暂存区的状态)
git restore readme.md
# 查看暂存区和本地仓库的差异
git diff --cached
# 查看工作区和暂存区的差异
git diff
七、为什么 Git 对 Vibe Coding Harness 工程如此重要?
什么是 Vibe Coding?
2025 年 2 月,前特斯拉 AI 总监、OpenAI 联合创始人 Andrej Karpathy 发了一条推文,提出了一个新概念:
"There's a new kind of coding I call 'vibe coding', where you fully give in to the vibes, embrace exponentials, and forget that the code even exists."
"有一种新的编程方式,我称之为'氛围编程'------你完全沉浸在氛围中,拥抱指数级,忘记代码的存在。"
Vibe Coding(氛围编程) 的核心是:用自然语言告诉 AI 你想要什么,AI(Cursor、Claude Code、Copilot 等)自动生成代码,你只看结果,不太深入审查代码本身。
听起来很美对吧?但现实很骨感。
一个真实的翻车故事
我用 Cursor 开发一个 React 待办应用,AI 干得很漂亮------组件拆分清晰,样式精美。第三天,我让 AI "重构一下组件结构,优化性能"。
AI 把三个组件合并成了一个,跑起来没问题,我满意地 commit 了。
三天后,bug 来了。 用户反馈:筛选"已完成"任务时,偶尔会显示未完成的任务。
我翻了半小时代码才找到原因------AI 在重构时,悄悄删掉了一个 useEffect 里的依赖项。那个依赖项负责在筛选条件变化时重置内部状态。删掉后 90% 的场景正常,只有快速切换筛选时才出 bug。
如果没有 Git,我根本不知道是哪次改动引入的。但有了 Git:
bash
git log --oneline
# f4a5b6c 重构:合并组件优化性能 ← 怀疑这次
# 8d2e1f9 feat: 添加筛选功能 ← 这次还正常
# ...
git diff 8d2e1f9 f4a5b6c ← 查看 AI 到底改了什么
# - useEffect(() => { setFilter(defaultFilter) }, [filterType]) ← 找到了!AI 删了这行
一行 git revert f4a5b6c 解决问题。
这就是 Vibe Coding 的真相:AI 的速度是优势,也是风险。而 Git 是你唯一的安全网。
Vibe Coding 的致命陷阱
通过 Vibe Coding,项目推进特别快。但越往后,代码越乱,慢慢变成屎山,越改越差,最后整个项目崩盘。
问题不在于 AI 强不强,而在于:
Vibe Coding 不是说把活丢给 AI,就可以去喝咖啡了。而是你还要构建一套工程流程去驾驭 AI------这就是 Harness Engineering(驾驭工程)。
Git 在 Vibe Coding 中为什么是生命线?
1️⃣ AI 生成的代码需要验证
AI 会"幻觉"------生成看起来像回事、一跑就出错的代码。更可怕的是,AI 可能在你不知情的情况下改坏已有的好代码(就像上面那个翻车故事)。
没有 Git,你连"改坏了什么"都看不出来。
bash
# 每次 AI 生成代码后,立刻 commit 一个安全点
git add .
git commit -m "checkpoint: AI 生成登录模块 v1"
# 如果 AI 下一步改坏了,先看改了什么
git diff
# 只想取消暂存(代码还在工作区)
git restore --staged .
# 彻底丢弃 AI 的修改(确认不需要了)
git restore .
2️⃣ diff 是你审查 AI 的唯一武器
Vibe Coding 的正确姿势不是"闭眼 accept all",而是审查 AI 每次改了什么:
bash
# AI 改完代码后,看看它到底改了啥
git diff
# 如果改得合理,加入暂存
git add .
# 如果改得离谱,丢弃
git restore .
没有 Git diff,你就是在盲开。
3️⃣ 分支是你的实验场
Vibe Coding 中,你经常需要让 AI 尝试不同的方案。分支让你可以安全地"开平行宇宙":
bash
# 方案 A:用 React 实现
git checkout -b feature/react-approach
# ... 让 AI 写代码 ...
# 方案 B:用 Vue 实现(完全不影响方案 A)
git checkout main
git checkout -b feature/vue-approach
# ... 让 AI 写代码 ...
# 最后选择更好的方案
git checkout main
git merge feature/react-approach
4️⃣ commit 历史是你的"后悔药"
Vibe Coding 的开发速度极快,一天可能产生几十次变更。每次有意义的 commit 都是一个存档点:
bash
git log --oneline
# a1b2c3d 完成用户登录功能
# d4e5f6g AI 重构了组件结构(这次改得好)
# 7890abc AI 加了拖拽排序(这次有 bug,已回退)
# ...
当你发现 AI 三天前引入了一个隐蔽的 bug,你可以:
bash
git log --oneline --all # 找到 bug 引入前的版本
git diff abc1234 HEAD # 看看这期间到底改了什么
git bisect start # 自动二分查找 bug 引入点
5️⃣ .gitignore + commit 规范 = 工程纪律
Vibe Coding Harness 工程要求你定规矩:
gitignore
# .gitignore
node_modules/
dist/
.env
*.log
bash
# commit 规范
git commit -m "feat: AI 实现用户注册功能"
git commit -m "fix: 修复 AI 引入的登录 bug"
git commit -m "revert: 回退 AI 的错误重构"
八、Vibe Coding 标准工作流中的 Git 节点
在 Vibe Coding 中,先规划再编码是避免屎山的核心原则。整个流程分三个阶段,Git 在每个阶段都是你的安全网:
阶段一:定图纸(只聊需求,禁止写代码)
🎯 目标:把模糊的想法变成可验收的文档
| 步骤 | 做什么 | 关键产出 | Git 操作 |
|---|---|---|---|
| 1 | 导需求:像和朋友聊天一样,把痛点、目标用户、使用场景、核心功能告诉 AI | 需求草稿 | --- |
| 2 | 整理 PRD:让 AI 输出结构化文档(功能列表、用户流程、页面清单),每个功能补上验收标准 | PRD.md | git commit -m "docs: 确定产品需求" |
| 3 | 定视觉框架:找 2-3 个参考网站,确定布局、风格、配色 | DESIGN.md | git commit -m "docs: 确定设计框架" |
⚠️ 没有验收标准,AI 会越写越发散。"登录成功"不是标准,"登录失败提示什么、成功后跳转到哪"才是。
阶段二:打地基(选技术栈,出架构)
🎯 目标:把"要做什么"变成"怎么实现"
| 步骤 | 做什么 | 关键产出 | Git 操作 |
|---|---|---|---|
| 4 | 明确边界:本地跑还是线上?用户量?有没有支付、用户数据?安全/性能/成本上限? | 需求补充 | git commit -m "docs: 明确非功能需求" |
| 5 | 锁定技术栈:选适合的而非最炫的,越可验证越好 | claude.md | git commit -m "docs: 锁定技术栈" |
| 6 | AI 出架构草案:目录分层、核心模块、数据模型、组件清单 | ARCH.md | git commit -m "docs: 系统架构草案" |
💡 安全、性能、可用性、成本------这四个非功能需求不写清楚,后面一定会返工。
阶段三:立规矩 + 开发(定规范,开始写代码)
🎯 目标:给 AI 套上缰绳,让它在规范内干活
| 步骤 | 做什么 | 关键产出 | Git 操作 |
|---|---|---|---|
| 7 | 固化文档:把 PRD、设计、架构、当前状态写成项目根目录下的几个 md 文件 | PRD.md / ARCH.md / Project.md | git commit -m "docs: 固化项目文档" |
| 8 | 定开发规范:代码规范、错误处理、API 接口规范,给一个样本参考 | 规范文档 | git commit -m "docs: 开发规范" |
| 9 | 搞好 Git 和质量阀门:从此开始,每次 AI 生成代码都走审查流程 | Git 工作流 | 👇 见下方 |
第 9 步的标准 Git 工作流:
sql
AI 生成代码
↓
git diff ← 审查 AI 改了什么
↓
改得好? ──── 是 ───→ git add . → git commit -m "feat: xxx"
│
否
↓
git restore --staged . ← 取消暂存,保留代码
↓
还有用? ──── 是 ───→ 手动修改后再 commit
│
否
↓
git restore . ← 彻底丢弃
九、总结
| 问题 | 答案 |
|---|---|
--soft 回退什么? |
只回退本地仓库的 HEAD |
--hard 回退什么? |
回退全部三个区域(仓库 + 暂存区 + 工作区) |
--soft 会丢代码吗? |
不会,修改保留在暂存区 |
--hard 会丢代码吗? |
会!未 commit 的修改永久丢失 |
| 该用哪个? | 默认 --soft,不确定时分步走,最后才 --hard |
| Vibe Coding 能离开 Git 吗? | 不能。Git 是你的安全网、审查工具和后悔药 |
记住:Vibe Coding 的速度 × Git 的安全 = 真正的生产力。
没有 Git 的 Vibe Coding,就是在悬崖边飙车------速度很快,但翻车就是万丈深渊。
🔥 你在 Vibe Coding 中用 git 救过命吗? 评论区说说你的翻车故事,或者分享你的 Git 小技巧。
💬 你觉得 AI 写的代码,应该每次改动都 commit,还是攒一批再提交? 我是 checkpoint 派------每让 AI 改一次就存一个档,宁可 commit 多一点也不冒丢代码的风险。
📌 下一篇预告:《Vibe Coding 实战:用 Claude Code + Git 从零搭建一个完整项目》------手把手带你走一遍"三阶段九步法"的完整流程。