分支與合併

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