
超越 git add 和 git commit
大多数开发者只使用了 Git 约 10% 的功能。剩下的 90%——当你需要时——决定了解决问题是花 2 分钟还是 2 小时。本指南涵盖那些能改变你工作方式的 Git 命令。

交互式 Rebase:重写历史
# 在推送前清理最近 5 个提交
git rebase -i HEAD~5
# 打开编辑器,显示:
pick a1b2c3d Fix: handle null user
pick b2c3d4e WIP: add validation
pick c3d4e5f Add more validation
pick d4e5f6g Fix typo in validation
pick e5f6g7h Add tests for validation
# 将 'pick' 改为:
# r/reword — 修改提交信息
# s/squash — 合并到前一个提交(保留两条信息)
# f/fixup — 合并到前一个(丢弃此提交的信息)
# d/drop — 完全删除提交
# e/edit — 暂停并允许你修改提交
# 结果:干净的历史,讲述一个故事
pick a1b2c3d Fix: handle null user
reword c3d4e5f Add user input validation
squash d4e5f6g fix typo
fixup b2c3d4e WIP cleanup
pick e5f6g7h Add tests for validation
# 将特性分支变基到更新的 main 上
git checkout feature/my-feature
git rebase main
# 如果发生冲突:
git rebase --continue # 解决后继续
git rebase --abort # 重新开始
# 使用 autosquash 变基(提交信息中带 squash! 前缀)
git commit --fixup HEAD~2 # 创建 "fixup! <原始信息>"
git rebase -i --autosquash HEAD~5 # 自动合并 fixup 提交
Cherry-pick:应用特定提交
# 将单个提交从另一个分支应用到当前分支
git cherry-pick a1b2c3d
# Cherry-pick 一段范围的提交
git cherry-pick a1b2c3d..e5f6g7h # 不包括第一个
git cherry-pick a1b2c3d^..e5f6g7h # 包括第一个
# Cherry-pick 但不提交(先审查)
git cherry-pick --no-commit a1b2c3d
# Cherry-pick 并编辑提交信息
git cherry-pick -e a1b2c3d
# 常见用例:将热修复部署到 main 和特性分支
git checkout main
git cherry-pick fix-commit-hash
git checkout feature/new-feature
git cherry-pick fix-commit-hash

git bisect:二分查找 Bug
当你知道“这个版本能工作,但那个版本坏了”时:
# 开始二分查找
git bisect start
# 标记当前提交为 bad(存在 bug)
git bisect bad
# 标记最后一个已知的好提交
git bisect good v1.2.0 # 标签
# 或
git bisect good a1b2c3d # 提交哈希
# Git 检出中间的提交——测试它
# 如果 bug 存在:
git bisect bad
# 如果 bug 不存在:
git bisect good
# Git 不断缩小范围,直到找到罪魁祸首
# Bisecting: 25 revisions left to test after this (roughly 5 steps)
# [a1b2c3d] Add new feature X
# ...
# [c3d4e5f] is the first bad commit!
# 结束二分查找会话
git bisect reset
# 自动化二分查找(使用测试脚本)
git bisect start HEAD v1.2.0
git bisect run npm test # 自动在每个提交上运行测试
git stash:临时搁置
# 暂存所有更改(已暂存和未暂存)
git stash
# 带描述信息暂存
git stash push -m "WIP: adding payment validation"
# 包含未跟踪的文件
git stash push --include-untracked
# 列出所有暂存
git stash list
# stash@{0}: WIP: adding payment validation
# stash@{1}: On main: quick fix attempt
# 应用最近的暂存(保留在暂存列表中)
git stash apply
# 应用并从暂存列表中移除
git stash pop
# 应用特定暂存
git stash apply stash@{2}
# 从暂存创建分支
git stash branch feature/payment-from-stash stash@{0}
# 删除一个暂存
git stash drop stash@{0}
# 清除所有暂存
git stash clear

git reflog:时间机器
Reflog 记录每一次 HEAD 移动——你的安全网:
# 查看所有最近的 HEAD 更改
git reflog
# a1b2c3d HEAD@{0}: commit: Add new feature
# b2c3d4e HEAD@{1}: rebase finished: returning to refs/heads/main
# c3d4e5f HEAD@{2}: reset: moving to HEAD~1
# d4e5f6g HEAD@{3}: commit: WIP: new feature
# 恢复意外 reset 后“丢失”的提交
git reset --hard HEAD~3 # "我删除了最后 3 个提交!"
git reflog # 找到提交哈希
git reset --hard HEAD@{3} # 恢复!
# 撤销错误的 rebase
git reflog # 找到变基前的提交
git reset --hard HEAD@{before-rebase}
高级 Diff 和 Log
# 可视化分支图
git log --oneline --graph --all --decorate
# 分支之间的差异
git diff main..feature/my-branch
# 显示某个提交的更改
git show a1b2c3d
# 谁改了这一行?(带上下文的 blame)
git blame -L 42,56 src/auth.ts
git log -S "functionName" --source --all # 查找字符串何时出现/消失
# 特定文件的更改
git log --follow --all -p -- src/deleted-file.ts
# 尚未合并到 main 的提交
git log main..HEAD --oneline
强大的别名
# 添加到 ~/.gitconfig
[alias]
# 紧凑状态
st = status -sb
# 漂亮的日志
lg = log --oneline --graph --all --decorate
# 最近的分支
recent = for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(refname:short)'
# 撤销上次提交(保留更改暂存)
undo = reset --soft HEAD~1
# 修改上次提交而不更改信息
amend = commit --amend --no-edit
# 清理已合并的分支
cleanup = "!git branch --merged main | grep -v main | xargs -n 1 git branch -d"
# 我今天做了什么?
today = log --since=midnight --author="$(git config user.name)" --oneline
有用的 Git 工作流
# 场景:在开发特性过程中需要快速修复 bug
git stash push -m "WIP: feature X" # 保存当前工作
git checkout main
git checkout -b fix/critical-bug
# ... 进行修复 ...
git commit -am "Fix: critical bug"
git checkout main
git merge fix/critical-bug
git checkout feature/x
git stash pop # 恢复工作
# 场景:提交到了错误的分支
git log --oneline -3 # 找到提交
git reset --soft HEAD~1 # 取消提交(保留更改)
git stash
git checkout correct-branch
git stash pop
git commit -m "Same message"
# 场景:只包含文件中的部分更改
git add -p src/feature.ts # 交互式暂存——选择代码块
→ 使用内置的 Git Memo 快速参考常用 Git 命令。