Featured image of post How git works_1

How git works_1

大部分 Git 教學教你碰到怎樣的狀況要用怎樣的指令。而 pluralsight 這兩篇教學教你 Git 最重要的規則、觀念。懂得這些,要去文件中找千百種指令來應用才能輕鬆自在。

這篇文章是兩篇教學其中一篇『how git works 』的心得整理(約一半內容)。

課程連結

在此記錄我的學習心得,若有錯誤之處歡迎 comment 更正。還有一些譬喻法是自己想出來可以幫助記憶的,如果有譬喻不當或是有更好的譬喻方式,歡迎 comment 更正。

我之前把 branch (分支) 當成是『線』的概念,完蛋了,Git 整個變成謎一般的外星生物無法預測。

分支 branch 這個名詞很容易讓人誤會,好像是樹的分支那樣一整條,這是錯誤觀念。重點再說一次,branch 是 『點』的概念。

branch 就像是便利貼,可以隨時移動(待會說明什麼意思)、增加、或是刪除(但是 branch 至少要有一個,不能沒有)。

master 就是一張在 local 端的便利貼;origin/master 就是一張拿來參照在 remote 端的便利貼。

HEAD :HEAD 好比一張金牌(稀有),只會有一個HEAD(也一定存在不會沒有),不像 branch 那樣,它不能增加、刪除。不過金牌可以隨時移動。

tag : 通常比較少用到,把它當成是 『圖釘』的概念好了,tag 可以隨時增加、刪除;但是 tag 不能移動,當一個 tag 釘在某個 commit 上之後,這個 tag 就不能再拿起來釘到別的 commit 了。

可以隨時移動: branch , HEAD 可以隨時從某個 commit 貼到 另一個 commit。

Branch 一定貼在某個 commit 上面,可以隨時撕下來貼到另外一個 commit 上。(使用 reset 指令)

HEAD 絕大部分狀況是貼在某個 branch 上面的

branch 一定是貼在某個 commit 上

然後 HEAD 貼在某個 branch 上

HEAD 也可以直接貼在某顆 commit 上,他們中間沒有 branch 。這種狀況比較少見

順序是:HEAD -> branch -> commit (大部分狀況)

或是: HEAD -> commit (比較少見)

如果 HEAD 直接指向(貼在) 某顆 commit , 就是 Detached HEAD

Detached HEAD

Detached HEAD

當 HEAD 回到其它分支之後,這個 Commit 就不容易被找到,如果一直沒人來找它,過一段時間就會被 Git 資源回收機制給收掉。

爲什麼要瞭解 branch , HEAD 他們的行爲?因爲它們是一個好理解的參考指標。branch , HEAD, tag 就好比跟朋友約見面,我們會說:在忠孝復興站見面吧。而 commit 就好比地球座標:我們約在 北緯25.041557, 東經 121.54314 見面吧。獨一無二絕對的準確,但是意義上不明顯。

git checkout lisa 之後,HEAD 移動到了 lias 這個便利貼上

  • 切換分支(checkout),就只是很單純的把金牌(圖中灰色的 HEAD)從 master 這張便利貼,移動到 lisa 這張便利貼
  • HEAD 指向的 branch ,也叫做 current branch ( lisa 目前就成爲了 current branch)

一步步解釋 merge 發生了那些事

先長出 ecbe 這顆 commit ,然後 master 便利貼撕下來,貼到 ecbe 上面

由於 HEAD 先前是放在 master 上的,此時 HEAD 會跟隨着 master 移動。

Git Object Model

一個 Git repo 是一個在圖形中彼此鏈接的一組對象。

它們可以是 commits ,blobs,trees 或 tags。

branch 貼到 一個 commit 上。HEAD 也是一個參考,但它只有一個,它標誌著我們在圖中的當前位置。

圈在 commit 上的綠色圈圈,代表現在 HEAD 的位置

某個 commit 可以連接到的 blob , tree ,就代表當下工作區域的狀態

這是 commit 時項目的整個狀態,每個文件和每個文件夾的完整快照。Git使用這些信息來替換你的工作目錄的內容。

這是版本控制的重點。

Git並不真正關心你的工作區域。當你 checkout 時(HEAD 移動),Git 只是用 object database 中的東西來替換工作區域

Git cares about the objects in the database, not your working directory. repo 中的對像是不可變的並且是持久的。

總結三個規則

The current branch tracks new commits.

如果 使用 git commit或git merge來創建新的 commit ,那麼 current branch 將移動到新 commit 。如果處於 detached HEAD狀態,則HEAD 本身會移至新 commit 。

when you move to another commit, Git updates your working directory

例如使用git checkout,Git用你 commit 的內容替換你的工作目錄的內容。

Unreachable objects are garbage collected

branch,HEAD或 tags 無法觸及的任何 commit ,blob 或 tree,會被認為是無效的,會被 Git 回收。

Branches, merges, moving back in forth in time,都歸結為這些簡單的規則。

(待續)

最後更新 Feb 15, 2022 01:32 +0800