2009-08-06 49 views
263

假設我是一個回購的維護者,我想從一個貢獻者的變化來拉,有幾個可能的工作流程:Git的摘櫻桃VS合併工作流程

  1. 我每個cherry-pick從遠程提交(爲了)。在這種情況下,git將提交記錄爲與遠程分支無關。
  2. I merge該分支,引入所有更改並添加新的「衝突」提交(如果需要)。
  3. I merge每個分別從遠程分支提交(再次按順序),允許爲每次提交記錄衝突,而不是將所有提交分組爲一個整體。
  4. 爲了完整起見,您可以做rebase(與cherry-pick選項相同?),但我的理解是這可能會導致撰寫者混淆。也許這消除選項1.

在這兩種情況下,2和3,git的記錄提交的分支歷史,不像1.

親的和反對的使用無論是cherry-pickmerge方法之間描述的是?我的理解是方法2是常態,但我覺得用單個「衝突」合併來解決大規模提交併不是最乾淨的解決方案。

回答

253

rebase(和cherry-pick)和merge都有它們的優點和缺點。我認爲在這裏merge,但它是值得理解。 (在這裏尋找一個備用中,公認爲answer枚舉的情況下rebase是優選的。)

merge優於cherry-pickrebase爲幾個原因。

  1. 健壯性。提交的SHA1標識符不僅標識它本身,而且還標識之前的所有其他提交。這爲您提供了一個保證,即給定SHA1中的存儲庫的狀態在所有克隆中都是相同的。 (理論上)有人沒有機會做出看起來像是一樣的變化,但實際上是破壞或劫持你的存儲庫。你可以挑選個人變化,他們可能是相同的,但你沒有保證。 (作爲次要問題,如果其他人再次選擇同一次提交,那麼新的櫻桃挑選的提交將佔用額外的空間,因爲即使您的工作副本完全相同,它們也會出現在歷史記錄中。)
  2. 易用性。人們往往很容易理解merge工作流程。 rebase往往被認爲更先進。最好是瞭解這兩者,但不想成爲版本控制專家的人(根據我的經驗,包括許多擅長自己的工作但不想花費額外時間的同事)更容易時間只是合併。

即使合併重的工作流程rebasecherry-pick仍然是有用的特殊情況:

  1. 一個缺點merge是混亂的歷史。rebase可以防止在您的歷史中散佈大量的提交,就像您定期合併其他人的更改一樣。事實上,這是我使用它的主要目的。你想成爲非常小心,永遠不會rebase代碼,你已與其他存儲庫共享。一旦某個提交是push,那麼其他人可能會對其進行承諾,而重新綁定最多會導致上面討論的那種重複。在最糟糕的情況下,最終可能會出現一個非常混亂的存儲庫和微妙的錯誤,需要很長時間才能發現。
  2. cherry-pick可用於從主題分支中抽取出一小部分變化,這些主題分支基本上決定放棄,但意識到有幾個有用的部分。

至於寧願合併許多變化:它只是簡單得多。一旦開始擁有大量變更集合,就會變得非常繁瑣。 git(以及Mercurial和Bazaar中)的合併解決方案非常好。大部分時間你都不會遇到長期分支融合的重大問題。我通常一次合併所有東西,只有如果我得到大量的衝突,我是否備份並重新運行合併零碎。即使那樣,我也是以大塊的方式做到這一點。作爲一個非常實際的例子,我有一位同事對合並進行了3個月的修改,並且在250000行代碼庫中遇到了9000次衝突。我們所要解決的問題是,一次合併一個月的價值:衝突不會線性增加,並且這樣做會導致遠遠少於少於9000個衝突。這仍然是很多工作,但不是一次嘗試一次就能完成。

+1

實際上,理論上Mallory可能會通過創建具有相同SHA1但不同內容的提交來破壞存儲庫,但實際上可能不會發生。 :) – Bombe 2009-08-07 06:55:08

+1

哈:)我的意思是「理論上賠率很低,你可以依靠它不發生」,但你說得對,它看起來顛倒。 – quark 2009-08-07 14:45:04

+0

您如何看待「merge --squash」? – cmcginty 2009-09-29 04:02:41

84

在我看來,櫻桃採摘應該保留在需要它的罕見情況下,例如,如果你直接在'master'分支(樹幹,主開發分支)上做了一些修復,然後意識到它應該被應用也要'保姆'。您應該將工作流基於合併或rebase(或「git pull --rebase」)。

請記住,從Git(具有不同的SHA-1標識符)角度來看,挑選或重定位提交是不同,因此它與遠程存儲庫中的提交不同。 (Rebase通常可以處理這個問題,因爲它檢查補丁ID,即更改,而不是提交ID)。

也在git中,你可以一次合併很多分支:所謂的章魚合併。請注意,章魚合併必須沒有衝突才能成功。儘管如此,它可能有用。

HTH。

+16

+1表示rebase/cherry-picking實際上「複製」了提交,因此失去了與原提交的鏈接。 – studgeek 2011-09-17 22:34:12

+1

我們以這種方式使用櫻桃挑選,專門用於將錯誤修復(可能非常小的功能)提交移動到現有版本分支中以準備修補程序。跨越多個提交的功能通常保證進入基於主控的發佈分支。 – foxxtrot 2011-10-29 02:42:59

+3

@foxxtrot:另一個解決方案是爲bug修復創建一個單獨的分支,它基於展現這個bug的最老的提交,並且將它合併到'maint'和'master'中......雖然在這種情況下你需要知道所說的bugfix適用於兩個分支。 – 2011-10-29 11:41:29

0

Rebase和Cherry-pick是保持清潔提交歷史記錄的唯一方法。 避免使用合併並避免創建合併衝突。如果您正在使用gerrit,則在必要時將一個項目設置爲合併,並將一個項目設置爲櫻桃模式並嘗試自己。

+0

能否詳細說明一下。 ... – 2017-12-13 06:34:57