用git整合分支的時候,大家比較常用的是變基操作(git rebase)還是合併操作(git merge),你們覺得哪個比較好?
PHPz
PHPz 2017-05-02 09:44:25
0
2
856

git整合分支一般有兩種方法-變基操作(git rebase)和合併操作(git merge),但是在你們實際的團隊開發中,哪種方式用的最多,或者你們覺得那個好呢?

PHPz
PHPz

学习是最好的投资!

全部回覆(2)
Peter_Zhu

我猜現實中的情況是這樣的:

  1. 使用 git 的人群中,不會用 rebase(哪怕是基礎功能的)的至少一半(這個估計恐怕很保守了)

  2. 剩下一半裡真正理解何時應該正確 rebase 的恐怕也就一半…

merge 還是rebase 並不是一個二者選其一的問題,而是應該根據具體情況來選擇使用,而這個「具體情況」在現實中實在是不好一一列舉出來了,對於大多數開發者來說在團隊中的職能比較單一,也不是經常有機會遇到,所以在這裡我只總結兩個人人都應該理解並遵守的準則:

  1. 當你從 remote 去 pull 的時候,永遠使用 rebase(除了一個例外,後面會講)

  2. 當你完成了一個功能(假定你是單獨開本地分支去做的)後打算合併到主幹分支的時候,永遠使用 merge

開發者應當理解:不同的合併策略影響的或許不是最終的程式碼結果,但卻會影響 git 如何記錄提交的歷史(儘管很多時候這種理解只對個別人受益,而對自己沒有什麼影響)。其他的人在使用這些歷史的時候(例如 code review 的時候,或是 bisect 的時候等等)會因為過去你做過的事情而感到無比幸福或痛苦。

第二點比較容易理解,把開發一個功能的具體細節隱藏在本地分支中,而把最終的結果作為一條完整的記錄合併(merge)到主幹分支去。

關鍵是第一點。大多數情況下大家會選擇預設的 pull,也就是 fetch + merge,也就是 fetch + merge,於是我們會看到主幹上不停的出現 Merge commit xxx into xxx 之類的干擾訊息。如果所有的人都圖方便這麼做,那就永遠都別想有乾淨漂亮的歷史樹了,取而代之是類似這樣的東西:

如果你去 clone 一個正確使用 git 的項目,你絕對不會看到上圖這樣亂七八糟的 master。為什麼呢?答案就是:git pull --rebase,這條指令會使用rebase 來取代預設的git pull --rebase,这条命令会使用 rebase 来代替默认的 pull 對合併的歷史樹進行變基處理,就可以避免因為無法快進(fast forward)而產生的額外合併記錄。

現在絕大多數的 git 用戶端都允許設定 git pull 的默认行为是 --rebase,所以掌握了這個訣竅可以讓大部分的日常拉取操作都產生清爽漂亮的歷史記錄,但這並不是完美的結局。有一種例外是這樣的:

  1. 在你使用 git merge 完成了一个功能分支向主干分支的合并之后(当然是 --no-ff 的)

  2. 在你運行 git fetch 發現遠端主幹又領先你若干提交

  3. 此時你若 git pull --rebase,你會發現你剛才合併功能分支的記錄沒了…

這是因為變基會忽略合併記錄,因此變基指令會有一個特別的參數叫做:--preserve-merges 用來重建被忽略的合併記錄。所以比 --preserve-merges 用于重建被忽略的合并记录。所以比 git pull --rebase 更好的方案就是用 git fetch + git rebase -p 更好的方案就是用

+

來代替。

    當然這個僅針對上面提到的特殊情況,隨著 git 的升級說不好哪一天就不存在這種問題了也不一定。我通常不會遇到這種情況,因為我都是這麼做的:
  1. git pull --rebase

    完成功能分支之後先不 merge,而是回到主幹分支去
  2. 如果主幹有更新,rebase 更新的內容到功能分支來預檢一下,看看在加入了最近別人的改動之後我的功能是否依然OK(在這個過程中可能會有衝突處理,別怪我沒提醒哦)
  3. git fetch

    一切就緒之後再次
  4. 主幹看看有沒有變動(因為在第二步的進行期間沒準又有人 push 了新的變化),有的話重複第二步,沒有則——
  5. 合併功能分支到主幹然後 push,收工。

git rebase -p

我這麼做可以避免前面提到的意外,看似複雜了些但其實做熟練了之後也沒什麼難度,更重要的原因是
    是有缺陷的:
  1. git pull

    不能和
  2. 連用,一條命令分成倆,怎麼都覺得「虧」了(雖說你可以寫腳本,但最好不要因為習慣了之後反而有時候會害了你)
  3. git pull 配合使用,所以你必须指明目标分支给 rebase,这一点比较烦人,特别是很多 GUI 客户端压根不支持 git rebase -p

    由於無法和
  4. 配合使用,所以你必須指明目標分支給rebase,這一點比較煩人,特別是很多GUI 客戶端壓根不支援
  5. 的時候(我經常會在CLI/GUI 之間切換環境使用git)

    ORIG_HEAD

會被破壞。

ORIG_HEAD 在很多情形下非常有用,比如说你可以用 git log -p -reverse ORIG_HEAD 来回看最近一次合并所产生的所有变化等等。--preserve-merges

在許多情況下非常有用,比如說你可以用 git log -p -reverse ORIG_HEAD 來回看最近一次合併所產生的所有變化等等。 --preserve-merges 會讓它失去原本應該指向的位置,你必須先找到正確的 hash 來代替它,這會有點煩。 🎜 🎜以上答案最終說明一件事情,現實的複雜性永遠超出你在菜鳥時期所能做出的想像,真想把git 用好那就要在日常工作的基礎上好好理解git 的工作原理吧,可以去看官方網站電子書(中文版),裡面的git internal 一節仔細看懂之後,該用什麼指令心裡就有數了。 🎜

補充一點:如果你的團隊不在乎主幹分支上有很多不重要的干擾提交記錄,那你可以始終使用rebase,這樣至少可以不會出現很多分岔,處理得當也可以得到乾淨(但是囉嗦)的主幹分支歷史記錄。

淡淡烟草味

不強制, 但是要求push後所有測試是綠的

(我們沒有特別長的分支, 大部分在2-3天內合併, 很少超過一周)

一般是大家根據merge難度自己選, 沒差別時優先rebase... 因為好看一點

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板