Git Step by Step (5):Git分支(branch)
在前面兩篇文章中介紹了Git的基本原理,都是理論知識。這篇文章我們再次回到實踐中,看看Git分支(branch)的使用。
在代碼版本控制工具中,都會有branch的概念。剛開始建立版本倉庫的時候,我們只有一個主分支(master branch),我們不可能把日常的新功能開發、代碼優化以及bug修復等概念工作全都放在主分支上,這樣會使主分支很難維護。這就是為什么會有branch。
分支的創建及刪除
分支的創建
在Git中,branch的創建很簡單,我們可以通過下面的命令創建一個”release-1.0″的branch。
然后通過”checkout”命令來切換branch。
在Git中,我們可以通過”git checkout -b”命令來達到同時創建并切換branch的效果。
注意:大家一定還記得第二篇文章中我們通過”checkout”命令來還原WorkSpace中的更新,在還原的命令中我們使用的是”checkout –”,如果沒有”–”就代表切換branch。
根據前面兩篇文章的知識,我們進入”.git/refs/heads”目錄,發現有”HEAD”和”release-1.0″兩個文件,并且兩個文件包含的哈希值相同,根據”git log”可以知道這個哈希值代表master上最新的提交。所以,創建分支后我們會得到下面的關系圖,從值張圖中可以看到,branch的切換對應HEAD引用值的改變。
有了新的branch之后,我們就可以分別在不同的branch上工作了。假設我們現在更新”app.py”,并且在release-1.0 branch上面提交,重新查看對象關系圖。
根據上面的對象圖,可以分析出以下信息:
- “ref/heads/release-1.0″文件內的哈希值將更新為release-1.0 branch上最新的更新
- release-1.0 branch上面的更新不會體現在master branch
經過查看,”ref/heads/release-1.0″文件的內容確實是release-1.0 branch上最新的更新。并且,當我們切換到master branch的時候,所有master上的東西都沒有變化。
分支的刪除
分支的刪除比較簡單,可以使用”git branch -d”命令,為了不影響后面的內容,這里演示新建、刪除dev branch。
分支的合并
branch的創建是為了方便開發、修復bug以及保持master的穩定。但是最終branch上的內容還是要合并到master的,接下來就看看分支的合并。
在Git中,可以通過”Git merge”來合并分支,繼續前面的例子,我們可以把”app.py”的更新merge到master branch上。
這時候,master的HEAD就被更新了,跟release-1.0內容一致了,這些就是merge命令做的事情。
合并沖突
在branch的合并中,很多時候我們會遇到沖突,那么我們就需要手動解決沖突,然后再提交了。
為了演示沖突合并,我們回退master到上一次提交(一定還記得git reset吧),然后同樣更新”app.py”提交到master。
通過上面可以看到,master和release-1.0上同時修改了”app.py”,合并時引起了沖突。在Git中,會用”<<<<<<<”,”=======”,”>>>>>>>”標記出沖突區域,我們需要根據這些符號找到所有的沖突并解決。
沖突解決之后,我們通過”git log”來產看一些結果,但是這次我們要給”git log”加一些參數。
同時,這里給出最新的對象關系圖
branch相關操作
在branch的使用過程中,我們還會經常使用到stash和diff操作,下面分別進行介紹。
stash
在Git中,stash是個很有用的命令,可以保存我們做到一半的工作,可以理解成一個未完成工作的保存區。
假如我們在release-1.0 branch做了一些更新,但是想做的事情還沒有全部完成,不能提交,這是我們又要切換到master branch,這是Git會禁止branch切換。
比如,例子中我們從app.py中刪除”div(16, 4)”。
這個時候我們就需要使用stash來保存未完成的工作了。
如果需要繼續前面的工作,我們可以通過”git stash apply”來還原被保存的工作狀態。
stash空間就像是一個棧空間,每次通過stash保存等內容都會被壓入stash棧。命令不僅僅是支持簡單的list、apply操作,接下來我們看看更多的stash命令。
-
git stash save:可以通過自定義的信息來描述一個stash
- git stash apply stash@{n}:通過這個命令,我們可以選擇stash棧中的stash,從而恢復到特定的狀態;”git stash apply”使用棧頂來還原WorkSpace。
- git stash pop:就像”git stash apply”使用棧頂來還原WorkSpace,但是同時會從stash棧中刪除當前的棧頂stash。
stash工作原理
相信大家都看到了stash的強大,下面我們來看看stash的工作原理。在使用過stash保存之后,我們會發現.git目錄中出現了兩個新文件”.git/refs/stash”和”.git/logs/refs/stash”。兩個文件內容分別如下:
.git/refs/stash
dcac98e565864edc6f636b08660baebe2c97e7d2
.git/logs/refs/stash
0000000000000000000000000000000000000000 dcac98e565864edc6f636b08660baebe2c97e7d2 WilberTian <Wilber***com> 1420201804 +0800 WIP on release-1.0: ed17809 update app.py on release branch
根據我們在對象關系模型那篇文章中學到的內容,我們可以得到以下信息,所以可以看到,stash存放內容也是可以根據對象關系模型一點點找出來。
這里就不提供對象關系圖了,比較復雜,有興趣的同學可以自己畫一個看看各個對象之間的關系。
branch之間的diff
在前面的文章中我們通過diff比較過同一個分支上的內容在WrokSpace、stage和repo中的差別。
同樣diff可以支持分支之間的比較。
- git diff branchName:把當前branch跟branchName進行比較,也可以使用”git diff branchNameA branchNameB”
- git diff branchName — fileName:比較兩個branch的fileName文件差異
總結
通過這篇文章介紹了分支的基本使用,同時介紹了一個非常有用的stash命令。
在使用Git進行代碼控制中,分支是很容易創建的,所以也建議使用分支來進行開發新功能、bug修復。