并不是说Git没有意识到你已经修复了冲突,因为Git的作者认为这是一个很好的安全设备。
这种情况发生在提交你挑肥拣瘦,记得git rebase
是,是否有效或实际,只是很多重复挑肥拣瘦,改变的是不完全一样,但非常相似到,您在重新分配的提交中已经发生了变化。
例如,假设原来的工作是这样的:
...--o--* <-- origin/develop
\
A--B--C <-- develop
这里A
,B
和C
是你已经三次提交。提交*
是其中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 rebase
您develop
在新origin/develop
。这将在一般复制A
,B
和C
新提交A'
,B'
,并C'
这样,如果一切顺利的话,你将最终获得:
...--o--*--D--E <-- origin/develop
\ \
\ A'-B'-C' <-- develop
\
A--B--C [abandoned]
新A'-B'-C'
提交仅仅是git cherry-pick
原件的副本。
Git是足够聪明,如果你的提交A
介绍完全相同的变化这也是要么D
或E
,Git会简单地下降A
当复制:它会跳过它,只复制B
和C
。但是,假设在这个意义上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]
但混帐想成为真的确定从省略B
和C
复制是正确的,因为它是相当容易的,毫不夸张地说忘记到git add
运行时git rebase --continue
。
这可能更有意义,如果你意识到这一点,很早就上的Git没有有良好的内置git cherry-pick
命令。相反,重新绑定将一个提交变成了一个补丁,然后试图应用该补丁,就好像有人将它邮寄给了你。那么Git将无法判断你是否忘记了应用该补丁。