Git 筆記
這篇 Git 文章的主要目的是為了加深對 Git 的基本觀念,並非只是跟著描述打指令的皮毛,而是對 Git 實際在做的事有更進一步的了解。文章主旨不在介紹指令是因為從 google 或 AI 上就可以很快找到解釋指令的資源,所以本篇文章的價值會著重在 Git 的觀念和應用情境上,以及一些容易混淆或誤會的知識點上。
Git 是什麼
雖然大部分的軟體開發者應該都對 Git 不陌生,但在開始之前還是想先說明 Git 是什麼。
Git 是一個版本控制系統,專業一點的說法是分散式版本的版本控制系統,是由 Linux 核心的作者 Linus Torvalds 在 2005 年開發而來。
Git 工具有三個非常知名的優點:
- 免費的開源工具: 具有強大功能的開源版控工具收服了眾多軟體開發者的喜愛
- 速度快、體積小: 由於是使用快照的方式去記錄變更,所以運作很快,且比較不佔記憶體空間
- 分散式的設計: 支援離線時的操作,能在地端做儲存,待下次連線時再更新變更,降低用戶對伺服器的依賴性
Git 運作方式主要是紀錄目錄和樹狀結構,會記得目錄底下有變更的檔案,對於沒變更的檔案會指向前一個版本,因為目前版本沒有變更到此檔案內容,故也不需要重複紀錄相同的內文
Git 概念
基本流程
- 流程階段 -
在開發程式碼的電腦上,Git 劃分了三個主要區域:
工作區 (working directory)、暫存區 (staging area)、儲存庫 (repository)
- 工作區: 起始寫入或編輯程式碼的地方就是工作區,也是所有流程的起點
- 暫存區: 又稱為預存區,當檔案編輯到一個段落在放入儲存庫之前會先加到暫存區,此時 Git 會新增檔案的快照
- 儲存庫: 又叫做永久存放區,會將暫存區產生的快照放到 Git 目錄中永久保存
從工作區要進到暫存區會使用 git add
指令來將檔案加入暫存區,接著要從暫存區將檔案提交到儲存庫會使用 git commit
指令; 相反地,如果想退回到上一個階段區域就可以使用圖中的另一邊指令來退到上一個階段,例如: 使用 git reset
將剛提交到儲存庫的檔案回推到暫存區存放,而使用 git restore
則是可以把暫存區的檔案再推回到起點工作區。
- 檔案狀態 -
在 Git 的版本控制中,檔案狀態會有四種分類,分別是: Untracked、Modified、Staged、Commited。檔案狀態的目的就是為了顯示目前檔案是存放在哪個區域階段。
檔案狀態 | 狀態描述 |
---|---|
Untracked | 在工作區新建立的檔案 |
Modified | 在工作區域有修改的檔案 |
Staged | 在暫存區的檔案 |
Commited | 在儲存庫的檔案 |
- Untracked: 在資料夾中新建立的檔案,還從未加入過 Git 的工作流程中,會被歸類在 ‘Untracked’
- Modified: 原本就存在在資料夾中,但是被修改了卻還沒將變更放入暫存區的檔案
- Staged: 編輯過後放入暫存區的檔案
- Commited: 放入儲存庫的檔案
備註: 使用 git status
能查看目前檔案的狀態
Commit 的重點
Commit 指的是在 Git 流程中 git commit
指令執行的這一步,詳細的指令寫法會是 git commit -m "message"
,這邊的 message 就是你想為此次變動留下的訊息資訊。這邊舉一個簡單的故事來說: 公司網站的首頁背景圖無法顯示,所以小明工程師修正了程式碼中的錯誤,並想將此次變更提交到儲存庫中,所以小明便在終端機輸入指令 git commit -m “修正首頁背景圖無法顯示問題”,並成功地提交到儲存庫中,後續小明的同事小花工程師看了小明留下的 commit 訊息便知道這次專案的改動目的。
Commit 的意義
從上面簡單的例子中,可以隱約看出 commit 在 git 中扮演著很重要的角色,小花工程師能在第一時間透過 commit 資訊來掌握專案的改動原因,而不需要透過看完 Git 檔案中一大堆改動的程式碼來了解。所以 commit 的訊息在版本控制中訴說了此版本第一線的資訊,讓在追溯版本變動和尋找變更的程式碼時變得相對容易,這也就是 commit 的意義所在。
- Commit 的目的:
- 記錄做了哪些異動,和為什麼要做這些改動
- 讓團隊成員或其他想貢獻的開發者能夠快速地了解變動內容,方便回溯程式碼已經修改的錯誤或新添加的功能
什麼是好的 commit
了解到 commit 的意義後,在寫 commit 時就需要格外地慎重和注意,並且要確保 commit 的可讀性,另外,若是和團隊一起開發的專案就需要符合團隊的規則並保持一致性。自己寫的專案也別認為只要 commit 訊息自己看得懂就好,因為有可能你寫的專案有一天會變成一項其他人也想參與的開源專案。既然 commit 如此重要,那要如何寫出好的 commit 呢?
要寫出好的 commit 不外乎三個要項: Why, What, How,Why 代表說明這項改動的目的,讓其他人能了解為什麼要做這個變更; What 描述你改動了什麼內容; How 表達用什麼方式做到的。也就是只要將主旨表達清楚並且讓他人可以理解,就是一個好的 commit,至於格式要 follow 哪種規則就取決於你的團隊或大家討論的共識。坊間有一派主流寫法,其寫法格式如下,會用空行分隔出三個段落,分別為 Type: Subject、Body、Footer
1 | Type: Subject |
- Type: 共有九種類型
類型 描述 feat 新增、修改功能 fix 修正 Bug docs 修改文件 (通常指技術文件) style 程式碼風格調整 (Format 不影響功能運作) refactor 程式碼重構但維持原邏輯 perf 改善效能 (performance) test 新增或修改測試 chore 更新專案建置設定、更新版本號或輔助工具的變更等瑣事 revert 撤銷先前的 commit
- Subject
- 主旨不超出 50 個字元
- 第一個英文字母需要大寫
- 通常以動詞開頭
- 不使用標點符號做結尾
- Body
- 非必要內容,視情況而定
- 撰寫時需要將改了什麼以及為什麼修改交代清楚
- 每行不得超過 72 字
- Footer
- 非必要內容,視情況而定
- 通常用來標註對應的 issue 編號
現在我們試試將原本小明提交的訊息按照此規則來做修改,原本是: ‘修正首頁背景圖無法顯示問題’
修改為:
1 | fix: 修正首頁背景圖無法顯示問題 |
軟體中有許多 commit 輔助工具,像是 Commitlint、Husky 等工具可以自動檢查提交的訊息格式,確認是否符合使用者所設定之規則,或者有些人會用 AI 輔助來快速生成搭配已經定義給它的 commit 格式。
Commit 的時機點
其實並沒有一定要寫到哪個進度才能提交,有些開發者習慣將很多檔案一次改好再一起 commit`, 而有些開發者則是習慣完成一個任務,不管任務大小,完成一項就可以 commit 一項。雖然沒有一定的標準答案,但是有幾個小建議可以 follow:
- 保持 commit 小而專注
- 確保每次的提交是針對一個功能或解決一個錯誤
- commit 盡量只關注在一個議題上
- 盡量避免 ‘Work in progress’ (WIP) 的提交
- 還在修正或編輯中的任務或議題先不做 commit 直到修改好
以上這些建議的主要目的不外乎就是維持乾淨的 commit 歷史紀錄,後續追蹤回溯時也比較不會有過多需要過濾掉的 commit。
從地端推送到遠端儲存庫
Git 基本流程中的儲存庫是在本地端,也就是你所編寫程式碼的電腦,但存放在自己電腦中的編碼基本上無法讓他人讀取或修改,所以需要多人協作的專案或是想開源的專案該如何讓其他人也能看見呢? 那就是放在大家都可以看到的地方: 遠端儲存庫。遠端儲存庫平台有 GitHub、GitLab、Codeberg 等多樣資源供選擇。Git push
指令會用來將放置於本地電腦儲存庫的資料推送到遠端儲存庫,完成推送流程後便可以在遠端儲存庫看到與地端相同的檔案資料。
Reference
Git 基礎要點
為你自己學 Git - 高見龍
圖解Git
Git Commit Message 格式與規範整理
Git Commit Message 這樣寫會更好,替專案引入規範與範例
Day03 Git 版本控制 - 什麼是 Git