Git 全景課 / 第一部分 建立心智模型 · M2

M2 基本循環

日常用 Git,九成時間都在重複同一個循環:改、看、暫存、提交、查歷史。本單元把這個循環練熟,並學會兩件讓歷史「有用」的事:忽略不該提交的檔案,以及寫好 commit 說明。
約 60 分鐘沙盒 7 個任務 · 互動 ×2 · 小測 4 題先修:M1
學完本單元,你能夠:
  1. 用 git init 建立倉庫,並完成「改 → 看 → 暫存 → 提交 → 查歷史」的循環;
  2. 用 .gitignore 排除系統雜物、個人設定和密鑰;
  3. 寫出清楚的 commit 說明;
  4. 判斷甚麼時候該把改動拆成幾個 commit。

1循環一覽 The everyday loop

Git 的基本循環 五個步驟排成一個循環:改(編輯檔案)、看(git status、git diff)、暫存(git add)、提交(git commit)、查(git log、git show),然後回到改。 ① 改 在編輯器修改 ② 看 status · diff ③ 暫存 git add ④ 提交 git commit ⑤ 查 log · show 下一輪修改 一開始只做一次:git init(建立倉庫)· 寫好 .gitignore

②「看」是最常被跳過的一步,也是最值得養成的習慣:每次 add 之前用 git status 和 git diff 看一眼,就能避免把不該提交的東西封進歷史。

2建立倉庫:git init Creating a repository

在一個資料夾裏執行 git init,Git 會在裏面建立一個隱藏的 .git 資料夾。倉庫就是這個 .git 資料夾:所有 commit、暫存區、設定都在裏面。你的檔案本身不會被改動,也還沒有任何檔案被追蹤,要等你 add 和 commit。

另一種開始方式 如果專案已經在 GitHub 等地方,就不用 init,而是用 git clone 把整個倉庫複製下來。這在 M9 介紹。

3.gitignore:不該提交的檔案 Ignoring files

每個資料夾裏都有一些檔案不應該進入歷史:

類別知識線例子軟件線例子
作業系統雜物.DS_Store(macOS)、Thumbs.db同左
個人設定.obsidian/workspace.json(你的視窗佈局).vscode/、.idea/
可以重新產生的檔案匯出的 PDF__pycache__/、node_modules/、build/
密鑰與私人資料含個人資料的名單.env(API key、密碼)

在倉庫根目錄建立一個叫 .gitignore 的純文字檔,每行寫一條規則,Git 就會當這些檔案不存在:git status 不再列出它們,git add . 也會跳過它們。

寫法意思
.DS_Store任何位置叫這個名字的檔案
*.pdf所有 .pdf 檔
build/整個 build 資料夾
!keep.pdf例外:前面的規則排除了它,這一行再把它納回來
# 說明註解

.gitignore 本身要提交,這樣團隊每個人都套用同一套規則。

兩個陷阱
  • 已追蹤的檔案不受 .gitignore 影響。如果某個檔案早已提交,事後才寫進 .gitignore 是沒有用的。要先用 git rm --cached <檔名> 讓 Git 停止追蹤(檔案本身保留),再提交。
  • 密鑰一旦提交,就永遠留在歷史裏。即使下一個 commit 把它刪掉,舊 commit 仍然有它,任何拿到倉庫的人都看得到。補救方法是立即作廢那條密鑰、換一條新的。最好的做法是在第一次 commit 之前就寫好 .gitignore。

4沙盒:從零開始的五次提交 Sandbox: five commits

互動 1 從零建立一個倉庫

這是一個還沒有用 Git 管理的資料夾。按順序完成七個任務,途中會做五次提交;完成一個,下一個才會出現。卡片上的「編輯」按鈕,或命令 edit <檔名>,模擬你在編輯器裏修改並儲存(檔案不存在時會建立)。

應用線:

5寫好 commit 說明 Writing commit messages

commit 說明是寫給將來的人看的,包括半年後的你。他們看歷史時,只有這一句話可以判斷「這次改了甚麼、要不要細看」。好的說明有幾個共通點:

  1. 第一行是標題,簡短概括做了甚麼。習慣上不超過 50 個字元(中文字大約 25 個字),因為很多工具只顯示這一行。
  2. 用動詞開頭,寫具體的事。「修正第三節的樣本數」勝過「修改」;「加入 CSV 匯出」勝過「update」。
  3. 需要解釋「為甚麼」時,空一行再寫正文。改了甚麼,git show 會告訴讀者;為甚麼要改,只有你知道。
  4. 一個 commit 只做一件事。如果標題需要用「和」連接兩件事,通常代表應該拆成兩個 commit。

互動 2 commit 說明檢查器

輸入一個 commit 說明,即時看看它符合哪些原則。可以先試試「更新」,再試試「修正第三節的樣本數:應為 120」。

    6一個大 commit,還是幾個小 commit? One big commit or several?

    一天下來你可能改了五件事。全部放進一個 commit 最省事,但代價會在之後出現。試試看:

    互動 3 拆分 commit

    替每件改動選擇放進哪個 commit。之後會發現,其中一件改動(標紅色)是錯的,需要撤銷。看看你的分法會連累哪些改動。

    一個大 commit幾個小 commit
    提交時省事要逐件 add、分開寫說明
    說明只能寫得含糊(「更新報告」)每個都具體
    撤銷其中一件會連帶撤銷其他改動只撤銷那一件
    找出問題何時出現難,要在大 commit 裏逐行找容易(M14 的 bisect)
    審查(PR)審查者要一次看懂所有改動可以逐件理解

    準則不是「越小越好」,而是一個 commit 一件完整的事:它本身說得清楚,撤銷它也不會留下半件事。

    7查看歷史 Viewing history

    命令用途
    git log完整列出 commit:編號、作者、時間、說明
    git log --oneline每個 commit 一行,最常用
    git log -n 3只看最近 3 個
    git log --stat同時列出每個 commit 改了哪些檔案
    git log -p notes.md只看和 notes.md 有關的 commit,並顯示改動內容
    git show最新一個 commit 的說明和改動
    git show a1b2c3d指定某個 commit(編號寫頭幾位就夠)

    git commit -a:方便,但要知道它跳過了甚麼

    git commit -a -m "說明"(可合寫成 -am)會先把所有已追蹤檔案的修改自動 add,再提交。它省了一步,但有兩點要記住:

    8小測 Quiz

    1. 執行 git init 之後,以下哪一句正確?
    2. config.yml 早已提交。你今天把它寫進 .gitignore,再修改它。git status 會顯示甚麼?
    3. 以下哪一個 commit 說明最好?
    4. 你不小心提交了含 API key 的 .env,下一個 commit 已經把它刪除。最重要的補救是:

    本單元重點 Summary

    延伸閱讀