git rebase因命令的未知退出代码(128)而失败:git-merge-recursive

时间:2014-02-21 07:54:46

标签: git github merge git-svn rebase

请考虑以下情形: - 具有2500的上游存储库存储在SVN中 - git user A将存储库导入git并提交1个补丁 - git用户B将存储库导入git并提交1个补丁 - git用户A想要从git用户B合并补丁

在这种情况下,如果用户A使用git merge,那么git历史记录将被公共svn提交污染(即代替2502次提交,历史记录将包含2501 + 2501 = 5002次提交!)

如果用户A使用git rebase,则git历史记录将是正确的(2502次提交)。这在这个简单的场景中工作正常,但是如果用户A和用户B每次都没有1次提交,那么会出现一个奇怪的复杂情况:git rebase -Xours失败并显示以下消息:

First, rewinding head to replay your work on top of it...
fatal: Could not parse object '98d7cd83de321e737b22240752cd178622d29406^'
Unknown exit code (128) from command: git-merge-recursive 98d7cd83de321e737b22240752cd178622d29406^ -- HEAD 98d7cd83de321e737b22240752cd178622d29406

你可以,例如使用以下github存储库重现此问题:

git clone https://github.com/opentk/opentk
cd opentk
git remote add mono https://github.com/mono/opentk
git fetch mono
git checkout -b integrate
git rebase -Xours mono/rodo-consolidate-opentk

有谁知道为什么会这样?有任何想法如何解决这个问题?

4 个答案:

答案 0 :(得分:6)

这似乎是一个很少需要探索的问题。我只是偶然发现了这个问题,正如this email中所建议的那样,问题实际上似乎是因为你试图使用递归策略来进行没有父项的提交(例如,另一个存储库的主分支)。 / p>

在我的场景中,我加入了两个git存储库,在另一个的master中重新定义了一个git存储库。在你的情况下,转换和合并svn repos,所以我想这几乎是相同的情况。

在我的场景中,我再次使用strategy = recursive和strategy-option = renormalize来忽略恼人的行结尾冲突。它工作得非常好,虽然在给定时间我不得不在历史中间发出一个额外的提交,只是为了从提交的文件中丢弃行结尾(保持为'修改'直到你提交它们)。

以下是我克服这个问题的方法:

  1. git rebase <branch> --strategy=recursive --strategy-option=ours
  2. First, rewinding head to replay your work on top of it...
    fatal: Could not parse object '67fceed5a80ff78ac6f9a437620323131c88cd51^'
    Unknown exit code (128) from command: git-merge-recursive 67fceed5a80ff78ac6f9a437620323131c88cd51^ -- HEAD 67fceed5a80ff78ac6f9a437620323131c88cd51
    1. git cherry-pick 67fceed5a80ff78ac6f9a437620323131c88cd51 (注意,它是错误消息中显示的哈希!)

    2. 解决冲突(如果有)

    3. git rebase --continue

    4. 从第二次提交开始,递归策略将起作用,因为它们都有父级(你刚刚挑选的那个)。

      你会有一些冲突和一些需要提交来偶尔规范化代码,但是你将不再被许多无用的行结束冲突所困扰,这些冲突只会混淆并在合并代码中产生错误。< / p>

      我认为这是一个错误,因为递归策略可能只是假设没有父母,一个空的&#39;应该使用提交/工作树作为比较的基础(因此提交中的所有内容都是实际添加而不是修改)。

答案 1 :(得分:1)

我遇到了与此错误类似的问题,我放弃了rebase,而是使用cherry-pick来选择更改,并且工作正常。

答案 2 :(得分:1)

其中一种可能的解决方案是使用git gc --aggressive删除旧提交的所有链接。这对我有帮助。

答案 3 :(得分:0)

现在已经很老了,但OP正在寻找的选项是--root

  

--root

     

重新启动所有可从<branch>到达的提交   限制他们<upstream>。这允许你变基   分支上的根提交。 [...]

正如另一个答案所提到的,这里真正的问题是git期望找到一个不存在的父提交。具体来说,当git在这两个分支之间寻找合并基础时会发生这种情况。 --root告诉git不要这样做。

归功于jthill和他的回答https://stackoverflow.com/a/23312760