GIT分支

本節指令
git branch
git checkout
git checkout -b
git branch -d
git branch -D
git reflog

當有多人同時進行開發,或是做實驗性的功能coding時,或是臨時有bug要處理,又不想放下手邊開發的流程,此時可以另開分支,來發揮GIT強大的合併追蹤能力。
不要害怕分支,也不要害怕改到同一個檔案而造成衝突(conflict),只要事前做好規畫,慢慢累積經驗一定會愈來愈厲害,希望我們有朝一日也能開出這麼漂亮的分支圖(gitignore)

一、分支建立、切換

請先建立本單元的工作環境:

mkdir branch1
cd branch1
git init
echo 1 > file1.txt
echo 1 > file2.txt
git add file1.txt
git commit -m "C1"
git add file2.txt
git commit -m "C2"

查看目前分支只要下branch即可,星號表示目前分支:

    git branch
    *master

若要在master另開分支,例如要開feature分支,做法是:

    git branch feature

建好後,要切換至新的分支上,用checkout指令就好了:

    git checkout feature

此時再下一次查看分支的指令,就可以看到星號指向feature了:

    git branch

其實還有更快的指令:

git checkout -b feature

這個指令包含建立分支及切換分支,所以一個指令等同於兩個指令

【git checkout -b feature】 = 【git branch feature】 + 【git checkout feature】

看一下分支圖,此時兩分支皆指向C2這個commit:

二、不同分支進行作業

接著我想在feature分支建一個file3.txt檔案,並且提交(commit)

echo 1 > file3.txt
git add .
git commit -m "C3"

接著又在feature分支建file4.txt檔,並且提交(commit)

echo 1 > file4.txt
git add .
git commit -m "C4"

此時的分支圖,想像一下長什麼樣子呢?

有沒有發現,這兩個分支已經漸漸分開了,而且master還停留在C2這個commit上。

接下來我們要換分支做事情了,先切換到master分支,接著建立file5.txt和file6.txt,並分別提交C5C6兩個版本,自己試看看吧!

git checkout master
echo 1 > file5.txt
git add .
git commit -m "C5"
echo 1 > file6.txt
git add .
git commit -m "C6"

做好之後,一樣想像一下分支圖長什麼樣子???

看答案吧!哇!總算看到「分支」了:

再來要考考大家了,如果將分支切換到master,此時開啟資料夾,你覺得會有哪些檔案呢?

再切換至feature分支,此時資料夾裡面又有哪些檔案呢?

切至master分支的檔案如下:

file1.txt、file2.txt、file5.txt、file6.txt

切換至feature分支的檔案如下:

file1.txt、file2.txt、file3.txt、file4.txt

有沒有看到GIT版控的強大啊!只要切換到該分支,就會馬上呈現出當時版本的檔案內容,而且切換的時間超短,即時你的檔案很多,切換速度也是粉…快喔!

來解釋一下,為什麼這兩個分支的檔案會變成這樣呢?做個比喻好了,你可以把每個分支想像成不同的水流:

水流的上游在左邊,下游在右邊,由左往右流。

分支的提交(commit)較早在左邊,較晚在右邊,時間由左往右推進。

先看master,從下游往上回溯,此條流水經過:

file1.txt、file2.txt、file5.txt、file6.txt

再看feature,從下游往上回溯,此條流水經過:

file1.txt、file2.txt、file3.txt、file4.txt

所以此兩分支的檔案才會長成這樣子囉!

再舉個例子,請能說出下圖不同分支所包含的提交(commit)嗎?

更多範例:用分支進行開發的工作流程

三、分支刪除

刪除分支的指令為branch -d,例如要刪除feature分支,記得要跳出此分支,總不可能自己刪自己吧:

git checkout master
git branch -d feature

結果刪不掉,怎麼回事?來看一下錯誤訊息:

原來GIT怕你誤刪,如果此分支尚未和別的人支合併,是無法直接刪除的,必須透過branch -D強制刪除:

git branch -D feature

這樣就刪除成功了!

那再問一個問題,C3C4這兩個commit還在嗎?

git log --oneline

打開sourceTree看一下:

C3C4不見了,疑?之前在2-1節曾說過,刪除分支並不會刪掉提交(commit)啊!怎會這樣呢?
其實C3C4還在,只是「隱藏」起來罷了,我們來施點魔法找出來吧!

git reflog
git checkout [C4的SHA1值]
git checkout -b feature

再去看sourceTree的分支圖,是不是又長出來了啊!

在上圖中,可以發現有一個detached HEAD訊息,表示你的工作目錄並不是在
最新版本上。原來GIT會自動建立一個HEAD指標,這個指標會指向目前分支的最新版本

另一個作法:

git reflog
git branch feature [C4的SHA1值]

其實在GIT裡開分支只是多一個指標而已,這個指標會指向該分支的最新Commit,
這個分支名稱儲存在.git\refs\heads中,打開feature可看到一串SHA1值表示此分支。
若要刪除分支,甚至只要把.git\refs\heads\feature刪除就搞定,
要復原只要再把這個feature檔再放回來即可,
因此開分支只是多了一個檔案,非常節省檔案資源,不要再把分支想得那…麼可怕了。

另一個較簡單的作法,直接在tortoiseGit操作:

    我懶得寫詳細操作了…大家仔細聽我示範吧(側耳…)

PS.做到檔案亂七八糟嗎?來…來…來…這帖服用下去,砍掉重練(請分三次複製貼上喔):

mkdir branch1
cd branch1
git init
echo 1 > file1.txt
echo 1 > file2.txt
git add file1.txt
git commit -m "C1"
git add file2.txt
git commit -m "C2"
------------------------------
git checkout -b feature
echo 1 > file3.txt
git add .
git commit -m "C3"
echo 1 > file4.txt
git add .
git commit -m "C4"
------------------------------
git checkout master
echo 1 > file5.txt
git add .
git commit -m "C5"
echo 1 > file6.txt
git add .
git commit -m "C6"

四、分支圖反解

接著我們來看圖說故事。如果看懂分支圖,進而模仿做出一樣的分支圖,表示你快出師啦!

【Ex-301 分支圖練習】

【Ex-302 分支圖練習】

【Ex-303 分支圖練習】

results matching ""

    No results matching ""