极狐GitLab rebase 通过将您的提交移动到目标分支的末端来将一个分支的更改合并到另一个分支。此操作:

  • 使用目标分支的最新代码更新分支。
  • 保持干净的线性提交历史,以便于调试和代码审查。
  • 在提交级别解决合并冲突
  • 保留代码更改的时间顺序。

当您进行 rebase 时:

  1. Git 导入您从目标分支创建分支后提交到目标分支的所有提交。
  2. Git 将您的分支提交应用到导入的提交之上。在此示例中,在创建名为 feature 的分支(橙色)后,将来自 main 的四个提交(紫色)导入到 feature 分支:

    Git rebase illustration

虽然大多数 rebase 是针对 main 执行的,但您可以针对任何其他分支进行 rebase。您还可以指定不同的远程仓库。例如,使用 upstream 而不是 origin

{{< alert type=”warning” >}}

git rebase 重写提交历史。它可能会导致共享分支中的冲突和复杂的合并冲突。考虑使用 git pull origin master 而不是将您的分支与默认分支进行 rebase。拉取具有类似效果,但风险较低,不会影响其他人的工作。

{{< /alert >}}

Rebase

使用极狐GitLab进行 rebase 时,每个提交都会应用到您的分支上。当出现合并冲突时,系统会提示您解决它们。

有关提交的更高级选项,请使用交互式 rebase

先决条件:

  • 您必须拥有权限来强制推送到分支。

使用极狐GitLab将您的分支与目标分支进行 rebase:

  1. 打开终端并切换到您的项目目录。
  2. 确保您拥有目标分支的最新内容。在此示例中,目标分支是 main

    git fetch origin main
    
  3. 检出您的分支:

    git checkout my-branch
    
  4. 可选。创建分支的备份:

    git branch my-branch-backup
    

    如果您从备份分支恢复,my-branch 中此时之后添加的更改将丢失。

  5. 针对 main 分支进行 rebase:

    git rebase origin/main
    
  6. 如果存在合并冲突:
    1. 在编辑器中解决冲突。

    2. 暂存更改:

      git add .
      
    3. 继续 rebase:

      git rebase --continue
      
  7. 强制推送您的更改到目标分支,同时保护其他人的提交:

    git push origin my-branch --force-with-lease
    

交互式 rebase

使用交互式 rebase 来指定如何处理每个提交。以下说明使用 Vim 文本编辑器来编辑提交。

交互式 rebase:

  1. 打开终端并切换到您的项目目录。
  2. 确保您拥有目标分支的最新内容。在此示例中,目标分支是 main

    git fetch origin main
    
  3. 检出您的分支:

    git checkout my-branch
    
  4. 可选。创建分支的备份:

    git branch my-branch-backup
    

    如果您从备份分支恢复,my-branch 中此时之后添加的更改将丢失。

  5. 在极狐GitLab UI 中,在您的合并请求中,确认要在 提交 标签中进行 rebase 的提交数量。
  6. 打开这些提交。例如,要编辑最近的五个提交:

    git rebase -i HEAD~5
    

    Git 在您的终端文本编辑器中打开提交,最早的提交在前。每个提交显示要采取的操作、SHA 和提交标题。例如:

    pick 111111111111 Second round of structural revisions
    pick 222222222222 Update inbound link to this changed page
    pick 333333333333 Shifts from H4 to H3
    pick 444444444444 Adds revisions from editorial
    pick 555555555555 Revisions continue to build the concept part out
    
    # Rebase 111111111111..222222222222 onto zzzzzzzzzzzz (5 commands)
    #
    # Commands:
    # p, pick <commit> = use commit
    # r, reword <commit> = use commit, but edit the commit message
    # e, edit <commit> = use commit, but stop for amending
    # s, squash <commit> = use commit, but meld into previous commit
    # f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
    
  7. i 键切换到 Vim 的编辑模式。
  8. 使用箭头键将光标移动到要编辑的提交。
  9. 对于除第一个提交之外的每个提交,将 pick 更改为 squashfixup(或 sf)。
  10. 对剩余的提交重复此过程。
  11. 结束编辑模式,保存并退出:

    • ESC 键。
    • 输入 :wq
  12. 在进行 squash 时,Git 会提示您编辑提交消息:

    • # 开头的行将被忽略,不会包含在提交消息中。
    • 如果要保留当前消息,请输入 :wq
    • 如果要编辑提交消息,请切换到编辑模式,进行更改并保存。
  13. 将您的更改推送到目标分支。

    • 如果您在 rebase 之前没有将提交推送到目标分支:

      git push origin my-branch
      
    • 如果您已推送提交:

      git push origin my-branch --force-with-lease
      

      某些操作需要强制推送以更改分支。有关更多信息,请参阅强制推送到远程分支

从命令行解决冲突

为了让您对每个更改拥有最大控制权,您应该从命令行本地修复复杂的冲突,而不是在极狐GitLab中。

先决条件:

  • 您必须拥有权限来强制推送到分支。
  1. 打开终端并检出您的功能分支:

    git switch my-feature-branch
    
  2. 将您的分支与目标分支进行 rebase。在此示例中,目标分支是 main

    git fetch
    git rebase origin/main
    
  3. 在您喜欢的代码编辑器中打开冲突文件。
  4. 定位并解决冲突块:
    1. 选择您要保留的版本(在 ======= 之前或之后)。
    2. 删除您不想保留的版本。
    3. 删除冲突标记。
  5. 保存文件。
  6. 对每个存在冲突的文件重复此过程。
  7. 暂存您的更改:

    git add .
    
  8. 提交您的更改:

    git commit -m "Resolve merge conflicts"
    

    {{< alert type=”warning” >}}

    您可以在此之前运行 git rebase --abort 来停止该过程。Git 会中止 rebase 并将分支回滚到运行 git rebase 之前的状态。在您运行 git rebase --continue 之后,您无法中止 rebase。

    {{< /alert >}}

  9. 继续 rebase:

    git rebase --continue
    
  10. 将更改强制推送到您的远程分支:

     git push origin my-feature-branch --force-with-lease
    

强制推送到远程分支

复杂的 Git 操作如压缩提交、重置分支或 rebase 会重写分支历史。Git 需要强制更新这些更改。

不建议在共享分支上进行强制推送,因为您可能会破坏其他人的更改。

如果分支是受保护的,除非您:

  • 取消保护它。
  • 允许强制推送。

有关更多信息,请参阅在受保护分支上允许强制推送

恢复您的备份分支

如果 rebase 或强制推送失败,请从备份恢复您的分支:

  1. 确保您在正确的分支上:

    git checkout my-branch
    
  2. 将您的分支重置为备份:

    git reset --hard my-branch-backup
    

在 rebase 后批准

如果您 rebase 了一个分支,那么您添加了提交。如果您的项目配置为阻止添加提交的用户批准,您不能批准您已 rebase 的合并请求。

相关主题

故障排除

有关 CI/CD 流水线故障排除的信息,请参阅调试 CI/CD 流水线

/rebase 快捷操作后的 不可合并状态

/rebase 命令安排后台任务。任务尝试在目标分支的最新提交上重新基准源分支的更改。如果在使用 /rebase 快捷操作后看到此错误,则无法安排 rebase:

This merge request is currently in an unmergeable state, and cannot be rebased.

如果这些条件中的任何一个为真,则会发生此错误:

  • 源分支和目标分支之间存在冲突。
  • 源分支不包含提交。
  • 源分支或目标分支不存在。
  • 发生错误,导致未生成差异。

解决 不可合并状态 错误:

  1. 解决所有合并冲突。
  2. 确认源分支存在,并且有提交。
  3. 确认目标分支存在。
  4. 确认已生成差异。

/rebase 后忽略 /merge 快捷操作

如果使用了 /rebase,则忽略 /merge 以避免在源分支被合并或删除之前进行重新基准的竞争条件。