溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Git的merge命令實(shí)例分析

發(fā)布時(shí)間:2022-03-19 08:55:33 來源:億速云 閱讀:238 作者:iii 欄目:軟件技術(shù)

這篇文章主要介紹“Git的merge命令實(shí)例分析”的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“Git的merge命令實(shí)例分析”文章能幫助大家解決問題。

它是如何運(yùn)行的

git merge會(huì)將多個(gè)提交序列合并進(jìn)一個(gè)統(tǒng)一的提交歷史。在最常見的使用場(chǎng)景中,git merge被用來合并兩個(gè)分支。在本文檔接下來的部分,我們會(huì)專注于這種合并場(chǎng)景。在這種場(chǎng)景中,git merge接受兩個(gè)commit指針,通常是兩個(gè)分支的頂部commit,然后向前追溯到這兩個(gè)分支最近的一個(gè)共同提交。一旦找到這個(gè)共同提交,Git就會(huì)創(chuàng)建一個(gè)新的"merge commit",用來合并兩個(gè)分支上各自的提交序列。

比如說我們有一個(gè)功能分支由main分支派生出來,現(xiàn)在我們希望將這個(gè)功能分支合并回main分支。

執(zhí)行合并命令會(huì)將指定分支合并到當(dāng)前工作分支上,我們假設(shè)當(dāng)前工作分支為main。Git根據(jù)兩個(gè)分支自行決定合并提交的算法(將在下面具體討論)。

合并commit與普通commit不一樣,因?yàn)楹喜ommit會(huì)有兩個(gè)父提交。創(chuàng)建一個(gè)合并commit時(shí)Git會(huì)嘗試自動(dòng)將兩個(gè)獨(dú)立的提交歷史合并為一個(gè)。不過當(dāng)Git發(fā)現(xiàn)某一塊數(shù)據(jù)在兩邊的提交歷史中都含有變更,它將無法自動(dòng)對(duì)其進(jìn)行合并。這種情況被稱為版本沖突,此時(shí)Git需要人為介入調(diào)整才能繼續(xù)進(jìn)行合并。

準(zhǔn)備合并

在實(shí)際進(jìn)行合并操作之前,需要進(jìn)行一些準(zhǔn)備步驟,以保證合并過程能夠順利進(jìn)行。

確認(rèn)接收合并的分支

執(zhí)行git status命令查看當(dāng)前分支的狀態(tài),確保HEAD指正指向的是正確的接收合并的分支。如果不是,執(zhí)行git checkout命令切換到正確的分支。在我們的示例中,執(zhí)行git checkout main

獲取最新的遠(yuǎn)程提交

確保合并操作涉及的兩個(gè)分支都更新到遠(yuǎn)程倉(cāng)庫(kù)的最新狀態(tài)。執(zhí)行git fetch拉取遠(yuǎn)程倉(cāng)庫(kù)的最新提交。一旦fetch操作完成,為了保證main分支與遠(yuǎn)程分支同步,還需執(zhí)行git pull命令。

合并

當(dāng)上面提及的準(zhǔn)備工作都已完備,合并就可以正式開始了。執(zhí)行git merge <branch>命令,其中為需要合并到當(dāng)前分支的目標(biāo)分支名稱。

快進(jìn)合并

當(dāng)前工作分支到合并目標(biāo)分支之間的提交歷史是線性路徑時(shí),可以進(jìn)行快進(jìn)合并。在這種情況下,不需要真實(shí)的合并兩個(gè)分支,Git只需要把當(dāng)前分支的頂端指針移動(dòng)到目標(biāo)分支的頂端就可以了(也就是快進(jìn)的意思)。在這種情況下快進(jìn)合并成功的將提交歷史合并至一處,畢竟目標(biāo)分支中的提交此時(shí)都包含在當(dāng)前分支的提交歷史中了。

然而快進(jìn)合并在兩個(gè)分支出現(xiàn)分叉的情況下是不允許執(zhí)行的。當(dāng)目標(biāo)分支相對(duì)于當(dāng)前分支的提交歷史不是線性的,Git只能通過三路合并算法來決定如何對(duì)兩個(gè)分支進(jìn)行合并。三路合并算法需要使用一個(gè)專用commit來整合兩邊的提交歷史。這個(gè)名詞源于Git要想生成合并commit,需要用到三個(gè)commits:兩個(gè)分支的頂端commit,以及它們的共同祖先commit。

雖然實(shí)際上可以選擇使用這些不同的合并策略,但是大多數(shù)開發(fā)者更喜歡快進(jìn)合并(通過利用 rebasing 命令),尤其是用于小功能的開發(fā)或者bug修復(fù);反之對(duì)于合并長(zhǎng)期開發(fā)的功能分支,則更傾向于使用三路合并的方式。在第二種場(chǎng)景中,merge產(chǎn)生的合并commit會(huì)作為兩個(gè)分支合并的標(biāo)志保留在提交歷史中。

接下來我們用下面第一個(gè)例子來展示如何進(jìn)行快進(jìn)合并。下面的命令會(huì)先創(chuàng)建一個(gè)新分支,在新分支上進(jìn)行兩次提交,然后用快進(jìn)合并把新分支合并回main分支。

# Start a new feature
git checkout -b new-feature main
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Merge in the new-feature branch
git checkout main
git merge new-feature
git branch -d new-feature

這個(gè)例子中的工作流程通常用于短期功能的開發(fā),這種開發(fā)流程更多地被當(dāng)做是比較獨(dú)立的一次開發(fā)流程,與之對(duì)應(yīng)的則是需要協(xié)調(diào)和管理的長(zhǎng)期功能開發(fā)分支。

另外還需注意到,在此例中Git不會(huì)對(duì)git branch -d命令發(fā)出警告,因?yàn)閚ew-feature的內(nèi)容已經(jīng)合并到主分支里了。

在某些情況下,雖然目標(biāo)分支的提交歷史相對(duì)于當(dāng)前分支是線性的,可以進(jìn)行快進(jìn)合并,但你仍然希望有一個(gè)合并commit來標(biāo)志合并在此commit發(fā)生過,那么可以在執(zhí)行git merge命令時(shí)使用--no-ff選項(xiàng)。

git merge --no-ff <branch>

以上命令將指定分支合并到當(dāng)前分支,但總會(huì)生成一個(gè)合并commit(即便這一合并操作可以快進(jìn))。當(dāng)你需要在倉(cāng)庫(kù)的提交歷史中標(biāo)記合并事件時(shí)這一命令相當(dāng)有用。

三路合并

接下來的例子與上面比較像,但是因?yàn)?code>main分支在feature分支向前發(fā)展的過程中,自身也發(fā)生的改變,因此在合并時(shí)需要進(jìn)行三路合并。在進(jìn)行大的功能開發(fā)或者有多個(gè)開發(fā)者同時(shí)進(jìn)行開發(fā)時(shí)這種場(chǎng)景相當(dāng)常見。

Start a new feature
git checkout -b new-feature main
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Develop the main branch
git checkout main
# Edit some files
git add <file>
git commit -m "Make some super-stable changes to main"
# Merge in the new-feature branch
git merge new-feature
git branch -d new-feature

需注意在這種情況下,由于沒有辦法直接把main的頂端指針移動(dòng)到new-feature分支上,因此Git無法執(zhí)行快進(jìn)合并。

在大多數(shù)實(shí)際工作場(chǎng)景中,new-feature應(yīng)該是一個(gè)很大的功能,開發(fā)過程持續(xù)了相當(dāng)長(zhǎng)的時(shí)間,這也就難免同時(shí)期在main分支上也有新的提交。如果你的功能分支大小像上面的例子一樣小,則完全可以使用rebase將new-feature分支變基到main分支上,然后再執(zhí)行一次快進(jìn)合并。這樣也會(huì)避免在項(xiàng)目提交歷史中產(chǎn)生過多的冗余。

解決沖突

如果將要合并的兩個(gè)分支都修改了同一個(gè)而文件的同一個(gè)部分內(nèi)容,Git就無法確定應(yīng)該使用哪個(gè)版本的內(nèi)容。當(dāng)這種情況發(fā)生時(shí),合并過程會(huì)停止在合并commit提交之前,以便給用戶留下機(jī)會(huì)手動(dòng)修復(fù)這些沖突。

在Git的合并過程中,很棒的一點(diǎn)是它使用人們熟知的 編輯 / 暫存 / 提交 這樣的工作流程來解決沖突。當(dāng)碰到合并沖突時(shí),執(zhí)行git status命令會(huì)列出哪些文件含有沖突并需要手動(dòng)解決。比如說當(dāng)兩個(gè)分支都修改了hello.py文件的同一部分,你會(huì)看到類似下面這樣的信息:

On branch main
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both modified: hello.py

沖突是如何顯示的

當(dāng)Git在合并過程中碰到了沖突,它會(huì)編輯受影響的文件中的相關(guān)內(nèi)容,并添加視覺標(biāo)記用以展示沖突中雙方在此部分的不同內(nèi)容。這些視覺標(biāo)記為:<<<<<<<,=======,>>>>>>>。要找到?jīng)_突發(fā)生的具體位置,在文件中搜索這些視覺標(biāo)記會(huì)非常便捷地達(dá)成目的。

here is some content not affected by the conflict
<<<<<<< main
this is conflicted text from main
=======
this is conflicted text from feature branch
>>>>>>> feature branch;

通常來說在 ====== 標(biāo)記之前的內(nèi)容來自于接收合并的分支,而在這之后的內(nèi)容來自于要合并的分支。

一旦找到?jīng)_突的部分,就可以根據(jù)需要來修正沖突。當(dāng)你完成了沖突的修復(fù)并準(zhǔn)備好繼續(xù)進(jìn)行合并,只需要執(zhí)行git add命令把已經(jīng)解決好沖突的文件添加暫存區(qū),告訴Git這些沖突已經(jīng)解決完畢即可。這之后就像正常提交代碼一樣執(zhí)行git commit完成合并commit。這個(gè)過程跟正常情況下提交代碼是完全一樣的,也就是說對(duì)于普通開發(fā)者來說處理沖突也是小菜一碟。

還需注意合并沖突只可能出現(xiàn)在三路合并過程中,在快進(jìn)合并中不會(huì)出現(xiàn)沖突。

關(guān)于“Git的merge命令實(shí)例分析”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI