手把手教學(xué),如何解決 Git 沖突?
閱讀本文大概需要 3 分鐘。
Git 是現(xiàn)在使用最廣泛的源代碼管理程序。一個(gè)合格的程序員必須要熟練掌握 Git。在使用 Git 的時(shí)候,最讓人頭疼的問(wèn)題是什么?肯定是解沖突了。如果兩個(gè)人修改了同一個(gè)文件的相同位置,那么當(dāng)一個(gè)人提交代碼并合并到主分支以后,第二個(gè)人嘗試合并時(shí)就會(huì)觸發(fā)沖突。大多數(shù)情況下,Git 自己知道如何把兩份代碼合并起來(lái)。但有時(shí)候當(dāng) Git 不知道應(yīng)該怎么合并,就會(huì)提示你需要手動(dòng)解決沖突。
我以前學(xué)習(xí) Git 的時(shí)候,由于沒(méi)有人跟我一起提交代碼,所以我為了模擬兩人提交的情況,會(huì)把代碼 clone 到兩個(gè)文件夾里面,然后把相同的位置分別做不同的修改,再分別提交。過(guò)程非常繁瑣。
最近因?yàn)樵u(píng)上了微軟 MVP 的關(guān)系,會(huì)主動(dòng)關(guān)注一下微軟的在線課程,結(jié)果發(fā)現(xiàn)微軟悄無(wú)聲息地出了一整套的 Github 課程。而這其中,有一套交互式的課程手把手指導(dǎo)如何解決 Git 的沖突:在 GitHub 上使用合并沖突解決來(lái)解決競(jìng)爭(zhēng)提交[1],由于 Github 是基于 Git 的,所以只要稍作設(shè)置,這個(gè)課程就能變成通用的 Git 操作指導(dǎo)教程。
一開(kāi)始我以為這個(gè)課程只有 MVP 能看,后來(lái)發(fā)現(xiàn),課程不僅完全免費(fèi),而且不需要注冊(cè),所有人都能隨時(shí)學(xué)習(xí)。只要你有一個(gè) Github 賬號(hào)就能參加。大家點(diǎn)擊公眾號(hào)下方的閱讀原文就可以打開(kāi)這個(gè)課程頁(yè)面。
打開(kāi)課程以后,頁(yè)面如下圖所示:
點(diǎn)擊其中的“開(kāi)始”按鈕,就可以開(kāi)始學(xué)習(xí)。課程一共有5個(gè)單元,如下圖所示。
其中,第1,2單元是知識(shí)性介紹,大家可以看一下。今天我們重點(diǎn)說(shuō)一下第3單元《練習(xí)-管理合并沖突》。這一單元,會(huì)基于 Github Lab(Github 學(xué)習(xí)實(shí)驗(yàn)室)來(lái)一步一步手把手指導(dǎo)。我們點(diǎn)擊在 Github 上啟動(dòng)學(xué)習(xí)實(shí)驗(yàn)室按鈕。
此時(shí),瀏覽器會(huì)新開(kāi)一個(gè)選項(xiàng)卡,如下圖所示。點(diǎn)擊Start free course,如下圖所示。
此時(shí),會(huì)讓你登錄 Github,并授權(quán) Github Lab 創(chuàng)建一個(gè)練習(xí)源,如下圖所示:
大家可以創(chuàng)建公共源,也可以創(chuàng)建私有源。如果是創(chuàng)建私有源的話,之后每次從遠(yuǎn)程推拉代碼時(shí),會(huì)讓你輸入 Github 賬號(hào)密碼。需要注意的是Additional Options這一項(xiàng)一定要選擇Use the command line,這樣我們才能學(xué)習(xí)通用的 Git 操作。另外兩項(xiàng)都是 Github 專(zhuān)用的操作。對(duì)我們幫助不大。
授權(quán)完成以后,你的 Github 上會(huì)自動(dòng)創(chuàng)建一個(gè)源,并且有很多的沖突,如下圖所示:
回到剛才的課程頁(yè)面,可以看到下面出現(xiàn)了幾個(gè)課程階段,如下圖所示。
我們點(diǎn)擊第一課的Start按鈕,開(kāi)始第一課。瀏覽器彈出了新的頁(yè)面(實(shí)際上就是 Github 的 PR 頁(yè)面),在這里,我們可以根據(jù)它的提示和說(shuō)明進(jìn)行操作。如下圖所示:
大家不要擔(dān)心全是英文看不懂,真正需要你進(jìn)行的操作,都是灰色背景的代碼片段,這些代碼是很容易看懂的。
根據(jù)提示,首先 clone 代碼:
git?clone?https://github.com/kingname/merge-conflicts.git
cd?merge-conflicts
接下來(lái),切換到update-config分支,然后拉取遠(yuǎn)程最新代碼。
git?checkout?update-config
git?pull
然后,我們把遠(yuǎn)程的master分支代碼合并到update-config分支中:
git?merge?origin/master
發(fā)現(xiàn)了沖突,如下圖所示:
它已經(jīng)提示了_config.yml文件有沖突。所以我們可以直接打開(kāi)_config.yml文件。你可以使用自己喜歡的編輯器打開(kāi)。我這里使用 Vim。打開(kāi)以后的代碼如下圖所示:
注意,這里的實(shí)際代碼可能跟教程不一樣。教程里面說(shuō)沖突內(nèi)容是被<<<<<<< update-config和>>>>>>> master包起來(lái)的,但實(shí)際上代碼里面的沖突內(nèi)容是被<<<<<<< HEAD和>>>>>>> origin/master包起來(lái)的。
大家可以看到,在<<<<<<< HEAD與=======中間的內(nèi)容,與=======到>>>>>>> origin/master中間的內(nèi)容,他們的字段名是一樣的,但是值不一樣,所以 Git 不知道應(yīng)該以哪個(gè)為準(zhǔn),需要我們?nèi)斯Q斷。
假設(shè)我想以上面這一段為準(zhǔn)(在實(shí)際開(kāi)發(fā)過(guò)程中,可能上下要各取一部分合并),如下圖所示:
保存修改,根據(jù)它的提示,執(zhí)行以下代碼進(jìn)行提交:
git?add?.
git?commit?-m?"merge?master?into?update-config"
git?push
提交成功以后,網(wǎng)頁(yè)上會(huì)立刻給出反饋:
我們繼續(xù)往下看,根據(jù)它的提示,首先切換回master分支,然后拉取最新代碼,然后把update-config分支的內(nèi)容合并進(jìn)入master:
git?checkout?master
git?pull
git?merge?update-config
合并成功,如下圖所示。
最后把本地已經(jīng)合并的代碼使用git push推到遠(yuǎn)程即可。
第二個(gè)問(wèn)題更復(fù)雜一些,這次有兩個(gè)沖突文件,如下圖所示:
并且沖突的內(nèi)容有好幾個(gè),如下圖所示:
但解決方法還是一樣的,人來(lái)決定要保留哪些內(nèi)容,把不要的地方刪掉:
保存修改,然后檢查第二個(gè)文件。第二個(gè)文件也解決以后,根據(jù)頁(yè)面上的提示輸入代碼,合并提交就可以了。
前兩個(gè)問(wèn)題,是別人創(chuàng)建了沖突,需要我們來(lái)改。第三個(gè)問(wèn)題,是我們自己導(dǎo)致了沖突,我們自己來(lái)解決。方法跟之前是一樣的,就不多說(shuō)了。
最后這一步,讓你完善這個(gè)源里面的內(nèi)容。因?yàn)檫@個(gè)模擬沖突的源本質(zhì)上是一個(gè)在線簡(jiǎn)歷頁(yè)面,你可以把里面的內(nèi)容改成你自己的。當(dāng)然,這是選做題,可做可不做。

所有任務(wù)都做完了,是不是很有成就感:
最后還能解鎖成就:
總結(jié)
根據(jù)上面的學(xué)習(xí)過(guò)程,我總結(jié)了一個(gè)解決沖突的常規(guī)流程:
前提條件:不能在 master 分支上修改任何文件。master 分支的變更只能通過(guò) git pull 和 git merge 獲得。在 master 分支下面,不能手動(dòng)修改任何文件。 我們自己有一個(gè)分支用來(lái)修改代碼,例如我的分支叫做 dev分支。我把代碼修改完成了,現(xiàn)在不知道有沒(méi)有沖突。在 dev 分支里面,執(zhí)行命令 git merge origin/master,把遠(yuǎn)程的master分支合并到當(dāng)前dev分支中。如果沒(méi)有任何報(bào)錯(cuò),那么直接轉(zhuǎn)到第5步。如果有沖突,根據(jù)提示,把沖突解決,保存文件。然后執(zhí)行命令 git add xxx把你修改的文件添加到緩存區(qū)。然后執(zhí)行命令git commit -m "xxx"添加 commit 信息。執(zhí)行如下命令,切換到 master 分支: git checkout master。執(zhí)行命令 git pull確保當(dāng)前 master 分支是最新代碼。把 dev分支的代碼合并回 master 分支:git merge dev。提交代碼: git push。
只要所有開(kāi)發(fā)者都遵守這個(gè)規(guī)則,那么解決沖突是一件非常容易的事情。
參考資料
在 GitHub 上使用合并沖突解決來(lái)解決競(jìng)爭(zhēng)提交: https://docs.microsoft.com/zh-cn/learn/modules/resolve-merge-conflicts-github/?WT.mc_id=DT-MVP-5003916
推薦閱讀
1
2
3
4
崔慶才
靜覓博客博主,《Python3網(wǎng)絡(luò)爬蟲(chóng)開(kāi)發(fā)實(shí)戰(zhàn)》作者
隱形字
個(gè)人公眾號(hào):進(jìn)擊的Coder
長(zhǎng)按識(shí)別二維碼關(guān)注




















