iT邦幫忙

2021 iThome 鐵人賽

DAY 20
2
Modern Web

【Git】從零開始學習 Git - 30 天的學習筆記系列 第 20

Day20|【Git】介紹分支觀念與切換分支指令動作

上篇介紹關於分支的常用指令,那麼這篇讓我們好好了解分支是什麼吧!

分享我最初聽到「分支」時,我的理解是:

在原有的支線上,另闢一條新的支線,然後把內容移過去,之後新增的 Commit 都會在這分支上,當分支移除後 Commit 也跟著刪除,整個動作都著重在分支的變化影響 Commit 的去留,而不是 Commit 本身的內容,其實這是一個錯誤的理解喔!或許看到這裡你會覺得我在鬼打牆?繞口令?反而更加對分支毫無頭緒。

沒關係!我們可以先記住一個觀念,它將會貫穿之後介紹分支時每個動作的原理。

✏️ 分支只是一個指向某個 Commit 的指標,即使刪除分支,也不會影響 Commit 的內容。

分支只是一個「指標」

在 Git 的世界裡,分支並不是透過複製得到相同的目錄跟檔案後進行修改,修改完畢後再合併把更新之後的檔案放回原本的目錄。

其實分支只是方便讓我們了解現在的檔案是跟原本的流程分開,不受其他分支影響,他就是一個「指標」,告訴我們現在所在位子,而不會影響內容本身。

也許我們可以把分支想像成路線名稱牌號,而 HEAD 想像成自己的定位系統 ...

分支 - 路線名稱指標

HEAD - 定位指摽(當前所在位子)

看看分支的與 Commit 之間的關係變化|

簡單的一個分支情境:

  1. Commit / master / HEAD 基本關係

    https://ithelp.ithome.com.tw/upload/images/20211002/20141010qu21S8ZlVJ.png

    HEAD 現在在 master 支線上

  2. 假設新增了一次新的 Commit 之後,新的 Commit 會指向前一個 Commit

    https://ithelp.ithome.com.tw/upload/images/20211002/201410108P8uYH72WK.png

    https://ithelp.ithome.com.tw/upload/images/20211002/20141010GAc0nYRHCY.png

    想像我們現在抵達下一站 Commit ,這個 Commit 位於 master 分支路線上,而我們 HEAD 也表示我們在 master 這條支線。

    新增的 Commit 指向前一個 Commit 之後,HEAD 與 mater 同時跟著前進。

多個分支情境:

  1. 在原先的 Commit 上透過指令又多了一個新的分支。

    $ git branch one # 新增一個 one 分支
    

    https://ithelp.ithome.com.tw/upload/images/20211002/20141010uqt3P0wKrh.png

    將此 Commit 多新增一個路線指標給它,此時會有 master 與 one 兩個分支同時貼在同個 Commit 上。

  2. 執行切換分支指令到 one 分支,此時 HEAD 也會跟著換成 one 分支。

    $ git checkout one # 切換到 one 分支上
    

    https://ithelp.ithome.com.tw/upload/images/20211002/20141010usVFggtKf1.png

    依照比喻可以想像成我們準備在同一個 Commit 站上,要走向 one 指標路線,HEAD 告訴我們現在在哪個分支上。

  3. 接著我們在 one 的分支上,又新增一個 Commit,此時這個新的 Commit 會指向前一個 Commit。

    https://ithelp.ithome.com.tw/upload/images/20211002/20141010LmTQiwJK2e.png

    https://ithelp.ithome.com.tw/upload/images/20211002/20141010HYZ41Wr8u3.png

    小提醒: HEAD 通常會指向最新的 Commit

看完上述範例,應該對分支有點概念了吧?接下來就讓我們了解,當我們切換分支時,有什麼事情變化呢?

當我們切換分支時, Git 做了兩件事:

  1. 更新暫存區以及工作目錄
  2. 變更 HEAD 的位置

更新暫存區以及工作目錄 |

當 Git 切換分支時,會從當前的 Commit 的內容來「更新」暫存區以及工作目錄。

範例:

  1. 假設我在 one 分支上新增了 hello1.html 、 hello2.html 兩個檔案,那麼此時 commit 的內容會拿來更新暫存區與工作目錄。

    https://ithelp.ithome.com.tw/upload/images/20211002/20141010Vchv5afFbi.png

  2. 後續 commit 提交後,又新增了 hello3.html 檔案,並再提交一次,總共提交了兩次。

    https://ithelp.ithome.com.tw/upload/images/20211002/20141010DoUUXDipYY.png

    兩次 Commit 的 SHA-1 值分別是:4f18d8b 、 dba939f

  3. 查看一下 Git 紀錄:

    $ git log --oneline # 查看紀錄
    

    https://ithelp.ithome.com.tw/upload/images/20211002/20141010Fk7WUX7YpV.png

    https://ithelp.ithome.com.tw/upload/images/20211002/20141010GixEcyhArC.png

    可以看到 one 分支比 master 分支多了兩次 commit 紀錄。

    按下 q 按鍵,即可退回原畫面。

  4. 接著查看一下在 one 分支的時候,檔案列表會長怎麼樣:

    https://ithelp.ithome.com.tw/upload/images/20211002/2014101092K4uonlr4.png

    可以看到先前兩次新增的三個檔案都有在內。此時的工作目錄:

    https://ithelp.ithome.com.tw/upload/images/20211002/20141010nbuxRTZXfl.png

  5. 改切回 master 分支,並查看檔案列表:

    $ git checkout master # 切換到 master 分支
    $ ls -al # 查看檔案列表
    

    https://ithelp.ithome.com.tw/upload/images/20211002/20141010baoRAYu3oV.png

    切回 master 分支後,此時 master 分支的 Commit 並沒有先前的三個檔案。

    這時的工作目錄:

    https://ithelp.ithome.com.tw/upload/images/20211002/20141010uWA6qKFFNx.png

    檔案不見了嗎?並不是唷!它依然存在,只是在 one 分支上而已,只要切回 one 分支後,檔案就會再出現了。

    https://ithelp.ithome.com.tw/upload/images/20211002/201410102eZp8FP3dk.png

從上面的範例操作,試著思考當我們切換到 master 分支的時候,one 分支 commit 的東西從本地端的工作目錄上畫面不見了,這樣是代表被刪掉了嗎?

答案是沒有的,他依然會存在工作目錄上,即使我們切回 master 分支,先前所做的 commit 更新會留在工作目錄不被受影響。只是在 master 分支上的 Commit 的工作目錄並沒有這個內容的存在。

👉 觀念:切換分支之前的修改依然會留在工作目錄,不受影響。

補充複習:在 Git 世界裡, 每新增一次 Commit 就相當新增一個物件,而他會指向某個 Tree 物件(目錄)。

變更 HEAD 的位置 |

先前的範例可以發現,當我們切換分支時,HEAD 也會跟著移動,指向當前的 Commit。這個動作同時也會修改 .git/HEAD 中的檔案。


總結:
Git 切換分支的時候,會使用此分支所指向的 Commit 來更新暫存區與工作目錄。即使切換分支後,先前的修改動作依然會留在工作目錄中,不被受影響。


上一篇
Day19|【Git】開始使用分支 - git branch(基本常用指令)
下一篇
Day21|【Git】合併分支 git merge 指令 、快轉模式Fast Forward 、救回被砍掉的未合併分支方法
系列文
【Git】從零開始學習 Git - 30 天的學習筆記30

尚未有邦友留言

立即登入留言