簡體   English   中英

Git 合並只在分支內提交

[英]Git merge only commits within branch

考慮下面的這棵樹。 請原諒這個蹩腳的圖表,但我想你明白了。

我有一個MASTER分支和一個MY BRANCH 我從MASTER創建了一個PATCH分支並在這個分支上進行修復。 然后我合並修復到兩個MASTERMY BRANCH 當我這樣做時, MY BRANCH也會隨之提交C & D

MASTER----A----B----C----D-------------MERGE
                \         \             /
                 \       PATCH----E----F
                  \                     \
             MY BRANCH----G----H-------MERGE

如何將補丁中的提交合並到MASTERMY BRANCH

正如 RomainValeri 指出的那樣,可以更好地繪制圖形。 我將借用他的變體開始,但您嘗試進行任何合並之前先繪制我們擁有的內容:

              E---F <<< patch
             /
A---B---C---D <<< master
     \
      G---H <<< my-branch

名稱patch是指現有的提交F ,名稱mastermy-branch是指現有的提交H

您遇到的問題是因為git merge基於提交圖而不是分支名稱工作 名稱找到提交,就目前而言是可以的,但是如果您運行git merge <commit F> ,結果將包括提交F ,其中將包括提交E ,其中將包括提交D ,其中將包括提交C ,這將包括提交B ,依此類推。

也就是說,提交F任何成功合並都會自動包括導致並包括F本身的每個提交

您可以使用git cherry-pick復制單個提交。 請記住,提交是一個快照,即所有文件的完整集合。 但是每個提交也有一個提交。 1如果將提交E中的快照與其父提交D的快照進行比較,您將看到提交E更改 如果您將提交F的快照與其在提交E父快照進行比較,您將看到在提交F所做的更改 挑選本質上允許您在其他地方“重播”這些更改。

這導致人們經常提出的建議,在這里使用cherry-pick。 如果您創建一個名為patch2的新分支,從提交H開始,並將EF復制到新的和改進的提交E'F' ,其中E'F'出現在提交H ,您將得到:

              E---F   <-- patch
             /
A---B---C---D   <-- master
     \
      G---H   <-- my-branch
           \
            E'-F'  <-- patch2

您現在可以將原始補丁合並到master並將新的和不同的(據說改進的) patch2分支合並到my-branch

有一個更好的方法! 好吧,無論如何,經常 讓我們退后一步問:你為什么首先要寫提交EF

有可能是修復提交A或提交B或兩者中的錯誤。 或者它可能添加了提交B缺少的功能。 無論如何,您相信它可以在提交CD的情況下應用。

你現在應該做的是證明這一點 創建一個新分支patch2但不要將其指向現有提交H 改為在提交B啟動它。 然后將EF復制到新改進的E'F' ,給出:

          E--F   <-- patch
         /
     C--D   <-- master
    /
A--B--E'-F'  <-- patch2
    \
     G--H   <-- my-branch

請注意,所有現有的提交仍然存在,完全相同。 (你還沒有在任何地方合並任何東西。)但是如果patch2真的有效,我們現在可以扔掉名為patch的分支,放棄提交EF

          E--F   [abandoned]
         /
     C--D   <-- master
    /
A--B--E'-F'  <-- patch2
    \
     G--H   <-- my-branch

現在我們已經完成了,讓我們停止繪制它們,並將現有分支patch2重命名為patch

     C--D   <-- master
    /
A--B--E'-F'  <-- patch
    \
     G--H   <-- my-branch

復制的(櫻桃挑選的或重新定位的)提交E'-F'現在處於我們可以運行git checkout master; git merge patch git checkout master; git merge patchgit checkout my-branch; git merge patch git checkout my-branch; git merge patch 當我們這樣做時,我們會得到兩個合並提交:

     C--D--M1   <-- master
    /     /
A--B--E'-F'  <-- patch
    \     \
     G--H--M2   <-- my-branch

這些合並按您喜歡的方式運行:它們將補丁帶入分支,而不是任何其他與補丁無關的提交。

這導致了關於制作補丁的一般規則

如果您要修復錯誤或添加共享功能,請在圖表中找到錯誤或功能可以到達的最早提交 在這種情況下,那是在提交B (也許可以將它放在提交A ,如果是這樣,您可以改為這樣做。但是,如果錯誤或功能需要提交B一部分,則提交B是您可以走的最遠的地方。)

這樣做的原因是生成的補丁可以干凈地合並到該點“下游”的任何提交。 在這種情況下,你想合並補丁放到提交D ,在master ,下游B ,並進入H ,在my-branch ,下游B 由於patch在提交F'處位於B下游,因此將patch合並到任何分支都將引入提交B 但是提交B是分支patch有用的第一個地方。 任何尖端不在B下游的分支根本不能使用補丁! 因此,通過在可能使用的第一個位置之后立即放置補丁本身,所有其他可以使用補丁的分支都可以輕松干凈地使用補丁。

使用rebasecherry-pick手動將EF應用到MYBRANCH或僅以EF開始正確創建PATCH分支。

您可以使用范圍來指定目標分支上的哪些提交:

git checkout my-branch
git cherry-pick master..patch

其中master..patch意味着:
一切patch減號一切已知的master


作為旁注,對更好的樹模式的建議

              E---F <<< patch
             /     \
A---B---C---D-------I <<< master
     \
      G---H <<< my-branch

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM