首先簡單介紹幾乎所有版本控制系統的工作原理和工作原理。
標準合併是一種三種合併方式。在此,您將兩個版本的最後一個共同祖先與兩個版本進行比較。例如,我從樹幹分支。分支前的主幹上的版本是最後一個共同祖先。
目的是爲了能夠看到一個流與其他流的變化。 (一個流可能是一個特定的分支或幹線)。例如,如果我正在從樹幹合併到分支,我想確保不會用樹幹上的這些行覆蓋我的特定分支更改。
與上一個共同祖先的比較可以讓您僅查看自該分支點以來發生在樹幹上的變化。
當我從以前的合併中倒退時,會出現問題。例如,我完成了我的功能分支,並希望所有功能更改都在主幹上。這是一個問題,因爲我已將所有樹幹更改合併到分支上。這意味着我的分支的流顯示我對分支進行了更改,並且這些應該合併到主幹中。但是,這些變化已經在主幹上了!要處理這個問題,你可以強制雙向合併。在這種情況下,您只將兩個獨立流的頭部相互比較,並將所有差異從一個流複製到另一個流。
現在怎麼顛覆處理合並:
首先,顛覆愛挑櫻桃mergin。 Subversion允許你指定你想要合併的版本。例如,我有一個分支,發現了一個bug並將它修復在分支上。我現在可以合併包含我的錯誤修復的特定修訂版或修訂版集。當你在Subversion中挑選櫻桃時,你正在做一個三方合併,但你只考慮那些特定的櫻桃挑選的版本中所表示的變化,而不是樹幹或分支上的所有變化。
事實上,即使您沒有指定櫻桃挑選修訂,Subversion幾乎總是會進行櫻桃挑選合併。 Subversion追蹤通過svn:mergeinfo
屬性合併的修訂版本。假設我在版本100分支,現在我正在將我的主幹更改合併到我的分支中。最新的trunk版本現在是版本150. Subversion認爲你正在從版本100(但不包括版本100)到修訂版本150的所有版本上進行櫻桃選擇。下一次我從我的trunk到我的分支(假設我的主幹最後一次更改爲175),Subversion將櫻桃挑選從(但不包括150)到修訂175的變化。
請注意,當我指定櫻桃挑選版本,我可以毫無問題地在我的分行和我的行李箱之間來回走動。如果我從我的功能分支合併到我的主幹,我可以在我實現該功能的功能分支上指定修訂,並跳過作爲從主幹合併結果的功能分支上的更改。
這個問題,只有當我讓Subversion處理櫻桃採摘。當我從我的分支合併到我的分支時,Subversion跟蹤我分支上的我的分支的修訂。然而,Subversion無法知道我的特性分支上的哪些修訂是我的主幹合併的結果。因此,當我將我的特性分支合併回主幹時,Subversion會考慮所有未合併的修訂 - 包括那些由分支合併到分支的修訂,並嘗試將所有這些修訂合併回我的主幹。
爲了處理這個問題,Subversion有一個特殊的合併,稱爲重新合併合併。我將我的最後一組變化合併到我的分支中,然後當我將分支合併到我的主幹時,我希望我的主幹和分支完全相同。因此,Subversion想要進行雙向合併,並使樹幹和分支匹配。
在老版本的Subversion中,我將不得不手動指定我正在與svn merge
命令中的--reintegration
參數進行雙向合併。
Subversion的合併跟蹤還導致重複使用功能分支的一個有趣的問題。假設我做了從trunk到我的分支的最後一組合並。在trunk上的最後一次修訂和Subversion的最後一次修訂是修訂版100.當我將我的更改從trunk中合併到我的分支上時,現在我在我的分支上創建了修訂版101。該分支上的svn:mergeinfo
屬性表明,我已將我的所有更改合併到只有我的分支的主幹上的修訂版本100。
現在,我做我的重新整合合併,提交更改,並在我的主幹創建修訂版102。
現在,我在我的主幹上做了更多的工作(比如修訂版103),並且我想將這些更改合併到我的功能分支上。
從trunk到我的特性分支合併的最後一次修訂是什麼?看着svn:mergeinfo
,我看到它的修訂100.而且,由於從主幹分支,去年的合併,現在有一些還沒有被合併到我的特性分支樹幹上的兩個新版本:版本102和103.修訂
所以,Subversion會執行挑選櫻桃並嘗試將修訂版本102和修訂版本103中包含的更改合併到我的功能分支上。但是等等...修訂版102是我的所有功能分支更改被合併到主幹上!我將重新將這些功能更改應用於我的功能分支!
有兩種方法可以解決這個問題:方法一:一旦你做了重新整合合併,你永遠不應該再次使用該功能分支。刪除它。把它鎖在庵裏。不要再說出它的名字。如果我再次需要該功能分支,我應該從主幹創建一個新的功能分支。
的另一種方式是Munge時間svn:mergeinfo
的特性分支進行顛覆知道中繼線修訂版102已經被合併到我的特性分支。你可以用--record-only
參數做到這一點:
$ svn co $REPO/branches/feature/myproj
$ cd myproj
$ svn merge --record-only -r102 $REPO/trunk/myproj
正如你所看到的,這一切的手動工作 - 知道何時使用--reintegration
開關和理解,當你做一個重返社會合併發生了什麼 - 引起的混亂。因此,更新版本的Subversion(我相信自修訂1.8版本)現在試圖爲你處理這個問題。
如果您使用Subversion 1.8作爲客戶端,則不必指定--reintegration
參數。 Subversion將以編程方式確定您正在進行典型的三路合併還是合併,並進行相應的合併。
如果我試圖做什麼顛覆認爲一個重返合併,而我還沒有合併,所有我的樹幹修訂到我的特性分支,Subversion會提醒我,不讓我做的合併。如果我在重新集成合並時重新使用了一個功能分支,Subversion將會檢測到這一點,並在重新集成後自動處理分支重用問題。 (有時簡化版,相當的工作。但是,Subversion會不會讓你重用安置在合併後的特性分支,但可能給你一個錯誤,你可能需要手動做--record-only
合併。)
所以在Subversion中,你應該怎麼做你的工作流程?
與Git不同的是,每個bug和特性都應該位於自己的分支上,所以您需要將該bug修復或特性合併到多個分支上,您幾乎可以將所有工作都放在主幹上(或任何您喜歡的分支)。在大多數Subversion商店中,分支僅適用於候選版本。也就是說,我即將發佈一個版本,我爲該版本分支。一些開發人員在發佈上工作,其他人則繼續在主幹上工作。
如果在主幹上發現了一個錯誤,它可以固定在主幹上,並且該錯誤已修復的版本或修訂版本可以合併到發佈分支上。或者,如果在功能分支上發現需要在主幹上修復的錯誤,則可以修復功能分支上的該錯誤,並將該修訂或修訂集合併到主幹上。
它簡單,直接,易於實現。
這並不意味着您不能分支功能。事實上,有時你必須這樣做。想象一下正在深入實施的功能。您不希望在主幹上進行這些更改。在這種情況下,請創建功能分支,並將您的主幹更改定期合併到該功能分支上。請記住,將該功能合併到主幹時可能會有問題。只要你明白髮生了什麼事情。沒問題。
而且,如果你想瘋狂地爲每個功能和bug創建一個gazillion分支,你也可以這樣做。不過,我建議你使用Subversion 1.8,它會爲你做到這一點。
很多很好的信息 – Slav
Damm.You可以寫一本svn書。 – Geddon