用了三年 Git,我依然每周至少 Google 两次 Git 命令。不是不会用,是有些操作一个月才遇到一次,每次都记不住。上周 merge 出了冲突,我又条件反射打开浏览器搜"git 怎么撤销 merge"——搜完之后我决定,把这些反复 Google 的操作整理成一篇速查表,以后直接查这篇。
这是我踩得最多的——手速太快,git commit -m "fix" 回车完才发现,应该写清楚改了什么。
# 改最近一次的 commit 信息(还没 push 的情况下)
git commit --amend -m "fix: 修复登录页表单验证逻辑"
注意:如果已经 push 了,amend 会改变 commit hash,再 push 需要 --force。 如果是团队协作的分支,不要 force push,改用新 commit。
写了一小时代码,突然发现自己在 main 上改的,不是 feature 分支。
# 把当前改动暂存起来
git stash
# 切到正确的分支
git checkout feature/login
# 把暂存的改动拿出来
git stash pop
git stash 就像一个"临时口袋",把没提交的改动先装进去,换完分支再掏出来。
这个坑不是不知道怎么解决冲突,而是解决到一半不想解决了,想撤回去。
# 取消这次 merge,回到 merge 之前的状态
git merge --abort
如果已经解决完冲突但还没 commit,想重新来过:
# 放弃所有冲突解决的改动
git checkout --conflict=merge .
手滑 git add . 把 .env 或 node_modules 加进去了。
# 从暂存区移除,但保留本地文件
git reset HEAD .env
# 如果已经 commit 了,需要从历史中删除
git rm --cached .env
echo ".env" >> .gitignore
git commit -m "chore: 移除误提交的 .env 文件"
预防方法:项目第一天就把 .gitignore 配好。别问我怎么知道的。
commit 之后发现漏了一个文件,或者想把两个 commit 合成一个。
# 撤销 commit,但代码改动保留在暂存区
git reset --soft HEAD~1
# 撤销 commit,代码改动保留但不在暂存区
git reset --mixed HEAD~1
# ⚠️ 撤销 commit,代码改动也丢弃(慎用!)
git reset --hard HEAD~1
三种 reset 的区别,一张图:
| 模式 | commit | 暂存区 | 工作目录 | 适用场景 |
|---|---|---|---|---|
--soft |
撤销 | 保留 | 保留 | 想重新组织 commit |
--mixed |
撤销 | 清空 | 保留 | 想重新选择要 add 的文件 |
--hard |
撤销 | 清空 | 清空 | 这次改动彻底不要了 |
每个人职业生涯里至少 --hard 错一次。别慌:
# 查看所有操作记录(包括已经"删掉"的 commit)
git reflog
# 找到你想恢复的那个 commit hash,然后
git reset --hard abc1234
reflog 是 Git 的"后悔药",它记录了你所有的 HEAD 移动历史,包括 reset 掉的。只要没 git gc,30 天内都能找回来。
不记得这个文件上周长什么样了,想对比一下。
# 看某个文件在某次 commit 时的内容
git show abc1234:src/utils/auth.js
# 对比当前版本和上一次 commit 的差异
git diff HEAD~1 -- src/utils/auth.js
# 对比两个分支之间某个文件的差异
git diff main..feature/login -- src/utils/auth.js
不想 merge 整个分支,只想拿其中一个 commit 的改动过来。
# cherry-pick:把指定 commit 的改动应用到当前分支
git cherry-pick abc1234
常见场景:在 dev 上修了一个 bug,想把这个修复也带到 release 分支,但不想把 dev 上其他未完成的功能也带过去。
开了一堆 feature/xxx 分支,合并完忘了删,git branch 列出来一屏都放不下。
# 查看哪些分支已经合并到 main(可以安全删除)
git branch --merged main
# 删除已合并的本地分支
git branch --merged main | grep -v "main" | xargs git branch -d
# 清理远程已删除但本地还有引用的分支
git fetch --prune
同事在你之前 push 了,你的本地落后于远程。
# 方案一:先拉再推(会产生一个 merge commit)
git pull
git push
# 方案二:rebase 后推(保持线性历史,更干净)
git pull --rebase
git push
团队约定用哪种就用哪种。 我个人偏好 --rebase,因为 git log 更干净。但有些团队觉得 merge commit 能清晰看到"谁什么时候合并了什么"。
| 场景 | 命令 | 说明 |
|---|---|---|
| 改 commit 信息 | git commit --amend -m "新信息" |
未 push 时用 |
| 改错分支了 |
git stash → 切分支 → git stash pop
|
临时口袋 |
| 取消 merge | git merge --abort |
冲突解决到一半想撤回 |
| 撤销 add | git reset HEAD 文件名 |
从暂存区移除 |
| 撤销 commit 保留代码 | git reset --soft HEAD~1 |
最常用 |
| 找回 hard 删掉的代码 |
git reflog → git reset --hard hash
|
后悔药 |
| 看文件历史版本 | git show hash:文件路径 |
|
| 只拿一个 commit | git cherry-pick hash |
不 merge 整个分支 |
| 删已合并的分支 | `git branch --merged main \ | xargs git branch -d` |
| push 被拒绝 |
git pull --rebase → git push
|
保持线性历史 |
如果你和我一样经常忘 Git 命令,在 ~/.bashrc 或 ~/.zshrc 里加几个 alias:
alias gs="git status"
alias gl="git log --oneline -10"
alias gco="git checkout"
alias gcm="git commit -m"
alias gst="git stash"
alias gsp="git stash pop"
不用记命令了,记缩写就行。
Git 这东西,用了十年的人也经常 Google。不是因为难,是因为有些操作真的一个月才用一次。这篇速查表我自己也会收藏,以后忘了直接查。
你最常 Google 的 Git 命令是什么? 评论区补充,我加到速查表里。