2013-07-04 154 views
3

我們正在兩個版本,一個小和一個主要的,每個都有自己的git分支。在我們創建主要分支之前,一個功能最初被添加到小分支。之後,該功能從小分支中刪除(提交revert),因爲我們決定在主要版本中引入該功能。合併git分支時,有一個恢復,其他不想要

所以,現在我們有一種情況,如果我們將小分支的變化合併到主分支中,它將包含回覆提交,這在主分支中是沒有意義的。

我考慮過的一個選擇是在恢復提交後對次分支提交使用cherry-pick,但這有一個缺點,即基於次分支的任何分支都不能與主分支合併。 (我們必須繼續使用cherry-pick來處理類似的事情。)雖然它的優點是具有更準確的歷史記錄,因爲不會包含恢復提交。

另一種選擇是將所有小分支合併到主分支中,並僅「忽略」還原更改。通過「忽略」,我的意思是在合併時手動還原已恢復的更改。從git的角度來看,這更好地保留了歷史記錄,但可能意味着在合併過程中會出現一些問題。

通常我們只在主分支中使用合併,而櫻桃採摘只是爲了在修改最新代碼之前將它們合併。所以我的選擇是第二種選擇,但我想知道這是否是處理這種情況的正確方法,或者是否有我缺少的東西。

編輯:這裏是ASCII藝術:-)

* (major) 
| * (minor) 
* | ... 
| * revert feature on minor 
* | major: unrelated commit 
| * minor: unrelated commit 
* | 
|/ 
* common ancestor 
| 
* add feature to main branch 
+1

你的問題是缺少ASCII藝術:)。您是否恢復了僅在小分支上進行的提交或者是在分支或合併到小分支之前在主分支中創建的提交? – Chronial

+0

在將功能添加到次分支之後但在將還原添加到次分支之前,小分支合併到主分支中了嗎? –

+0

我不清楚這兩個分支上的功能提交是否通用。 –

回答

6

我很好奇你的意思,「在主要分支中沒有意義。」您是否擔心該功能將在主要分支上恢復?或者,你是否只是覺得在主要分支的歷史中會出現名爲「恢復功能」的提交,而實際上該功能在那裏?

很難說,合併的結果會是什麼沒有更多的細節,但這裏有一些可能性:

如果你的歷史看起來是這樣的:

* (major) 
| * (minor) 
* | 
| * revert feature on minor 
* | cherry-pick feature onto major 
| * add feature to minor 
* | 
|/ 
* common ancestor 
| 

然後,你可以簡單地合併minor進入major沒有任何問題。

爲什麼?想想這樣說:當你合併minormajor,你實際上走的是共同的祖先(git merge-base major minor)和minor之間的差異,把它當成一個補丁到major,然後創建一個承諾,恰好擁有二者majorminor作爲父母。

公共祖先與minor之間的差異不包含任何已添加的特徵提示,然後因兩個提交相互抵消而被還原。因此,將引入major的唯一更改將會由於minor上的其他提交而引起更改。

如果你的歷史是這樣的:

* (major) 
| * (minor) 
* | 
| * revert feature on minor 
* | merge minor into major 
|\| 
* | cherry-pick feature onto major 
| * add feature to minor 
* | 
|/ 
* 
| 

那麼你有問題。在這種情況下,majorminor之間的共同祖先是標有「add feature to minor」的提交。如果你看看這個共同的祖先和minor之間的差異,差異將包括該特徵的恢復。當您將minor合併到major時,此差異將應用於major,在major上還原該功能。

在這種情況下,有幾個簡單的方法可以防止丟失在major功能:

  • 合併minormajor,然後恢復的復歸。結果圖應該是這樣的:

    * revert the revert (major) 
    | 
    * merge minor into major 
    |\ 
    * | 
    | * (minor) 
    * | 
    | * revert feature on minor 
    * | merge minor into major 
    |\| 
    * | cherry-pick feature onto major 
    | * add feature to minor 
    * | 
    |/ 
    * 
    | 
    
  • 創建一個新的分支關閉的minor。我們稱之爲minor-for-merge。在這個分支上,恢復回覆。然後將分支合併到major並刪除分支。結果圖應該是這樣的:

    *  merge minor-for-merge into major (major) 
    |\ 
    | * revert the revert 
    * \ 
    | * (minor) 
    * | 
    | * revert feature on minor 
    * | merge minor into major 
    |\_ | 
    * \| cherry-pick feature onto major 
    | * add feature to minor 
    * _/ 
    |/ 
    * 
    | 
    

兩種方法都可行。後者有點尷尬—承諾恢復恢復是在無人地帶搖晃—,但它可以幫助您避免合併到major時大量的合併衝突。

無論哪種方式,minor的任何分支將合併到major而不會恢復該功能。如果minor之前的分支是在回覆之前完成的,則回覆將不會被合併到歷史記錄中。如果在回覆之後關閉minor的分支(或者minor在歸還之後合併到分支中) ,那麼回覆仍然不會被合併到歷史中,因爲該提交已經在major的祖先中。

+0

其實你的第二個場景與我所擁有的相似。我喜歡在合併之前提供恢復提交提交的想法。我會嘗試一下,看看它是如何工作的。感謝您的詳細解答。 –

+0

所以我在合併之前恢復了恢復提交。它工作完美無瑕。再次感謝。 –

2

我想你可以合併未成年分支和「恢復的恢復」,我的意思是

git merge <minor branch> 
git revert <revert commit> 

還要檢查這個「How to Revert Faulty Merge ',這完全與你的問題無關,但你可以對'恢復還原'的效果有所瞭解。

+0

感謝您的回答。我很感激幫助。 –

+0

@MichaelBest不客氣:)我很高興理查德漢森提出了一個很好的答案,這個答案解釋了我的英語不好。 – dyng