变基和合并冲突解决
在 Git 中,变基就是用其他分支的内容更新您的分支。变基是为了确认您的分支不会和目标分支发生冲突。
如果您有合并冲突,您可以通过变基来修复。
当您变基时:
大多数的变基都是基于 main
分支,当然,您也可以基于其他分支进行变基。您还可以指定一个不同的远端仓库。比如 upstream
而不是 origin
。
git rebase
会重写提交历史。它可能会在共享分支和复杂合并冲突中引起冲突。与其基于默认分支变基您的分支,不如考虑拉取默认分支(git pull origin master
)。拉取有类似的作用,但是可能对其他工作的风险会比较小。Git 变基
当您使用 Git 来变基时,每个提交都会应用到您的分支上。当发生合并冲突时,您需要解决它们。
对于更多关于提交的高级选项,请使用交互式变基。
先决条件:
- 您必须有权限强制推送分支。
要使用 Git 来基于目标分支对您的分支进行变基。
- 打开终端并前往您的项目目录。
-
确保您有目标分支的最新内容。在此示例中,目标分支为
main
:git fetch origin main
-
检出您的分支:
git checkout my-branch
-
可选。创建您分支的备份:
git branch my-branch-backup
如果您从备份分支恢复,则此在节点后添加到
my-branch
的任何更改都将丢失。 -
基于
main
分支变基:git rebase origin/main
- 如果存在合并冲突合并冲突:
-
在您的编辑器中解决合并冲突。
-
暂存变更:
git add .
-
继续变基:
git rebase --continue
-
-
强制推送您的变更到目标分支,同时保护其他提交:
git push origin my-branch --force-with-lease
交互式变基
使用交互式变基来指定如何处理每个提交。下面的指南使用 Vim 文本编辑器来编辑提交。
要交互式地变基:
- 打开终端并前往您的项目目录。
-
确保您有目标分支的最新内容。在此示例中,目标分支为
main
:git fetch origin main
-
检出您的分支:
git checkout my-branch
-
可选。创建您分支的备份:
git branch my-branch-backup
如果您从备份分支恢复,则此在节点后添加到
my-branch
的任何更改都将丢失。 - 在极狐GitLab UI 上,在您的合并请求中,在 提交 选项卡中确认需要变基的提交数量。
-
打开这些提交。比如,要编辑最近 5 个提交:
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
- 通过按 i 来切换到 Vim 的编辑模式。
- 使用箭头来将光标移动至您想要编辑的提交上。
- 对于每一个提交,除了第一个,将
pick
改为squash
或fixup
(或s
或f
)。 - 在剩余的提交上重复相同的操作。
-
结束编辑模式,保存并退出:
- 按 ESC.
- 输入
:wq
.
-
当压缩时,Git 提示您来编辑提交信息:
- 以
#
开头的行将被忽略并且不包含在提交消息中。 - 保持原样,输入
:wq
。 - 编辑提交消息,切换到编辑模式,变更然后保存。
- 以
-
推送您的变更到目标分支。
-
如果在变基前您无法推送提交到目标分支:
git push origin my-branch
-
如果您已经推送了提交:
git push origin my-branch --force-with-lease
有些操作需要强制推送变更到分支。更多详情,可以查阅强制推送到远端分支。
-
从命令行解决冲突
为了对每个变更有更多的控制,您应该从命令行从本地修复复杂的冲突,而不是在极狐GitLab 中修复。
先决条件:
- 您必须具有强制推送到分支的权限。
-
打开终端并检出您的功能分支:
git switch my-feature-branch
-
基于目标分支来变基您的分支。在此示例中,目标分支是
main
:git fetch git rebase origin/main
- 在您偏爱的代码编辑器中。
- 定位并解决冲突块:
- 选择您想要保持的版本(
=======
之前或之后的内容)。 - 删除您不想保持的版本。
- 删除冲突标记符。
- 选择您想要保持的版本(
- 保存文件。
- 为冲突的每个文件执行此流程。
-
暂存变更:
git add .
-
提交变更:
git commit -m "Resolve merge conflicts"
您可以运行git rebase --abort
来终止流程。Git 会中断变基而且恢复到您执行git rebase
前的状态。在您运行git rebase --continue
后,您就无法再中止变基了。 -
继续变基:
git rebase --continue
-
强制推送变更到远端分支:
git push origin my-feature-branch --force-with-lease
强制推送到远端分支
复杂的 Git 操作,诸如压缩提交、重置分支或编辑重写分支历史等。Git 都需要强制推送这些变更。
不推荐在共享分支上强制推送,因为您会毁掉其他人的变更。
如果您的分支是受保护的,您无法强制推送,除非您:
- 取消分支保护。
- 允许强制推送。
更多详情,可查阅允许在受保护分支上强制推送。
恢复您的备份分支
如果变基或强制推送失败,从您的备份分支恢复:
-
确保您在正确的分支上:
git checkout my-branch
-
将您的分支重置到备份分支:
git reset --hard my-branch-backup
变基后的审批
如果您变基了一个分支,就意味着您添加了提交。如果您的项目配置了阻止添加了提交的用户审批,您将无法审批您变基的合并请求。
相关主题
故障排查
对 CI/CD 流水线的故障排查信息,可查阅调试 CI/CD 流水线。
/rebase
快速操作后的 Unmergeable state
/rebase
快速操作命令会定时一个后台任务。任务会尝试变基源分支到目标分支的最新提交。如果,在使用 /rebase
快速操作后,您看到这个错误,变基无法被调度:
This merge request is currently in an unmergeable state, and cannot be rebased.
如果如下任何条件为真,就会出现此错误:
- 源分支和目标分支之间存在冲突。
- 源分支没有提交。
- 源分支或目标分支不存在。
- 出现了错误,导致没有生成差异。
要解决 unmergeable state
错误:
- 解决合并冲突。
- 确保源分支存在且包含提交。
- 确保目标分支存在。
- 确保差异已生成。
/rebase
之后忽略 /merge
快速操作
如果使用了 /rebase
,/merge
快速操作将被忽略,以避免一个极端情况:远分支在变基前被合并或删除。