git分支的合并解說

原文:

http://gitbook.liuhui998.com/3_3.html

http://gitbook.liuhui998.com/5_3.html

一嗜价、如何分支的合并

在git中,可以使用git merge和git rebase兩個命令來進(jìn)行分支的合并原在。

git merge和git rebase在大體上都差不多冷守,下文主要以git merge來例來講解分支的合并流程茂嗓。

如果你想了解分支合并的更多內(nèi)容尘惧,請閱讀《git merge簡介》惭适,《git rebase簡介(基本篇)》和《git rebase簡介(高級篇)》笙瑟。

git merge命令示例:

$gitmergebranchname

這個命令把分支"branchname"合并到了當(dāng)前分支里面。

如有沖突(沖突--同一個文件在遠(yuǎn)程分支和本地分支里按不同的方式被修改了)腥沽;那么命令的執(zhí)行輸出就像下面一樣

$gitmergenext

100% (4/4) done

Auto-merged file.txt

CONFLICT (content): Merge conflict in file.txt

Automatic merge failed; fix conflicts and then commit the result.

在有問題的文件上會有沖突標(biāo)記逮走,在你手動解決完沖突后就可以把此文件添 加到索引(index)中去,用git commit命令來提交今阳,就像平時修改了一個文件 一樣师溅。

如果你用gitk來查看commit的結(jié)果,你會看到它有兩個父分支:一個指向當(dāng)前的分支盾舌,另外一個指向剛才合并進(jìn)來的分支墓臭。

二、解決合并中的沖突

如果執(zhí)行自動合并沒有成功的話妖谴,git會在索引和工作樹里設(shè)置一個特殊的狀態(tài)窿锉, 提示你如何解決合并中出現(xiàn)的沖突。

有沖突(conflicts)的文件會保存在索引中膝舅,除非你解決了問題了并且更新了索引嗡载,否則執(zhí)行 git commit都會失敗:

$gitcommit

file.txt: needs merge

如果執(zhí)行g(shù)it status會顯示這些文件沒有合并(unmerged),這些有沖突的文件里面會添加像下面的沖突標(biāo)識符:

<<<<<<< HEAD:file.txt

Hello world

=======

Goodbye

>>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt

你所需要的做是就是編輯解決沖突,(接著把沖突標(biāo)識符刪掉)仍稀,再執(zhí)行下面的命令:

$ git add file.txt

$ git commit

注意:提交注釋里已經(jīng)有一些關(guān)于合并的信息了洼滚,通常是用這些默認(rèn)信息,但是你可以添加一些你想要的注釋技潘。

上面這些就是你要做一個簡單合并所要知道的遥巴,但是git提供更多的一些信息來 幫助解決沖突。

三享幽、撒銷一個合并

如果你覺得你合并后的狀態(tài)是一團(tuán)亂麻铲掐,想把當(dāng)前的修改都放棄,你可以用下面的命令回到合并之前的狀態(tài):

$gitreset--hardHEAD

或者你已經(jīng)把合并后的代碼提交值桩,但還是想把它們?nèi)鲣N:

$gitreset--hardORIG_HEAD

但是剛才這條命令在某些情況會很危險摆霉,如果你把一個已經(jīng)被另一個分支合并的分支給刪了,那么 以后在合并相關(guān)的分支時會出錯奔坟。

關(guān)于撤銷的更多內(nèi)容請參考《git reset簡介

四携栋、快速向前合并

還有一種需要特殊對待的情況,在前面沒有提到蛀蜜。通常刻两,一個合并會產(chǎn)生一個合并提交(commit), 把兩個父分支里的每一行內(nèi)容都合并進(jìn)來。

但是滴某,如果當(dāng)前的分支和另一個分支沒有內(nèi)容上的差異磅摹,就是說當(dāng)前分支的每一個提交(commit)都已經(jīng)存在另一個分支里了滋迈,git 就會執(zhí)行一個“快速向前"(fast forward)操作;git 不創(chuàng)建任何新的提交(commit),只是將當(dāng)前分支指向合并進(jìn)來的分支户誓。

五饼灿、在合并過程中得到解決沖突的協(xié)助

git會把所有可以自動合并的修改加入到索引中去, 所以git diff只會顯示有沖突的部分. 它使用了一種不常見的語法:

$gitdiff

diff --cc file.txt

index 802992c,2b60207..0000000

--- a/file.txt

+++ b/file.txt

@@@ -1,1 -1,1 +1,5 @@@

++<<<<<<< HEAD:file.txt

+Hello world

++=======

+ Goodbye

++>>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt

回憶一下, 在我們解決沖突之后, 得到的提交會有兩個而不是一個父提交:一個父提交是當(dāng)前分支提交前的HEAD,; 另外一個父提交是被合并分支的HEAD, 被暫時存在MERGE_HEAD.

在合并過程中, 索引中保存著每個文件的三個版本. 三個"文件暫存(file stage)"中的每一個都代表了文件的不同版本:

$ git show :1:file.txt# 兩個分支共同祖先中的版本.

$ git show :2:file.txt# HEAD中的版本.

$ git show :3:file.txt# MERGE_HEAD中的版本.

當(dāng)你使用git diff去顯示沖突時, 它在工作樹(work tree),暫存2(stage 2)和暫存3(stage 3)之間執(zhí)行三路diff操作, 只顯示那些兩方都有的塊(換句話說, 當(dāng)一個塊的合并結(jié)果只從暫存2中得到時, 是不會被顯示出來的; 對于暫存3來說也是一樣).

上面的diff結(jié)果顯示了file.txt在工作樹, 暫存2和暫存3中的差異.git不在每行前面加上單個'+'或者'-', 相反地, 它使用兩欄去顯示差異: 第一欄用于顯示第一個父提交與工作目錄文件拷貝的差異, 第二欄用于顯示第二個父提交與工作文件拷貝的差異.(參見git diff-files中的"COMBINED DIFF FORMAT"取得此格式詳細(xì)信息.)

在用直觀的方法解決沖突之后(但是在更新索引之前), diff輸出會變成下面的樣子:

$git diff

diff --cc file.txt

index 802992c,2b60207..0000000

--- a/file.txt

+++ b/file.txt

@@@ -1,1 -1,1 +1,1 @@@

- Hello world

-Goodbye

++Goodbye world

上面的輸出顯示了解決沖突后的版本刪除了第一個父版本提供的"Hello world"和第二個父版本提供的"Goodbye", 然后加入了兩個父版本中都沒有的"Goodbye world".

一些特別diff選項允許你對比工作目錄和三個暫存中任何一個的差異:

$ git diff -1 file.txt# 與暫存1進(jìn)行比較

$ git diff --base file.txt# 與上相同

$ git diff -2 file.txt# 與暫存2進(jìn)行比較

$ git diff --ours file.txt# 與上相同

$ git diff -3 file.txt# 與暫存3進(jìn)行比較

$ git diff --theirs file.txt# 與上相同.

還有,git log和gitk命令也為合并操作提供了特別的協(xié)助:

$git log--merge

$gitk--merge

這會顯示所有那些只在HEAD或者只在MERGE_HEAD中存在的提交, 還有那些更新(touch)了未合并文件的提交.

你也可以使用git mergetool, 它允許你使用外部工具如emacs或kdiff3去合并文件.

每次你解決沖突之后, 應(yīng)該更新索引:

$git addfile.txt

完成索引更新之后, git-diff(缺省地)不再顯示那個文件的差異, 所以那個文件的不同暫存版本會被"折疊"起來.

六帝美、多路合并

你可以一次合并多個頭, 只需簡單地把它們作為git merge的參數(shù)列出. 例如,

$ git merge scott/master rick/master tom/master

相當(dāng)于:

$ git merge scott/master

$ git merge rick/master

$ git merge tom/master

七碍彭、子樹

有時會出現(xiàn)你想在自己項目中引入其他獨立開發(fā)項目的內(nèi)容的情況. 在沒有路徑?jīng)_突的前提下, 你只需要簡單地從其他項目拉取內(nèi)容即可.

如果有沖突的文件, 那么就會出現(xiàn)問題. 可能的例子包括Makefile和其他一些標(biāo)準(zhǔn)文件名. 你可以選擇合并這些沖突的文件, 但是更多的情況是你不愿意把它們合并. 一個更好解決方案是把外部項目作為一個子目錄進(jìn)行合并. 這種情況不被遞歸合并策略所支持, 所以簡單的拉取是無用的.

在這種情況下, 你需要的是子樹合并策略.

這下面例子中, 我們設(shè)定你有一個倉庫位于/path/to/B (如果你需要的話, 也可以是一個URL). 你想要合并那個倉庫的master分支到你當(dāng)前倉庫的dir-B子目錄下.

下面就是你所需要的命令序列:

$ git remote add -f Bproject /path/to/B (1)

$ git merge -s ours --no-commit Bproject/master (2)

$ git read-tree --prefix=dir-B/ -u Bproject/master (3)

$ git commit -m "Merge B project as our subdirectory" (4)

$ git pull -s subtree Bproject master (5)

子樹合并的好處就是它并沒有給你倉庫的用戶增加太多的管理負(fù)擔(dān). 它兼容于較老(版本號小于1.5.2)的客戶端, 克隆完成之后馬上可以得到代碼.

然而, 如果你使用子模塊(submodule), 你可以選擇不傳輸這些子模塊對象. 這可能在子樹合并過程中造成問題.

譯者注: submodule是Git的另一種將別的倉庫嵌入到本地倉庫方法.

另外, 若你需要修改內(nèi)嵌外部項目的內(nèi)容, 使用子模塊方式可以更容易地提交你的修改.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市悼潭,隨后出現(xiàn)的幾起案子庇忌,更是在濱河造成了極大的恐慌,老刑警劉巖舰褪,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件皆疹,死亡現(xiàn)場離奇詭異,居然都是意外死亡占拍,警方通過查閱死者的電腦和手機(jī)略就,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晃酒,“玉大人表牢,你說我怎么就攤上這事”创危” “怎么了崔兴?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長浊闪。 經(jīng)常有香客問我恼布,道長螺戳,這世上最難降的妖魔是什么搁宾? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮倔幼,結(jié)果婚禮上盖腿,老公的妹妹穿的比我還像新娘。我一直安慰自己损同,他們只是感情好翩腐,可當(dāng)我...
    茶點故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著膏燃,像睡著了一般茂卦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上组哩,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天等龙,我揣著相機(jī)與錄音处渣,去河邊找鬼。 笑死蛛砰,一個胖子當(dāng)著我的面吹牛罐栈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播泥畅,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼荠诬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了位仁?” 一聲冷哼從身側(cè)響起柑贞,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎聂抢,沒想到半個月后凌外,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡涛浙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年康辑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轿亮。...
    茶點故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡疮薇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出我注,到底是詐尸還是另有隱情按咒,我是刑警寧澤,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布但骨,位于F島的核電站励七,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏奔缠。R本人自食惡果不足惜掠抬,卻給世界環(huán)境...
    茶點故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望校哎。 院中可真熱鬧两波,春花似錦、人聲如沸闷哆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抱怔。三九已至劣坊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間屈留,已是汗流浹背局冰。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工括儒, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锐想。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓帮寻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赠摇。 傳聞我的和親對象是個殘疾皇子固逗,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,446評論 2 359

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