Git 日常用到的命令其实不多,真正让人慌的是"改错了怎么撤"。这篇把高频命令和撤销场景整理成一张对照表,需要的时候直接查。
日常高频命令
# 状态与差异
git status # 查看工作区状态
git diff # 未暂存的改动
git diff --staged # 已暂存的改动
# 提交与同步
git add -A # 暂存所有改动
git commit -m "feat: 说明" # 提交
git pull --rebase # 拉取并变基,避免多余 merge 节点
git push # 推送
# 分支
git switch -c feature/xxx # 新建并切换分支
git switch main # 切回主分支
git branch -d feature/xxx # 删除已合并的分支
# 临时存放
git stash # 暂存未提交的改动
git stash pop # 恢复最近一次 stash
撤销操作对照表
先明确三个区域:工作区(已修改未 add)、暂存区(已 add 未 commit)、版本库(已 commit)。不同区域用不同的命令。
- 丢弃工作区某个文件的改动 →
git restore <file> - 把文件从暂存区撤回工作区 →
git restore --staged <file> - 修改上一次的提交信息 →
git commit --amend -m "新信息" - 撤销某次提交但保留历史 →
git revert <commit> - 回退到某次提交并抹掉之后的历史 →
git reset --hard <commit>
reset 的三种模式
reset 最容易用错的是参数,区别只在于"动到哪一层":
--soft:只移动 HEAD,改动留在暂存区。适合把多个提交合并成一个。--mixed(默认):移动 HEAD 并重置暂存区,改动留在工作区。--hard:HEAD、暂存区、工作区全部重置,改动直接丢弃。
--hard 是唯一会真正弄丢代码的选项。执行前先确认改动已经 commit 或 stash,否则找不回来。
reset 还是 revert
判断标准只有一条:这个分支有没有别人在用。
- 本地分支、尚未推送:用
reset,历史干净,像什么都没发生过。 - 已经推送到远程、或多人协作:必须用
revert。它会新增一个"反向提交"来抵消之前的改动,不改写历史,不会让队友的本地仓库和远程冲突。
rebase 的适用边界
rebase 的作用是"把我的改动接到最新的基线上",好处是历史是一条直线,没有分叉。但它会改写提交,所以遵循一条铁律:
只对尚未推送的本地提交做 rebase,永远不要 rebase 已经共享的分支。
日常最安全的用法是拉取时用 git pull --rebase,它只变基你本地那些还没推上去的提交。也可以在全局配置里一劳永逸:
git config --global pull.rebase true
小结
撤销之前先问自己两件事:改动在哪个区域?这个分支有没有别人?前者决定用 restore 还是 reset,后者决定用 reset 还是 revert。想清楚这两点,基本不会出事。
— 全文完 —