2013-05-22 102 views
4

在我們的Git過程中,「master」是當前發佈週期的主題和修復分支的集成分支,但我們也保持「stable」我們必須小心地回溯一些已經成功在主服務器上測試過的修復程序。如何將git backport(rebase/cherry-pick)一個已經合併的分支

所有的困難是分支已合併早在「大師」(否則它與重訂--onto很容易)

  • 我們不希望改變的過程中其他方式,因爲a)我們不想修復「stable」分支中的所有內容,以及b)我們有時必須對「stable」分支進行一些更改,我們不想在「master」中進行合併。
  • 顯然,我們無法將修復程序合併到「穩定」分支中,因爲這會反向運行許多不需要的功能。

圖的初步情況我形容:

  I--J (stable) 
     /
     /
    /
- A - B - C - D - E - F - G (master) 
       \ /
       X -- Y (fix/123) 

的那種情況的圖表,我們要達到:

  I--J (stable) 
     / \ 
     / X'- Y' (fix/123-stable) 
    /
- A - B - C - D - E - F - G (master) 
       \ /
       X -- Y (fix/123) 

更復雜的情況是可能的,如多合併到完成修復:

- A - B - C - D - E - F - G - H (master) 
       \ / /
       X - Y ----- Z (fix/123) 

但是我們沒有允許合併成一個固定的分支,所以我們永遠不會有這樣的事情:

- A - B - C - D - E - F - G (master) 
       \ \ /
       X - Y - Z (fix/123) 

要做到這一點,我們就可以摘櫻桃或重訂修復分支:

1)摘櫻桃(typicaly How do I backport a commit in git? ):

git checkout -b fix/123-stable stable 
git cherry-pick X Y 

這似乎很容易,但它不是在處理現實生活中的例子;總會有忘記一些提交或挑錯的風險!

2)重訂--onto(https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html):

2.A)中的 「不工作」 的方式:

git rebase --onto stable master fix/123 

這並沒有什麼,因爲修復/ 123已經合併掌握! 2.B)中的「不遠比摘櫻桃更好」的方式:

git rebase --onto stable D fix/123 

這仍然是一種有風險的,因爲你需要採取d的SHA(不是X的實例)。

2.C)中的「使用臨時起點裁判」的方式:

git tag begin D 
git rebase --onto stable begin fix/123 
git tag -d begin 

這改善了以往的情況來看,作爲標籤使其更容易做,或在圖形工具圖片,但它仍然是很多手工工作。

3.d)「合併之前復位硬盤主」(到第一個分支點) 嗡嗡聲,似乎很難描述和做。

因此,我正在尋找的是git 便攜式(不含bash/grep/cut/sed暗示)的方式;

1)列出所有的提交上一個分支的已合併到「主」(這裏的X和Y,而且中的Z「多合併」的情況下)輕鬆摘櫻桃他們

2)獲得已經合併回「主」的分支的第一個分支點的提交

2.a)這不能通過「git merge-base」命令完成,因爲合併已經完成(甚至多次)

2.b)我在這裏找到Finding a branch point with Git?下面的bash命令我調整了一下:

git rev-list --boundary --date-order --reverse fix/123..master | grep -m 1 - | cut -c2- 

但他不是一個git容易,也不移植的命令(不bash或Cygwin的工具,即不工作)

回答

4

爲了記錄在案,這裏是我最後使用基於在answer of lindes on "Finding a branch point with Git"answer of Craig Otis here指向了兩種解決方案,使用bash別名「的.gitconfig」文件

初始狀態,(在Linux操作系統Ubuntu 12.10測試)其中分支「修復/ 123」已經被合併到「主」

 I--J (stable) 
    /
- A - B - C - D - E - F - G (master) 
       \ /
       X - Y (fix/123) 

1)變基的分支「修復/ 123」,由「主」開始到「穩定」(這是大多數人讀這一個通用的答案):

以下猛砸別名添加到您「的.gitconfig」文件:

[alias] 
    oldest-ancestor = !bash -c 'diff -u <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | sed -ne \"s/^ //p\" | head -1' - 
    rebase-onto  = !bash -c 'git rebase --onto $1 `git oldest-ancestor $2 $3` $3' - 

然後使用命令行:

git rebase-onto stable master fix/123 

在這裏你是:

  I--J (stable) 
     / \ 
     / X'- Y' (fix/123) 
    /
- A - B - C - D - E - F - G (master) 
       \ /
       X - Y 

2)向變基的分支「修復/ 123」,由「主」開始,創建一個新的分支「修復/ 123-穩定的」到「穩定」(這是更具體的答案我要去使用)。

添加以下猛砸別名到您 「的.gitconfig」 文件:

[alias] 
    oldest-ancestor = !bash -c 'diff -u <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | sed -ne \"s/^ //p\" | head -1' - 
    rebase-onto  = !bash -c 'git branch $4 $2 && git rebase --onto $3 `git oldest-ancestor $1 $4` $4' - 

然後使用命令行:

git rebase-onto master fix/123 stable fix/123-stable 

在這裏你是:

  I--J (stable) 
     / \ 
     / X'- Y' (fix/123-stable) 
    /
- A - B - C - D - E - F - G (master) 
       \ /
       X - Y (fix/123) 
+2

既然你的答案是基於克雷格的工作,我認爲他也應該得到讚揚。 – inger

+0

當你運行'''''git rebase-on'''命令時,你在哪裏? – Chucky

4

我是相當新的Git的,所以請原諒我可能會在您的情況作出任何誤解。

使用此代碼段:

diff -u <(git rev-list --first-parent fix/123) <(git rev-list --first-parent master) | sed -ne 's/^ //p' | head -1 

從這樣的回答:@lindes answer to "Finding a branch point with Git?"

如果你有一個這樣的樹:

Initial Tree

接着上面的命令與結果some-fix代替fix/123將是:

f1efa4a9c029281a22d4fa8dd6607c523e7191f5

這是您創建初始修復分支時的提交。

然後,您可以同時運行快速merge-base來確定some-fix結束:

$ git merge-base master some-fix 
1b9ebb7157a958e9adc3b8eda9bf4175cd821c4b 

,然後使用修訂範圍的摘櫻桃,你可以把這些變化:

$ git cherry-pick f1efa4a..1b9ebb7 

而且你結束了:

Final Tree

其中包含來自您的初始修復分支的額外提交。您需要執行額外的checkout -b來創建您的fix/123-stable分支,而不是將它們添加到stable,但方法應該相同。

還要注意,我引用的答案提到安裝的是冗長乏味diff命令作爲一個別名叫做oldest-ancestor,這應該爲您節省大量的時間。

+0

其實,這是不正確的 - 因爲一旦你的'fix/123'分支被合併回'master','cherry'不包含提交。我仍在研究。 –

+0

是的,我打算告訴你,這是我的問題的關鍵(所有的困難是該分支已被合併回「主」)。但是,謝謝你的嘗試! – SRombauts

+0

更新的答案 - 現在應該是可靠的。 –