上一節講了如何和遠端的倉庫協同工作,這一節介紹一下分支
————————————————————————————
提要
//創建一個分支dev
$ git branch dev
//切換到dev分支
$ git checkout dev
//創建並切換到dev2分支
$ git checkout -b dev2
//查看當前的分支列表
$ git branch
//合並dev2分支到當前分支
$ git merge dev2
//刪除dev2分支
$ git branch -d dev2
//查看gitlog,以圖標形式,單行展示,版本號縮寫
$ git log --graph --pretty=oneline --abbrev-commit
一、創建分支、合並、刪除
之前的小節里,我們講到的分支都只有master只一個默認分支,使用分支的場景如下:
你想做一個A功能,但還有一個B功能也需要你開發。這兩個功能哪個先做完就要先提交不能相互影響;如果你在master分支上同時進行開發,AB功能之間會互相影響,只等你等到你把兩個功能都開發完之后才能提交;這時就需要用到分支來解決這個問題,一個A分支用來開發A功能,一個B分支用來開發B功能,哪個先開發完把那個分支合並到master,這樣不僅可以做到同時開發,還能不互相影響。
之前講到版本回退的時候用到指令git reset --hard HEAD^,其中這個HEAD就是一個指向master分支的指針,其實master也是一個指針,它才真正指向當前的分支。
每次對master的commit都會有一個記錄,這些記錄會連成一條線;如果此時創建一個分支dev,則dev會指向當前的提交,並且HEAD指向了dev。
當我們在dev分支開發完成了一個提交,此時dev分支會指向新的提交,而HEAD依然指向dev。
加入dev的工作完成了,就可以把dev合並到master,然后銷毀dev
以下上指令:
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
先創建一個分支,然后切換到新的分支,這里的checkout和之前撤銷工作區修改的命令相同,只是少了--
可以用1條命令代替以上2條命令
$ git checkout -b dev2
Switched to a new branch 'dev2'
$ git branch
dev
* dev2
master
-b就代表創建並切換,使用git branch指令可以查看當前所有的分支,前面有*表示當前所在的分支
現在我們在新的dev2分支上做修改,add並commit一次修改后,再切換回master
$ git add .
$ git commit -m "dev2 commit"
[dev2 1c6205f] dev2 commit
1 file changed, 2 insertions(+), 1 deletion(-)
$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
你會發現你剛才的修改不見了~因為剛剛的修改提交在了dev2分支,master是沒有的,現在把dev2合並到master
$ git merge dev2
Updating 175d6f5..1c6205f
Fast-forward
testgit.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
git merge dev2 這句指令是在master分支時敲的,表示將dev2分支合並到當前分支,合並只會將新的提交合並到老的提交,將時間軸靠后的合並到時間軸靠前的;這里的Fast-forward表示合並是快進模式,直接將指針指向了最新的分支,現在master和dev2一致了,如果dev2不再使用,可以刪除
$ git branch -d dev2
Deleted branch dev2 (was 1c6205f).
二、分支的沖突解決
剛剛提到的使用分支的場景,是同時修改兩個功能,難免修改中我們修改了同一個文件,這時想把兩個分支合並在一起,就會產生沖突
例如,我們先在master分支上修改testgit.txt文件,然后add、commit
再切換到dev分支,同樣修改testgit.txt文件,然后add、commit
切回master分支,合並dev到master,這時會出現沖突
//修改master文件
$ git add .
$ git commit -m "master modify"
[master 7160ae0] master modify
1 file changed, 3 insertions(+), 1 deletion(-)
//切換分支,修改dev文件
$ git checkout dev
Switched to branch 'dev'
$ git add .
$ git commit -m "dev modify"
[dev 217c01e] dev modify
1 file changed, 3 insertions(+), 1 deletion(-)
//切回master,合並dev到master
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
$ git merge dev
Auto-merging testgit.txt
CONFLICT (content): Merge conflict in testgit.txt
Automatic merge failed; fix conflicts and then commit the result.
此時testgit.txt文件會變成這樣,同時展示master的修改和dev的修改,然后待你解決沖突
Git用<<<<<<<,=======,>>>>>>>標記出不同分支的內容,我們修改如下后保存:
解決沖突后要進行add、commit操作,解決沖突的代碼才會被提交到master,此時dev分支還是只有dev的修改,而master已經是解決沖突后的狀態了。如果dev不用了,可以將其刪除;或將master同步到dev,這時不會再有沖突
我們可以通過log來查看分支的合並情況
$ git log --graph --pretty=oneline --abbrev-commit
* ddfb691 (HEAD -> dev, master) conflict
|\
| * 217c01e dev modify
* | 7160ae0 master modify
* | 1c6205f (origin/master) dev2 commit
* | 175d6f5 init
|/
* 1f79d9c Merge branch 'master' of github.com:ls199242/DemoRepo
|\
| * 95a3e58 Initial commit
* a472776 commit testgit.txt
* e8c7ff0 delete test.txt
* 499094d test commit
* e6ded21 test commit2
* a50498c test commit,2 files is commited
* 81a320c readme file
這是從我創建版本庫以來的所有log,指令里面graph表示用圖形展示合並歷史,pretty=oneline表示只展示一行,abbrev表示版本號展示縮寫。95a3e58 這個版本是和遠程倉庫創建時候的記錄;ddfb691這一次是沖突那一次的提交