跳轉到內容

Git 高級技巧與團隊協作工作流 2026

Git 高級技巧

🌿 Git 是開發者最重要的協作工具。 掌握 Git 基礎只是開始,真正的高效協作需要掌握高級技巧和規範的工作流。本文涵蓋從進階操作到團隊協作的最佳實踐,幫助你成為 Git 高手。

本文將帶你係統掌握:

  • ✅ 變基(rebase)與合併(merge)的選擇
  • ✅ 歷史重寫與提交整理
  • ✅ 儲藏(stash)與挑選(cherry-pick)
  • ✅ 子模塊與子樹
  • ✅ Git Hooks 與自動化
  • ✅ 常見分支策略(Git Flow / GitHub Flow / Trunk-Based)
  • ✅ 代碼審查最佳實踐
  • ✅ 常見問題處理

一、變基(Rebase)

1.1 什麼是變基

變基將一個分支的提交"搬"到另一個分支之上,使提交歷史變成一條直線。

變基前:
  A---B---C  main
       \
        D---E  feature

變基後:
  A---B---C---D'---E'  feature
          main

1.2 基本用法

bash
# 將 feature 分支變基到 main 之上
git checkout feature
git rebase main

# 或一步完成
git rebase main feature

1.3 交互式變基

交互式變基可以修改、合併、刪除提交:

bash
# 對最近 3 個提交進行交互式變基
git rebase -i HEAD~3

會出現編輯器:

pick f7f3f6d 提交信息1
pick 310154e 提交信息2
pick a5f4a0d 提交信息3

# 命令:
# p, pick = 使用該提交
# r, reword = 使用該提交,但修改信息
# e, edit = 使用該提交,但暫停修改
# s, squash = 合併到上一個提交
# f, fixup = 合併到上一個提交,丟棄信息
# d, drop = 刪除該提交

常用操作:

操作命令
修改提交信息rewordr
合併多個提交squashs
刪除提交dropd
重新排序調整行順序

1.4 解決變基衝突

bash
# 衝突時,修改文件後
git add <file>
git rebase --continue

# 放棄變基
git rebase --abort

# 跳過當前提交
git rebase --skip

1.5 merge vs rebase

特性mergerebase
歷史記錄保留所有合併線性歷史
衝突處理一次解決逐個提交解決
公共分支✅ 推薦❌ 禁止
私有分支可用✅ 推薦
追溯問題更真實更清晰

⚠️ 黃金法則: 永遠不要在公共分支(如 main/master)上使用 rebase!


二、儲藏(Stash)

2.1 基本用法

當工作區有未提交的修改,但需要切換分支時:

bash
# 儲藏當前修改
git stash

# 儲藏並添加說明
git stash save "work in progress on login feature"

# 查看儲藏列表
git stash list
# stash@{0}: On feature/login: work in progress on login feature
# stash@{1}: On main: WIP

# 應用最近的儲藏並刪除
git stash pop

# 應用指定儲藏(不刪除)
git stash apply stash@{1}

# 刪除指定儲藏
git stash drop stash@{0}

# 清空所有儲藏
git stash clear

2.2 高級用法

bash
# 只儲藏暫存區的內容
git stash --staged

# 同時儲藏未跟蹤的文件
git stash -u
# 或
git stash --include-untracked

# 查看儲藏內容
git stash show stash@{0}
git stash show -p stash@{0}  # 顯示 diff

# 從儲藏創建新分支
git stash branch new-branch stash@{0}

三、挑選(Cherry-pick)

3.1 基本用法

將某個分支的特定提交應用到當前分支:

bash
# 挑選一個提交
git cherry-pick <commit-hash>

# 挑選多個提交
git cherry-pick <hash1> <hash2> <hash3>

# 挑選一個範圍的提交(不包含 start)
git cherry-pick start..end

# 包含 start
git cherry-pick start^..end

3.2 處理衝突

bash
# 解決衝突後
git add <file>
git cherry-pick --continue

# 放棄 cherry-pick
git cherry-pick --abort

# 跳過當前提交
git cherry-pick --skip

3.3 只修改不提交

bash
# 只應用更改,不創建提交
git cherry-pick --no-commit <hash>

3.4 使用場景

  • 修復了 main 上的 bug,需要同步到其他版本分支
  • 錯誤地在錯誤的分支上提交了代碼
  • 只需要某個分支的特定功能

四、提交歷史管理

4.1 修改最近提交

bash
# 修改提交信息
git commit --amend -m "新的提交信息"

# 將暫存區的修改加入最近一次提交(不改信息)
git add <file>
git commit --amend --no-edit

⚠️ 如果已經推送到遠程,需要 git push --force-with-lease 強制推送(僅私有分支)

4.2 重置(Reset)

bash
# 三種模式

# soft: 僅移動 HEAD,更改保留在暫存區
git reset --soft HEAD~1

# mixed (默認): 移動 HEAD,更改保留在工作區
git reset HEAD~1
git reset --mixed HEAD~1

# hard: 移動 HEAD,丟棄所有更改(危險!)
git reset --hard HEAD~1
模式HEAD暫存區工作區
--soft✅ 移動不變不變
--mixed✅ 移動✅ 重置不變
--hard✅ 移動✅ 重置✅ 重置

4.3 撤銷操作指南

場景命令
撤銷工作區修改git checkout -- file
撤銷暫存git reset HEAD file
撤銷最近提交(保留更改)git reset HEAD~1
撤銷最近提交(丟棄更改)git reset --hard HEAD~1
撤銷已推送的提交git revert <hash>
撤銷 mergegit reset --hard ORIG_HEAD

4.4 Revert(反向提交)

bash
# 創建一個反向提交,撤銷指定提交的更改
git revert <commit-hash>

# 撤銷 merge 提交
git revert -m 1 <merge-commit-hash>

revert 不會修改歷史,適合公共分支上的撤銷操作。

4.5 Reflog 找回丟失的提交

bash
# 查看引用日誌
git reflog

# 找回丟失的提交
git reset --hard <hash-from-reflog>

# 找回被刪除的分支
git checkout -b recovered-branch <hash-from-reflog>

💡 reflog 保留 90 天,是救命稻草!


五、子模塊與子樹

5.1 Git Submodule

將另一個倉庫作為子目錄嵌入:

bash
# 添加子模塊
git submodule add https://github.com/user/repo.git path/to/submodule

# 克隆包含子模塊的倉庫
git clone --recursive https://github.com/user/main.git
# 或克隆後初始化
git submodule update --init --recursive

# 更新所有子模塊
git submodule update --remote --merge

# 進入子模塊操作
cd path/to/submodule
git checkout main
git pull

# 刪除子模塊
git submodule deinit path/to/submodule
git rm path/to/submodule
rm -rf .git/modules/path/to/submodule

5.2 Git Subtree

子樹將另一個倉庫的內容合併為當前倉庫的一部分:

bash
# 添加子樹
git subtree add --prefix=path/to/subtree https://github.com/user/repo.git main

# 拉取子樹更新
git subtree pull --prefix=path/to/subtree https://github.com/user/repo.git main

# 推送子樹更改
git subtree push --prefix=path/to/subtree https://github.com/user/repo.git main

5.3 Submodule vs Subtree

特性SubmoduleSubtree
倉庫獨立性各自獨立合併到主倉庫
克隆體驗需要 --recursive直接克隆
更新方式submodule updatesubtree pull
貢獻回去簡單較複雜
歷史記錄分開合併
適合場景依賴第三方庫自己維護的共享代碼

六、Git Hooks

6.1 常用鉤子

鉤子觸發時機用途
pre-commit提交前代碼檢查、格式化
commit-msg提交信息校驗提交信息格式
pre-push推送前運行測試
pre-receive接收前服務器端校驗
post-receive接收後觸發部署

6.2 pre-commit 示例

bash
#!/bin/sh
# .git/hooks/pre-commit

# 檢查代碼格式
if ! npx prettier --check "**/*.{js,ts,md}" 2>/dev/null; then
  echo "❌ 代碼格式錯誤,請運行 npx prettier --write"
  exit 1
fi

# 運行 lint
if ! npm run lint 2>/dev/null; then
  echo "❌ Lint 檢查失敗"
  exit 1
fi

echo "✅ 檢查通過"
exit 0
bash
# 賦予執行權限
chmod +x .git/hooks/pre-commit

6.3 使用 Husky 管理鉤子

bash
# 安裝
npm install -D husky
npx husky init

# 添加 pre-commit 鉤子
echo "npx lint-staged" > .husky/pre-commit

package.json 配置:

json
{
  "lint-staged": {
    "*.{js,ts,vue}": ["eslint --fix", "prettier --write"],
    "*.{md,json}": ["prettier --write"]
  }
}

七、分支策略

7.1 Git Flow

適用於有明確發佈週期的項目:

main (生產)
  ↑ 合併發佈
release-x.x
  ↑ 合併功能
develop
  ↑ 合併功能分支
feature/xxx  feature/yyy

hotfix/xxx  ←  從 main 分出修復後合併回 main 和 develop

命令速查:

bash
# 安裝 git-flow
brew install git-flow-avh

# 初始化
git flow init

# 開始功能
git flow feature start my-feature

# 完成功能
git flow feature finish my-feature

# 開始發佈
git flow release start 1.0.0

# 完成發佈
git flow release finish 1.0.0

# 開始修復
git flow hotfix start bugfix-1

# 完成修復
git flow hotfix finish bugfix-1

7.2 GitHub Flow

更簡單,適合持續部署:

main (可隨時部署)

feature/xxx → Pull Request → Code Review → Merge

流程:

  1. 從 main 創建功能分支
  2. 開發並提交
  3. 提交 Pull Request
  4. 代碼審查 + CI 通過
  5. 合併到 main
  6. 自動部署

7.3 Trunk-Based Development

最敏捷,適合小團隊:

main (trunk)
  ├── 小功能直接提交
  └── Feature Flag 控制未完成功能

特點:

  • 沒有長期功能分支
  • 頻繁合併(每天至少一次)
  • 使用 Feature Flag 控制功能開關
  • CI/CD 必須完善

7.4 選擇建議

項目類型推薦策略
有版本發佈週期Git Flow
持續部署的 SaaSGitHub Flow
小團隊、快速迭代Trunk-Based
開源項目GitHub Flow + Fork PR

八、代碼審查最佳實踐

8.1 提交 PR 前檢查清單

8.2 好的 PR 描述模板

markdown
## 變更類型
- [ ] Bug 修復
- [ ] 新功能
- [ ] 性能優化
- [ ] 代碼重構
- [ ] 文檔更新

## 變更內容
簡要描述這次變更做了什麼。

## 關聯 Issue
Closes #123

## 測試方法
1. 運行 `npm test`
2. 訪問 `/page` 驗證功能

## 截圖(可選)

8.3 審查代碼時關注什麼

必須檢查:

  • 邏輯正確性
  • 安全漏洞
  • 邊界情況處理
  • 錯誤處理

應該檢查:

  • 代碼風格
  • 命名規範
  • 重複代碼
  • 測試覆蓋

建議檢查:

  • 性能優化
  • 架構設計
  • 文檔完整性

8.4 評論禮儀

  • ❌ "這裡寫錯了"

  • ✅ "這裡我理解是 xxx,對嗎?如果是 xxx 的話,建議用 yyy 方式"

  • ❌ "變量名不好"

  • ✅ "這個變量能不能叫 xxx,更清晰地表達它的用途?"

原則:

  1. 對事不對人
  2. 提問而非指責
  3. 給出建議而非要求
  4. 肯定好的做法

九、常用高級技巧

9.1 Bisect 二分查找 bug

bash
# 開始 bisect
git bisect start

# 標記當前版本為壞
git bisect bad

# 標記某個已知好的版本
git bisect good v1.0.0

# Git 會自動切換到中間版本
# 測試後標記
git bisect good   # 如果版本是好的
git bisect bad    # 如果版本是壞的

# 重複直到找到引入 bug 的提交

# 結束 bisect
git bisect reset

9.2 Blame 追溯修改

bash
# 查看某文件每一行最後是誰修改的
git blame file.js

# 查看特定行範圍
git blame -L 10,50 file.js

# 顯示作者郵箱
git blame -e file.js

9.3 Grep 搜索歷史

bash
# 搜索所有提交中包含某關鍵詞的
git log -S "關鍵詞"

# 使用正則搜索
git log -G "正則表達式"

# 搜索提交信息
git log --grep="關鍵詞"

9.4 Worktree 多分支同時工作

bash
# 創建新的 worktree(在不同目錄同時工作在不同分支)
git worktree add ../project-feature feature-branch

# 列出所有 worktree
git worktree list

# 刪除 worktree
git worktree remove ../project-feature

9.5 自定義別名

bash
# 添加別名
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.lg "log --oneline --graph --all"

# 更復雜的別名
git config --global alias.last "log -1 HEAD"
git config --global alias.unstage "reset HEAD --"
git config --global alias.visual "!gitk"

十、常見問題處理

10.1 不小心 commit 了大文件

bash
# 安裝 git-filter-repo
pip install git-filter-repo

# 從歷史中刪除文件
git filter-repo --path large-file.zip --invert-paths

# 強制推送
git push --force --all

10.2 merge 衝突太多

bash
# 使用 ours/theirs 策略
git merge main -X ours    # 衝突時使用當前分支的
git merge main -X theirs  # 衝突時使用對方的

# 或使用 rebase 逐個解決
git rebase main

10.3 錯誤地 reset --hard

bash
# 用 reflog 找回
git reflog
git reset --hard <hash>

10.4 提交信息寫錯了

bash
# 最近一個提交
git commit --amend -m "新信息"

# 更早的提交
git rebase -i HEAD~3
# 把 pick 改成 reword

十一、總結

Git 高級技巧是團隊高效協作的基礎:

  1. 變基讓歷史更清晰,但不要在公共分支使用
  2. 儲藏幫你在分支間無縫切換
  3. cherry-pick選擇性同步提交
  4. 分支策略選擇適合團隊的工作流
  5. 代碼審查提升代碼質量和團隊成長
  6. reflog是你的救命稻草

🌿 好的 Git 工作流讓團隊協作如絲般順滑。


相關文章推薦:

最後更新於: