並不是說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將無法判斷你是否忘記了應用該補丁。