正在加载,请稍候…

Git 高级命令:Rebase、Cherry-pick、Bisect 和 Stash

掌握 Git 高级命令:交互式 rebase、cherry-pick 特定提交、bisect 二分查找 bug、reflog 恢复以及强大的 stash 工作流

Git 高级命令:Rebase、Cherry-pick、Bisect 和 Stash

超越 git add 和 git commit

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

Git 高级命令:Rebase、Cherry-pick、Bisect 和 Stash 插图

交互式 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 高级命令:Rebase、Cherry-pick、Bisect 和 Stash 插图

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 高级命令:Rebase、Cherry-pick、Bisect 和 Stash 插图

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 命令。