把 Git 当"后悔药"用:一个大三程序员的版本控制踩坑史

把 Git 当"后悔药"用:一个大三程序员的版本控制踩坑史

以前我觉得 Git 是"上传代码的工具";后来发现,它真正的价值是——让你有底气删掉任何东西。

大三上做 ERP 项目时,我干过一件蠢事:本地改崩了,一气之下 rm -rf 删了整个项目目录,然后才想起来没提交。那一晚上的进度,全没了。

从那之后,我开始认真把 Git 当成"后悔药"来用。下面是我踩过的六个坑,以及现在的工作流。


坑一:git reset --hard,让我丢了一整晚的作业

刚学 Git 时,看到工作区一堆红字(未提交改动),我嫌烦,直接:

git reset --hard HEAD

然后发现——昨晚写的 300 行全没了。reset --hard 不会进回收站,它是物理删除。

保命命令是 git reflog:它记录你的每一次 HEAD 移动,哪怕你 reset 过、checkout 过,都能找回。

git reflog
# a1b2c3d HEAD@{0}: reset: moving to HEAD~1
# e4f5g6h HEAD@{1}: commit: 完成订单导出功能   ← 我要的!

git checkout e4f5g6h          # 先看看当时长啥样
git checkout -b save-my-work  # 开个分支把代码留住

现在我给自己的铁律:删东西之前,先 git commit 一次。commit 了就进历史,reflog 兜底,天塌不下来。


坑二:直接往 main 上怼,冲突到怀疑人生

团队项目早期,我们五个人全在 main 上改。某次我想 pull,Git 报了一屏冲突,我硬着头皮手动改,结果把队友的支付逻辑删了,上线当天收款失败。

现在的标准动作是 feature 分支 + PR(Pull Request)

git checkout -b feature/order-export main   # 从 main 切出新分支
# ... 写代码,多次小提交 ...
git push -u origin feature/order-export      # 推远端,提 PR

好处:主干永远是可运行的版本;冲突在 PR 里小范围解决,而不是在发布前大爆炸。


坑三:merge 还是 rebase?我终于想明白了

这是个经典纠结。简单说:

  • git merge:保留真实历史,但会产生大量 merge commit,历史线像毛线球。
  • git rebase:把你的提交"重放"到最新主干上,历史是一条干净的直线,但改写了提交历史

我的现行规则:

# 本地未推送的提交:用 rebase 保持线性
git fetch origin
git rebase origin/main      # 把我的提交接在最新 main 后面

# 已经 push 到远端的提交:只用 merge,绝不对公共分支 rebase
git merge origin/main

一句话记忆:私有分支随便 rebase,公共历史碰都别碰。


坑四:.gitignore 没写好,node_modules 传上去了

第一次用 create-react-app,傻乎乎地把整个 node_modules(300MB+)add 了进去。后来招人看我仓库,clone 五分钟没下完。

现在每个项目初始化第一件事就是写 .gitignore,前端和 Python 各一份模板:

# Python
__pycache__/
*.pyc
.venv/
.env

# Node
node_modules/
dist/
npm-debug.log

# 通用
.DS_Store
.idea/
*.log

提示:如果已经误提交了大文件,光加 .gitignore 不够,得把它从历史里抠掉(git rm --cached + 重写历史,或引入 git lfs)。


坑五:git stash 救过我三次命

场景很常见:你正在 feature 分支改到一半,导师突然让你修一个 main 上的紧急 Bug。代码没写完不能 commit,又得切分支。

以前我会把改动复制粘贴到记事本——蠢到家。git stash 才是正解:

git stash push -m "订单导出做到一半"   # 把改动藏起来
git checkout main
git checkout -b hotfix/login-bug        # 去修紧急 Bug
# ... 修完提交 ...
git checkout feature/order-export
git stash pop                            # 把藏起来的改动还原回来

-m 加描述很重要,stash 多了你不记得哪个是哪个。


坑六:commit message 写 "fix",三个月后看不懂

早期我的提交记录是这样的:

fix
fix again
really fix
update

半年后回看,完全不知道当时改了啥。后来我套用了 Conventional Commits 规范,门槛很低但收益巨大:

<type>(<scope>): <subject>

# 示例
feat(order): 支持导出 Excel 报表
fix(pay): 修复微信支付回调重复入账
refactor(user): 抽离权限校验为中间件
docs(readme): 补充本地启动步骤

常用 type:feat(新功能)、fix(修 Bug)、refactor(重构)、docs(文档)、test(测试)、chore(杂事)。

好处是 git log --oneline 一眼能扫出项目演进,CI 甚至能根据 type 自动决定是否发版。


总结:Git 不是上传工具,是安全网

回头看这六个坑,本质都是同一个问题——把 Git 当成了"把代码发出去"的按钮,而不是"随时能回退"的保险

我现在的 Git 工作流可以浓缩成三句话:

  1. 小步提交:别等"做完再提交",提交越碎,回退越精准。
  2. 主干保护:所有改动走分支 + PR,main 永远能跑。
  3. 敢删敢试:只要 commit 了就进历史,reflog 兜底,放心折腾。

Git 最迷人的地方在于——它假设你会犯错,所以给你留了无数次后悔的机会。问题是,很多人(包括曾经的我)根本不知道这些机会在哪。

(写于 2026 年夏,ERP 项目复盘之余)

posted @ 2026-07-13 15:04  C(5,3)  阅读(10)  评论(0)    收藏  举报