merge:合并 commits

前面說到,pull 的內(nèi)部操作其實(shí)是把遠(yuǎn)程倉庫取到本地后(使用的是 fetch)涮较,再用一次 merge 來把遠(yuǎn)端倉庫的新 commits 合并到本地迁筛。這一節(jié)就說一下商佑,merge 到底是什么豪嚎。

含義和用法

merge 的意思是「合并」搔驼,它做的事也是合并:指定一個(gè) commit,把它合并到當(dāng)前的 commit 來侈询。具體來講舌涨,merge 做的事是:

從目標(biāo) commit 和當(dāng)前 commit (即 HEAD 所指向的 commit)分叉的位置起,把目標(biāo) commit 的路徑上的所有 commit 的內(nèi)容一并應(yīng)用到當(dāng)前 commit妄荔,然后自動(dòng)生成一個(gè)新的 commit泼菌。

例如下面這個(gè)圖中:

HEAD 指向了 master,所以如果這時(shí)執(zhí)行:

git merge branch1

Git 會(huì)把 56 這兩個(gè) commit 的內(nèi)容一并應(yīng)用到 4 上啦租,然后生成一個(gè)新的提交,并跳轉(zhuǎn)到提交信息填寫的界面:

merge 操作會(huì)幫你自動(dòng)地填寫簡要的提交信息荒揣。在提交信息修改完成后(或者你打算不修改默認(rèn)的提交信息)篷角,就可以退出這個(gè)界面,然后這次 merge 就算完成了系任。

適用場景

merge 有什么用恳蹲?最常用的場景有兩處:

  1. 合并分支

    當(dāng)一個(gè) branch 的開發(fā)已經(jīng)完成,需要把內(nèi)容合并回去時(shí)俩滥,用 merge 來進(jìn)行合并嘉蕾。

    branch 又應(yīng)該怎么用呢?

    下節(jié)就說霜旧。

  2. pull 的內(nèi)部操作

    之前說過错忱,pull 的實(shí)際操作其實(shí)是把遠(yuǎn)端倉庫的內(nèi)容用 fetch 取下來之后,用 merge 來合并挂据。

特殊情況 1:沖突

merge 在做合并的時(shí)候以清,是有一定的自動(dòng)合并能力的:如果一個(gè)分支改了 A 文件,另一個(gè)分支改了 B 文件崎逃,那么合并后就是既改 A 也改 B掷倔,這個(gè)動(dòng)作會(huì)自動(dòng)完成;如果兩個(gè)分支都改了同一個(gè)文件个绍,但一個(gè)改的是第 1 行勒葱,另一個(gè)改的是第 2 行,那么合并后就是第 1 行和第 2 行都改巴柿,也是自動(dòng)完成凛虽。

image

但,如果兩個(gè)分支修改了同一部分內(nèi)容篮洁,merge 的自動(dòng)算法就搞不定了涩维。這種情況 Git 稱之為:沖突(Conflict)。

直白點(diǎn)說就是,你的兩個(gè)分支改了相同的內(nèi)容瓦阐,Git 不知道應(yīng)該以哪個(gè)為準(zhǔn)蜗侈。如果在 merge 的時(shí)候發(fā)生了這種情況,Git 就會(huì)把問題交給你來決定睡蟋。具體地踏幻,它會(huì)告訴你 merge 失敗,以及失敗的原因:

git merge feature1

提示信息說戳杀,在 shopping list.txt 中出現(xiàn)了 "merge conflict"该面,自動(dòng)合并失敗,要求 "fix conflicts and then commit the result"(把沖突解決掉后提交)信卡。那么你現(xiàn)在需要做兩件事:

  1. 解決掉沖突
  2. 手動(dòng) commit 一下

1. 解決沖突

解決掉沖突的方式有多個(gè)隔缀,我現(xiàn)在說最直接的一個(gè)。你現(xiàn)在再打開 shopping list.txt 看一下傍菇,會(huì)發(fā)現(xiàn)它的內(nèi)容變了:

可以看到猾瘸,Git 雖然沒有幫你完成自動(dòng) merge,但它對(duì)文件還是做了一些工作:它把兩個(gè)分支沖突的內(nèi)容放在了一起丢习,并用符號(hào)標(biāo)記出了它們的邊界以及它們的出處牵触。上面圖中表示,HEAD 中的內(nèi)容是 移動(dòng)硬盤(已買)咐低,而 feature1 中的內(nèi)容則是 移動(dòng)硬盤(不買了)揽思。這兩個(gè)改動(dòng) Git 不知道應(yīng)該怎樣合并,于是把它們放在一起见擦,由你來決定钉汗。假設(shè)你決定保留 HEAD 的修改,那么只要?jiǎng)h除掉 feature1 的修改锡宋,再把 Git 添加的那三行 <<< === >>> 輔助文字也刪掉儡湾,保存文件退出,所謂的「解決掉沖突」就完成了执俩。

你也可以選擇使用更方便的 merge 工具來解決沖突徐钠,這個(gè)你可以自己搜索一下。

2. 手動(dòng)提交

解決完沖突以后役首,就可以進(jìn)行第二步—— commit 了尝丐。

git add shopping\ list.txt # 嗯是的,這里 commit 前也需要先 add 一下
git commit

可以看到衡奥,被沖突中斷的 merge爹袁,在手動(dòng) commit 的時(shí)候依然會(huì)自動(dòng)填寫提交信息。這是因?yàn)樵诎l(fā)生沖突后矮固,Git 倉庫處于一個(gè)「merge 沖突待解決」的中間狀態(tài)失息,在這種狀態(tài)下 commit譬淳,Git 就會(huì)自動(dòng)地幫你添加「這是一個(gè) merge commit」的提交信息。

放棄解決沖突盹兢,取消 merge邻梆?

同理,由于現(xiàn)在 Git 倉庫處于沖突待解決的中間狀態(tài)绎秒,所以如果你最終決定放棄這次 merge浦妄,也需要執(zhí)行一次 merge --abort 來手動(dòng)取消它:

git merge --abort

輸入這行代碼,你的 Git 倉庫就會(huì)回到 merge 前的狀態(tài)见芹。

特殊情況 2:HEAD 領(lǐng)先于目標(biāo) commit

如果 merge 時(shí)的目標(biāo) commitHEAD 處的 commit 并不存在分叉剂娄,而是 HEAD 領(lǐng)先于目標(biāo) commit

那么 merge 就沒必要再創(chuàng)建一個(gè)新的 commit 來進(jìn)行合并操作,因?yàn)椴]有什么需要合并的玄呛。在這種情況下阅懦, Git 什么也不會(huì)做,merge 是一個(gè)空操作把鉴。

特殊情況 3:HEAD 落后于 目標(biāo) commit——fast-forward

而另一種情況:如果 HEAD 和目標(biāo) commit 依然是不存在分叉故黑,但 HEAD 不是領(lǐng)先于目標(biāo) commit,而是落后于目標(biāo) commit

那么 Git 會(huì)直接把 HEAD(以及它所指向的 branch庭砍,如果有的話)移動(dòng)到目標(biāo) commit

git merge feature1

這種操作有一個(gè)專有稱謂,叫做 "fast-forward"(快速前移)混埠。

一般情況下怠缸,創(chuàng)建新的 branch 都是會(huì)和原 branch (例如上圖中的 master )并行開發(fā)的,不然沒必要開 branch 钳宪,直接在原 branch 上開發(fā)就好揭北。但事實(shí)上,上圖中的情形其實(shí)很常見吏颖,因?yàn)檫@其實(shí)是 pull 操作的一種經(jīng)典情形:本地的 master 沒有新提交搔体,而遠(yuǎn)端倉庫中有同事提交了新內(nèi)容到 master

那么這時(shí)如果在本地執(zhí)行一次 pull 操作,就會(huì)由于 HEAD 落后于目標(biāo) commit (也就是遠(yuǎn)端的 master)而造成 "fast-forward":

git pull

簡單解釋一下上圖中的 origin/masterorigin/HEAD 是什么鬼:它們是對(duì)遠(yuǎn)端倉庫的 masterHEAD 的本地鏡像半醉,在 git pull 的「兩步走」中的第一步——git fetch 下載遠(yuǎn)端倉庫內(nèi)容時(shí)疚俱,這兩個(gè)鏡像引用得到了更新,也就是上面這個(gè)動(dòng)圖中的第一步:origin/masterorigin/HEAD 移動(dòng)到了最新的 commit缩多。

為什么前面的圖里面從來都沒有這兩個(gè)「鏡像引用」呆奕?因?yàn)槲覜]有畫呀!其實(shí)它們是一直存在的衬吆。

git pull 的第二步操作 merge 的目標(biāo) commit 梁钾,是遠(yuǎn)端倉庫的 HEAD,也就是 origin/HEAD 逊抡,所以 git pull 的第二步的完整內(nèi)容是:

git merge origin/HEAD

因此 HEAD 就會(huì)帶著 master 一起姆泻,也指向圖中綠色的最新 commit 了。

小結(jié)

本節(jié)對(duì) merge 進(jìn)行了介紹,內(nèi)容大概有這么幾點(diǎn):

  1. merge 的含義:從兩個(gè) commit「分叉」的位置起拇勃,把目標(biāo) commit 的內(nèi)容應(yīng)用到當(dāng)前 commitHEAD 所指向的 commit)四苇,并生成一個(gè)新的 commit
  2. merge 的適用場景:
    1. 單獨(dú)開發(fā)的 branch 用完了以后潜秋,合并回原先的 branch蛔琅;
    2. git pull 的內(nèi)部自動(dòng)操作。
  3. merge 的三種特殊情況:
    1. 沖突
      1. 原因:當(dāng)前分支和目標(biāo)分支修改了同一部分內(nèi)容峻呛,Git 無法確定應(yīng)該怎樣合并罗售;
      2. 應(yīng)對(duì)方法:解決沖突后手動(dòng) commit
    2. HEAD 領(lǐng)先于目標(biāo) commit:Git 什么也不做钩述,空操作寨躁;
    3. HEAD 落后于目標(biāo) commit:fast-forward。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末牙勘,一起剝皮案震驚了整個(gè)濱河市职恳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌方面,老刑警劉巖放钦,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異恭金,居然都是意外死亡操禀,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門横腿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颓屑,“玉大人,你說我怎么就攤上這事耿焊【镜耄” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵罗侯,是天一觀的道長器腋。 經(jīng)常有香客問我,道長歇父,這世上最難降的妖魔是什么蒂培? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮榜苫,結(jié)果婚禮上贡羔,老公的妹妹穿的比我還像新娘窄陡。我一直安慰自己君编,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布抗悍。 她就那樣靜靜地躺著,像睡著了一般钳枕。 火紅的嫁衣襯著肌膚如雪缴渊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天鱼炒,我揣著相機(jī)與錄音衔沼,去河邊找鬼。 笑死昔瞧,一個(gè)胖子當(dāng)著我的面吹牛指蚁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播自晰,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼凝化,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了酬荞?” 一聲冷哼從身側(cè)響起搓劫,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎混巧,沒想到半個(gè)月后枪向,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡咧党,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年遣疯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凿傅。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖数苫,靈堂內(nèi)的尸體忽然破棺而出聪舒,到底是詐尸還是另有隱情,我是刑警寧澤虐急,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布箱残,位于F島的核電站,受9級(jí)特大地震影響止吁,放射性物質(zhì)發(fā)生泄漏被辑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一敬惦、第九天 我趴在偏房一處隱蔽的房頂上張望盼理。 院中可真熱鬧,春花似錦俄删、人聲如沸宏怔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽臊诊。三九已至鸽粉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抓艳,已是汗流浹背触机。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留玷或,地道東北人儡首。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像庐椒,于是被迫代替她去往敵國和親椒舵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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

  • git常用命令 GIT常用命令備忘:http://stormzhang.com/git/2014/01/27/gi...
    新篇章閱讀 8,472評(píng)論 1 26
  • 1. 安裝 Github 查看是否安裝git: $ git config --global user.name "...
    Albert_Sun閱讀 13,661評(píng)論 9 163
  • Git常用語法 [TOC] Git簡介 描述 ? Git(讀音為/g?t/约谈。)是一個(gè)開源的分布式版本控制系統(tǒng)笔宿,...
    君惜丶閱讀 3,511評(píng)論 0 13
  • 二泼橘、化灰 沒有長明燈,她在黑暗中靜靜地過了一晚迈勋。當(dāng)然她已經(jīng)不怕黑了炬灭。 早晨,子孫們很忙靡菇。他們把一...
    亭子2016閱讀 242評(píng)論 0 1
  • 手捧蓮花送給你 滿目憐愛伊 忽迎風(fēng)飄起 誰知今日來香移 駐見荷塘笑依依 著落香濃亦 朵朵試春泥 親欲盡享花語滴
    秋葉的味道閱讀 278評(píng)論 2 2