git-rebase-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Git 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 mainCreating branches →
git-branch-naming
Cleaning up commit history before PRCreating PRs →
git-branch-pr-workflow
Managing stacked PRs (PR chains)Simple commits →
git-commit-workflow
Converting merge-heavy branches to linearBasic git operations →
git-cli-agentic
适用场景...其他场景(使用其他方法)...
将功能分支变基到已更新的main分支创建分支 →
git-branch-naming
提交PR前清理提交历史创建PR →
git-branch-pr-workflow
管理堆叠PR(PR链)简单提交 →
git-commit-workflow
将频繁合并的分支转换为线性历史基础Git操作 →
git-cli-agentic

Linear History Basics

线性历史基础

Trunk-Based Development

基于主干的开发

bash
undefined
bash
undefined

Feature 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
undefined
git push -u origin feat/user-auth
undefined

Squash Merge Strategy

合并压缩策略

Maintain linear main branch history:
bash
undefined
维护main分支的线性历史:
bash
undefined

Manual 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"
undefined
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"
undefined

Interactive Rebase Workflow

交互式变基工作流

Clean up commits before sharing:
bash
undefined
分享前清理提交:
bash
undefined

Rebase 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
undefined
pick a1b2c3d feat: add login form fixup d4e5f6g fix typo in login form squash g7h8i9j add form validation reword j1k2l3m implement JWT tokens
undefined

Advanced Rebase Flags

高级变基参数

Reapply Cherry-Picks (
--reapply-cherry-picks
)

重新应用Cherry-Picks (
--reapply-cherry-picks
)

Problem: After merging trunk into your feature branch multiple times (via
git merge main
), you want to rebase onto fresh trunk. Default rebase behavior may create conflicts or duplicate commits.
Solution:
--reapply-cherry-picks
detects commits that were already applied via merge and drops the merge commits, keeping only your original changes.
bash
undefined
问题: 多次将主干合并到功能分支后(通过
git merge main
),你想要将分支变基到最新的主干。默认的变基行为可能会产生冲突或重复提交。
解决方案:
--reapply-cherry-picks
可以检测到已通过合并应用的提交,并丢弃合并提交,只保留你原本的修改。
bash
undefined

Scenario: 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
)

Problem: With stacked PRs (PR chains), rebasing one branch requires manually rebasing all dependent branches. Moving commits between branches in the stack is painful.
Solution:
--update-refs
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.
bash
undefined
问题: 在使用堆叠PR(PR链)时,变基一个分支需要手动变基所有依赖分支。在栈中不同分支间移动提交非常繁琐。
解决方案:
--update-refs
会在你变基时自动更新链中的所有分支。结合交互式变基,你可以在一次操作中重新组织整个PR栈中的提交。
bash
undefined

Scenario: 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工作流:**

```bash

Create 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 rebase
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

**适用场景:**
- 管理堆叠PR(存在依赖的PR链)
- 在多个分支间重新组织提交
- 变基时保持分支层级同步

Explicit Base Control (
--onto
)

显式基础控制 (
--onto
)

Problem: Git's automatic base detection can be ambiguous or incorrect. You want precise control over where commits are rebased.
Solution:
--onto
explicitly specifies the new base, bypassing Git's base detection heuristics.
bash
undefined
问题: Git的自动基础检测可能模糊或错误。你想要精确控制提交变基的目标位置。
解决方案:
--onto
显式指定新的基础,绕过Git的基础检测启发式算法。
bash
undefined

Syntax: 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
undefined

Rebase 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
undefined
git rebase --reapply-cherry-picks --update-refs --onto origin/develop origin/main
undefined

Conflict Resolution

冲突解决

bash
undefined
bash
undefined

When 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
undefined
git rebase --abort git merge main
undefined

Safe Force Pushing

安全强制推送

bash
undefined
bash
undefined

Always 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'
undefined
git config alias.pushf 'push --force-with-lease'
undefined

Quick Reference

快速参考

OperationCommand
Rebase onto main
git rebase main
Interactive rebase
git rebase -i HEAD~N
Rebase with cherry-pick cleanup
git rebase --reapply-cherry-picks origin/main
Rebase stacked PRs
git rebase --update-refs main
Rebase last N commits
git rebase --onto origin/main HEAD~N
Change branch base
git rebase --onto <new> <old>
Abort failed rebase
git rebase --abort
Continue after conflict
git rebase --continue
Skip problematic commit
git rebase --skip
操作命令
变基到main分支
git rebase main
交互式变基
git rebase -i HEAD~N
结合Cherry-Pick清理的变基
git rebase --reapply-cherry-picks origin/main
变基堆叠PR
git rebase --update-refs main
变基最近N个提交
git rebase --onto origin/main HEAD~N
更改分支基础
git rebase --onto <new> <old>
终止失败的变基
git rebase --abort
冲突修复后继续变基
git rebase --continue
跳过有问题的提交
git rebase --skip

Troubleshooting

故障排除

Rebase Conflicts Are Too Complex

变基冲突过于复杂

bash
undefined
bash
undefined

Abort rebase and use merge instead

终止变基并改用合并

git rebase --abort git merge main
undefined
git rebase --abort git merge main
undefined

Branch Diverged from Remote

分支与远程版本分歧

bash
undefined
bash
undefined

Pull 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
undefined
git fetch origin git reset --hard origin/feat/branch-name
undefined

Lost Commits After Rebase

变基后丢失提交

bash
undefined
bash
undefined

Find lost commits in reflog

在reflog中查找丢失的提交

git reflog
git reflog

Restore to previous state

恢复到之前的状态

git reset --hard HEAD@{N}
undefined
git reset --hard HEAD@{N}
undefined