Git rebase在删除/修改冲突后无法继续。

72

我正在将我的主分支(master) 与一个暂存分支(stage branch) 进行合并

git checkout stage
git rebase master

有时我删除了两个文件,然后根据GIT修改了这两个文件。

warning: too many files, skipping inexact rename detection
CONFLICT (delete/modify): test-recommendation-result.php deleted in HEAD and modified in [Bug] Fix test recommender. Version [Bug] Fix test recommender of test-recommendation-result.php left in tree.
CONFLICT (delete/modify): test-recommendation.php deleted in HEAD and modified in [Bug] Fix test recommender. Version [Bug] Fix test recommender of test-recommendation.php left in tree.
Failed to merge in the changes.
Patch failed at 0015.

我想说“是的,Git,请继续删除那些文件”,因此....

git rm test-recommendation-result.php
git rm test-recommendation.php
git rebase --continue

Git 说:

Applying [Bug] Fix test recommender
No changes - did you forget to use 'git add', Stupid?

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

我说“不要叫我‘傻瓜’,只需按照我告诉你的做!”

现在我们陷入了僵局。谁是对的,我该怎么解决这个问题?

6个回答

68

执行 git add -A 命令,然后再执行 git rebase --continue 命令。这应该会添加所有更改-包括你删除的文件,然后继续。

不能保证提交中没有其他未发生冲突且应该合并的文件。git rebase --skip 命令会丢失这些文件。你不想要这种情况发生。


1
总的来说,你是正确的,但在这种情况下,似乎我们可以推断出没有其他更改存在。Git 要么会抱怨其他冲突,要么 rebase --continue 将会起作用。 - Cascabel
2
你没有理解重点。这里的第一步是“检查git状态的输出”。如果没有列出冲突,并且没有暂存任何内容,那么跳过是正确的选择 - 并且添加/继续不会做任何事情,就像OP看到的那样。如果只列出了已暂存的更改,则首先没有冲突,您可以继续(根本不会问问题)。如果存在冲突,则仍然不会提出问题,您的答案是危险的 - 您需要在盲目添加所有内容之前修复冲突。 - Cascabel
3
简短版:当变基在某个阶段停止时,没有一条特定的命令序列是你应该始终运行的。你需要理解发生了什么,并相应地采取行动。 - Cascabel
1
我接受你的答案,但我想知道为什么它是正确的。为什么仅使用“git rm”不能让git知道您的意图是确认删除那些文件(并将删除条目添加到索引),而在“git rm”之后使用“git add”实际上意味着什么? - metamatt
2
如果您的存储库中有未跟踪的文件,请小心使用“-A”将它们全部添加。在我的情况下,冲突发生在子目录中,我只需执行“git add subdir”。 - Gogowitsch
显示剩余4条评论

3

当一切都失败了,阅读信息。

此补丁尝试修改两个文件,但它们已经被删除;再次删除它们没有任何作用。

只需运行git rebase --skip


4
不能保证是否还有其他文件合并正确,如果选择跳过rebase就会丢失这些更改。 - Adam Dymitruk
哦,我以为如果其他文件合并正确,rebase 就不会抱怨。 - Josh Lee
1
问题在于它抱怨这2个文件存在冲突。该提交可能不仅仅修改了这2个文件。如果您跳过,那么您也会跳过那些没有报告冲突的文件,而不仅仅是那些报告冲突的文件。 - Adam Dymitruk
1
@adymitruk:这是唯一报告的两个冲突,因此如果其他文件已更改,则它们已经在索引中,并且rebase --continue不会抱怨缺少文件。在这种情况下,rebase --skip是完全正确的。 - Cascabel
这是关于覆盖索引中存在和不存在文件且没有冲突的情况。请参考上面的评论。 - Adam Dymitruk

2

当一个提交添加了一个与现有文件冲突的二进制文件时,我遇到了这个问题。

我通过以下方式解决:

  • 删除现有文件,
  • 在另一个文件的注释中进行单个字符更改,并且
  • "git add" 那些无关紧要的更改。

Git 再次愉快地工作了。 :)


1
作为我的问题:
当我执行 git add . 时,所有的更改都消失了。我需要更改任何文档(只需添加少量更改,例如添加注释),然后执行 git add . ,然后 git rebase --continue 才能正常工作。这是git的已知错误。

0

解决这种情况并没有一组神奇的命令序列。如果有的话,GIT的开发人员会执行该操作而不会打扰用户。

请注意,如果您正在挑选/移植/回溯影响已重构或重命名文件的更改,则也可能发生此错误。

例如,假设您有一个名为support/1.0的分支,看起来像这样:

    com.somewhere.package-a/
      MyClass.java
      MyOtherClass.java

现在,假设在版本1.0和1.5之间进行了重构。因此,release/1.5现在看起来像这样:

    com.somewhere.package/
      a/
        MyClass.java
        ANewClass.java
      b/
        MyOtherClass.java

现在,假设您有一个从发布1.5开始的功能分支,您正在尝试将其回溯到基于support/1.0的功能分支。在该提交中,所有三个文件都进行了更改(来自发布1.5的MyClass.javaANewClass.javaMyOtherClass.java)。

如果您尝试使用rebase或普通的cherry pick来帮助进行回溯,可能会发生以下两种情况之一:

  • 如果文件在被移植的更改中重命名,或者在被移植的更改的直接父提交中重命名,GIT内置的重命名检测可能会捕获到这些文件是具有原始名称的文件的后代,并简单地将更改应用于原始文件。

  • 如果文件在1.5版本发布历史的足够远的位置被重命名(在1.0版本发布之后),GIT会告诉您这些文件已在release/1.0中被删除,因为它不知道1.0中的哪些文件对应于从1.5开始的更改。

ANewClass.java几乎肯定会触发关于已被删除的错误,除非它是在被回溯的更改中添加的。

因此,由于如果您盲目地遵循一组命令来解决此情况可能会丢失代码,这就是为什么GIT提示您手动指导的原因。


0

如果您像我一样做了某些事情,因为文件应该被忽略,但在某个时候它没有被忽略 - 所以它最终进入了源代码控制,请从文件系统中删除这些文件,然后中止rebase。

之后,您可以重新启动而不会出现此错误。

这不是理想的解决方案,但不幸的是,一旦发生这种情况,我没有找到任何其他可接受的解决方法。


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