[轉(zhuǎn)] 譯:Git rebase VS. Git merge

原文:Merging vs. Rebasing
git rebase一直是初級程序員想遠離的黑魔法,但事實上在開發(fā)團隊小心的使用該命令可以令我們的工作更輕松科盛。本文將git rebasegit merge做對比份汗,來看看在典型的Git工作流中引入git rebase可以帶來什么好處怎憋。

概念縱覽

首先我們要了解git rebasegit merge作用是相同的映跟,都可以用來將一個分支上的代碼合并到另一個分支——只是實現(xiàn)方式不同迹卢。
當(dāng)你使用專門的分支開發(fā)feature時惠豺,其他團隊成員如果繼續(xù)向master分支提交银还。就會產(chǎn)生一個分叉的歷史,任何使用Git作為協(xié)同工具的開發(fā)人員應(yīng)該都很熟悉這樣的場景洁墙。

image

假設(shè)提交到master的代碼跟你正在開發(fā)的feature相關(guān)蛹疯,為了將新的提交合并到feature分支,你有兩個選項:git mergegit rebase热监。

Git merge

最簡單的方法就是使用以下命令將master分支合并到feature分支:

git checkout feature
git merge master

或者簡化成一行命令:

git merge master feature

該操作會在feature分支上產(chǎn)生一個新的“合并提交”捺弦,將兩個分支的歷史合并在一起,如圖示這樣:

image

git merge很好用因為它是一個非破壞性的操作。當(dāng)前分支不會被改變列吼。因此避免了git rebase操作可能帶來的所有隱患(詳見下文)幽崩。
然而另一方面,這意味著每一次合并操作都會在feature分支上產(chǎn)生一個額外的“合并提交”寞钥。如果master分支更新頻繁的話會導(dǎo)致feature分支的歷史記錄被污染慌申,令其他開發(fā)者難以理解項目的歷史記錄。

Git rebase

合并操作的另一個選擇是使用git rebase理郑,例如如下命令蹄溉,將feature分支rebase到master分支:

git checkout feature
git rebase master

該操作將整個feature分支的記錄移到了master分支的頭部,將所有的新提交都并入了master分支香浩。但是不同于"合并提交"类缤,git rebase通過對原分支上的提交做標記重寫了項目的提交記錄。

image

使用git rebase的最大好處是可以得到更干凈的項目記錄邻吭。首先餐弱,它消除了git merge帶來的無用的"合并提交"。其次囱晴,對比上面的圖我們看到膏蚓,git rebase可以產(chǎn)生完美的線性歷史記錄——可以方便的使用git loggit bisectgitk追蹤提交記錄畸写。
但是驮瞧,在追求干凈的提交記錄的同時還要權(quán)衡兩個方面:安全性和可追溯性。如果沒有遵循git rebase的最佳實踐枯芬,重寫項目的歷史記錄可能會毀滅合作工作流论笔。另外,git rebase丟失了合并操作的上下文信息——我們無法得知某一次合并操作具體發(fā)生在何時千所。

交互式rebase

交互式的rebase可以對要移到新分支上的提交記錄進行修改狂魔,它能夠完全控制分支的提交記錄,因此比自動rebase功能更強大淫痰。通常最楷,在將一個功能分支合并到master分支前,可以用其來整理混亂的提交歷史待错。

-i傳入git rebase來進入交互式rebase會話

git checkout feature
git rebase -i master

命令執(zhí)行完成之后會打開一個文本編輯器籽孙,其中列出了所有要被移到新分支的提交:

pick 33d5b7a Message for commit #1
pick 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3

這個列表展現(xiàn)了rebase執(zhí)行之后分支的提交記錄』鸲恚可以通過修改pick命令或調(diào)整條目順序來改變分支的提交歷史犯建。例如,假設(shè)第二次提交是為了修復(fù)第一次提交中的一個小問題瓜客,我們可以通過fixup將這兩次提交合并:

pick 33d5b7a Message for commit #1
fixup 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3

保存并退出該文件后适瓦,Git會通過該文件的內(nèi)容執(zhí)行rebase沟启。最終項目的提交記錄如圖所示:

image

通過交互式rebase可以忽略不重要的提交令分支歷史更容易理解,這一點是git merge無法比擬的犹菇。

Git rebase的金律

現(xiàn)在我們理解了什么是git rebase,但最重要的是要知道什么時候不要用它芽卿。Git rebase的金律是:永遠不要在公有分支上用它揭芍。
例如,試想一下如果將master分支rebase到feature分支會發(fā)生什么:

image

這個rebase操作將master分支的所有提交移動到了feature分支的頭部卸例。但問題是這一切都發(fā)生在你本地称杨。其他開發(fā)者依然在原master分支上繼續(xù)工作。因為rebase會導(dǎo)致新的提交筷转,Git會認為你的master分支和其他開發(fā)者的出現(xiàn)了分叉姑原。
唯一同步這兩個版本master的方式是將它們git merge,但是這樣會導(dǎo)致一個額外的合并提交記錄和包含相同修改的兩次提交(原始master分支和被rebase的master分支)呜舒。不用說锭汛,這是一個令人困惑的情況。
所以袭蝗,在執(zhí)行git rebase之前唤殴,總是問問自己,“其他人用這個分支嗎到腥?”如果答案是yes朵逝,把手從鍵盤上拿開,考慮使用一種非破壞性的方法來達到同樣的目的(例如git revert)乡范。否則配名,放心的按自己的喜好去重寫歷史吧。(譯注:修改歷史提交記錄)

Force-Pushing

Rebase過的master分支與遠程倉庫的master分支會存在沖突晋辆,所以Git不允許將rebase過的分支推送到遠程倉庫渠脉。但是可以通過傳遞--force標簽進行強制推送:

# Be very careful with this command!
git push --force

該操作會將遠程倉庫的master分支替換為rebase過的master分支,這會給團隊的其他成員帶來困擾栈拖。所以连舍,小心使用該命令,除非你知道自己在做什么涩哟。
少數(shù)幾個需要使用強制推送的場景之一是將私有分支推送到遠程倉庫(例如:以備份為目的)后索赏,對該分支上的提交進行了清理。這就像說贴彼,“我不想推之前那版feature分支了潜腻,用這個替換吧”。再強調(diào)一次器仗,一定要確保沒有其他開發(fā)人員在使用該分支融涣。

工作流演練

git rebase可以根據(jù)團隊的需要或多或少的與現(xiàn)存的Git工作流進行整合童番。這一章,我們來看看在一個feature分支的不同開發(fā)階段威鹿,使用git rebase能帶來什么好處剃斧。
對于任何工作流來說,要使用git rebase的第一步是為每個feature創(chuàng)建一個專門的分支忽你。這種分支策略可以幫助我們安全的使用git rebase

image

整理本地分支

rebase加入到工作流的一個好處是整理本地進行中的功能分支幼东。通過定期執(zhí)行交互式rebase,可以保證每一次提交(commit)都是有意義的科雳。這可以讓我們在寫代碼時不用擔(dān)心每次提交是不是都有意義——可以之后通過交互式rebase修復(fù)根蟹。
調(diào)用git rebase時可以傳入兩種參數(shù):父分支(例如master),或當(dāng)前分支的前幾次提交糟秘。在交互式rebase章節(jié)中我們看到了傳入父分支的用法简逮。當(dāng)我們需要整理最后幾次提交時后者比較有用。例如尿赚,以下命令為最后3次提交開啟了交互式rebase霍比。

git checkout feature
git rebase -i HEAD~3

通過指定HEAD~3嗜愈,我們并沒有移動分支——只是重寫了最后三次提交观堂。注意不包含其他提交懈万。

image

如果想用這個方法重寫整個分支,git merge-base命令可以用來追尋feature分支的original base泻蚊。以下命令返回original base的commitID躲舌,可以將該commitID傳給git rebase

git merge-base feature master

可以通過這種交互式rebase的用法將git rebase引入到你日常的工作流中,因為它只會影響本地分支性雄。其他開發(fā)者僅僅會在你開發(fā)完成之后看到一個提交記錄干凈的没卸,易于追溯的feature分支。
但是再一次強調(diào)秒旋,這種用法只針對本地私有分支约计。如果你在和其他開發(fā)者在某一個feature分支上進行合作開發(fā),那么這個分支是共有的迁筛,請不要試圖去重新提交歷史煤蚌。
git merge無法做到清理本地提交歷史。

作者:李小西033
鏈接:http://www.reibang.com/p/318b4f0f57ff
來源:簡書
簡書著作權(quán)歸作者所有细卧,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處尉桩。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市贪庙,隨后出現(xiàn)的幾起案子蜘犁,更是在濱河造成了極大的恐慌,老刑警劉巖止邮,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件这橙,死亡現(xiàn)場離奇詭異奏窑,居然都是意外死亡,警方通過查閱死者的電腦和手機屈扎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門埃唯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鹰晨,你說我怎么就攤上這事筑凫。” “怎么了并村?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長滓技。 經(jīng)常有香客問我哩牍,道長,這世上最難降的妖魔是什么令漂? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任膝昆,我火速辦了婚禮,結(jié)果婚禮上叠必,老公的妹妹穿的比我還像新娘荚孵。我一直安慰自己,他們只是感情好纬朝,可當(dāng)我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布收叶。 她就那樣靜靜地躺著,像睡著了一般共苛。 火紅的嫁衣襯著肌膚如雪判没。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天隅茎,我揣著相機與錄音澄峰,去河邊找鬼。 笑死辟犀,一個胖子當(dāng)著我的面吹牛俏竞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播堂竟,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼魂毁,長吁一口氣:“原來是場噩夢啊……” “哼出嘹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起酣胀,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤刁赦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后闻镶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡牺氨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了墩剖。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猴凹。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡岭皂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出书劝,到底是詐尸還是另有隱情土至,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布骡苞,位于F島的核電站楷扬,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏亚铁。R本人自食惡果不足惜螟加,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望然爆。 院中可真熱鬧黍图,春花似錦、人聲如沸剖张。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽顾犹。三九已至,卻和暖如春炫刷,著一層夾襖步出監(jiān)牢的瞬間浑玛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留剧腻,地道東北人。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓灰伟,卻偏偏與公主長得像栏账,于是被迫代替她去往敵國和親栈源。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容