← 返回文章列表

Git 日常操作与四类常见事故的恢复方法

Git命令行避坑

先记住:绝大多数操作都能恢复

Git 的提交几乎不会真正消失:reset、rebase、误删分支之后,提交对象仍然留在对象库里,直到被垃圾回收。reflog 记录了 HEAD 的每一次移动,是找回内容的第一选择——先用 git reflog 找到目标哈希,再 git checkout <hash> 查看,或 git reset --hard <hash> 回到那个点。

日常高频命令

场景命令说明
查看状态git status -sb简洁显示分支与改动
暂存部分改动git add -p逐块选择,避免误提交调试代码
临时存放git stash push -m "msg"切分支前暂存,回来用 pop 恢复
修改上一次提交git commit --amend仅用于尚未推送的提交
查看某行的来源git blame -L 10,20 file定位问题引入点
二分定位坏提交git bisect start在好/坏提交之间自动二分

四类常见事故与处理

  1. 提交错分支:git reset --soft HEAD~1 撤回提交但保留改动,再切到正确分支提交;
  2. 已推送的错误提交:不要对公共分支 force push,改用 git revert <commit> 生成反向提交;
  3. 误删分支:git reflog 找到该分支最后一次提交的哈希,git branch <name> <hash> 重建分支;
  4. 改动被覆盖:git fsck --lost-found 可找回悬空对象,配合 git show <hash> 确认内容后再恢复。

团队协作的三条底线

  • 公共分支不 rebase、不 force push:会重写他人已经基于其工作的历史;
  • 提交信息写清「为什么」:改动本身看 diff 就知道,动机看不出来;
  • 大改动拆成小提交:便于回滚、评审与二分定位。

建议的分支与提交节奏

  1. 从主干拉出短生命周期分支,一个分支对应一个可交付的改动;
  2. 本地先整理提交(squash / fixup),再推送到远端;
  3. 合并前同步主干,冲突在本地解决,不在网页端硬改;
  4. 合并后删除分支,保持仓库整洁。

常见问题

reset、revert、checkout 怎么选?reset 移动分支指针(改写历史,适合未推送的提交),revert 生成反向提交(不改写历史,适合已推送的提交),checkout 只是切换去查看。git pull 和 git fetch 有什么区别?pull = fetch + 合并;想先看清差异时,用 fetch 再手动合并更安全。如何撤销已 add 但未提交的内容?git restore --staged <file>,工作区改动会保留。

分支策略与协作约定

日常使用 Git 时,真正影响协作效率的不是命令熟练度,而是分支与提交的约定是否清晰。

  1. 提交要能单独回滚:每个提交应完成一件完整的事,避免把格式化与功能修改混在一起。混合提交会让回滚变成两难:要么带着无关改动回退,要么放弃想保留的修改。
  2. 提交信息写清“为什么”:标题说明改了什么,正文说明为什么这样改、有哪些取舍。半年后回溯时,原因比改动本身更有价值。
  3. 小步提交、及时合并:长期存在的分支会持续累积冲突,且与主干差异越大,合并风险越高。应以天为单位合并,而不是以周或月。
  4. 保护主干:主干禁止直接推送,要求评审与自动化检查通过。强行推送与改写公共历史应被明确禁止,它会破坏其他人的本地仓库。
  5. 约定同步方式:明确团队使用变基还是合并来同步主干,并保持一致。两种方式混用会造成历史难以阅读,也容易出现重复提交。

历史清理的边界

改写历史只应作用于尚未共享的本地提交。已经推送并被他人拉取的分支不应重新改写,遇到错误应使用反向提交来纠正,这样所有人的本地仓库都能正常同步。

仓库体积与历史治理

长期运行的仓库要关注体积增长,尤其是曾经提交过大文件或二进制资源的情况。定期检查包体积与大对象清单,必要时用专门工具做历史瘦身。日常提交时避免把构建产物与依赖目录纳入版本控制,能省去日后大量清理工作。