git-rebase-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGit Rebase Patterns
Git Rebase 进阶模式
Advanced rebase techniques for maintaining linear history, managing stacked PRs, and cleaning up commit history.
用于维护线性历史、管理堆叠PR和清理提交历史的高级变基技巧。
When to Use This Skill
适用场景
| Use this skill when... | Use something else when... |
|---|---|
| Rebasing feature branches onto updated main | Creating branches → |
| Cleaning up commit history before PR | Creating PRs → |
| Managing stacked PRs (PR chains) | Simple commits → |
| Converting merge-heavy branches to linear | Basic git operations → |
| 适用场景... | 其他场景(使用其他方法)... |
|---|---|
| 将功能分支变基到已更新的main分支 | 创建分支 → |
| 提交PR前清理提交历史 | 创建PR → |
| 管理堆叠PR(PR链) | 简单提交 → |
| 将频繁合并的分支转换为线性历史 | 基础Git操作 → |
Linear History Basics
线性历史基础
Trunk-Based Development
基于主干的开发
bash
undefinedbash
undefinedFeature branch lifecycle (keep short - max 2 days)
功能分支生命周期(保持简短 - 最多2天)
git switch main
git pull origin main
git switch -c feat/user-auth
git switch main
git pull origin main
git switch -c feat/user-auth
Daily rebase to stay current
每日变基以保持同步
git switch main && git pull
git switch feat/user-auth
git rebase main
git switch main && git pull
git switch feat/user-auth
git rebase main
Interactive cleanup before PR
提交PR前进行交互式清理
git rebase -i main
git rebase -i main
Squash, fixup, reword commits for clean history
合并、修正、重写提交以获得整洁的历史
Push and create PR
推送并创建PR
git push -u origin feat/user-auth
undefinedgit push -u origin feat/user-auth
undefinedSquash Merge Strategy
合并压缩策略
Maintain linear main branch history:
bash
undefined维护main分支的线性历史:
bash
undefinedManual squash merge
手动压缩合并
git switch main
git merge --squash feat/user-auth
git commit -m "feat: add user authentication system
- Implement JWT token validation
- Add login/logout endpoints
- Create user session management
Closes #123"
undefinedgit switch main
git merge --squash feat/user-auth
git commit -m "feat: add user authentication system
- Implement JWT token validation
- Add login/logout endpoints
- Create user session management
Closes #123"
undefinedInteractive Rebase Workflow
交互式变基工作流
Clean up commits before sharing:
bash
undefined分享前清理提交:
bash
undefinedRebase last 3 commits
变基最近3个提交
git rebase -i HEAD~3
git rebase -i HEAD~3
Common rebase commands:
常用变基命令:
pick = use commit as-is
pick = 保留原提交
squash = combine with previous commit
squash = 与上一个提交合并
fixup = squash without editing message
fixup = 合并到上一个提交且不修改提交信息
reword = change commit message
reword = 修改提交信息
drop = remove commit entirely
drop = 完全移除提交
Example rebase todo list:
变基任务列表示例:
pick a1b2c3d feat: add login form
fixup d4e5f6g fix typo in login form
squash g7h8i9j add form validation
reword j1k2l3m implement JWT tokens
undefinedpick a1b2c3d feat: add login form
fixup d4e5f6g fix typo in login form
squash g7h8i9j add form validation
reword j1k2l3m implement JWT tokens
undefinedAdvanced Rebase Flags
高级变基参数
Reapply Cherry-Picks (--reapply-cherry-picks
)
--reapply-cherry-picks重新应用Cherry-Picks (--reapply-cherry-picks
)
--reapply-cherry-picksProblem: After merging trunk into your feature branch multiple times (via ), you want to rebase onto fresh trunk. Default rebase behavior may create conflicts or duplicate commits.
git merge mainSolution: detects commits that were already applied via merge and drops the merge commits, keeping only your original changes.
--reapply-cherry-picksbash
undefined问题: 多次将主干合并到功能分支后(通过),你想要将分支变基到最新的主干。默认的变基行为可能会产生冲突或重复提交。
git merge main解决方案: 可以检测到已通过合并应用的提交,并丢弃合并提交,只保留你原本的修改。
--reapply-cherry-picksbash
undefinedScenario: You merged main into your branch a few times
场景:你已多次将main合并到你的分支
git log --oneline
git log --oneline
abc123 Merge branch 'main' into feat/auth
abc123 Merge branch 'main' into feat/auth
def456 feat: add login endpoint
def456 feat: add login endpoint
ghi789 Merge branch 'main' into feat/auth
ghi789 Merge branch 'main' into feat/auth
jkl012 feat: add user validation
jkl012 feat: add user validation
Rebase onto fresh main, dropping merge commits
变基到最新的main,丢弃合并提交
git fetch origin
git rebase --reapply-cherry-picks origin/main
git fetch origin
git rebase --reapply-cherry-picks origin/main
Result: Clean linear history with just your feature commits
结果:仅保留功能提交的整洁线性历史
jkl012 feat: add user validation
jkl012 feat: add user validation
def456 feat: add login endpoint
def456 feat: add login endpoint
**When to use:**
- After merging trunk into your branch to resolve conflicts
- Converting a merge-heavy branch to linear history
- Before creating a PR to clean up integration merges
**适用场景:**
- 合并主干到分支以解决冲突后
- 将频繁合并的分支转换为线性历史
- 提交PR前清理集成合并记录Update Refs (--update-refs
)
--update-refs更新引用 (--update-refs
)
--update-refsProblem: With stacked PRs (PR chains), rebasing one branch requires manually rebasing all dependent branches. Moving commits between branches in the stack is painful.
Solution: automatically updates all branches in the chain when you rebase. Combined with interactive rebase, you can reorganize commits across your entire PR stack in one operation.
--update-refsbash
undefined问题: 在使用堆叠PR(PR链)时,变基一个分支需要手动变基所有依赖分支。在栈中不同分支间移动提交非常繁琐。
解决方案: 会在你变基时自动更新链中的所有分支。结合交互式变基,你可以在一次操作中重新组织整个PR栈中的提交。
--update-refsbash
undefinedScenario: Stacked PRs
场景:堆叠PR
main <- feat/auth-base <- feat/auth-oauth <- feat/auth-refresh
main <- feat/auth-base <- feat/auth-oauth <- feat/auth-refresh
Rebase the entire stack onto updated main
将整个栈变基到已更新的main
git switch feat/auth-refresh
git rebase --update-refs main
git switch feat/auth-refresh
git rebase --update-refs main
All three branches (auth-base, auth-oauth, auth-refresh) are updated
所有三个分支(auth-base、auth-oauth、auth-refresh)都会被更新
No manual rebasing of each branch needed
无需手动逐个分支变基
Interactive rebase to move commits between branches
交互式变基以在分支间移动提交
git rebase -i --update-refs main
git rebase -i --update-refs main
In the editor, move commit lines around to reorganize the stack:
在编辑器中,移动提交行以重新组织栈:
pick abc123 feat: add auth base # Will update feat/auth-base
pick abc123 feat: add auth base # 将更新feat/auth-base
pick def456 feat: add OAuth support # Will update feat/auth-oauth
pick def456 feat: add OAuth support # 将更新feat/auth-oauth
pick ghi789 feat: add token refresh # Will update feat/auth-refresh
pick ghi789 feat: add token refresh # 将更新feat/auth-refresh
**Stacked PR workflow with update-refs:**
```bash
**结合update-refs的堆叠PR工作流:**
```bashCreate PR stack
创建PR栈
git switch main
git pull origin main
git switch main
git pull origin main
First PR: Base authentication
第一个PR:基础认证
git switch -c feat/auth-base
git switch -c feat/auth-base
... make commits ...
... 提交修改 ...
git push -u origin feat/auth-base
git push -u origin feat/auth-base
Second PR: OAuth (depends on first)
第二个PR:OAuth(依赖第一个PR)
git switch -c feat/auth-oauth
git switch -c feat/auth-oauth
... make commits ...
... 提交修改 ...
git push -u origin feat/auth-oauth
git push -u origin feat/auth-oauth
Third PR: Token refresh (depends on second)
第三个PR:Token刷新(依赖第二个PR)
git switch -c feat/auth-refresh
git switch -c feat/auth-refresh
... make commits ...
... 提交修改 ...
git push -u origin feat/auth-refresh
git push -u origin feat/auth-refresh
Main updated - rebase entire stack
main分支已更新 - 变基整个栈
git fetch origin
git switch feat/auth-refresh
git rebase --update-refs origin/main
git fetch origin
git switch feat/auth-refresh
git rebase --update-refs origin/main
All branches rebased in one command
所有分支已通过一个命令完成变基
git push --force-with-lease origin feat/auth-base
git push --force-with-lease origin feat/auth-oauth
git push --force-with-lease origin feat/auth-refresh
**When to use:**
- Managing stacked PRs (PR chains with dependencies)
- Reorganizing commits across multiple branches
- Keeping branch hierarchies in sync during rebasegit push --force-with-lease origin feat/auth-base
git push --force-with-lease origin feat/auth-oauth
git push --force-with-lease origin feat/auth-refresh
**适用场景:**
- 管理堆叠PR(存在依赖的PR链)
- 在多个分支间重新组织提交
- 变基时保持分支层级同步Explicit Base Control (--onto
)
--onto显式基础控制 (--onto
)
--ontoProblem: Git's automatic base detection can be ambiguous or incorrect. You want precise control over where commits are rebased.
Solution: explicitly specifies the new base, bypassing Git's base detection heuristics.
--ontobash
undefined问题: Git的自动基础检测可能模糊或错误。你想要精确控制提交变基的目标位置。
解决方案: 显式指定新的基础,绕过Git的基础检测启发式算法。
--ontobash
undefinedSyntax: git rebase --onto <newbase> <upstream> <branch>
语法:git rebase --onto <newbase> <upstream> <branch>
Translates to: Take commits from <upstream>..<branch> and put them onto <newbase>
含义:提取<upstream>..<branch>范围内的提交,并将它们应用到<newbase>上
Common pattern: Rebase last N commits onto a specific branch
常见模式:将最近N个提交变基到指定分支
git rebase --onto origin/develop HEAD~5
git rebase --onto origin/develop HEAD~5
Takes your last 5 commits and puts them on top of origin/develop
提取最近5个提交并应用到origin/develop上
Equivalent to: git rebase --onto origin/develop HEAD~5 HEAD
等价于:git rebase --onto origin/develop HEAD~5 HEAD
Example: Move feature commits from old base to new base
示例:将功能提交从旧基础迁移到新基础
Scenario: You branched from develop, but should have branched from main
场景:你从develop分支创建了功能分支,但实际上应该从main分支创建
git switch feat/payment
git rebase --onto main develop feat/payment
git switch feat/payment
git rebase --onto main develop feat/payment
Takes commits from develop..feat/payment and moves them onto main
提取develop..feat/payment范围内的提交并迁移到main分支上
Example: Rebase specific commit range
示例:变基特定提交范围
Move commits from abc123 to def456 onto main
将abc123到def456的提交迁移到main分支
git rebase --onto main abc123^ def456
git rebase --onto main abc123^ def456
The ^ includes abc123 in the range
^ 符号表示包含abc123提交
Example: Extract commits to new branch
示例:提取提交到新分支
You have commits on feat/auth that should be on separate branch
你在feat/auth分支上的部分提交应该放到单独的分支上
git switch -c feat/auth-ui feat/auth # Create new branch
git rebase --onto main feat/auth~3 feat/auth-ui
git switch -c feat/auth-ui feat/auth # 创建新分支
git rebase --onto main feat/auth~3 feat/auth-ui
Takes last 3 commits from feat/auth and puts them on main
提取feat/auth分支的最后3个提交并应用到main分支上
**Common --onto patterns:**
| Pattern | Command | Use Case |
|---------|---------|----------|
| Last N commits on trunk | `git rebase --onto origin/main HEAD~N` | Rebase recent work onto updated trunk |
| Change branch base | `git rebase --onto <new-base> <old-base>` | Fix branch created from wrong base |
| Extract commit range | `git rebase --onto <target> <start>^ <end>` | Move specific commits to new location |
| Interactive with onto | `git rebase -i --onto <base> HEAD~N` | Clean up and rebase last N commits |
**When to use:**
- When you don't trust Git's automatic base detection
- Rebasing a specific number of recent commits (`HEAD~N` pattern)
- Changing the base of a branch after it was created
- Extracting a subset of commits to a new location
**常见--onto模式:**
| 模式 | 命令 | 适用场景 |
|---------|---------|----------|
| 将最近N个提交变基到主干 | `git rebase --onto origin/main HEAD~N` | 将近期工作变基到已更新的主干 |
| 更改分支基础 | `git rebase --onto <new-base> <old-base>` | 修正从错误分支创建的功能分支 |
| 提取提交范围 | `git rebase --onto <target> <start>^ <end>` | 将特定提交迁移到新位置 |
| 结合交互式变基与--onto | `git rebase -i --onto <base> HEAD~N` | 清理并变基最近N个提交 |
**适用场景:**
- 你不信任Git的自动基础检测时
- 变基特定数量的最近提交(`HEAD~N`模式)
- 分支创建后更改其基础
- 提取部分提交到新位置Combining Advanced Flags
组合高级参数
These flags work together for powerful workflows:
bash
undefined这些参数可以组合使用,实现强大的工作流:
bash
undefinedRebase stacked PRs with cherry-pick detection
结合Cherry-Pick清理与更新引用,变基堆叠PR
git rebase --reapply-cherry-picks --update-refs origin/main
git rebase --reapply-cherry-picks --update-refs origin/main
Interactive rebase with explicit base and branch updates
结合显式基础、更新引用的交互式变基
git rebase -i --onto origin/main HEAD~10 --update-refs
git rebase -i --onto origin/main HEAD~10 --update-refs
Clean up merged history and update dependent branches
清理合并历史并更新依赖分支
git rebase --reapply-cherry-picks --update-refs --onto origin/develop origin/main
undefinedgit rebase --reapply-cherry-picks --update-refs --onto origin/develop origin/main
undefinedConflict Resolution
冲突解决
bash
undefinedbash
undefinedWhen rebase conflicts occur
变基发生冲突时
git rebase main
git rebase main
Fix conflicts in editor
在编辑器中修复冲突
git add resolved-file.txt
git rebase --continue
git add resolved-file.txt
git rebase --continue
If rebase gets messy, abort and merge instead
如果变基过于混乱,可终止并改用合并
git rebase --abort
git merge main
undefinedgit rebase --abort
git merge main
undefinedSafe Force Pushing
安全强制推送
bash
undefinedbash
undefinedAlways use --force-with-lease to prevent overwriting others' work
始终使用--force-with-lease以避免覆盖他人的工作
git push --force-with-lease origin feat/branch-name
git push --force-with-lease origin feat/branch-name
Never force push to main/shared branches
永远不要对main或共享分支执行强制推送
Use this alias for safety:
可设置别名以简化安全推送:
git config alias.pushf 'push --force-with-lease'
undefinedgit config alias.pushf 'push --force-with-lease'
undefinedQuick Reference
快速参考
| Operation | Command |
|---|---|
| Rebase onto main | |
| Interactive rebase | |
| Rebase with cherry-pick cleanup | |
| Rebase stacked PRs | |
| Rebase last N commits | |
| Change branch base | |
| Abort failed rebase | |
| Continue after conflict | |
| Skip problematic commit | |
| 操作 | 命令 |
|---|---|
| 变基到main分支 | |
| 交互式变基 | |
| 结合Cherry-Pick清理的变基 | |
| 变基堆叠PR | |
| 变基最近N个提交 | |
| 更改分支基础 | |
| 终止失败的变基 | |
| 冲突修复后继续变基 | |
| 跳过有问题的提交 | |
Troubleshooting
故障排除
Rebase Conflicts Are Too Complex
变基冲突过于复杂
bash
undefinedbash
undefinedAbort rebase and use merge instead
终止变基并改用合并
git rebase --abort
git merge main
undefinedgit rebase --abort
git merge main
undefinedBranch Diverged from Remote
分支与远程版本分歧
bash
undefinedbash
undefinedPull with rebase to maintain linear history
使用变基拉取以保持线性历史
git pull --rebase origin feat/branch-name
git pull --rebase origin feat/branch-name
Or reset if local changes can be discarded
或如果本地修改可丢弃,直接重置
git fetch origin
git reset --hard origin/feat/branch-name
undefinedgit fetch origin
git reset --hard origin/feat/branch-name
undefinedLost Commits After Rebase
变基后丢失提交
bash
undefinedbash
undefinedFind lost commits in reflog
在reflog中查找丢失的提交
git reflog
git reflog
Restore to previous state
恢复到之前的状态
git reset --hard HEAD@{N}
undefinedgit reset --hard HEAD@{N}
undefined