從什麼都不懂開始(三) 實踐帶你飛之Branch操作
本篇將介紹一下Git中經常需要操作到的東西,以及專案中運用到的場景,會稍微帶一點基礎知識,筆者覺得阮一峰老師的Git入門講的非常到位了,我就不班門弄斧了,就講一下專案中遇到的一些情況。若是Git大牛就可以點選返回或者關閉啦~
此文多圖預警~用流量的童鞋注意哦。
Repository介紹
在版本管理中,Repository翻譯成中文就是倉庫的意思,每個提交到本地,或者push到遠端伺服器的Project,被Git以資料結構的形式儲存,而這個資料結構被稱之為Repository即倉庫。
對於我們來說,在Repository中,我們看的見的顯示資訊就是程式碼,而其他的比如分支資訊、Commit資訊、Status這些狀態則通過命令列去檢視。
Branch介紹
當我們多個人合作開發的時候,為了方便管理程式碼,會每個組開一個Branch,而master稱為主分支——主幹,這些Branch則稱為分支。
檢視當前分支
在命令列輸入git branch
就可以看到當前分支為master :
輸入git branch -a
可以檢視本地和遠端所有分支
切換分支
初始化Git後,當前預設在master分支,這個時候如果你想新建一個分支,可以執行 git branch [branchName]
後面的[branchName]是指你的分支名。這樣就能把master當前的commit資訊’拎’出來,成為了一個新的分支。
執行完branch命令後,你會發現你還是在原來的分支上,在master前有一個*號表示當前分支是master,這個時候執行以下 git checkout [branchName]
。
其實呢,你可以執行
git checkout -b [branchName] [fromBranchName]
生成新的Branch,後面這個[fromBranchName] 就是你想要從哪個分支生成新的分支,不寫則是當前分支。
HEAD資訊
為什麼要在這裡講HEAD呢,那HEAD又是什麼呢,其實HEAD可以理解成一個指標,每次都是指向當前Branch的最後一次資訊(可以是Commit或者Pull之類的),通過移動HEAD來達到切換分支的作用。
如果當前分支在master,那麼HEAD資訊如下:
真實測試效果:
在checkout到BranchC的時候變成了如下圖所示:
真實測試效果:
合併分支
當你的專案上線後,發現有個bug,這個時候需要在master分支上checkout -b
一個新的分支用來修bug,那麼這個bug分支上的程式碼,最後怎麼給’整’到master上去呢。很簡單先切回master分支,然後git merge bugBranch
就好了。
衝突
當你merge的時候出現了
$ git merge myBranch
Auto-merging AndroidManifest.xml
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
這個時候會提示你有程式碼衝突,那麼你需要執行git status
,檢視當前檔案哪些需要解決衝突。解決完再提交就好了。筆者很喜歡用AndroidStudio自帶的git進行合併等操作,可以直接在Compare檢視上解決衝突,非常方便。
這個時候回發現 <<<<<<<<<< HEAD
到 ========
是當前所在分支的內容,下面從 =======
到 >>>>>>>> fixBug
是合併過來的分支,解決完,再執行git add .
然後就可以提交啦。
接下來為大家看一下編譯器的merge:
選擇分支:
衝突提示:
衝突比較 :
rebase
rebase和merge的功能其實是一樣的,都是合併程式碼,只是對於修改資訊的節點會發生變化,rebase和merge最大的區別就是在最後的程式碼樹上,有興趣的同學可以用SourceTree看看,或者直接在命令列輸入gitk。
當前工作狀態,箭頭表示上一次資訊:
執行merge後:
執行rebase後
之所以會有5-1,6-1就是和原來的commit是不同的,算是一次新的commit了。
簡而言之就是rebase的程式碼會比merge的乾淨許多。rebase會保留你合併的順序,而merge則會按照你的修改時間排序。筆者有點強迫症,會使用rebase(搞基),另外一些圖方便的人喜歡merge(合體)。
另外值得注意的是,在rebase前,千萬別push,不然等rebase完畢後,因為tree發生了變化,會提示push reject,意味著你需要 git push --f
才能提交了,這是有風險的!!!注意安全!!!
比如branch要reabse onto master,那麼會比較兩個分支的最近的共同節點,再根據master提交的節點生成一系列不同的檔案,最後在branch上針對每個提交將之前不同的檔案去合併,並且生成新的commit節點
,這時rebase完畢後branch的tree已經和rebase前的branch tree完全不一樣了,所以在rebase前你push過後,rebase後再push會提示不是同一個tree而reject(拒絕)
提交。
下面是AndroidStudio上的rebase操作:
想要從哪個分支rebase到當前分支,就選擇哪個Rebase on
:
stash
當你想切換分支時,又不想提交當前程式碼,那就需要stash啦,簡單的意思就是講你當前的修改資訊全部暫存起來,放進一個stack棧中,這個時候你就可以checkout到別的分支啦。下次再回來的時候
git stash pop
就好了。
這個時候Leader轉頭對我說:XXX模組程式碼我提交了,你拉一下程式碼,我改了你可能要用到的東西。
這個時候我對著一螢幕的藍色提示,心想:不能commit把,都沒測試過。這個時候就用到stash
這個神器了。
沒有提交檔案,本地修改過的檔案會顯示藍色:
專案裡有幾個檔案都沒有提交,只能選擇專案根目錄,右擊,選擇stash:
會彈出一個stash的彈出框,會顯示當前分支,填入message:
點選createStash後,建立一個當前的stash,可以點選剛剛的StashChanges下面的UnstashChanges檢視當前的stash列表:
或者在命令列輸入git stash list
檢視當前的stash棧:
好啦,當前的工作全部都暫存起來了!要把剛剛Leader放到master的程式碼都合併過來啦!我選擇的當然是rebase啦。在這之前必須得把伺服器的master程式碼pull到本地是不是,先切換到master,然後還是選擇編譯器的git,在剛剛stash介面下面有個pull
。點選pull彈出一個介面,選擇master分支:
點選pull就能拉下程式碼啦,如果有衝突也能借助編譯器的compare進行合併啦。
pull完程式碼後,要reabse啦:
按照步驟來,1、點選當前分支,選擇要rebase的目標分支,點選後選擇Rebase onto
就可以執行rebase啦,rebase過程中發現出現了一個衝突:
和前面的merge一樣,選擇在這裡解決衝突:
這個時候master的程式碼就過來啦,然後再把之前修改的程式碼拿出來繼續工作:
pop完後可以繼續快樂的工作啦:
在這裡說明一下紅色
的檔案表示沒有add,綠色
檔案表示add過了但是沒有commit,藍色
檔案表示修改過,和遠端的分支程式碼不一樣,綠色和藍色的檔案執行stash會被暫存,而紅色的不會。
拓展
如果對Git原理有興趣的同學,可以自己再去深入研究一下Git,很多東西雖然平時用不到,但是又很有深度。大家按興趣就好啦
總結
一邊寫部落格,一邊翻閱資料,自己也又溫習一遍,接下來打算繼續深入下去,下一篇將會講幾個指令的原理,以及git物件之類的。最近比較忙,需要用點心去學習,也會把自己遇到的場景儘量告訴大家,讓大家能接觸到更多的實際場景,努力把這個系列寫的更乾貨一些!
其實AndroidStudio能覆蓋大多數的使用場景了,下一篇將會說一些revert、reset,當發生錯誤提交時,怎麼回滾程式碼。
最近大帥的開了個QQ實踐群(568863373),歡迎大家一起討論,也可以關注我們的公眾號:魔都三帥