Git 是我入行以来用得最频繁、也踩坑最多的工具。它的命令看起来都差不多——add、commit、push、pull——但每一条背后都藏着能让你睡不着觉的陷阱。这篇日记记下我踩过的 5 个真实坑,每一个都附上当时的命令和补救方法,希望你能在踩到之前先看到。
坑一:强制推送覆盖了同事的代码
那次我本地 rebase 之后,push 被拒绝,提示远端有新提交。我图省事直接 git push --force,结果把同事半小时前推上去的代码全冲掉了。好在他本地还有,但那次我写了三页检讨。
踩坑命令:
# 危险:直接强推,无视远端新提交
git push --force
正确做法:永远用 --force-with-lease,它会在远端被别人更新过时拒绝推送,相当于带了个安全栓。
# 安全:远端有新提交时会拒绝,避免覆盖别人代码
git push --force-with-lease
坑二:误删分支,以为代码全没了
有次我切到 main 分支后随手 git branch -D feature-login,删完才想起来这个分支还没合并。当时心跳到嗓子眼,以为一上午白干了。后来才知道 Git 几乎不会真的删掉任何东西,分支删除只是丢了指针,提交对象还在。
踩坑命令:
# 误删未合并的分支
git branch -D feature-login
补救方法:用 git reflog 找到该分支最后一次提交的哈希,然后基于它重建分支。
# 查看引用日志,定位最后那次提交的哈希
git reflog
# 哈希形如 abc1234,基于它重新创建分支
git branch feature-login abc1234
坑三:合并冲突一通乱改,结果代码跑不起来
合并分支时遇到冲突,我图快把所有 <<<<<<< 标记随便删了,留了一半旧代码一半新代码。push 上去之后 CI 直接红了,因为文件里残留了冲突标记,语法都过不了。
踩坑命令:
git merge feature-branch
# 冲突来了,手忙脚乱地改文件……
正确姿势:冲突要一个文件一个文件地看,改完用 git add 标记已解决,最后再 commit。改完一定要本地跑一遍再 push。
# 查看哪些文件有冲突
git status
# 逐个文件解决后,标记已解决
git add <file>
# 全部解决后继续合并
git commit
坑四:.gitignore 没生效,node_modules 被提交了
这个坑几乎所有新手都踩过。我在项目里加了个 .gitignore 写了 node_modules,结果发现它已经被追踪了,再写忽略规则也没用——.gitignore 只对未追踪的文件生效。
踩坑命令:
# 错误示范:已经被追踪的文件,gitignore 管不到
git add node_modules
git commit -m "oops"
补救方法:先从暂存区移除(但保留本地文件),再提交,之后 .gitignore 才会生效。
# 从 Git 索引移除,但保留本地文件(--cached 关键)
git rm -r --cached node_modules
git commit -m "stop tracking node_modules"
坑五:回滚用错了命令,把别人的提交也撤了
有次线上出问题要回滚一次提交,我直接用了 git reset --hard HEAD~1 然后 force push。结果不仅撤掉了我的提交,还把后面同事的两个提交一起干掉了。那一刻会议室里所有人都看着我。
踩坑命令:
# 危险:reset 会改写历史,公共分支上等于删别人的提交
git reset --hard HEAD~1
git push --force
正确做法:在公共分支上回滚,永远用 git revert,它会产生一个反向提交,不改写历史,安全可追溯。
# 安全:生成一个反向提交,不改写历史
git revert <commit-hash>
git push
Git 的危险命令大多看起来无害。养成"公共分支不 reset、不 force"的习惯,能避开 90% 的灾难。
写在最后
这 5 个坑教会我一件事:Git 的命令不难,难的是知道每条命令改写了什么。背命令没意义,理解"工作区、暂存区、本地仓库、远端仓库"这四个区域的关系,才是关键。理解了之后,你会发现大部分坑都能自己推导出来避开。希望这份清单能让你少出几身冷汗。