git cherry-pick 详解 —— Git 学习笔记 18
git cherry-pick 詳解
初識 git cherry-pick(揀選)
揀選會提取某次提交的補丁,之后嘗試將其重新應用到當前分支上。 這種方式在你只想引入特性分支中的某個提交時很有用。
假設你的項目提交歷史如下:
如果你希望將提交 e43a6 拉取到 master 分支,你可以運行:
# 當前處于 master 分支$ git cherry-pick e43a6 Finished one cherry-pick. [master]: created a0a41a9: "More friendly message when locking the index fails."3 files changed, 17 insertions(+), 3 deletions(-)這樣會拉取和 e43a6 相同的更改,但是因為應用的日期不同,你會得到一個新的提交 SHA-1 值。 現在你的歷史會變成這樣:
現在你可以刪除這個特性分支(ruby_client),并丟棄不想拉入的提交(5ddae)。
需要說明的是,提取某次提交的“補丁”,這個補丁是基于其父提交的。
下圖可以說明:
我們要揀選提交 C4 到 maint 分支(maint 指向 C7),Git 會生成一個補丁(Δ=C4?C3\Delta = C4-C3Δ=C4?C3),然后把Δ\DeltaΔ應用到C7上,也就是說把 C4 對 C3 的變化在 C7 上重放一遍。
為何會產生沖突
同 merge 操作一樣,揀選操作也可能產生沖突。有人會問:不會吧,打個補丁也能沖突?
當然能。
用 diff 工具生成 patch 時,我們所做的每一處修改都會連同它的“定位信息”(原始文件中的行號、修改處前三行和后三行的原始文本)一并保存到 patch 文件中。patch 被應用時,會在目標文件中尋找“定位信息”,找到后再實施修改。可是,當我們把補丁應用到 C7 上時,有可能找不到那些定位信息了:在master分支上,C2變成了C3,在maint分支上,C2變成了C6,又變成了C7,也許C3和C7相差越來越遠,C3中的上下文在C7中早已面目全非,不見蹤跡。于是應用patch失敗,即發生沖突。
沖突了怎么辦
當揀選發生沖突的時候,GIT 會采用三路合并算法。還是以上面的圖為例子,
當你運行命令 git cherry-pick C4 的時候,Local是C7,Remote是C4,Base是C3(即C4的父提交)。總結:
當你運行命令
git cherry-pick <commit C>
如果沖突了,那么Git會嘗試三方合并
- LOCAL: the commit you’re merging on top of (i.e. the HEAD of your branch)
- REMOTE: the commit you’re cherry picking (i.e. commit C)
- BASE: the parent of the commit you’re cherry-picking (i.e. C^, ie the parent of C)
如果三方合并的時候又沖突了怎么辦?那只能靠我們人工解決了。
參考資料
【0】《Pro Git》(Scott Chacon, Ben Straub Version 2.1.14, 2018-05-19)
【1】 https://my.oschina.net/jiangyouxin/blog/108717
【2】《Git 高手之路》,人民郵電出版社
【3】 StackOverflow, https://stackoverflow.com/questions/10058068/in-a-git-cherry-pick-or-rebase-merge-conflict-how-are-base-aka-the-ancestor
總結
以上是生活随笔為你收集整理的git cherry-pick 详解 —— Git 学习笔记 18的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android p安装教程,Androi
- 下一篇: git rebase(变基)—— Git