Git 里最容易用错的六个操作
先说在前面
Git 的难处不在命令多,而在于不少命令名字相近、行为差别很大,一旦用错就会丢掉还没提交的代码。下面六个是我见过最高频的混淆点,按「用错的后果」从轻到重排。
1. git restore 和 git reset 不是一回事
只想把工作区某个文件恢复到上一次提交的样子,用 restore;reset 动的是 HEAD 和暂存区。
git restore app.py # 丢弃工作区改动
git restore --staged app.py # 只从暂存区撤出,工作区不动
git reset --soft HEAD~1 # 撤销提交,改动留在暂存区
git reset --hard HEAD~1 # 撤销提交并丢弃所有改动(不可恢复)
最容易出事的是 --hard。真手滑了也别慌,先用 git reflog 找到之前的 commit hash,再 git reset --hard <hash> 通常还能救回来——前提是别顺手清理 reflog。
2. git pull 之前先看清楚
默认的 git pull 等于 fetch + merge,会在多人同时提交时生成一堆「Merge branch ...」的噪音提交。团队里更常见的约定是:
git pull --rebase
# 或者把它设成默认
git config --global pull.rebase true
注意:已经 push 出去、别人可能基于它工作的提交,不要再用 rebase 改写历史。
3. stash 不是保险箱
git stash 默认只存已跟踪文件的改动,新建的未跟踪文件不会被收进去。想连新文件一起存,要加 -u:
git stash push -u -m "wip: 登录页改到一半"
git stash list
git stash pop # 应用并删除;想保留用 apply
还有一点:pop 遇到冲突时 stash 不会被删除,很多人以为「已经恢复了」就不再管,结果改动一直躺在栈里。恢复后记得 git stash list 看一眼。
4. commit --amend 只改最后一次
补文件或改提交信息时用 git commit --amend 很方便,但它会生成一个新的 commit 对象。如果这个提交已经 push 过,就要 git push --force-with-lease(比 --force 安全,会检查远程有没有被别人更新过)。再往前的历史要用 git rebase -i HEAD~3。
5. 别在 .gitignore 里救已经跟踪的文件
把 .env 加进 .gitignore 之后发现它还是被提交着——因为它早就被 Git 跟踪了,忽略规则只作用于未跟踪文件。正确做法是先从索引里移除:
git rm --cached .env
git commit -m "stop tracking .env"
--cached 只删索引不改本地文件,别忘了这一步;直接 git rm .env 会把文件一起删掉。已经进过历史的密钥,光停止跟踪不够,还得考虑轮换。
6. 分支名删错了怎么找回来
git branch -D 删掉了还没合并的分支,提交对象其实还在,只是没有引用指向它。git reflog 里找到那个提交的 hash,再 git checkout -b recovered <hash> 就能重建。Git 的「删除」大多数情况下只是「解除引用」,真正清理要等 gc。
小结
把这六条记住,基本能覆盖日常八成的 Git 事故。真正的兜底其实是 git reflog——它记录了 HEAD 的每一次移动,很多看似不可逆的操作,都能从这里找回来。
- 点赞
- 收藏
- 关注作者
评论(0)