Git 是全球最流行的分散式版本控制系統,由林納斯 · 托瓦齊 (Linus Torvalds) 在 2005 年創建。無論是個人專案、團隊協作,或是開源貢獻,Git 都是開發者的必備利器。
本文整理 Git 的核心概念與日常使用指令,從安裝到進階操作,幫你一次搞懂。
Git 核心概念
Git 的設計理念基於三個重要概念:
1. 快照 (Snapshot) 而非差異 (Diff)
Git 將每次提交視為一個完整的「快照」,而不是記錄與上次的差異。這意味著你可以隨時回到任何歷史版本,看到當時的完整檔案狀態。
2. 分散式 (Distributed)
每個開發者電腦上都擁有完整的 Git 倉庫,包括完整的歷史記錄。即使中央伺服器掛了,你仍可以繼續工作,然後日後合併。
3. 三種狀態
Git 中的檔案有三種狀態:
| 狀態 | 說明 |
|---|---|
| 已提交 (Committed) | 檔案已安全地儲存在本地資料庫中 |
| 已修改 (Modified) | 檔案已修改,但未提交到資料庫 |
| 已暫存 (Staged) | 已修改的檔案已標記為下次提交的一部分 |
基本設定
首次使用 Git 前,需要設定使用者名稱和電子郵件:
git config --global user.name "你的名字"
git config --global user.email "your@email.com"
其他常用設定:
# 設定預設編輯器
git config --global core.editor "code --wait"
# 設定預設分支名稱為 main
git config --global init.defaultBranch "main"
# 顯示所有設定
git config --list
常用指令大全
初始化與克隆
| 指令 | 說明 |
|---|---|
git init |
在當前目錄初始化一個新的 Git 倉庫 |
git clone <url> |
從遠端倉庫複製到本地 |
git clone <url> <dir> |
克隆到指定目錄 |
基本操作流程
| 指令 | 說明 |
|---|---|
git status |
查看目前檔案狀態(是否修改、是否已暫存) |
git add <file> |
將修改的檔案添加到暫存區 |
git add . |
添加所有修改/新增的檔案到暫存區 |
git add -A |
添加所有變更(新增、修改、刪除)到暫存區 |
git reset <file> |
將檔案從暫存區移出(撤銷 add) |
git commit -m "訊息" |
提交到本地倉庫 |
git commit -am "訊息" |
跳過 add,直接提交已修改的追蹤檔案 |
💡 小技巧: git commit --amend 可以修改最後一次的提交訊息,常用於忘記加檔案或拼錯訊息時。
分支 (Branch) 操作
| 指令 | 說明 |
|---|---|
git branch |
列出所有分支 |
git branch <name> |
建立新分支(不會切換) |
git switch <name> |
切換到指定分支 |
git switch -c <name> |
建立並切換到新分支 |
git branch -d <name> |
刪除分支(無合併時會警告) |
git branch -D <name> |
強制刪除分支(無論合併狀態) |
遠端同步
| 指令 | 說明 |
|---|---|
git push |
推送本地分支到遠端 |
git push -u <repo> <branch> |
推送並設定上游分支(第一次推送) |
git pull |
拉取遠端分支到本地(fetch + merge) |
git fetch |
下載遠端更新但不合併 |
git remote -v |
列出遠端倉庫 URL |
查看歷史記錄
| 指令 | 說明 |
|---|---|
git log |
顯示提交歷史(最新的在上) |
git log --oneline |
精簡顯示(單行一條記錄) |
git log --oneline --graph |
顯示分支圖形 |
git log -p |
顯示每次提交的 diff |
git log --stat |
顯示每次提交影響的檔案統計 |
比對差異
# 比較工作目錄與暫存區
git diff
# 比較暫存區與上次提交
git diff --staged
# 比較兩次提交的差異
git diff HEAD~1 HEAD
# 比較某檔案在不同版本之間的差異
git diff HEAD~1 HEAD -- filename.js
復原與回退
⚠️ 注意: 以下指令可能會造成資料遺失,請在執行前確認清楚!
| 指令 | 說明 |
|---|---|
git checkout -- <file> |
捨棄工作目錄的修改(回到暫存狀態) |
git restore <file> |
新版指令,功能同上 |
git reset HEAD <file> |
將檔案從暫存區移出(撤銷 add) |
git reset --hard <commit> |
強制回到指定提交(會丟失修改) |
git revert <commit> |
建立一個反向提交來撤銷指定提交 |
git reflog |
查看所有操作記錄,可以找回「丟失」的提交 |
常見工作流程
開發新功能 (Feature Branch)
# 1. 確保主分支是最新的
git checkout main
git pull
# 2. 建立功能分支
git checkout -b feature/user-login
# 3. 開發... 提交...
git add .
git commit -m "實作使用者登入功能"
# 4. 推送到遠端
git push -u origin feature/user-login
# 5. 合併回主分支 (在遠端 PR/MR 完成後)
git checkout main
git pull
git merge feature/user-login
git push
處理衝突 (Conflict)
當合併或拉取時出現衝突,不要慌張:
- Git 會標記衝突的檔案,在檔案中找到
<<<<<<<標記 - 手動編輯檔案,移除標記並保留你想要的內容
- 保存檔案後,執行
git add <file> - 提交衝突解決:
git commit
進階技巧
暫存 (Stash)
在切換分支時不需要提交的修改,可以用 git stash 暫存:
# 暫存修改
git stash
# 恢復暫存
git stash pop
# 列出暫存
git stash list
# 套用第 N 個暫存(不刪除)
git stash apply stash@{2}
互動式 rebase
整理提交歷史,讓 commit log 更清晰:
# 互動式 rebase 最近 3 次提交
git rebase -i HEAD~3
# 可以選擇:
# pick - 保留
# squash - 合併到上一次
# edit - 修改
# drop - 刪除
別名 (Alias)
设置快捷指令別名,讓常用指令更簡短:
git config --global alias.st status
git config --global alias.ci commit
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.last 'log -1 HEAD'
# 現在可以這樣用:
git st # = git status
git ci # = git commit
git last # = git log -1 HEAD
常見錯誤排查
已經 push 的提交,不要亂 rebase!
如果提交已經推送到遠端,切記不要使用 git reset 或 git rebase 回退,否則在合併他人代碼時會產生衝突。
錯誤的分支上提交了
在錯誤的分支提交後,應該建立正確分支並移動提交:
# 建立正確分支
git branch correct-branch
# 回到提交前
git reset --hard HEAD~1 # 或使用 reflog 找回
# 切換到正確分支
git switch correct-branch
.gitignore 不生效
已追蹤的檔案即使加入 .gitignore 也不會停止追蹤:
git rm --cached filename
結語
Git 是一個強大的工具,掌握以下幾個原則就可以勝任日常開發:
- 頻繁提交 — 提交粒度越細,追踪問題越容易
- 分支策略 — 使用功能分支開發,完成後合併
- 不亂推遠端 — 已 push 的分支避免 force push
- 善用 reflog — 當心狀況外,reflog 總有辦法救回來
- 寫好 commit message — 為未來的自己謝謝
🎯 記住: Git 的學習來自於實操。不要害怕犯錯 — Git 的 reflog 幾乎可以恢復所有「意外」!