git圖解(3):分支操作

git 的分支是它最明顯的特性, 大部分人聽別人推薦使用git都會聽到「git分支操作方便...」,對比其他版本控制系統git 分支操作有難以置信的輕量,創建新分支幾乎瞬間完成,不同分支之間切換也非常快捷方便;本文將結合實踐以及繪圖歸納、總結git常見的分支操作指令以及注意事項;本文只總結git分支的實踐運用, git分支底層實現原理請閱讀ProGit第二版分支部分章節;

1.GIT創建分支;

首先我們得知道, GIT分支包括本地分支 跟 遠程分支; 慣例先上圖:

有時遠程有的分支我們本地沒有(其他同事維護的分支), 或者本地有的分支遠程沒有(修複線上小問題開的本地小分支);以下具體說下如何創建本地分支和遠程分支:

1.1 創建本地分支:

新分支都是基於原有分支創建, 而在實踐開發中基本從線上分支(與線上代碼同步的分支): master 分支創建。

而 從master創建本地分支也有兩種方式:基於本地master分支創建分支、基於線上master分支創建分支;

基於本地master分支創建分支(命令窗口進入工程根目錄):

查看當前是否在master分支:

// 查看本地分支信息ngit branchn

綠色分支表示其為當前分支,所以得切換至master分支

git checkout masterngit pulln// 創建並切換到新分支相當於:git branch xxx, git checkout xxxngit checkout -b newBranchNamen

"git checkout master" 切換到本地master分支;

"git pull" 更新本地master分支代碼至最新(如 本地master分支未關聯遠程master分支,「git pull origin master」);

"git checkout -b newBranchName" 基於本地master分支代碼創建新分支:newBranchName,並切換到該分支;

基於遠程master分支創建分支(命令窗口進入工程根目錄):

首先查看本地、線上分支信息(調用以下指令前建議先執行"git pull -p"防止本地git分支信息緩存):

git branch -an

白色顯示為本地分支、綠色顯示為當前分支、紅色顯示為遠程分支;

切換至遠程分支:

git checkout remotes/origin/mastern

基於遠程master分支創建新分支:

git checkout -b newBranchNamen

1.2 創建遠程分支:

創建遠程分支可以直接由本地新分支推送完成也可以在遠程分支管理系統(例如:github 、gitLab)上可視化操作完成;

本地新分支推送創建遠程分支

在 1.1 部分我們在本地創建了一新分支, 如果在該分支更新了代碼, 然後執行"git add "、"git commit"指令後, 再執行以下指令可在遠程創建新分支;

git push origin newBranch:newBranchn

git push <遠程主機名> <本地分支名>:<遠程分支名>

GitHub上創建遠程分支

選中項目, 然後在項目首頁左上側點選分支按鈕, 彈出的彈層輸入新分支名稱即可;

PS: 上述創建的同名本地分支跟遠程分支並沒建立關聯, 這樣操作指令會比較不方便(如「git pull」指令得輸入對應的遠程分支名), 怎麼讓其建立關聯?

切換到newBranchName分支(如當前處在其他分支):

git checkout newBranchNamen

執行更新代碼指令:

git pulln

就能看到git 的關聯提示:

按照其提示提示執行指令即可:

git branch --set-upstream-to=origin/newBranchName n

git branch --set-upstream-to=origin/<遠程分支名> <本地分支名>如設置當前分支,第二個參數可省略,;

校驗是否關聯成功:

git pulln

提示 「Already up-to-date.」 表示已關聯成功;

2.GIT切換分支;

2.1工作區沒新代碼切換分支:

創建好新分支後就可以在新分支進行開發, 但可能中途需要去維護其他分支代碼;這個時候就得切換分支了,切換分支指令:

git checkout newBranch2n

ps: 編輯代碼不會直接在develop、master分支操作,因為最終代碼要同時合併到這兩個分支上,所以一般均在新分支開發(即使是很小的改動);

2.2工作區有新代碼切換分支:

工作區間的代碼均已提交到本地倉庫(當前分支), 那切換分支沒什麼問題, 但如果工作區域代碼尚未提交,這時切換分支會怎樣呢?

有時候無法切換, 有時候能正常切換;

能正常切換:改動的代碼能正常合併到切換後的分支(自動合併成功)

無法切換:改動的代碼不能正常合併到切換後的分支(自動合併失敗)

工作區間有未提交代碼,切換分支自動執行"git merge"操作,故有衝突將無法切換成功;

當然也會有這樣的場景: 當前分支代碼沒寫完,還不想提交且因為有緊急需求不得不切換分支;這個時候可以 使用「工作現場」將代碼暫時放著:

// 如 直接 "git stash"則將上次commit注釋作為說明ngit stash save "存儲說明"ngit checkout Bn

處理完緊急需求拿出繼續開發:

git checkout Angit stash popn

如果本來想在A分支上開發, 開發過程中才發現當前處在B分支,想強制將工作區間代碼遷到A分支也可以藉助「工作現場」完成:

git stash save "存儲說明"ngit checkout Bn

git stash popn// 如有衝突且處理完所有衝突ngit add -An

2.3切換分支異常處理(windows下)

不少在windows下使用git的同學會碰到這樣的問題: 從A分支切換到B分支由於git異常導致雖然切換分支成功,但在當前B分支上留存了大量A分支的代碼(被git認為是新的改動或新增文件);

這個時候就得用到上一篇博文(git圖解2:git 代碼回退;)知識了!

我們可以將所有改動提交, 然後使用遠程分支代碼覆蓋!放心提交到本地倉庫,反正後面這個commit會被覆蓋。

// 將所有改動提交到本地倉庫ngit add -Angit commit -m "這個commit會被覆蓋"n//B 是當前分支名ngit reset --hard origin/Bn

慣例放圖:

3.GIT合併分支;

3.1正常合併分支代碼

分支代碼合併也有兩方式: 合併本地分支代碼、合併遠程分支代碼;

合併本地分支代碼: 例如在新分支 newBranch開發的功能已完成並已提交;接下來走測試流程需要將代碼合併到develop分支(我所在團隊develop為測試分支,不同團隊的測試分支會不一樣)。

// 切換到develop分支ngit checkout developn// 合併newBranch代碼ngit merge newBranchn// 提交commit到遠程(newBranch分支有多少個commit就會生成幾個)ngit pushn

合併遠程分支代碼: 如果新分支由多人維護,為保證更新代碼為最新,使用上述方式合併分支會比較麻煩:

首先得切換到本地newBranch分支(git checkout newBranch);

然後更新代碼(git pull);

再次切換回develop分支(git checkout develop);

最後才能執行合併操作(git merge newBranch);

其實可直接將遠程的 newBranch分支代碼合併到本地 develop分支:

git pull origin newBranchn

3.2合併代碼衝突解決

無論哪種方式合併分支代碼代碼衝突是無可避免的情況, 開發流程使用了typescript/sass等需要執行編譯的語言更容易產生衝突;

分支合併代碼衝突跟一般代碼衝突一樣: git能處理的衝突會自動解決, 否則就得手動解決衝突;衝突是由於多人維護代碼導致,一定要找到相關人一起討論衝突代碼的取捨;

如果待合併分支代碼跟當前分支前幾次commit修改了同一文件,合併分支就會出現以下提示:

以上提示git自動合併失敗,需要手動解決衝突, 打開衝突文件會發現以下:

"HEAD"到"======="之間為當前分支改動, "======="到">>>>>>> newBranch"為待合併分支的改動;

手動解決衝突後:

告訴git衝突已解決:

git add -An

合併完成,提交代碼:

git commit -m "[master]-合併newBranch代碼"ngit pushn

3.3合併代碼異常處理

同切換分支異常情況, 在windows下合併分支也會出現異常, 異常處理方式同上:

// 將所有改動提交到本地倉庫ngit add -Angit commit -m "這個commit會被覆蓋"n//B 是當前分支名ngit reset --hard origin/Bn

3.4合併代碼減少commit次數(簡潔合併)

在合併分支後使用可視化工具查看代碼提交記錄(或者 "git log" 指令), 有代碼潔癖的同學可能接受不了。如果 newBranch分支開發過程中有10個commit, 那合併完成後(沒產生衝突)也會產生10個commit;如何讓合併代碼後commit更簡潔?

使用"git rebase"合併分支代碼實際開發中會發現"git rebase"執行起來非常麻煩):

rebase,合併的結果好看:清晰、直觀,但合併過程中出現衝突處理比較麻煩(rebase過程中,一個commit出現衝突,下一個commit也極有可能出現衝突,一次rebase可能要解決多次衝突);

merge,合併結果不好看:一堆線交錯,但合併有衝突的話,只要解決一次就行了;

所以建議先"git rebase xxx",如有衝突,"git rebase --abort",再換用"git merge xxx"。

另一方案: 可以合併完成後("git push"之前)編輯commit 信息, 將多個commit合併成一個:

例如: 我再當前newBranch分支提交了三個commit :

執行"git rebase -i"進入交互模式,自動打開vim:

將後兩個「pick」改成(vim模式輸入「i」進入編輯狀態)「s」, 然後保存退出(esc退出編輯狀態,然後":"輸入「wq」保存退出):

保存成功後還有一個編輯vim, 合併commit後,新的commit注釋填寫下,保存退出:

合併完成:

ps: 簡潔合併付出的就是多餘的操作, 實際開發講求的是效率, 所以很多人懶得弄這些(例如我);

4.GIT刪除分支;

git的分支在完成它使命後就沒必要存在了:

上線流程完成:應刪除本地分支及遠程分支(git lab分支): git branch -D xxxx, 上線完成意味著當前xxx分支代碼已經合併到線上分支(master)以及開發分支(develop), 該分支後續功能的改動(bug修復或代碼擴展)完全可以在master新開分支完成;(否則可能遺忘刪除,導致遠程分支原來越多) ----git_tips - [ git常用指令排行榜 ] - 看雲

4.1刪除本地分支

// "-d" 如果該分支代碼未合併到其他分支,將無法刪除;n// "-D" 強制刪除分支,不會出現任何提示;ngit branch -D xxxxn

4.2刪除遠程分支

刪除遠程分支兩種方式:

1.在git管理系統的Web頁面操作(gitLab);

gitHub上無法刪除遠程分支, 如果你團隊使用的是gitLab那可以在gitLab管理頁面操作;

2.本地指令完成;

git push origin --delete newBranchn

參考資料:

git branch官方API文檔

重新組織git本地提交 | yongpoliu.com

git常用指令排行榜

相關文章:

git圖解1:git區域總結;

git圖解2:git 代碼回退;


推薦閱讀:

聊聊GITHUB上的那些小工具01——代碼質量
Android開源項目推薦之「圖片載入到底哪家強」
GitHub 上有哪些好的英文文章或書籍的翻譯項目?
在MSys版的Git中使用git pull --rebase進行代碼更新到底是做了什麼?

TAG:Git | GitHub | GIT项目 |