Git rebase合并冲突

143

我 fork 了一个 GitHub 代码库,然后在我的 GitHub 代码库上进行了修改。
我发起了拉取请求并已经完成了。

之后上游仓库有了更多的提交,所以现在我想要 rebase,我猜这就是我需要做的。
但是我遇到了这些合并冲突:

First, rewinding head to replay your work on top of it...
Applying: Issue 135 homepage refresh
Using index info to reconstruct a base tree...
<stdin>:17: trailing whitespace.
      %h4 
warning: 1 line adds whitespace errors.
Falling back to patching base and 3-way merge...
Auto-merging app/views/layouts/application.html.haml
CONFLICT (content): Merge conflict in app/views/layouts/application.html.haml
Auto-merging app/views/home/index.html.haml
CONFLICT (content): Merge conflict in app/views/home/index.html.haml
Auto-merging app/views/home/_group_projects.html.haml
CONFLICT (content): Merge conflict in app/views/home/_group_projects.html.haml
Failed to merge in the changes.
Patch failed at 0001 Issue 135 homepage refresh

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To check out the original branch and stop rebasing run "git rebase --abort".

我不知道如何修复这些问题,请帮忙。


请查看我在此帖子中的回答:https://stackoverflow.com/questions/48307297/how-to-update-forked-repo-with-original-repo-if-both-forked-repo-and-original-re/48337194 - Abhishek
5个回答

174

变基可能会让人头痛。您需要解决合并冲突并继续变基。例如,您可以使用合并工具(根据您的设置不同)。

git mergetool
然后添加你的更改并继续。
git rebase --continue

祝你好运


3
可以使用"git pull upstream master",这样做可以避免重新设置基础分支(rebase)所带来的麻烦。 - pahnin
2
是的,你可以尝试这样做。不同之处在于你的提交不会被放在上游的提交之上。潜在地,会有更少的合并冲突。 - iltempo
8
你不需要进行提交(commit),只需要执行git add命令就足以让代码重新合并(rebase)。 - enigmaticPhysicist
6
git mergetool 是什么意思?它的作用是打开一个可视化工具,帮助解决 Git 合并冲突。 - Sam
我不知道为什么这个评论会得到点赞。git mergetool是完全依赖于用户配置的,不应该被用作答案。git rebase --continue?好的,那之前的步骤呢?正如你所看到的,这个答案中缺少了一些步骤。@baur 的回答非常好,虽然有点技术性。 - VonSchnauzer
显示剩余4条评论

65
如果您有许多提交要变基,并且其中一部分引起冲突,那会非常痛苦。但我可以建议一个不太知名的方法来“压缩所有冲突”。首先,检出临时分支并开始标准合并。
git checkout -b temp
git merge origin/master

你需要解决冲突,但只需一次,并且只解决真正的冲突。然后将所有文件进行分组并完成合并。

git commit -m "Merge branch 'origin/master' into 'temp'"

然后回到你的分支(假设它是alpha)并开始变基,但自动解决任何冲突。

git checkout alpha
git rebase origin/master -X theirs

分支已经被变基了,但项目可能处于无效状态。没关系,我们只需要一个最后的步骤。我们只需要恢复项目状态,使其与'temp'分支上的完全一样。技术上,我们只需要通过低级命令git commit-tree复制它的树(文件夹状态)。此外,合并到当前分支刚刚创建的提交。

git merge --ff $(git commit-tree temp^{tree} -m "Fix after rebase" -p HEAD)

并删除临时分支

git branch -D temp

就这些了。我们通过隐藏式合并进行了一次变基。

此外我写了一个脚本,可以通过对话框的方式完成,你可以在这里找到它。


3
谢谢!“this just saved me a massive headache, thank you!” 的意思是 “这刚刚帮我避免了一个大麻烦,谢谢!”。“project is probably in invalid state” 意思是 “项目可能处于无效状态”,请问你在句子中的这个问题,“What do you mean by "project is probably in invalid state"?”,是指“project is probably in invalid state”的意思吗?如果是的话,那么您已经正确理解了它的含义。至于 git rebase origin/master -X theirs,一切看起来都很好,您不确定是否需要最终的 merge - jay
2
@jay,命令git rebase origin/master -X theirs只是进行机械式合并冲突解决。有时候这已经足够了,不需要其他操作。但有时候即使在此之后项目也无法编译。这就是为什么额外的提交可以帮助恢复正确的rebase结果,这个结果之前是通过传统的合并完成的。我建议你进行最终合并,看看是否引入了更改。 - Adam
2
我真正喜欢这个答案的原因是:1)我不必压缩我精心考虑过的所有提交,2)可以轻松地通过提交冲突的丛林。 如果使用“常规”rebase,我将处理每个提交的冲突。如果您有439个提交,那可能需要很长时间才能完成。 使用您的方法,我可以一次性处理所有冲突,然后进行rebase。 - VonSchnauzer
我刚刚尝试了这个方法,它有效果。但是,这和直接使用合并(merge)有什么不同呢?在你的分支上执行git merge origin/master难道不会得到相同的结果吗?*然而,使用rebase -X theirs仍然在两个步骤上与一个新文件发生了冲突。 - chrispepper1989
@chrispepper1989 合并和变基会导致你的提交与基础分支在不同的位置。实际上,rebase -X theirs 命令不应该引发任何冲突。 - Adam

22
注意:自Git 2.14.x/2.15(2017年第三季度)起,冲突时的git rebase消息将更加清晰。

请参见commit 5fdacc1(由William Duclot (williamdclt)于2017年7月16日提交)。
(由Junio C Hamano -- gitster --commit 076eeec中合并,于2017年8月11日)

rebase:使未经验用户更易理解解决消息

之前:

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort"

之后:

Resolve all conflicts manually, 
mark them as resolved with git add/rm <conflicted_files>
then run "git rebase --continue".

You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".')

git用户界面可以通过将错误信息针对那些需要帮助的人——经验不足和偶尔使用git的用户进行改进。为此,有助于确保这些消息中使用的术语可以被这个用户群理解,并引导他们解决问题。特别是,在git rebase期间未能应用补丁是一个常见的问题,对于经验不足的用户来说可能非常不稳定。重要的是引导他们解决冲突(这是一个三步骤的过程,因此比较复杂),并向他们保证他们可以通过“--abort”摆脱无法处理的情况。本次提交通过详细说明解决过程并避免晦涩的git术语来回答了这两个问题。

1
不错!帮助页面上说要通过提交更改来解决冲突,但是不!在这里我们需要跳过提交,直接继续合并!(帮助页面:https://help.github.com/articles/resolving-merge-conflicts-after-a-git-rebase/) - Jerther
说实话,我希望这个更清晰明了。例如,它说“使用git add/rm <conflicted_files>将它们标记为已解决”-好吧,我应该使用git add还是git rm - Jordan Mitchell Barrett
@JordanMitchellBarrett 如果你想将那个文件作为重拍的一部分保留,就添加它;如果你想要删除那个文件,就使用rm命令。 - VonC
作为一个例子,昨天发布的文章:"如何解决Git中的合并冲突-带有示例的实用指南",作者是Tapas Adhikary。在删除文件的合并冲突中,一个开发者在一个分支中删除了一个文件,而另一个开发者在另一个分支中编辑了同一个文件。在这种情况下,您需要决定是否要保留该文件,或者删除它是否正确。 - VonC

10
如果您不介意将所有更改压缩到一个提交中,最简单的方法是从当前分支运行git reset --soft <rebase-target> 然后运行git commit
例如,您正在自己的分支上,并且要在origin/master 上进行变基。 假设您没有未暂存/未完成的更改:
# Merge and fix any conflicts from master
git merge origin/master
# Push your changes in case you mess up and want to start over from remote
git push
# Move HEAD to rebase target, leaving all your work staged
git reset --soft origin/master
# Commit staged changes as giant commit
git commit -m "feat(foo): new feature"
# Confirm your changes, run tests, etc. Then force push
git push -f

您不必担心重新执行合并冲突,因为您的分支与变基目标之间的所有差异都已移动到暂存区,准备好提交。


简单来说,这是将分支合并到主分支。 - IsmailS
为了更好地理解,git checkout -b copy origin/master > git merge your_branch,解决冲突并提交。现在,copy是您的分支,在master上有1个提交。 - IsmailS

0
在一些过于复杂的情况下,当出现已删除、重命名或更改文件时,使用空的“缓冲”提交并删除所有文件可能是一个救命稻草。这样可以增加其灵活性,并且在空的提交之后,下一个提交将变得更加可靠且快照相似。

这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - OznOg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接