跳至内容
GitTree
Git 指南阅读 2 分钟

Git rebase 分支:如何一步一步安全地 rebase

变基只需一个命令。安全地做到这一点还需要更多的工作:保存旧的提示,处理每个冲突,比较结果,并在不覆盖队友的情况下推送。这是整个序列。

撰写者 Kodmora

GitTree 背后的软件公司

已更新
  • 变基
  • 分支
  • 合并冲突
  • 远程仓库和推送
在此页面上

要对分支进行变基,请获取、切换到该分支并将其重播到新的基础上:`git fetch origin`、`git switch topic`、`git rebase origin/main`。 Git 将分支自己的提交放在一边,将分支移动到 origin/main 的顶端,然后一次重新应用一个提交。历史记录保持一条直线,没有合并提交。每个重播的提交都会获得一个新的哈希值,因此您已经推送的分支之后需要 git push --force-with-lease。

git rebase 对分支做了什么?

假设 topic 有两个自己的提交,而 main 自分支启动以来已经获得了三个提交。变基更新该起点,而不将 main 合并到您的分支中:

# before
A---B---C---D---E   origin/main
     \
      F---G         topic

# after git rebase origin/main
A---B---C---D---E   origin/main
                 \
                  F'---G'   topic

F' 和 G' 包含与 F 和 G 相同的更改和消息,但它们是具有新哈希值的新提交,因为它们的父级发生了更改。从同一起点进行合并将保留两条线,并添加一个具有两个父项的提交。关于合并与变基 的课程在一张图表上显示了两者。

如何逐步安全地变基分支?

首先检查,保留旧提示,重播,然后测试。前三个命令不重写任何内容:

# 1. update origin/main, your files stay as they are
git fetch origin

# 2. list the commits Git will replay
git log --oneline origin/main..topic

# 3. keep a name on the old tip
git branch topic-backup topic

# 4. replay
git switch topic
git rebase origin/main

如果列表中有您无法识别的提交,请停止在步骤 2 处,因为这意味着分支并未从您认为的位置开始。当变基结束时,运行 git status 以确认其完成,然后运行测试。没有冲突的变基仍然会破坏行为。

每次都命名基地。裸的 git rebase 使用分支的上游,通常是 origin/topic 而不是 main。要移动从另一个功能分支开始的分支,请将旧基础也命名为:git rebase --onto main old-base topic。关于重新确定未发表工作的基准 的课程在真实图表上练习了这一点。

如何解决变基期间的冲突?

Git 一次应用一个提交,因此它可以多次停止,即使是在同一行中。仅修复 Git 停止的提交,因为后面的提交尚未应用:

# edit the file and remove the conflict markers, then
git add path/to/file
git rebase --continue
应对变基停止的三种方法
命令它的作用当
git rebase --continue记录暂存结果并移至下一个提交。冲突得到解决并暂存。
git rebase --skip删除正在重播的提交。您已确认更改已在上游。
git rebase --abort停止并将分支返回到原来的位置。你选择了错误的基地或分支,或者冲突需要更多的思考。

如果您经常重播相同的冲突,git config rerere.enabled true 会记录您的解决方案并重复使用它。检查每个重用的结果,因为昨天的答案在今天的代码中可能是错误的。关于继续、跳过和中止 的课程将介绍每种情况,而如何解决合并冲突 则涵盖阅读标记。

在推送之前如何检查变基?

在其他人看到之前将旧系列与新系列进行比较:

# old and new commits, matched pair by pair
git range-diff origin/main topic-backup topic

# everything the branch adds to main, as one diff
git diff origin/main...topic

# the shape of the history
git log --graph --oneline --decorate origin/main topic

git range-diff 显示冲突解决方案更改补丁的时间或提交丢失的时间。编译后的代码仍然可以隐藏删除的测试或更改的条件,这就是您捕获它的地方。

如何撤消变基?

当它运行时,使用 git rebase --abort。完成后,将分支移回旧尖端。首先检查 git status,因为 --hard 会丢弃未提交的更改:

git reset --hard topic-backup

# no backup? find the old tip in the reflog
git reflog show topic
git reset --hard <old-tip-hash>

撤消重置、变基或提交 指南更深入地介绍了引用日志。

如何推送变基后的分支?

正常的推送被拒绝,因为远程分支仍然保留旧的提交,并且 Git 看到非快进更新。检查您要更换的内容,然后通过租约推送:

git fetch origin
git log --oneline topic..origin/topic
git push --force-with-lease origin topic

该 git log 应仅列出您的旧提交。其他的事情都是队友的工作,所以停下来先把它带进来。仅当远程分支仍在上次提取时看到的位置时,--force-with-lease 才会替换远程分支,而普通的 --force 没有此类检查。后台获取会更新该值,因此脚本可以将其期望的提交命名为:git push --force-with-lease=topic:<expected-hash> origin topic。

我应该重新设置或合并这个分支吗?

根据情况重新设定基准或合并
情况使用为什么
你自己的短暂主题分支变基逐个读取提交的直接历史记录。
其他人已获取或构建的分支合并它不会重写任何内容,因此没有人需要修复他们的工作。
长期存在的集成分支合并它保留了两条开发线的记录。
审核中的分支重新设定基准,一旦审稿人同意评论可能指向即将更改的提交。

如何在 GitTree 中对分支进行变基

  1. 选择新基地

    检查您的分支,右键单击您想要在其上工作的分支,例如 develop,然后选择 Rebase … onto …。

  2. 检查选项

    确认信息表明每次提交都会使用新的 id 重播,并保留旧分支。您还可以隐藏本地更改并将其放回原处。

  3. 遵循每个步骤

    横幅显示Rebasing … onto …, step … of …。如果步骤发生冲突,Resolve 将打开文件,Continue 继续,Skip 会删除该提交,而 Abort… 将分支恢复原样。

  4. 回顾一下发生了什么变化

    What Changed… (Alt+D) 逐对比较变基之前和之后的提交,如 git range-diff。

  5. 推送或撤消

    对远程上已有的分支使用Force Push (With Lease)…。 Undo将分支返回到原来的位置,并且旧的提交保留在 refs/ogt/trash 下。

GitTree 中的停止步骤:两侧、输出以及横幅中的“继续”和“中止”。
GitTree 中的停止步骤:两侧、输出以及横幅中的“继续”和“中止”。

分支变基 指南提供了所有选项,而 强制推送带租约 涵盖了推送。要一路压缩、改写或重新排序,请阅读 GUI 中的交互式变基。

GitTree 中的交互式变基编辑器显示在任何更改之前将重播的每个提交。
GitTree 中的交互式变基编辑器显示在任何更改之前将重播的每个提交。

常见问题

git rebase 会丢失更改吗?

不是靠它自己。 Git 将您的更改重播为新的提交。当您放弃提交、运行 git rebase --skip 或以错误的方式解决冲突时,工作就会消失。 Git 还会忽略那些已经在上游进行更改的提交。

git rebase --abort 和 reflog 有什么区别?

git rebase --abort 仅在变基正在进行时有效。完成后,引用日志会保存该分支之前的提示,因此您可以重置为其中之一。

我可以对包含合并提交的分支进行变基吗?

是的。 git rebase --rebase-merges origin/main 保留它们。如果没有这个选项,Git 会展平分支并保留合并提交。

为什么 rebase 后 git push 会失败?

远程分支仍然具有旧的提交,而您重写的分支不包含这些提交。检查它们,然后使用 git push --force-with-lease origin topic。

我应该重新定位到 main 或 origin/main 吗?

在 git fetch origin 之后使用 origin/main。这是最新发布的状态,您不必先更新本地 main。

来源

有关其他产品的声明已根据其位于 2026年11月7日 的官方页面进行了检查。价格和功能发生变化;供应商的页面是事实的来源。