Git 基礎:版本控制入門
為什麼需要版本控制?
💡 比喻:遊戲存檔點 想像你在玩 RPG 遊戲,每到一個關鍵時刻都會「存檔」, 如果打輸了 Boss,可以回到存檔點重來。 Git 就是你程式碼的「存檔系統」—— 每次 commit 就像按下存檔鍵, 隨時可以回到任何一個存檔點。
沒有版本控制的悲劇
專案資料夾/
├── MyProject_v1.zip # 第一版
├── MyProject_v2.zip # 改了登入功能
├── MyProject_v2_final.zip # 老闆說的最終版
├── MyProject_v2_final2.zip # 真的最終版
├── MyProject_v2_真的最終版.zip # 拜託這次是真的
└── MyProject_別再改了.zip # 你已經崩潰了
有了 Git 之後
git log --oneline # 查看所有版本紀錄
# a1b2c3d 新增登入功能
# e4f5g6h 修復首頁 Bug
# i7j8k9l 初始化專案
git checkout a1b2c3d # 回到任何版本,就像讀取存檔
安裝與設定 Git
安裝 Git
# Windows:從官網下載安裝程式
# https://git-scm.com/download/win
# macOS:使用 Homebrew 安裝
brew install git # 透過 Homebrew 套件管理器安裝 Git
# Linux(Ubuntu/Debian):使用 apt 安裝
sudo apt install git # 透過 apt 套件管理器安裝 Git
# 確認安裝成功
git --version # 顯示 Git 版本號,確認安裝成功
初始設定(只需做一次)
# 設定使用者名稱(會出現在每次 commit 紀錄中)
git config --global user.name "你的名字" # 設定全域使用者名稱
# 設定電子信箱(建議用 GitHub 註冊的信箱)
git config --global user.email "you@example.com" # 設定全域電子信箱
# 設定預設編輯器為 VS Code
git config --global core.editor "code --wait" # 設定 VS Code 為預設編輯器
# 設定預設分支名稱為 main
git config --global init.defaultBranch main # 新建 repo 時預設分支名為 main
# 查看所有設定
git config --list # 列出目前所有 Git 設定值
工作區、暫存區、儲存庫
💡 比喻:寄包裹的流程
- 工作區(Working Directory) = 你的書桌,正在寫信
- 暫存區(Staging Area) = 把信放進信封,準備寄出
- 儲存庫(Repository) = 郵局收件,正式寄出紀錄
┌─────────────┐ git add ┌─────────────┐ git commit ┌─────────────┐
│ 工作區 │ ──────────→ │ 暫存區 │ ─────────────→ │ 儲存庫 │
│ Working Dir │ │ Staging Area │ │ Repository │
│ (你的書桌)│ │ (信封裡) │ │ (郵局紀錄)│
└─────────────┘ └─────────────┘ └─────────────┘
↑ │
└──────────────── git checkout ────────────────────────────┘
(讀取舊存檔)
實際操作流程
# 步驟 1:建立新專案資料夾
mkdir my-project # 建立新資料夾
cd my-project # 進入資料夾
# 步驟 2:初始化 Git 儲存庫
git init # 在當前資料夾建立 .git 子資料夾,開始版本控制
# 步驟 3:建立檔案(工作區)
echo "Hello Git" > hello.txt # 建立一個新檔案
# 步驟 4:查看目前狀態
git status # 顯示哪些檔案被修改、新增、刪除
# 步驟 5:加入暫存區
git add hello.txt # 把 hello.txt 放進暫存區(信封裡)
# 步驟 6:提交到儲存庫
git commit -m "新增 hello.txt 檔案" # 正式存檔,附上說明訊息
常用 Git 指令
git status — 查看狀態
# 查看目前工作區和暫存區的狀態
git status # 顯示檔案的追蹤狀態
# 簡短格式(更簡潔)
git status -s # 用縮寫顯示狀態(M=修改, A=新增, ?=未追蹤)
# 輸出範例:
# M README.md ← 已修改但未暫存
# A 新增的檔案.cs ← 已加入暫存區
# ?? 未追蹤的檔案.txt ← Git 還不認識的檔案
git add — 加入暫存區
# 加入單一檔案
git add index.html # 把 index.html 加入暫存區
# 加入多個檔案
git add file1.cs file2.cs # 同時把兩個檔案加入暫存區
# 加入所有變更的檔案
git add . # 把目前目錄下所有變更都加入暫存區
# 加入特定類型的檔案
git add "*.cs" # 把所有 .cs 檔案加入暫存區
# 互動式加入(選擇部分變更)
git add -p # 逐段檢視變更,選擇要暫存哪些部分
git commit — 提交存檔
# 基本提交(附上訊息)
git commit -m "修復登入頁面的驗證 Bug" # 提交暫存區的所有變更
# 多行提交訊息
git commit -m "修復登入驗證 Bug" -m "詳細說明:密碼欄位未做空值檢查" # 第二個 -m 會成為說明內文
# 跳過暫存區,直接提交所有已追蹤檔案的修改
git commit -am "快速修復 typo" # -a 自動暫存已追蹤的修改檔案,然後提交
# 修改最近一次的提交訊息
git commit --amend -m "修正:登入頁面驗證 Bug" # 覆蓋上一次的 commit 訊息
git log — 查看歷史紀錄
# 查看完整紀錄
git log # 顯示所有 commit 的詳細資訊
# 一行顯示(簡潔)
git log --oneline # 每個 commit 只顯示一行摘要
# 圖形化顯示分支
git log --oneline --graph --all # 用 ASCII 圖形顯示所有分支的合併歷史
# 顯示最近 5 筆
git log -5 # 只顯示最近 5 次的 commit
# 顯示每次 commit 修改了哪些檔案
git log --stat # 列出每次 commit 影響的檔案和行數統計
# 搜尋特定作者的 commit
git log --author="小明" # 只顯示作者名稱包含「小明」的 commit
.gitignore 設定
💡 比喻:搬家時的「不帶清單」 搬家不會把垃圾桶、用過的衛生紙一起搬走, .gitignore 就是告訴 Git 哪些檔案不需要追蹤。
.NET 專案常用 .gitignore
# 建立 .gitignore 檔案
touch .gitignore # 建立空的 .gitignore 檔案
# 使用 dotnet CLI 自動產生(推薦)
dotnet new gitignore # 自動產生適合 .NET 專案的 .gitignore
常用規則範例
# === 編譯輸出 ===
bin/ # 忽略編譯輸出資料夾
obj/ # 忽略中間編譯檔案資料夾
*.dll # 忽略所有動態連結庫檔案
*.exe # 忽略所有可執行檔
# === IDE 設定 ===
.vs/ # 忽略 Visual Studio 設定資料夾
.vscode/ # 忽略 VS Code 設定資料夾(視情況)
*.suo # 忽略 Visual Studio 使用者選項檔
*.user # 忽略使用者特定設定檔
# === 敏感資訊 ===
appsettings.Development.json # 忽略開發環境的敏感設定
*.pfx # 忽略憑證檔案
secrets.json # 忽略機密設定檔
# === 系統檔案 ===
.DS_Store # 忽略 macOS 系統檔案
Thumbs.db # 忽略 Windows 縮圖快取
# === 套件 ===
node_modules/ # 忽略 Node.js 套件資料夾(前端專案)
packages/ # 忽略 NuGet 套件資料夾
# === 日誌 ===
*.log # 忽略所有日誌檔案
logs/ # 忽略日誌資料夾
已經追蹤的檔案如何移除
# 如果檔案已經被 Git 追蹤了,光加 .gitignore 沒用
# 需要先從追蹤清單中移除
git rm --cached appsettings.Development.json # 從追蹤清單移除,但保留本地檔案
git commit -m "移除敏感設定檔的追蹤" # 提交這個變更
VS Code 與 Visual Studio 的 Git 整合
VS Code Git 整合
VS Code 左側邊欄:
┌──────────────────────────┐
│ 📁 Explorer │ ← 檔案總管
│ 🔍 Search │ ← 搜尋
│ 🔀 Source Control (Ctrl+Shift+G) │ ← Git 面板 ⭐
│ 🐛 Run and Debug │ ← 除錯
│ 📦 Extensions │ ← 擴充套件
└──────────────────────────┘
Source Control 面板功能:
- 查看所有變更的檔案(相當於 git status)
- 點擊 + 號暫存檔案(相當於 git add)
- 輸入訊息後按 ✓ 提交(相當於 git commit)
- 底部狀態列顯示目前分支名稱
推薦 VS Code 擴充套件
Git 相關擴充套件:
┌──────────────────────────────────────────────┐
│ GitLens │ 顯示每行程式碼的作者和時間 │
│ Git Graph │ 圖形化顯示分支和合併歷史 │
│ Git History │ 查看檔案的修改歷史 │
│ GitHub PR │ 在 VS Code 中管理 PR │
└──────────────────────────────────────────────┘
Visual Studio Git 整合
Visual Studio 的 Git 功能:
┌────────────────────────────────────────────────┐
│ Git > Changes(Git 變更視窗) │
│ - 相當於 git status + git add + git commit │
│ │
│ Git > Manage Branches(管理分支) │
│ - 圖形化建立、切換、合併分支 │
│ │
│ View > Git Repository(Git 儲存庫視窗) │
│ - 查看完整的 commit 歷史和分支圖 │
│ │
│ 右鍵 > Git > View History │
│ - 查看單一檔案的修改歷史 │
└────────────────────────────────────────────────┘
🤔 我這樣寫為什麼會錯?
❌ 錯誤 1:忘記設定使用者資訊就 commit
# 錯誤:沒設定 user.name 和 user.email 就提交
git commit -m "第一次提交" # 會出錯或顯示預設的不正確資訊
# ✅ 正確:先設定使用者資訊
git config --global user.name "你的名字" # 先設定名稱
git config --global user.email "you@example.com" # 再設定信箱
git commit -m "第一次提交" # 然後才提交
為什麼錯? Git 需要知道「誰」做了這次變更。就像寄信不寫寄件人,郵局不知道是誰寄的。
❌ 錯誤 2:把敏感資訊提交到 Git
# 錯誤:把含有密碼的設定檔提交了
git add appsettings.Development.json # 這個檔案可能包含資料庫密碼
git commit -m "新增設定" # 密碼就被記錄到歷史中了
# ✅ 正確:先設定 .gitignore
echo "appsettings.Development.json" >> .gitignore # 先加入忽略清單
git add .gitignore # 暫存 .gitignore
git commit -m "新增 .gitignore" # 提交忽略規則
為什麼錯? 即使後來刪除檔案,Git 歷史紀錄中仍然保留密碼。推上 GitHub 後全世界都看得到!
❌ 錯誤 3:不看 status 就 add .
# 錯誤:不檢查就全部加入
git add . # 可能把暫時檔案、測試資料、甚至密鑰都加進去了
git commit -m "更新" # 模糊的 commit 訊息
# ✅ 正確:先看狀態,再選擇性加入
git status # 先檢查有哪些變更
git add src/LoginController.cs # 只加入需要的檔案
git commit -m "修復登入頁面的密碼驗證邏輯" # 寫清楚做了什麼
為什麼錯? git add . 會把所有東西都加進去,可能包含不該追蹤的檔案。好的習慣是先 git status,確認變更內容後再有選擇地 git add。
📝 本章重點整理
| 指令 | 用途 | 比喻 |
|---|---|---|
git init |
初始化儲存庫 | 買一本新的筆記本 |
git add |
加入暫存區 | 把信放進信封 |
git commit |
提交到儲存庫 | 把信交給郵局 |
git status |
查看狀態 | 檢查書桌上還有什麼 |
git log |
查看歷史 | 翻看寄件紀錄 |
.gitignore |
忽略特定檔案 | 搬家時的「不帶清單」 |