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,並分別提交C5
、C6
兩個版本,自己試看看吧!
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
這樣就刪除成功了!
那再問一個問題,C3
、C4
這兩個commit還在嗎?
git log --oneline
打開sourceTree看一下:
C3
、C4
不見了,疑?之前在2-1節曾說過,刪除分支並不會刪掉提交(commit)啊!怎會這樣呢?
其實C3
、C4
還在,只是「隱藏
」起來罷了,我們來施點魔法找出來吧!
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 分支圖練習】