簡體   English   中英

git:將子樹從一個分支合並到另一個分支

[英]git: merging a subtree from one branch to another

我無法將開發分支的子樹合並回集成分支。

我有兩個分支,一個用於開發,一個用於集成。 在開發分支中已經進行了廣泛的開發,我想將其中的一部分合並回來。我想要合並的特定部分都包含在開發分支的一個子樹中。

我的目錄結構是這樣的:

[Branch A]              [Branch B]
    |                       |
    +--Dir1                 +--Dir1
    +--Dir2                 +--Dir2
        |                   |   |
        +--DirA             |   +--DirA
            |               |       |
            +--File1        |       +--File1
            +--File2        |       +--File2
                            |       +--File3
                            |       +--File4
                            +--Dir3

我想將Branch B / Dir2 / DirA合並到Branch A / Dir2 / DirA中。 我希望合並File1和File2,並且應該在分支A中創建File3和File4。我不想選擇Dir3或Dir1中的任何更改。

我已經嘗試了kernel.org概述的步驟來合並子樹 ,但是當我使用git read-tree時它們會失敗:

error: Entry 'Dir1/DirA/File1' overlaps with 'Dir1/DirA/File1'.  Cannot bind.

我已經嘗試使用github上托管的子樹腳本 ,但我沒有太多運氣。 當我做:

git checkout Branch_A
git subtree merge -P Dir2/DirA Branch_B

我看到證據表明Dir3已經合並,合並失敗並伴隨着沖突。

我可以挑選合並的文件,但這對於應該是一個普通和直接的問題似乎不必要地復雜化。

你想要的可能只是:

git merge Branch_B -s ours  [OPTIONAL]
git checkout Branch_B Dir2/DirA

細節

此配方將子樹從Branch_B復制到Branch_A,(OPTIONALLY)也在git的項目歷史中創建合並提交:

  1. 如果您還沒有,請切換到Branch_A。

    git checkout Branch_A

  2. (可選)建立合並提交,而不更改工作區中的任何文件( 合並策略“我們的”)。 這個“空”提交只是將另一個分支添加為第二個父,創建歷史鏈接。 如果這對你不重要,你可以跳過這一步; 后續步驟不需要它。

    git merge Branch_B -s ours

    注意:只能在干凈的工作空間中執行此操作; 如果您修改或暫存了任何文件,則此命令可能會失敗。

  3. 將子樹Dir2 / DirA的內容從Branch_B復制到工作區 ,而不更改活動分支。

    git checkout Branch_B Dir2/DirA

  4. 將Branch_B中的文件提交到Branch_A。 如果省略--amend則為此步驟創建新的提交; 使用它將使新文件成為早期合並提交的一部分。

    git commit --amend

步驟3中的結帳形式可能看起來不熟悉,但官方文檔指出,當使用此表單時,慣常的分支切換行為實際上只是一種便利:

如果沒有給出路徑,git checkout也會更新HEAD以將指定的分支設置為當前分支。

因此,如果您提供顯式路徑,則不會切換分支,只需從該路徑復制文件即可。

你遇到的問題是git不是為了做這樣的事情而設計的。 考慮以下歷史記錄,可能會導致您的兩個分支AB來自問題:

C - D - E - F - G - H
 \
  H - I

分支A指向提交I和分支B指向提交H 現在你想把B一些變化接管到A

例如提交DF改性Dir2EGH做了一些至Dir1Dir3 所以實際上你只想將提交DF添加到集成分支A

這意味着分支B沒有足夠仔細地創建,你實際上想要將它重做到(至少)兩個干凈的主題分支。 就像是:

git checkout -b topic_I_want_to_merge_touching_Dir2 C
git cherry-pick D
git cherry-pick F
git checkout -b topic_I_dont_want_to_merge_now C
git cherry-pick E
git cherry-pick G
git cherry-pick H
git checkout B
git merge topic_I_want_to_merge_touching_Dir2

如果存在同時觸及Dir1Dir2提交,那么這些提交都是“不好的”,因為它們不會解決單個主題,而是同時執行多項操作。 在這種情況下,您可能不僅要重新調整提交,還要使用git-rebase -i將提交更改為好的提交。

當然,您可以合並分支A並修復生成的樹。 但是,這將使它幾乎不可能繼續在“非合並”的轉變工作A ,因為當你合並的后代A你必須修復行動的結果樹一次,因為變化EGH不會包含在git為你准備的樹中,因為這些提交已經合並。

合並子樹實際上是指將外部項目的一部分合並到您的項目中。 我會參考這篇博文來完成你想要做的事情: http//jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-科/

我只是讓dirA成為一個子模塊並為它引入第三個回購。

暫無
暫無

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

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