2016-12-15 192 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將無法判斷你是否忘記了應用該補丁。