上篇介紹關於分支的常用指令,那麼這篇讓我們好好了解分支是什麼吧!
分享我最初聽到「分支」時,我的理解是:
在原有的支線上,另闢一條新的支線,然後把內容移過去,之後新增的 Commit 都會在這分支上,當分支移除後 Commit 也跟著刪除,整個動作都著重在分支的變化影響 Commit 的去留,而不是 Commit 本身的內容,其實這是一個錯誤的理解喔!或許看到這裡你會覺得我在鬼打牆?繞口令?反而更加對分支毫無頭緒。
沒關係!我們可以先記住一個觀念,它將會貫穿之後介紹分支時每個動作的原理。
✏️ 分支只是一個指向某個 Commit 的指標,即使刪除分支,也不會影響 Commit 的內容。
在 Git 的世界裡,分支並不是透過複製得到相同的目錄跟檔案後進行修改,修改完畢後再合併把更新之後的檔案放回原本的目錄。
其實分支只是方便讓我們了解現在的檔案是跟原本的流程分開,不受其他分支影響,他就是一個「指標」,告訴我們現在所在位子,而不會影響內容本身。
也許我們可以把分支想像成路線名稱牌號,而 HEAD 想像成自己的定位系統 ...
分支 - 路線名稱指標
HEAD - 定位指摽(當前所在位子)
看看分支的與 Commit 之間的關係變化|
簡單的一個分支情境:
Commit / master / HEAD 基本關係
HEAD 現在在 master 支線上
假設新增了一次新的 Commit 之後,新的 Commit 會指向前一個 Commit
想像我們現在抵達下一站 Commit ,這個 Commit 位於 master 分支路線上,而我們 HEAD 也表示我們在 master 這條支線。
新增的 Commit 指向前一個 Commit 之後,HEAD 與 mater 同時跟著前進。
多個分支情境:
在原先的 Commit 上透過指令又多了一個新的分支。
$ git branch one # 新增一個 one 分支
將此 Commit 多新增一個路線指標給它,此時會有 master 與 one 兩個分支同時貼在同個 Commit 上。
執行切換分支指令到 one 分支,此時 HEAD 也會跟著換成 one 分支。
$ git checkout one # 切換到 one 分支上
依照比喻可以想像成我們準備在同一個 Commit 站上,要走向 one 指標路線,HEAD 告訴我們現在在哪個分支上。
接著我們在 one 的分支上,又新增一個 Commit,此時這個新的 Commit 會指向前一個 Commit。
小提醒: HEAD 通常會指向最新的 Commit
看完上述範例,應該對分支有點概念了吧?接下來就讓我們了解,當我們切換分支時,有什麼事情變化呢?
當我們切換分支時, Git 做了兩件事:
更新暫存區以及工作目錄 |
當 Git 切換分支時,會從當前的 Commit 的內容來「更新」暫存區以及工作目錄。
範例:
假設我在 one 分支上新增了 hello1.html 、 hello2.html 兩個檔案,那麼此時 commit 的內容會拿來更新暫存區與工作目錄。
後續 commit 提交後,又新增了 hello3.html 檔案,並再提交一次,總共提交了兩次。
兩次 Commit 的 SHA-1 值分別是:4f18d8b 、 dba939f
查看一下 Git 紀錄:
$ git log --oneline # 查看紀錄
可以看到 one 分支比 master 分支多了兩次 commit 紀錄。
按下
q
按鍵,即可退回原畫面。
接著查看一下在 one 分支的時候,檔案列表會長怎麼樣:
可以看到先前兩次新增的三個檔案都有在內。此時的工作目錄:
改切回 master 分支,並查看檔案列表:
$ git checkout master # 切換到 master 分支
$ ls -al # 查看檔案列表
切回 master 分支後,此時 master 分支的 Commit 並沒有先前的三個檔案。
這時的工作目錄:
檔案不見了嗎?並不是唷!它依然存在,只是在 one 分支上而已,只要切回 one 分支後,檔案就會再出現了。
從上面的範例操作,試著思考當我們切換到 master 分支的時候,one 分支 commit 的東西從本地端的工作目錄上畫面不見了,這樣是代表被刪掉了嗎?
答案是沒有的,他依然會存在工作目錄上,即使我們切回 master 分支,先前所做的 commit 更新會留在工作目錄不被受影響。只是在 master 分支上的 Commit 的工作目錄並沒有這個內容的存在。
👉 觀念:切換分支之前的修改依然會留在工作目錄,不受影響。
補充複習:在 Git 世界裡, 每新增一次 Commit 就相當新增一個物件,而他會指向某個 Tree 物件(目錄)。
變更 HEAD 的位置 |
先前的範例可以發現,當我們切換分支時,HEAD 也會跟著移動,指向當前的 Commit。這個動作同時也會修改 .git/HEAD 中的檔案。
總結:
Git 切換分支的時候,會使用此分支所指向的 Commit 來更新暫存區與工作目錄。即使切換分支後,先前的修改動作依然會留在工作目錄中,不被受影響。