Git教學
Git 常用指令
TL;DR涵蓋:基本操作(init / clone / add / commit / push / pull)、分支管理(branch / checkout / merge)、實用技巧(stash / cherry-pick / reset / rebase)、強制重寫歷史(filter-branch / git filter-repo)。
基本操作
git init # 初始化倉庫
git clone <url> # 複製遠端倉庫
git status # 查看狀態
git add . # 加入所有變更
git add <file> # 加入特定檔
git commit -m "訊息" # 提交
git commit --amend # 修改最近一次 commit
git push origin main # 推送到遠端
git pull # 拉取遠端更新
git fetch # 只拉不合併
分支管理
git branch # 查看本地分支
git branch -r # 查看遠端分支
git branch -a # 全部分支
git branch <name> # 建立分支
git checkout <name> # 切換分支
git checkout -b <name> # 建立並切換
git switch <name> # 切換(現代版,Git 2.23+)
git switch -c <name> # 建立並切換
git merge <name> # 合併分支(產生 merge commit)
git merge --ff-only <name> # 只 fast-forward(乾淨歷史)
git merge --squash <name> # 壓成單一 commit
git rebase <name> # 重整 commits 接到對方上
git branch -d <name> # 刪除分支(已 merge)
git branch -D <name> # 強制刪除(未 merge 也刪)
實用技巧
# Stash(暫存未完成工作)
git stash # 暫存
git stash list # 看有哪些 stash
git stash pop # 取出最新 stash + 刪掉
git stash apply # 取出但保留
git stash drop # 刪除某 stash
# 查看歷史
git log # 完整歷史
git log --oneline # 簡潔(每行 1 commit)
git log --graph --all # 視覺化分支圖
git log -p <file> # 看某檔的修改歷史
# Diff
git diff # working dir vs staging
git diff --staged # staging vs HEAD
git diff <commit1> <commit2> # 兩個 commit 比較
git diff main..feature # branch 之間
# Reset(危險指令,慎用)
git reset --soft HEAD~1 # 撤銷 commit,保留變更在 staging
git reset --mixed HEAD~1 # 撤銷 commit,變更回 working dir(預設)
git reset --hard HEAD~1 # ⚠️ 撤銷 commit + 變更全砍
# Cherry-pick(挑特定 commit)
git cherry-pick <hash> # 把該 commit 套到當前分支
git cherry-pick <hash1>..<hash2># 範圍
# Tag
git tag v1.0.0 # 建立輕量 tag
git tag -a v1.0.0 -m "release" # 帶訊息的 tag
git push --tags # 推送所有 tag
強制刪除歷史(慎用)
某個 commit 含敏感資訊(API key、credential 不小心提交),要從歷史中徹底移除:
# 老做法(會 reset 所有 ref,慢)
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch path/to/secret.json" \
--prune-empty --tag-name-filter cat -- --all
# ✅ 現代推薦:git filter-repo
pip install git-filter-repo
git filter-repo --path path/to/secret.json --invert-paths
重寫歷史的代價
- 所有 commit hash 都會變
- 其他人 clone 過的 repo 必須
git fetch+ force reset- GitHub 可能仍 cache 舊 commit(找 support 徹底刪)
- 洩漏的 secret 要 rotate(刪 git 不代表沒人複製)
詳見 保護你的API KEY (React 前端)。
Rebase 進階
git rebase main # 把當前 branch rebase 到 main
git rebase -i HEAD~5 # 互動式 rebase 最近 5 commits
# 可以 squash / reword / edit / drop
git rebase --abort # 取消 rebase(衝突時)
git rebase --continue # 解完衝突後繼續
互動式 rebase 範例:
pick abc1234 Add feature
pick def5678 Fix typo
pick ghi9012 More feature work
pick jkl3456 Another typo
# 改成:
pick abc1234 Add feature
fixup def5678 # 把 typo fix 合進 abc1234
pick ghi9012 More feature work
fixup jkl3456 # 把 typo fix 合進 ghi9012
結果 從 4 個 commit 合成 2 個乾淨 commit。
我的常用 alias
git config --global alias.s "status -s"
git config --global alias.l "log --oneline --graph --decorate"
git config --global alias.co "checkout"
git config --global alias.br "branch"
git config --global alias.cm "commit -m"
git config --global alias.ca "commit -am"
# 用法
git s # 簡潔 status
git l # 視覺化 log
git co main # 切換 main
配置全域 user
git config --global user.name "Bobo100"
git config --global user.email "w150lione@gmail.com"
# 看設定
git config --global --list
多帳號切換 詳見 github 多個帳戶 SSH登入。