關於git cherry-pick的問題?
有一條主分支master,進行過兩次提交(m0和m1)。此時,新開了一個分支develop做開發,進行了三次提交(d0、d1和d2)。如果只想將d2這次提交合併到主分支master,查了很多資料說應該用cherry-pick指令,於是
git checkout mastergit 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 --squashcherry-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, 所以要分情況看:
- 所做更改沒有在diff信息的context範圍內, 沒有衝突.
- 所做更改在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 |