2013-01-24 22 views
8

假設我有以下情形:Git的變基樹

o (master) 
/  o--o (WIP1) 
/ /
o--o--o--o--o--o (WIP2) 
(X)  \ 
      o--o (WIP3) 

是否有這將創建一個新的分支,使其包含分支X之後的子樹一個git命令?我想執行一個「大轉型」,我想讓三個WIP分行重新發起主轉型。

我知道我可以用一些Bash腳本來做到這一點,但我想知道如何使用git命令來做到這一點。

+1

[衍合分支,包括它的所有兒童]的可能重複(http://stackoverflow.com/questions/5600659/rebasing-a-branch - 包括它的所有子項) –

+1

[Rebasing a tree(a commit/branch and its its children)](https://stackoverflow.com/questions/17315285/rebasing-a-tree-a-commit -branch-and-all-its-children) – carnicer

回答

2
o (master) 
/  o--o (WIP1) 
/ /
o--p--p--o--o--o (WIP2) 
(X)  (Y) 
      \ 
      o--o (WIP3) 

這應該是一個rebase --onto(你可以看到在 「How to move certain commits to another branch in git?」 一個例子):

git rebase --onto master X WIP1 
git rebase --onto master X WIP2 
git rebase --onto master X WIP3 

Chronialtest,將給予:

  p'--p'--o--o (WIP2) 
     /
o-----o-----p--p--o--o--o (WIP1) 
(X) (master) (Y') 
     \ 
     p''--p''--o--o (WIP3) 

所以第一次rebase是好的,但你需要得到Y SHA,並且:

git rebase --onto Y' Y WIP2 
git rebase --onto Y' Y WIP3 
+0

這將創建三個分支,主分歧,不是嗎?或者這會將主體背後的X背後的結構移動(以便分支稍後轉移)? – Chronial

+0

@Chronial是的,如果在目標分支上檢測到相同的內容,那麼存在這種風險,特別是考慮到rebase不會重放提交。我將不得不測試它。 – VonC

+0

剛剛測試過它們,它們分歧:/ – Chronial

0

如果你想有這樣的結果

o (oldmaster)--o--o--B--o--o(WIP1)--o--o(WIP2)--o--o(WIP3)(master) 
/  
/  
X 

你應該這樣做:

git rebase --onto master X WIP1   /* move WIP1 on master */ 
git rebase --onto WIP1 WIP2~3 WIP2  /* move WIP2 on WIP1 */ 
git rebase --onto WIP2 WIP3~3 WIP3  /* move WIP3 on WIP2 */ 
git reset --hard WIP3     /* move master index to WIP3 */ 
11

沒有爲任何單一的git命令。你將不得不做一些手動工作。在您的情況:

o (master) 
/  o--o (WIP1) 
/ /
X--o--o--B--o--o (WIP2) 
      \ 
      o--o (WIP3) 

你先重訂WIP1到主:

git rebase --onto master X WIP1 

這將導致這樣的:

   o--o (WIP1) 
(master) /
    o--o--o--B’ 
/ 
/  
X--o--o--B--o--o (WIP2) 
      \ 
      o--o (WIP3) 

如果你現在運行git rebase --onto master X WIP2,你會得到這樣的結構:

   o--o (WIP1) 
(master) /
    o--o--o--B’ 
    /\ 
/ o--o--B’’--o--o (WIP2) 
/  
X--o--o--B--o--o (WIP3) 

這可能不是你想要的,所以現在你應該變基WIP2和WIP3上​​:

git rebase --onto B’ B WIP2 
git rebase --onto B’ B WIP3 

這將導致這樣的:

    o--o (WIP1) 
(master)  /
    o--X--o--o--B’--o--o (WIP2) 
       \ 
        o--o (WIP3) 
+0

似乎與我的編輯類似。+1 – VonC

+0

是的,在提交之前看到了你的編輯,但到那時我已經畫出了所有那些ascii-art ^^ – Chronial

+0

你做了測試,你值得信用;) – VonC

1

我檢舉了這個問題,因爲重複的。我會寫我所解釋的 the other answer,但使用你的例子。

,我使用的這樣的用例的方法是所有分支 被移動合併成1個共同人工節點,然後用底墊命令 與--preserve-merges選項。合併所有分支將公開公開012,終點將被用作rebase --onto的最終輸入參數。起始點通常是顯而易見的,即子樹的起點移動。

當合並獲得子樹端點時,應該避免衝突 。因此,應該指示合併命令使用-Xours選項自動解決它們 。合併結果並不重要 由於這些人造合併節點將在轉置後被丟棄。

建議創建一個新分支爲了不丟失 原始參考。在上面下面的命令的例子將 進行:

$ git checkout -b pack WIP1 # create new branch at 'WIP1' 
$ git merge -s recursive -Xours WIP2 # merges WIP2 into pack (node p2) 
$ git merge -s recursive -Xours WIP3 # merges WIP3 into pack 

下面可以看到什麼樣的樹會變成。兩個新的人造節點 p2已創建與合併。

 o (master) 
    /
    /  (WIP1) (p2) 
/  o-----o-----o----o (pack) 
/ /  //
o--o--o--o-----o-----o /(WIP2) 
(X)  \   /
      o------------o (WIP3) 

現在是時候重新定位了。由於現在是所有 分支()共同的終點,很容易與移動整個樹:

$ git rebase --preserve-merges --onto master X pack 

將會產生這樣的:

     (WIP1') (p2') 
        o-----o-----o----o (pack') 
    (master)  /  //
o----o----o--o--o-----o-----o /(WIP2') 
(X)    \   /
        o------------o (WIP3') 

現在是時候重新安排參考文獻。我不知道爲什麼,在某些 的情況下,引用被移動,而其他的則不是。此型爲 每個參考WIP1,WIP2,WIP3或任何你需要:

$ git checkout WIP1 
$ git reset --hard <WIP1' hash> 

最後,擺脫對 產生一個共同的子樹端節點創建的人工提交的。

$ git branch -D pack 
$ git branch -D p2 # if there is any 

所以最終的樹是:

     (WIP1') 
        o-----o 
    (master)  /
o----o----o--o--o-----o-----o (WIP2') 
(X)    \ 
        o------------o (WIP3')