標籤:

關於git cherry-pick的問題?

有一條主分支master,進行過兩次提交(m0和m1)。此時,新開了一個分支develop做開發,進行了三次提交(d0、d1和d2)。如果只想將d2這次提交合併到主分支master,查了很多資料說應該用cherry-pick指令,於是

git checkout master

git cherry-pick d2的哈希碼

可是這時候,會產生一個衝突,需要用戶手動去編輯。這恰恰不是我想要的效果,我僅僅是想把d2這次提交插入到m1之後,然後head指針前移到d2,這不涉及到衝突啊。希望有大神來解決我的疑惑。


你只能解決衝突。

你無法 cherry-pick的原因是,你 d2 修改的文件,已經在 d1(or d0) 被修改過了,所以 cherry-pick 並不知道如何刪除和增加對應的 lines,所以就衝突了。你唯一的辦法就是解決衝突。

另外,cherry-pick 並不是將指針(是這麼翻譯?)移到d2,cherry-pick 更像 patch the changes,即使什麼衝突都沒有,commit hash 都是不一樣的。


比如你在d1裡面增加一行,然後在d2裡面刪除這一行,你cherry-pick d2的話必然衝突。原因就是m1不包含d0和d1,而d2是建立在d0和d1上的。


剛剛認真研究了一下cherry-pick。

是這樣的,cherry-pick只會將一個commit引入的更改應用到當前的commit上。而你的命令:

git cherry-pick d2的哈希碼

只會將從d1-&>d2的修改引入到m1中,這樣當然會造成衝突。

正確的做法是:

git checkout master
git cherry-pick --no-commit d0的哈希 d1的哈希 d2的哈希
git commit -m"merged commit"

--no-commit參數是防止cherry-pick每一次應用更改都commit一次。

----------------------------------------以上等效於-------------------------------------

git merge d2 --squash


cherry-pick操作過程相當於將該提交導出為補丁文件,然後在當前HEAD上重放,形成無論內容還是提交說明都一致的提交,衝突是可能的

另外,cherry-pick不是你描述的那樣,他會重新生成一個commit的,只是描述完全一樣


如果你只想把develop branch特定的commit apply到m1上,除了cherry-pick後解決衝突沒別的辦法

如果想把develop branch上d2當前的state完全apply到master上 其實checkout是比cherry-pick更好的選擇

git checkout master
git checkout develop &

&



這個其實跟你要cherry-pick的commit之間有沒有做過更改沒有直接關係.

如果沒有更改, 當然會直接merge沒有conflict.

如果二者之間還有過更改, 因為cherry-pick其實是用那次commit的內容進行patch, 所以要分情況看:

  1. 所做更改沒有在diff信息的context範圍內, 沒有衝突.
  2. 所做更改在diff信息的context範圍內, 你需要解決這個衝突才能merge.


git是跟蹤文件的變化而不是保存每個提交的完整文件,所以你git cherry-pick d2的哈希碼只是把develop分支上d1-&>d2的改動應用到了master分支的m1上,顯然m1-&>d1的變化沒有先應用上,所以導致衝突。


git checkout master

git rebase --onto master d1 d2

正好是你需要的, 意思是把 d1-d2 這一段嫁接到master上.

m0 --m1 -- d2

   

    d0 -- d1 -- d2


推薦閱讀:

使用git,用命令好還是客戶端好?
Oh shit, Git! 快速解決Git最常見問題
寫作和出版行業本身有沒有使用什麼版本管理、控制的系統嗎?一個專門針對文字的類 github 有市場嗎?
國內Git託管服務對比,各家優勢劣勢?

TAG:Git |