Git知識總覽(三) 分支的建立、刪除、切換、合併以及衝突解決
前兩篇部落格集中的聊了git的一些常用命令,具體請參見《》、《》。本篇部落格主要涉及了在git版本管理中的分支的建立、切換以及合併。並且羅列了在merge分支使發生衝突時的解決方式。同時還介紹瞭如何刪除本地分支以及遠端分支。本篇部落格除了參考ProGit中的內容,還參考了這個網站進行的git分支內容的學習和梳理。下方的示例有的給出了基於LearningBranching的示例,有的是基於真實分支操作的示例。本篇部落格只是git分支管理的部分知識,下篇部落格會繼續總結git分支的相關操作。
一、分支建立與切換
1、建立新的分支並切換到該分支上進行提交
首先我們先從最簡單的來,下方演示了git分支的建立和切換的最基本的操作,具體步驟如下:
-
git branch <分支名> : 首先使用 git branch bugfix01,在當前分支也就是master分支上建立了一個名為bugfix01的新分支。
-
git checkout <分支名> : 然後使用 git checkout bugfix01 命令來切換到我們新建立的bugfix01的新分支上。
-
git commit : 最後使用 git commit 命令在新的分支上進行程式碼提交。
從上面的操作上我們不難看出,其中的星號*表示git的 HEAD 指標,指向當前所在分支。開始時 HEAD指標指向的是master分支,也就是使用者當前所操作的分支是master。使用 git branch 建立一個新的分支後,HEAD的指向並沒有改變,仍然指向的是master分支。當使用 git checkout
上面還需要注意的時,在建立好分支後,如果在新的分支上沒有提交的話,那麼 bugfix01 分支和 master 分支所指向的提交號是一致的,上面都是 C1。 這個 C1 表示的就是每次提交的雜湊值,也就是提交號。當使用 git commit 時,說明在分支上有新的提交了,就會在之前的提交的基礎上往下延伸一個提交,也就是 C2。後提交的 C2 會有一個指標指向上一個提交C1。
2、上述操作在終端的表現
接下來我們來看一下終端的具體操作。下方是最初的狀態,目前所在的分支為master分支。從下方可以看出該分支上的Tag號,以及HEAD指標指向的master。
然後我們使用 git branch bugfix01 建立一個新的分支。從下方可以看出 bugfix01分支的指標指向的commit號和master的commit號一致,原因是我們從master中開出來的分支。不過當前所操作的分支仍然是master (HEAD -> master)。
因為我們從master分支上切換到了bugfix01分支上,所以此刻的HEAD指標指向的是bugfix01。
然後我們在bugfix01上提了一些程式碼,此刻我們看到bugfix01指向最新的commit,但是HEAD一直是指向當前分支bugfix的。
上面這些操作所使用的命令如下所示:
3、建立並切換分支
我們可以使用一個簡寫的命令來建立並切換到該分支上,下方就演示了這一操作:
-
git checkout -b <分支名> : 首先使用 git checkout -b bugfix02 命令在當前所在分支bugfix01上建立一個新的分支並且切換到新建立的bugfix02上。
-
git commit : 然後就可以使用 git commit 在新的分支 bugfix02 上進行提交了。
上述命令在終端上的執行結果就不做過多贅述了,請參見第二部分。
4、切換到之前的分支並提交
下方的使用場景是切換到之前已經建立好的分支上,並在切換後的分支上進行提交。下方操作後就會形成分叉。
-
git checkout <分支名> :目前所在分支是bugfix02, 然後使用 git checkout bugfix01 命令將分支切換到 bugfix01上。
-
git commit : 切換後就可以在bugfix01上進行提交操作了。
上篇部落格中也聊到了,在終端中,我們可以使用 git log --oneline --graph --all 來檢視所有分支情況。具體如下所示:
二、分支的合併與刪除以及衝突解決
上一部分是如何建立分支和在各個分支間進行切換,接下來我們就來看一下分支的合併與刪除。
1、分支的合併-merge
我們還以上面那個示例來看一下分支的合併。下方的操作主要是分支的合併、當在兩個分支 bugfix01 和 bugfix02 上修改了相關bug, 並且需要將修改後的程式碼合入到master分支上。下方就是這一系列的操作:
-
首先使用 git checkout master 命令切換到master分支上。
-
然後使用 git merge bugfix01 命令將 bugfix01 分支的修改合入到master分支上,在合入成功後會將合入後的新檔案進行提交,此刻會有一個新的commit號,也就對應著下方的C9。
-
然後使用 git merge bugfix02,在將 bugfix02上的修改合入到master分支上,merge 對應的commit號為C10。
-
最後還是可以在master分支上進行正常提交的。
下方就是我們在真正的分支中進行的分支合併的操作,我們將 bugfix01 分支merge到了master分支上。從下方可以看到 bugfix02 還尚未合入Master分支。稍後我們會在處理衝突的示例中將bugfix02分支合入到master分支中。
2、分支的刪除
上面可以看到,雖然 bugfix01 和 bugfix02 的分支已經被合入到master分支上了,但是這兩個分支還是存在的。如果我們不需要這兩個分支指標了,可以將兩個分支指標進行刪除:
-
首先使用 git branch -d bugfix01 對分支 bugfix01 進行刪除。
-
然後使用 git branch -d bugfix02 對分支 bugfix02 進行刪除。
從下方的操作上來看對分支的刪除只是刪除的指向該commit號的指標,並不會刪除其相關的提交號, 在日誌中仍然可以找到之前的commit記錄,也仍然可以在該commit上建立新的分支。如果你想刪除遠端的分支的話,那麼得使用 $ git push origin --delete <分支名> 了。
還是要依附於例項,下方對上一部分已經合入master分支的bugfix01分支執行了刪除操作,刪除成功後會提示 “Delete branch bugfix01 ( was 223aefb)”, 後邊這個就是刪除分支所對應的commit號的前7位。
從下方截圖中可以看到,其中bugfix01這個分支被刪除了,不過刪除的只是指向該commit號的一個指標或者別名,其他的都沒改變。
3、衝突解決
上面是不衝突時的正常流程,如果在分支合併時,兩個分支同時修改了同一個檔案的同一個地方。此刻分支合併時就會衝突,就需要人工介入來解決衝突的程式碼了。上面我們說留著 bugfix02 這個分支是有用的,現在就來看一下bugfix02 這個分支的用處。從下方的 log 中不難發現,bugfix02分支和 master 分支都修改該了README.md檔案的第二行資料。接下來我們就將 bugfix02 合入 master分支上。
下方截圖的內容就是我們將 bugfix02 分支合入到 master分支時所報的衝突。衝突的大概意思就是在合併 README.md 檔案時產生了衝突,自動合併失敗了,需要修復這個衝突,在修復之後再對結果進行提交。我們可以使用 git status來檢視一下當前的狀態(配置的別名 git st)。從 git status的提示中也可以看到,你可以修復該衝突,然後使用 git commit 進行提交,或者 使用 git merge --abort 命令放棄本次合併。如果放棄本次合併就會回到合併之前的狀態,當然,這並不是我們想要的,下方會對衝突進行解決,並提交,
接下來我們就來看一下衝突的具體內容,從<<<<<<<<開始到>>>>>>>>>結尾是衝突的部分,兩個分支的內容由========進行分割。上方是當前分支所修改的內容, 我們需要將衝突的內容進行合併,根據具體情況具體分析,看那些需要保留那些不需要保留。還是都需要保留。
下方就是我們修改衝突後的內容,修復策略是保留了master的修改,刪除了bugfix02分支的修改。然後將修改的檔案進行提交即可,在此就不做過多贅述了。
4、使用工具進行衝突解決
輸入 git mergetool 然後根據提示輸入opendiff, 在Mac下會開啟Xcode自帶的FileMerge工具。
下方就是啟動的 FileMerge 工具, 在使用該工具進行檔案merge時,可以選擇幾種檔案合併策略。比如以左邊為準,以右邊為準等。
上述工具位於Xcode的開發工具中,如下所示:
三、分支的檢視以及強制刪除
首先我們使用 git log --oneline --graph --all 命令來視覺化的看一下目前的分支狀態。從下方的截圖中我們可以看到,目前共有三個分支 master、bugfix02、bugfix03。並且我們可以看出bugfix02已經合入master分支,bugfix03尚未合入。
下方是一系列檢視分支的一些方法:
-
git branch : 檢視所有分支,其中前面有星號的是當前所在分支,下方即為master分支。
-
git branch -v : 檢視所有分支和該分支上最後的一次提交。
-
git branch --merged : 檢視已經合入當前分支的所有分支。
-
git branch --no-merged : 檢視未被合入分支。
今天部落格關於git分支管理的內容就先到這吧,下篇部落格會詳細介紹 rebase 以及 cherry-pick 等相關內容。