上一篇用 Log 替執行中的系統留下值班筆記。這一篇把視角拉回程式碼:昨天改了哪些檔案?哪一次修改讓功能壞掉?Agent 動過的內容要怎麼逐項檢查?這些問題會交給 Git 處理。
剛接觸 Git 時,通常只知道寫完程式要執行 git add、git commit,最後再把程式碼推到 GitHub。至於檔案經過這些指令後去了哪裡,往往沒有真的弄懂。終端機只要跳出一段沒看過的訊息,就會開始擔心程式是不是救不回來了。
後來開始用 Git 管理自己的程式學習筆記,才慢慢理解它的用途。Git 很像替專案設置存檔點:每次完成一小段工作,就把當下的狀態和修改原因記下來。日後除了能比較差異、追查問題,也能另外開一條路嘗試新功能,不必直接動到穩定版本。
這篇不會一次塞進所有 Git 指令,而是先走完開發時最常用的路線。重點不是背指令,是知道檔案現在在哪裡,以及下一個動作會影響什麼。
Git 是分散式版本控制工具,安裝在自己的電腦上。即使沒有網路,仍然可以建立版本、查看修改紀錄及切換分支。
GitHub 則是存放 Git 儲存庫的線上平台。它除了保存遠端版本,也提供 Pull Request、Issue、Code Review 與 GitHub Actions 等協作功能。Git 負責版本控制,GitHub 負責遠端保存與團隊協作,兩者並不是同一個工具。
可以把 Git 想成電腦裡的存檔系統,GitHub 則像團隊共用的遠端存檔櫃。沒有 GitHub,Git 仍然能在本機工作;只有本機 commit,也不代表內容已經出現在 GitHub,還要執行 git push 才會上傳。
安裝完成後,可以先確認 Git 是否可用:
git --version
第一次使用時,要設定 commit 的作者名稱與電子郵件:
git config --global user.name "你的名字"
git config --global user.email "你的電子郵件"
--global 代表這份設定會套用到目前帳號下的所有 Git 專案。如果公司專案與個人專案要使用不同身分,可以進入指定專案後,省略 --global 再設定一次。
剛開始學 Git,最容易卡住的不是指令本身,而是不知道檔案目前在哪一站。可以先記住下面這條路徑:

圖 1:Git 檔案從編輯、挑選修改、建立版本紀錄到上傳遠端的流程
平常開啟的專案資料夾就是工作目錄。這裡像工作桌,檔案還可以繼續修改。執行 git add 後,指定的內容會進入暫存區,像是把這次準備歸檔的文件放進托盤。執行 git commit,才會把托盤裡的內容收進本機儲存庫,成為一筆有編號、有說明的版本紀錄。
git push 是另一個步驟,它只負責把本機已有的 commit 上傳到遠端。這四站很重要,因為「存檔」和「上傳」不是同一件事:commit 不等於 push。
如果手上已有一個資料夾,想讓 Git 開始管理它,可以在資料夾內執行:
git init
這會建立隱藏的 .git 目錄,裡面保存此專案的版本歷史與設定。它像 Git 的檔案室,不要直接修改或刪除。
如果專案已經放在 GitHub,則使用 clone 下載:
git clone https://github.com/使用者名稱/專案名稱.git
cd 專案名稱
git clone 取得的不只是目前的檔案,也包含可供本機查看的版本歷史與遠端設定。
假設修改了 README.md,先別急著把整個資料夾打包。第一步是確認目前狀態:
git status
git status 像桌面清單,會列出已修改、尚未被 Git 追蹤,以及已放入暫存區的檔案。接著查看實際改了什麼:
git diff
git diff 顯示工作目錄中還沒加入暫存區的修改。確認內容後,再把這次要提交的檔案放進暫存區:
git add README.md
很多人會直接使用 git add .,一次加入目前目錄下的所有修改。這個指令很方便,也可能順手把測試輸出、秘密設定或做到一半的內容一起裝進托盤。剛開始練習時,建議先指定檔案,再檢查一次準備提交的內容:
git diff --staged
git status
git diff --staged 顯示的內容,才是下一筆 commit 真正會收進去的修改。確認無誤後再建立 commit:
git commit -m "docs: 更新專案使用說明"
一筆 commit 最好只處理一個目的,訊息則寫清楚做了什麼。日後看到 docs: 更新專案使用說明,會比 update 或 fix 更容易理解。如果「修正登入」和「重寫首頁版面」沒有必須綁在一起,就應該分開提交。這樣日後要找問題或撤銷修改時,才不會一次牽動兩件事。
要查看過去建立的存檔點,可以使用:
git log --oneline
git log --graph --oneline --decorate --all
如果要開發登入功能,可以從目前版本建立新分支:
git switch -c feature/login
switch -c 會建立分支並立刻切換過去。完成修改與 commit 後,再回到主分支進行合併:
git switch main
git merge feature/login
確認功能已經合併,才刪除本機分支:
git branch -d feature/login
分支像從目前版本另外拉出一張工作桌。登入功能還在施工時,main 可以繼續保持穩定;完成並確認後,再把這張工作桌的成果合併回去。
團隊專案通常會把功能分支推到 GitHub,再透過 Pull Request 讓其他人檢查差異,而不是每個人都直接修改 main。切換分支前先執行 git status,如果工作目錄還有未提交內容,先判斷要 commit、stash,還是繼續留在原分支,不要看到錯誤就急著使用強制指令。
先用下面的指令查看專案連到哪些遠端位置:
git remote -v
常見的遠端名稱是 origin。如果是用 git init 建立的本機專案,可以自行加入遠端:
git remote add origin https://github.com/使用者名稱/專案名稱.git
遠端操作中,常用的三個指令是:
git fetch
git pull
git push
git fetch 像先把遠端最新目錄拿回來看,不會立刻改動目前的工作分支。git pull 會下載並整合遠端變更,實際採用 merge 或 rebase 要看專案設定;git push 則把本機 commit 上傳。
第一次推送新的功能分支時,可以設定它所追蹤的遠端分支:
git push -u origin feature/login
之後在同一個分支通常只要執行 git push 即可。多人協作時,先確認工作目錄乾淨,再依團隊約定同步遠端變更,可以減少分支落後太多才發生衝突的情況。
兩個人修改同一段內容時,Git 不知道哪一邊才是正確答案,就會停下來請人判斷。這就是 merge conflict。檔案裡可能會看到下面的標記:
<<<<<<< HEAD
目前分支的內容
=======
準備合併進來的內容
>>>>>>> feature/login
這不是亂碼,也不是要把兩邊無條件選一邊。先理解兩份修改各自在解決什麼問題,再編輯成最後應保留的內容,並刪除 <<<<<<<、=======、>>>>>>>。接著執行:
git status
git add <已解決的檔案>
git commit
如果不確定該保留哪一版,先找修改者確認。Git 能指出「兩邊撞在一起」,但無法替專案決定業務規則。
如果檔案已加入暫存區,但還不想提交,可以取消暫存,工作目錄中的修改仍會保留:
git restore --staged README.md
如果確定要放棄工作目錄中尚未加入暫存區的修改,可以使用:
git restore README.md
這會用暫存區裡的版本覆蓋工作目錄,未提交的修改可能無法找回。一般尚未暫存的情況下,看起來就像把檔案退回上一次 commit;但只要檔案曾經 git add 過,暫存區可能已經不是上一次 commit 的內容。執行前先看 git status 與 git diff,不要只靠印象判斷。
若要撤銷已經推送並與其他人共用的 commit,通常使用 git revert <commit-id>。它不會偷偷改寫舊歷史,而是新增一筆反向修改,讓團隊仍能看懂發生過什麼事。
git reset --hard 會同時改動工作目錄、暫存區與版本位置,可能直接清掉尚未保存的內容。第一次接觸 Git 時,不要因為看到網路上的解法就直接貼上執行,先確認它會影響哪些資料。
工作做到一半,需要暫時切去處理其他分支時,可以先把已追蹤檔案的修改收進 stash:
git stash
git stash list
git stash pop
git stash pop 會嘗試取回最近一筆 stash,成功後再把它從清單移除。取回時仍可能發生衝突,因此要重新執行 git status。預設的 git stash 不會收進未追蹤檔案;如果資料很重要,commit 往往比把內容長時間藏在 stash 裡更容易追查。
.gitignore 用來排除不需要版本控制的檔案,例如編譯產物、套件快取、IDE 設定與本機環境變數:
bin/
obj/
node_modules/
.env
*.log
.DS_Store
.gitignore 只會忽略尚未被追蹤的檔案,不會讓已經加入 Git 的檔案自動消失。它更不是秘密清除工具。如果 API Key、密碼或私鑰已經進入 commit,就算後來刪除檔案,仍可能從 Git 歷史中找到。發生這種情況時,第一件事是撤銷並更換憑證,接著才處理版本歷史。
| 指令 | 用途 |
|---|---|
git init |
讓目前資料夾成為 Git 儲存庫 |
git clone <url> |
複製遠端儲存庫 |
git status |
查看檔案與暫存區狀態 |
git diff |
查看尚未加入暫存區的差異 |
git diff --staged |
查看準備提交的差異 |
git add <file> |
將指定修改加入暫存區 |
git commit -m "訊息" |
建立一筆本機版本紀錄 |
git log --oneline |
查看精簡的提交歷史 |
git switch -c <branch> |
建立並切換到新分支 |
git merge <branch> |
將指定分支合併到目前分支 |
git fetch |
下載遠端紀錄但不自動整合 |
git pull |
下載並整合遠端變更 |
git push |
將本機 commit 上傳至遠端 |
git restore --staged <file> |
將檔案移出暫存區 |
git stash |
暫時收起尚未提交的修改 |
前面的操作都透過 Git 指令完成。熟悉這些指令很有幫助,因為遇到問題時,才能看懂檔案位於工作目錄、暫存區,還是已經建立成 commit。不過,實際工作不一定每次都要自己拼出完整指令。AI 搭配 GitHub MCP Server 後,可以直接用自然語言說明想完成的事情,再由 Agent 呼叫對應工具。
MCP 是 Model Context Protocol 的縮寫,可以把它想成 AI 與外部服務之間的轉接頭。接上 GitHub MCP 後,Agent 可以在授權範圍內讀取 Repository、Issue、commit 與 Pull Request;如果開放寫入工具,也能建立分支、更新 Issue、建立 Pull Request 或進行其他 GitHub 操作。
以下使用 GitHub 託管的遠端 MCP Server。這種方式不需要先安裝 Docker,只要準備支援 MCP 的 Codex 與 GitHub Personal Access Token(PAT)即可。
第一步,先確認目前的 Codex 可以管理 MCP Server:
codex mcp --help
第二步,到 GitHub 建立 PAT。依序開啟「個人頭像 → Settings → Developer settings → Personal access tokens → Fine-grained tokens」,再按下「Generate new token」。Fine-grained token 可以限制能存取的 Repository 與操作權限,比一次開放整個帳號更容易控制範圍。
建立時,先設定到期日,只選擇這次要操作的 Repository,權限也從唯讀開始;真的需要建立 Issue、Pull Request 或執行其他寫入操作時,再增加對應權限。Token 只會在 GitHub 建立時完整顯示一次,請存進密碼管理工具,不要貼進文章、程式碼或 Git Repository。
在 macOS 的 zsh 終端機中,可以用下面的方式將 Token 暫時放進環境變數。輸入時畫面不會顯示內容:
read -s "GITHUB_PAT_TOKEN?請貼上 GitHub PAT:"
echo
export GITHUB_PAT_TOKEN
這個環境變數只在目前的終端機工作階段有效。關閉終端機後就會消失,適合先確認安裝流程。若要長期使用,應改由作業系統的憑證保存機制管理,不要把 Token 明文寫進會提交到 Git 的設定檔。
第三步,將 GitHub MCP 加入 Codex:
codex mcp add github \
--url https://api.githubcopilot.com/mcp/ \
--bearer-token-env-var GITHUB_PAT_TOKEN
--bearer-token-env-var 後面放的是環境變數名稱,不是 Token 本身。Codex 的設定只會記住 GITHUB_PAT_TOKEN 這個名稱,連線時才從環境讀取真正的 Token。
如果 Codex 顯示 github 已經存在,先查看原本的設定,不要急著覆蓋:
codex mcp get github
第四步,確認 Server 已經出現在清單中:
codex mcp list
codex mcp get github
接著從同一個終端機啟動 Codex,在 TUI 輸入 /mcp,應該可以看到 github 提供的工具。也可以先用不會修改資料的問題測試:
請列出目前帳號可以存取的 GitHub Repository,不要進行任何修改。
如果出現 401 Unauthorized,先檢查 Token 是否過期、環境變數是否仍存在,以及 PAT 是否具有目標 Repository 的存取權。Server 有出現在清單中,但完全看不到工具時,通常是 Token 權限不足或 Codex 啟動時沒有讀到環境變數。
不再使用時,可以移除這筆 MCP 設定:
codex mcp remove github
例如,原本需要切換頁面、尋找選單或輸入多段指令的工作,可以直接這樣交代:
範例1:
請讀取 Issue #23,整理需求與可能受影響的檔案,先不要修改。
範例2:
請比較 feature/login 與 develop 的差異,整理這個分支完成了哪些功能。
範例3:
請用 feature/login 作為來源分支、develop 作為目標分支建立 Pull Request,
並根據 commit 與 diff 撰寫摘要和測試說明。建立前先讓人確認內容。
這種方式的好處,是先描述目的,不必一開始就記住每一個 GitHub 操作的位置或 API。Agent 也能把原本很長的 commit 清單整理成摘要,協助檢查 Pull Request 是否混入無關檔案。對剛接觸版本控制的人來說,比起直接面對一整排選項,先說清楚「想查什麼」或「想建立什麼」容易得多。
如果 Agent 同時能操作本機專案與 GitHub MCP,兩邊會有不同分工:
| 工作位置 | Agent 可以協助的事情 |
|---|---|
| 本機 Git | 修改檔案、執行測試、查看 git status 與 git diff、建立 commit、push 分支 |
| GitHub MCP | 讀取 Repository、Issue 與 Pull Request,整理 commit,建立或更新 Pull Request |
GitHub MCP 讓操作方式更接近對話,但不會改變 Git 原本的規則。commit 仍然只會建立本機紀錄,push 之後才會出現在遠端;發生 conflict 時,也還是要判斷最後應保留的內容。
第一次使用可以先開唯讀模式,確認 Agent 讀到的 Repository、分支與 Issue 都正確,再依工作需要開放寫入工具。讀取程式碼和合併 Pull Request 是不同權限,不需要因為想請 Agent 整理資料,就同時交出所有操作能力。
比較穩妥的流程是先請 Agent 說明準備執行的動作,再檢查 git status、git diff、測試結果與 Pull Request 內容。確認範圍正確後,才進行 commit、push 或 merge。
Agent 回覆「完成了」只是一則工作回報。Git diff、測試結果與 Pull Request 實際包含的檔案,才是可以逐項核對的結果。
第一次學 Git,不用急著背完所有指令。先熟悉 status → diff → add → diff --staged → commit 這條路徑,再練習分支與遠端同步,已經足以處理多數日常開發。Git 真正讓人安心的地方,不是它有多少復原指令,而是每次修改前後都有狀態與差異可以確認。
接下來讓 Agent 協助開發時,Git 會成為修改程式的安全網。可以從 diff 確認 Agent 改過哪些檔案,把工作拆成容易審查的小型 commit;結果不符合需求時,也有清楚的紀錄可以追查。
下一篇會用 Docker 建立 SQL Server 環境。compose.yaml 和資料庫初始化腳本可以交給 Git 管理,真正的密碼與 Container 裡產生的資料則不該一起提交。Git 負責保存「如何重建環境」,Docker 負責把環境實際跑起來。