2016-12-15 191 views
2

有时我会在重新定位和修复冲突后遇到此问题。我做了git add .,我会跑git rebase --continuegit rebase修复冲突后

不过,我有时会收到此消息

Applying: xxxxxx 
No changes - did you forget to use 'git add'? 
If there is nothing left to stage, chances are that something else 
already introduced the same changes; you might want to skip this patch. 

我永远无法理解为什么会发生这种事。所以,我最终要做git rebase --skip才能继续。有人可以告诉我为什么Git没有意识到我解决了冲突吗?

回答

3

并不是说Git没有意识到你已经修复了冲突,因为Git的作者认为这是一个很好的安全设备。

这种情况发生在提交你挑肥拣瘦,记得git rebase是,是否有效或实际,只是很多重复挑肥拣瘦,改变的是不完全一样,但非常相似到,您在重新分配的提交中已经发生了变化。

例如,假设原来的工作是这样的:

...--o--*   <-- origin/develop 
     \ 
      A--B--C <-- develop 

这里ABC是你已经三次提交。提交*是其中develop是当你第一次开始时,origin/develop仍然记得它。

在提交A中,您修复了文件a中的某些内容,并更新了README.txt文件。在B中,您修复了文件b中的某些内容,但忘记更新README.txt。在承诺C你记得更新README.txt,所以你这样做。

现在别人已经进行了更改,并迫使他们将上游服务器,所以你git fetch他们工作:

...--o--*--D--E  <-- origin/develop 
     \ 
      A--B--C <-- develop 

,然后去到git rebasedevelop在新origin/develop。这将在一般复制ABC新提交A'B',并C'这样,如果一切顺利的话,你将最终获得:

...--o--*--D--E   <-- origin/develop 
     \  \ 
      \  A'-B'-C' <-- develop 
      \ 
      A--B--C  [abandoned] 

A'-B'-C'提交仅仅是git cherry-pick原件的副本。

Git是足够聪明,如果你的提交A介绍完全相同的变化这也是要么DE,Git会简单地下降A当复制:它会跳过它,只复制BC 。但是,假设在这个意义上A“等于”D,或者让我们假设第二种情况是正确的 - A是完全独立的并且被复制得很好。但是,它既不是B也不是C,即“等于”E,而是总和B+C,即“等于”E。也就是说,你和他们做了相同的修复程序,但他们记得在一次提交中修复了README.txt ...并且在对文件b的更改中存在一些小的拼写差异 - 或者文件b被重新格式化了或保留Git从现在开始应用您的更改。

你用手去解决Git所抱怨的b,而Git试图挑选承诺B来制作B'。然后你解决文件。但是现在您的文件b与上游的b完全匹配。虽然这是有意的 - 没有什么可以做b毕竟Git不知道你已经证实了这一点。 Git认为也许你只是跑git checkout HEAD -- b看看他们的版本是什么。这将提取他们的b并假装一切都已解决,并且在相同的情况下给你留下。

所以,因为这是要下降您提交B完全,Git会为您提供了这样的警告。如果正确的东西现在完全放弃提交B,那么毕竟您应该运行git rebase --skip,并跳过您的B

Git现在将尝试应用您的C修复README.txt。这将没有它需要做的事情,因为他们已经在他们的提交D中这样做了。你的Git在解决之后会再次看到 - 也许甚至是自动的,这次 - 冲突,没有什么可以提交的。 Git会想知道它是否有错误,并让你运行git rebase --skip以确认这是正确的。

一旦你做了,事实证明,只有A需要被复制,你居然结了:

...--o--*--D--E  <-- origin/develop 
     \  \ 
      \  A' <-- develop 
      \ 
      A--B--C [abandoned] 

但混帐想成为真的确定从省略BC复制是正确的,因为它是相当容易的,毫不夸张地说忘记git add运行时git rebase --continue


这可能更有意义,如果你意识到这一点,很早就上的Git没有良好的内置git cherry-pick命令。相反,重新绑定将一个提交变成了一个补丁,然后试图应用该补丁,就好像有人将它邮寄给了你。那么Git将无法判断你是否忘记了应用该补丁。