分支與合併
branch、merge
分支與合併可說是版本管控與協同開發時最需要了解的地方。
儲存庫的目錄樹
觀察主要分支
儲存庫在首次提交之後,預設就會產生一個主要分支,名稱為 master,它是一個指標,指向最新的提交點,另外還會有一個指標稱之為 HEAD,它會指向目前作用的分支,在進行第二次提交時,master 指標會移動到第二個提交點,當然因為目前只有主要分支,所以 HEAD 仍然指向 master,也會跟著移動到第二個提交點。

請注意 master 檔案的內容就是最後一次 commit 的雜湊值(40bit SHA-1)、HEAD檔案的內容就是master 檔案的路徑。 總之每一個分支,都會指向某個 commit 物件,而 HEAD 則會指著某一個分支。
Git 的標籤(tag)功能跟分支很像,差別在於 commit 時,分支指標會自動隨著往後移動,但標籤要手動設定,所以標籤定下來之後就不會再移動,因此分支指標會指向該分支最後一次提交,而標籤指標會指向有特定意義(例如 v1.3版)的提交。
建立分支
透過以下指令就可建立分支 testing,可想像最後一次的提交點上擁有 master 與 testing 二個分支 (指標)
# dir /b ".git\refs\heads" #觀察建立分支前有哪些分支檔
git branch testing
# dir /b ".git\refs\heads" #觀察建立分支後的分支檔案變化

查詢分支
透過以下指令可查詢目前有多少分支存在
git branch # 查詢目前有多少分支
* master # 目前分支 (HEAD指向)
testing
切換分支
透過以下 git checkout 指令就可切換到分支 testing,此時 HEAD 指標改為指向 testing 這個分支
# type ".git\HEAD" # 觀察 HEAD 目前指向的分支
git checkout testing
# type ".git\HEAD" # 觀察切換分支後 HEAD 指向是否有跟著改變
切換分支的同時,會將該分支的工作區一起切換到該分支當時的狀況。
請留意 checkout在此為切換分支的意思,並非取回檔案

建立後同時切換分支
建立與切換分支二行指令,可合併為以下一行
git checkout -b testing
# git branch testing # 建立分支
# git checkout testing # 切換分支
若目前分支與想切換的分支指向不同的提交點,在工作區有檔案異動尚未暫存或暫存區有檔案尚未提交時,是無法切換分支的。
在分支中隱藏封存目前進度(*進階)
若在分支中的工作尚未完成,所以無法 commit ,但又需要暫時切換到其他分支,此時可使用隱藏功能,將受 git 控管的檔案狀態暫時 stash 隱藏封存起來,
git checkout testing # 切到分支 testing
echo changed1>master.txt # 在分支建立檔案
git stage .
git commit -m "testing change1" # 在分支提交一次,
echo changed2>>master.txt # 在分支修改檔案
git checkout - # 切換到前一個分支(master),但會失敗

git stash # 將分支的工作區與暫存區檔案隱藏封存下來
git stash list
git checkout - # 切換到前一個分支(master),會將工作區與暫存區的檔案也一起還原
dir # 所以在前一個分支中找不到 master.txt
git stash pop # 叫回隱藏的進度
在分支提交
因為已經切換到 testing 分支,接下來透過以下指令提交
echo changed>testing.txt
git stage .
git commit -m "first commit on testing branch"

切換回主要分支
透過以下指令可切換回 master 分支,但此時請注意 HEAD 指標移動時會造成工作目錄的檔案內容改變,因此在 testing 分支增加的檔案,在切換到 master 分支後會看不見,因此若在 testing 分支中有檔案增修過但沒有提交(commit) 或隱藏(stash) 時,就不能夠切換分支(移動 HEAD)。
git checkout master
dir # 會發現工作目錄看不到 testing.txt

在主要分支提交
透過下列指令在主要分支提交時,此時產生的 commit 節點就是獨立的一條路徑了,未來可以在不同的分支切換,之後等 testing 的工作完成後,再合併回 master
echo changed>master.txt
git stage .
git commit -m "new change"

參考網頁
Last updated