有时我在重新定位和修复冲突后遇到这个问题。
我做了git add .
,我会运行git rebase --continue
。
但是,我有时会收到此消息
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没有意识到我修复了冲突?
答案 0 :(得分:3)
并不是说Git没有意识到你已经解决了冲突,因为Git的作者认为这是一个很好的安全设备。
这种情况发生在您正在挑选的提交时 - 记住git rebase
是,无论是有效还是实际,只是大量重复的挑选 - 一个与不完全相同的变化/ em>,但与非常相似,这是您在提交的提交中已经发生的变更。
例如,假设原始工作是这样的:
...--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'
和{{1}所以,如果一切顺利,你最终会得到:
C'
新的...--o--*--D--E <-- origin/develop
\ \
\ A'-B'-C' <-- develop
\
A--B--C [abandoned]
提交只是原件的A'-B'-C'
份。
Git非常聪明,如果您的提交git cherry-pick
引入完全相同的更改同样位于A
或D
,Git将只是 E
:它会跳过它并只复制A
和B
。但是假设C
&#34;等于&#34; {@ 1}}在这个意义上,或者 - 为了论证而说第二种情况是正确的 - A
是完全独立的并且被复制得很好。但是,它不是D
也不是 A
&#34;等于&#34; B
,而是总和C
,&#34;等于&#34; E
。也就是说,你和他们做了相同的修复,但他们记得在一次提交中修复了B+C
...并且他们对文件的更改存在一些轻微的拼写错误E
- 或者文件README.txt
被重新格式化或者其他内容,让Git无法按原样应用您的更改。
当Git试图挑选提交b
来制作b
时,你手动进入并解决Git抱怨的b
问题。然后你B
已解决的文件。但现在您的文件B'
与上游git add
完全匹配。虽然这是有目的的 - 但在所有文件b
之后没有任何关系 - Git 并不知道您已经验证了这一点。 Git认为也许你只是跑b
看看他们的版本是什么。这将提取他们的 b
并假装所有内容都已解决,并在其他情况下保持相同的情况。 1
因此,由于这将完全删除你的提交git checkout HEAD -- b
,Git会给你这个警告。如果正确的事情 现在完全放弃您的提交b
,那么您应该运行B
,然后跳过B
。
Git现在会尝试应用您的git rebase --skip
来修复B
。这将无需任何操作,因为他们已经在提交C
中执行了此操作。你的Git将再次看到解决后 - 或许甚至自动,这一次 - 冲突,没有什么可以承诺。 Git会怀疑它是否可能出错,并让你运行README.txt
以确认这是正确的。
一旦完成,事实证明只需要复制D
,并且您实际上最终得到:
git rebase --skip
但Git希望非常确定从复制中省略A
和...--o--*--D--E <-- origin/develop
\ \
\ A' <-- develop
\
A--B--C [abandoned]
是正确的,因为它相对容易实现运行B
时忘记到C
。
1 如果您意识到Git没有拥有良好的内置git add
命令,这可能会更有意义。相反,rebase将提交转换为补丁,然后尝试应用补丁,就好像有人邮寄给你。然后,Git将无法判断您是否忘记了根本不应用补丁。