Git知識總覽(三) 分支的創建、刪除、切換、合並以及沖突解決
前兩篇博客集中的聊了git的一些常用命令,具體請參見《Git知識總覽(一) 從 git clone 和 git status 談起》、《Git知識總覽(二) git常用命令概覽》。本篇博客主要涉及了在git版本管理中的分支的創建、切換以及合並。並且羅列了在merge分支使發生沖突時的解決方式。同時還介紹了如何刪除本地分支以及遠程分支。本篇博客除了參考ProGit中的內容,還參考了learngitbranching這個網站進行的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 命令後,HEAD 指針就由 master 分支轉向了 bugfix01 分支了,這樣我們就可以對bugfix01進行操作了。
上面還需要註意的時,在創建好分支後,如果在新的分支上沒有提交的話,那麽 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 等相關內容。
Git知識總覽(三) 分支的創建、刪除、切換、合並以及沖突解決