內(nèi)容簡介
- 分支簡介
- 創(chuàng)建分支
- 查看分支
- 切換分支
- 分支合并
- 刪除分支
- 分支管理
- 遠程分支
分支簡介
為了真正理解 Git 處理分支的方式,我們需要回顧一下 Git 是如何保存數(shù)據(jù)的。
Git 保存的不是文件的變化或者差異,而是一系列不同時刻的文件快照。
在進行提交操作時,Git 會保存一個提交對象(commit object)。知道了 Git 保存數(shù)據(jù)的方式,我們可以很自然的想到——該提交對象會包含一個指向暫存內(nèi)容快照的指針。 但不僅僅是這樣,該提交對象還包含了作者的姓名和郵箱、提交時輸入的信息以及指向它的父對象的指針。首次提交產(chǎn)生的提交對象沒有父對象,普通提交操作產(chǎn)生的提交對象有一個父對象,而由多個分支合并產(chǎn)生的提交對象有多個父對象。
Git 的分支,其實本質(zhì)上僅僅是指向提交對象的可變指針。 Git 的默認分支名字是 master。 在多次提交操作之后,你其實已經(jīng)有一個指向最后那個提交對象的 master 分支。 它會在每次的提交操作中自動向前移動。
創(chuàng)建分支
創(chuàng)建分支其實就是在當(dāng)前分支的提交快照中創(chuàng)建一個可以移動的新的指針。創(chuàng)建分支使用git branch [分支名],比如我們創(chuàng)建一個flowers分支。
$ git branch flowers
執(zhí)行這個命令,我們就創(chuàng)建了一個名字為flowers的分支。如何知道我們是否已經(jīng)創(chuàng)建了這個分支呢?
查看分支
查看分支使用如下命令:
$ git branch
結(jié)果如下:

從上圖我們看出,我們看到目前有兩個分支。一個是我們
git init的時候默認的分支master,一個是我們新創(chuàng)建的分支flowers。分支名稱前面的*代表我們當(dāng)前所在的分支。其實關(guān)于如何辨別當(dāng)前分支的方法,還有一個是查看HEAD指針的指向,執(zhí)行git log --oneline --decorate命令,結(jié)果如下:

從結(jié)果我們可以看出HEAD指針指向的是master,說明我們當(dāng)前所處的分支就在master分支。
切換分支
我們創(chuàng)建了flowers分支,但是Git并不會自動給我們切換到所創(chuàng)建的分支上。執(zhí)行git checkout [分支名]命令可以切換分支。
$ git checkout flowers

執(zhí)行git checkout -b [分支名]可以完成上面兩步的操作,1.創(chuàng)建分支2.切換到該分支。
查看分叉歷史
我們切換到flowers分支,并在此分支上面做些修改并提交,然后執(zhí)行下面的命令,我們可以看到:
$ git log --oneline --decorate --graph --all

從圖中我們可以看出,master分支和flowers分支所對應(yīng)的提交快照的SHA值不一樣,說明它們對應(yīng)的不同的提交。
現(xiàn)在我們再切換回master分支,并在此分支上面做些修改并提交,然后執(zhí)行上面同樣的命令,結(jié)果如下圖:

分支合并
分支合并的情況有兩種:
- 快進式(Fast-forward),就是簡單的指針向前移動。
- 遞歸式(recursive),就是三個快照的合并。
下面分別對這兩種情況來說明。
快進式
我們在master分支的基礎(chǔ)上新建立一個tree分支,然后在tree分支上面做些修改并提交,最后回到master分支,然后將tree分支里面的修改合并到master中。
$ git co -b tree
$ vi tree_test
$ git add tree_test
$ git ci -m "tree add tree_test"
$ git co master
$ git merge tree

命令git merge tree是將目標(biāo)分支tree合并到當(dāng)前分支master。
從最后的結(jié)果(Fast-forward)我們可以看出master指針只是向前移動了,指針移動到了tree分支所提交的快照指針處。
遞歸式
遞歸式合并的意思就是,如果你在創(chuàng)建一個新分支flowers后又回到master分支做了修改并提交。然后,此時你想把flowers分支合并到master分支上。因為此時,master分支和flowers分支它們有一個共同的祖先,所以這種合并會將兩個分支的末端和它們的共同祖先一起比較,最后生成一個新的快照并提交。

由于我們之前創(chuàng)建的flowers分支就是這樣的操作,所以我們省去了很多步驟。從結(jié)果(recursive)我們可以看出就是這種三方合并。
刪除分支
分支合并結(jié)束并確保分支已經(jīng)沒有必要存在的時候,就可以將分支刪除了。git branch -d [分支名]命令刪除分支。
$ git branch -d tree

刪除分支可能遇到分支不能刪除的情況。原因一種可能就是你的分支的修改內(nèi)容沒有同步到master分支,另外一種可能就是你刪除的分支是在當(dāng)前的分支(被刪除的分支不能是當(dāng)前分支)。
沖突解決
合并有時候并不是那么一帆風(fēng)順的,如果遇到?jīng)_突了怎么辦。如下:

此時 Git 做了合并,但是沒有自動地創(chuàng)建一個新的合并提交。 Git 會暫停下來,等待你去解決合并產(chǎn)生的沖突。 你可以在合并沖突后的任意時刻使用
git status命令來查看那些因包含合并沖突而處于未合并(unmerged)狀態(tài)的文件:

從提示中我們可以看出Git給了我們兩種方式。1.修復(fù)沖突文件,然后提交;2.運行git merge --abort 中止本次提交。
我們使用第一種來解決問題。首先查看一下沖突的文件:

=======這個分隔開的上下兩部分分別是當(dāng)前分支HEAD(master)和合并時的目標(biāo)分支road對應(yīng)的該文件的修改。此時,我們可以手動修改這個文件的內(nèi)容,然后把對應(yīng)不需要的內(nèi)容刪除(<<<<<<< HEAD 和 >>>>>>> road 以及 =======這三行的內(nèi)容),最后保存,然后提交即可。
分支管理
git branch參數(shù)說明
-v
如果需要查看每個分支的最后一次提交,可以運行git branch -v

--merged
這個參數(shù)可以查看哪些分支已經(jīng)合并到當(dāng)前分支

--no-merged
這個參數(shù)可以查看哪些分支沒有合并到當(dāng)前分支

遠程分支
查看遠程庫信息
$ git remote

獲取詳細的遠程庫信息
$ git remote -v

從圖中看出,我們可以抓取和推送的origin的地址。如果沒有推送權(quán)限,就看不到push的地址。
推送分支
推送分支,就是把該分支的本地提交都上傳的遠程庫。推送時,要指定本地分支,這樣,Git就好把該分支推送到遠程庫對應(yīng)的分支上。
$ git push origin road

抓取分支
如果你是運行git clone [url]獲取到的倉庫的時候,本地只有只有一個master分支。你可以運行git branch命令查看。如果你想獲取其他的分支,那么需要主動去獲取遠程分支到本地。
$ git co -b dog origin/dog

從圖中我們看出獲取失敗了,這個是因為獲取的遠程分支不存在導(dǎo)致的。

從圖中我們可以看出,我們獲取到了遠程分支road并且從master分支切換到了road分支
然后我們更新該分支的某個文件內(nèi)容,然后提交并推送到遠程庫中。

這是如果另外一人也修改了該分支的相同文件的相同代碼行。此時如何這個人提交的話,那么就會出現(xiàn)推送失敗,因為發(fā)生了沖突。

如果發(fā)生這樣的情況,那么我們可以根據(jù)提示,運行git pull命令,把遠程庫該分支的最新的提交給下載到本地。

此時發(fā)現(xiàn),Git提示我們沒有本地的road分支與遠程的origin/road分支的鏈接,再次失敗了。解決這個失敗的方法有兩種:1.git pull <remote> <branch>把遠程分支下載到本地,然后關(guān)聯(lián);2. git branch --set-upstream-to=origin/<branch> road關(guān)聯(lián)本地分支到遠程分支。第二種情況需要再運行git pull才可以把遠程庫該分支最新的內(nèi)容下載到本地。所以我采用第一種方法:

此時我們發(fā)現(xiàn)又沖突了,這個時候就像解決分支沖突一樣去解決這個沖突就可以了。