Git rebase持续失败并需要手动合并干预。

8

我在我的一个代码库中,尝试将主分支上的代码变基到“deploy”分支时出现了问题。

我的代码库设置如下:

master - of course, the main branch
deploy - a branch created where files like Capfile, deploy.rb etc are created and configured - these changes will NEVER be merged back into Master

通常我的工作流程是:

  1. 在主分支上进行开发……测试、微笑、提交。
  2. 检出deploy分支
  3. 在部署分支上执行git rebase master——这曾经可以毫无问题地完成
  4. 推送到远程,然后执行cap deploy
  5. 放松一下

我现在遇到的问题是,在部署分支上执行git rebase master时,会出现需要进行3方合并/手动合并的错误(我认为错误消息并不太通用,不能发布)。Git 告诉我执行合并,然后使用git rebase --continue来完成,但这从未奏效过。

我发现“可行”的方法是运行git rebase master --interactive,清理挑选列表(此列表中有5个或更多重复的“提交”,但具有不同的参考编号(相同的消息),因此我会选择其中一个),然后手动进行合并。完成每个提交后,我就可以继续进行变基,并且一切都很顺利……

直到下一次我需要执行变基。

那么有没有人知道可能是什么原因呢?该项目并不是真正的“机密”,因此如果需要,我可以发布消息、日志、分支图等。

谢谢


2
你的部署分支上有多少次提交,它们可以被压缩吗?rebase 必须保留所有中间提交的列表,并且似乎现在有些提交会导致人为冲突,因为它们试图保留一个不再有意义的人为中间状态。 - CB Bailey
3个回答

2
听起来可能发生的情况是,您已更改了那些“重复”提交的提交历史记录,以使它们具有不同的sha1。每个sha1不仅独特于提交,而且独特于提交历史记录。因此,在同一历史记录中具有两个相同的sha1或在两个不同的历史记录中具有两个sha1是不可能的(即使是宇宙寿命期间也极不可能)。如果您更改提交中的任何内容,例如使用修订或交互式变基,则会更改sha1。因此,看起来相同的两个提交实际上是被不同地处理的。
因此,很可能您从其他分支进行了变基,执行了某种类型的交互式变基或修订了提交,继续提交了一些修改了该代码部分的代码,然后在下次变基时,由于您在本地分支中具有的与正在进行变基的分支不同的提交被从分支中删除,上游被拉入包括您已经拉入并更改了sha1的提交,然后当提交被重新应用到分支上时,您会遇到冲突,因为代码的状态已经从提交所期望的状态发生了变化,因为它最初是从与您现在在分支上拥有的不同历史记录创建的。哇,那是一个长句子...
当您“清理”挑选列表时...您正在删除这些重复提交,然后进行变基,因此现在您不再重新应用已经应用的更改,因此没有更多冲突。
但是,如果您只想在变基期间解决冲突,这可能是最好的选择,以便您不会意外删除要保留的提交。解决冲突将使该提交的更改集与您拥有的历史记录相关并且不同。一旦您推送此合并冲突解决方案,除非您再次修改已经推送的提交,否则不应再看到问题。
要查找哪些文件具有合并冲突,请执行以下操作:
git status

或者

git ls-files -u

一旦您知道哪些文件存在冲突,如果您已经设置了合并工具,则可以执行以下操作:

git mergetool <file>

如果您更愿意手动合并,可以通过以下方式找到合并标记和行:

grep -Hnr '^=\{7\}\|^<\{7\}\|^>\{7\}' *

在您的代码库路径的顶层进行编辑。当您手动编辑时,请确保删除标记并使最终版本的文件看起来与您想要的样子相同...Git不会对标记做任何特殊处理。手动编辑完成后,请确保执行

git add <file>

将文件添加到索引中并移除未合并标志。当你完成解决所有未合并的文件后,请执行:

git rebase --continue

完成变基。

2
要使git rebase --continue工作,您必须实际合并冲突的文件(编辑它们,从冲突标记“<<<<<<<”、“=======”、“>>>>>>>”之间选择所需部分),然后将它们添加到索引中(索引是记录它们为冲突状态的地方,添加文件会清除其冲突状态)。使用git diff --cached检查当前差异,如果看起来正确,请使用git rebase --continue
在尝试重新定位(或中止有问题的重新定位之后),请使用git log -p master..deploy检出要重新定位的提交。其中一个提交与您在master中拥有的内容发生了冲突。
通过删除git rebase -i中的“pick”行而放弃这些提交可能不完全相同(即使它们在提交消息的“主题”中相同)。您认为应该只有其中一个提交的事实表明,您的deploy分支存在某些问题。这些“重复”的提交是否在deploy的末尾,还是在它们之后有其他提交?也许查看那些“可疑”的提交的内容(如上所述的log -p)会给您一个关于它们来源的线索。

1

您可以在“部署特定”文件的父目录中定义属性,以便在合并时始终选择部署分支的内容。

有关合并管理器的示例,请参见此SO答案

其他策略已经讨论过,但关键是:始终将合并视为“项目范围内的合并”,而不是基于文件的合并。因此,需要使用属性来细化该项目范围内的合并,以处理一些“特殊”的文件。


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