发生冲突时如何强制合并成功?

Posted

技术标签:

【中文标题】发生冲突时如何强制合并成功?【英文标题】:How to force a merge to succeed when there are conflicts? 【发布时间】:2016-08-17 15:13:56 【问题描述】:

我正在尝试合并在一个文件中存在一个冲突的拉取请求(见下文)。合并拉取请求的说明是provided by github,如下。执行此合并非常重要,这样提交 pr 的人才能获得功劳。

# Step 1: From your project repository, check out a new branch and test the changes.
git checkout -b droark-master master
git pull https://github.com/droark/cryptopp.git master

# Step 2: Merge the changes and update on GitHub.
git checkout master
git merge --no-ff droark-master
git push origin master

我知道如何修复一个冲突文件中的一行。我不知道该怎么做是让 Git 执行合并并停止抱怨损坏的索引文件。

我如何让 Git 执行合并,确保提供拉取请求的人得到认可,并停止破坏索引文件?


我尝试修复与Git merge errors 的合并。一组错误会变成另一组错误,无限。我还尝试根据Ignore files during merge 重置问题文件,并计划复制/粘贴所需的一行,但损坏的索引仍然存在。

这完全是浪费时间,我不再有兴趣尝试以 Git 的方式去做,因为它浪费了太多时间。现在我只想让 Git 执行合并并停止破坏索引文件。


这是使用 github 的指令合并时产生的输出:

$ git pull https://github.com/droark/cryptopp.git master
From https://github.com/droark/cryptopp
 * branch            master     -> FETCH_HEAD
Auto-merging validate.h
Auto-merging validat2.cpp
Auto-merging validat1.cpp
Auto-merging test.cpp
CONFLICT (content): Merge conflict in test.cpp
Auto-merging pubkey.h
Automatic merge failed; fix conflicts and then commit the result.

【问题讨论】:

“破坏索引文件”是什么意思? @Schwern - 合并失败后,由于索引文件的问题(无论它们在 Git 中是什么),我无法对 repo 做任何事情。例如,git checkout master 结果为 error: you need to resolve your current index first。我希望 Git 停止破坏它们,以便我可以继续手头的任务。 要回滚合并冲突,请参阅"How to undo a git merge with conflicts?" 的答案。 git-scm.com/docs/merge-strategies 【参考方案1】:

没有解决冲突就无法合并。否则,git 怎么知道要合并什么?但是,您可以使用 git checkout --ours <filepath>git checkout --theirs <filepath> 从要合并的任一分支中检出版本。这是一个例子:

假设你在 staging 合并的 master 分支上:

git checkout master
git merge staging

而git显示一堆冲突:

...
CONFLICT: Readme.md
...

如果您想保留 master 上的 Readme.md 版本,那么您可以运行:

git checkout --ours Readme.md

请注意,由于您在 master 上,--ours 指的是“this”分支,即 master。

现在,您可以简单地将其添加到索引中以将其标记为已解决:

git add Readme.md

这实际上忽略了对staging 分支上的Readme.md 的任何更改。

您可以对要从合并中省略的每个文件重复此过程。完成后,像往常一样提交:

git commit -m "whatever..."

为了对所有有冲突的文件重复它,你可以这样做

for f in $(git diff --name-only --diff-filter=U | cat); do
   echo "Resolve conflict in $f ..."
   git checkout --theirs $f
done

【讨论】:

警告:--ours/--theirs 不会合并更改,它会逐字获取文件的一个版本,而完全忽略另一个版本。 更糟糕的是,--ours/--theirs 什么都不做。 @5chdn 它肯定会从指定分支签出版本,如 ivan 的评论中所述【参考方案2】:

没有办法解决冲突,这就是修订控制的工作方式(如果 Alice 说“a”而 Bob 说“b”,除非 告诉它,否则 Git 如何知道哪个是正确的?) .您所能做的就是直接git 在合并several possible ways 之一时自行解决它们,例如

git merge -s recursive -X theirs <branch>

-s recursive 为默认值,&lt;branch&gt; 为默认值,此处可省略)

既然你的树中已经有冲突,你要么

关注manual resolution route 随心所欲地编辑文件 git add 它(add 在 Git 中兼作标记文件已解决) git commit 完成合并;或 使用 git merge --abort 恢复预合并状态,然后使用上述自动解析选项重试合并

【讨论】:

【参考方案3】:

解决冲突就像处理任何其他正在进行的工作一样。所有更改都必须暂存 (git add) 然后提交。已成功自动合并的文件已暂存。没有冲突的文件。

编辑冲突文件,让它们满意,暂存它们 (git add),当这一切都完成后,git commit

在你的情况下...

编辑 test.cpp 以修复冲突(它们有 &lt;&lt;&lt;&lt; 标记) git add test.cpp 运行测试以确保一切正常。 git commit

【讨论】:

谢谢。我不想解决冲突。我在这上面浪费了太多时间。我现在希望合并成功。手动重新添加需要的内容实际上需要 3 秒钟。 @jww 存在冲突时合并无法成功。你可以git add 冲突文件而不编辑它们,git commit 来完成合并,但是你必须在下一次提交中通过做同样的事情来修复它们。不妨在合并中修复它们,这将需要同样的努力,并且您不会有损坏的合并提交。【参考方案4】:

将开发推入master

git push --force origin branchA:branchB

这将强制合并然后推送

【讨论】:

那是破坏性的 它很危险,但文件仍然被跟踪【参考方案5】:

如果您知道当前工作分支中的更改是您想要的,您可以简单地将 ours 标志添加到 git 合并中。

git merge -s ours master

这有效地忽略了所有其他分支更改并保证合并输出是当前工作分支的输出。

更多信息和策略在这里:https://www.atlassian.com/git/tutorials/using-branches/merge-strategy

【讨论】:

以上是关于发生冲突时如何强制合并成功?的主要内容,如果未能解决你的问题,请参考以下文章

Git:如何避免在先前合并还原后合并功能分支时发生冲突

git 解决冲突

使用情节提要时iOS目标c中的合并冲突是啥

如何创作不易发生合并冲突的更改?

git分支合并为啥会发生冲突

如何在合并提交中列出已解决冲突的统计信息?