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

🌿 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
main1.2 基本用法
# 將 feature 分支變基到 main 之上
git checkout feature
git rebase main
# 或一步完成
git rebase main feature1.3 交互式變基
交互式變基可以修改、合併、刪除提交:
# 對最近 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 = 刪除該提交常用操作:
| 操作 | 命令 |
|---|---|
| 修改提交信息 | reword 或 r |
| 合併多個提交 | squash 或 s |
| 刪除提交 | drop 或 d |
| 重新排序 | 調整行順序 |
1.4 解決變基衝突
# 衝突時,修改文件後
git add <file>
git rebase --continue
# 放棄變基
git rebase --abort
# 跳過當前提交
git rebase --skip1.5 merge vs rebase
| 特性 | merge | rebase |
|---|---|---|
| 歷史記錄 | 保留所有合併 | 線性歷史 |
| 衝突處理 | 一次解決 | 逐個提交解決 |
| 公共分支 | ✅ 推薦 | ❌ 禁止 |
| 私有分支 | 可用 | ✅ 推薦 |
| 追溯問題 | 更真實 | 更清晰 |
⚠️ 黃金法則: 永遠不要在公共分支(如 main/master)上使用 rebase!
二、儲藏(Stash)
2.1 基本用法
當工作區有未提交的修改,但需要切換分支時:
# 儲藏當前修改
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 clear2.2 高級用法
# 只儲藏暫存區的內容
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 基本用法
將某個分支的特定提交應用到當前分支:
# 挑選一個提交
git cherry-pick <commit-hash>
# 挑選多個提交
git cherry-pick <hash1> <hash2> <hash3>
# 挑選一個範圍的提交(不包含 start)
git cherry-pick start..end
# 包含 start
git cherry-pick start^..end3.2 處理衝突
# 解決衝突後
git add <file>
git cherry-pick --continue
# 放棄 cherry-pick
git cherry-pick --abort
# 跳過當前提交
git cherry-pick --skip3.3 只修改不提交
# 只應用更改,不創建提交
git cherry-pick --no-commit <hash>3.4 使用場景
- 修復了 main 上的 bug,需要同步到其他版本分支
- 錯誤地在錯誤的分支上提交了代碼
- 只需要某個分支的特定功能
四、提交歷史管理
4.1 修改最近提交
# 修改提交信息
git commit --amend -m "新的提交信息"
# 將暫存區的修改加入最近一次提交(不改信息)
git add <file>
git commit --amend --no-edit⚠️ 如果已經推送到遠程,需要
git push --force-with-lease強制推送(僅私有分支)
4.2 重置(Reset)
# 三種模式
# 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> |
| 撤銷 merge | git reset --hard ORIG_HEAD |
4.4 Revert(反向提交)
# 創建一個反向提交,撤銷指定提交的更改
git revert <commit-hash>
# 撤銷 merge 提交
git revert -m 1 <merge-commit-hash>revert 不會修改歷史,適合公共分支上的撤銷操作。
4.5 Reflog 找回丟失的提交
# 查看引用日誌
git reflog
# 找回丟失的提交
git reset --hard <hash-from-reflog>
# 找回被刪除的分支
git checkout -b recovered-branch <hash-from-reflog>💡 reflog 保留 90 天,是救命稻草!
五、子模塊與子樹
5.1 Git Submodule
將另一個倉庫作為子目錄嵌入:
# 添加子模塊
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/submodule5.2 Git Subtree
子樹將另一個倉庫的內容合併為當前倉庫的一部分:
# 添加子樹
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 main5.3 Submodule vs Subtree
| 特性 | Submodule | Subtree |
|---|---|---|
| 倉庫獨立性 | 各自獨立 | 合併到主倉庫 |
| 克隆體驗 | 需要 --recursive | 直接克隆 |
| 更新方式 | submodule update | subtree pull |
| 貢獻回去 | 簡單 | 較複雜 |
| 歷史記錄 | 分開 | 合併 |
| 適合場景 | 依賴第三方庫 | 自己維護的共享代碼 |
六、Git Hooks
6.1 常用鉤子
| 鉤子 | 觸發時機 | 用途 |
|---|---|---|
| pre-commit | 提交前 | 代碼檢查、格式化 |
| commit-msg | 提交信息 | 校驗提交信息格式 |
| pre-push | 推送前 | 運行測試 |
| pre-receive | 接收前 | 服務器端校驗 |
| post-receive | 接收後 | 觸發部署 |
6.2 pre-commit 示例
#!/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# 賦予執行權限
chmod +x .git/hooks/pre-commit6.3 使用 Husky 管理鉤子
# 安裝
npm install -D husky
npx husky init
# 添加 pre-commit 鉤子
echo "npx lint-staged" > .husky/pre-commitpackage.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命令速查:
# 安裝 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-17.2 GitHub Flow
更簡單,適合持續部署:
main (可隨時部署)
↑
feature/xxx → Pull Request → Code Review → Merge流程:
- 從 main 創建功能分支
- 開發並提交
- 提交 Pull Request
- 代碼審查 + CI 通過
- 合併到 main
- 自動部署
7.3 Trunk-Based Development
最敏捷,適合小團隊:
main (trunk)
├── 小功能直接提交
└── Feature Flag 控制未完成功能特點:
- 沒有長期功能分支
- 頻繁合併(每天至少一次)
- 使用 Feature Flag 控制功能開關
- CI/CD 必須完善
7.4 選擇建議
| 項目類型 | 推薦策略 |
|---|---|
| 有版本發佈週期 | Git Flow |
| 持續部署的 SaaS | GitHub Flow |
| 小團隊、快速迭代 | Trunk-Based |
| 開源項目 | GitHub Flow + Fork PR |
八、代碼審查最佳實踐
8.1 提交 PR 前檢查清單
8.2 好的 PR 描述模板
## 變更類型
- [ ] Bug 修復
- [ ] 新功能
- [ ] 性能優化
- [ ] 代碼重構
- [ ] 文檔更新
## 變更內容
簡要描述這次變更做了什麼。
## 關聯 Issue
Closes #123
## 測試方法
1. 運行 `npm test`
2. 訪問 `/page` 驗證功能
## 截圖(可選)8.3 審查代碼時關注什麼
必須檢查:
- 邏輯正確性
- 安全漏洞
- 邊界情況處理
- 錯誤處理
應該檢查:
- 代碼風格
- 命名規範
- 重複代碼
- 測試覆蓋
建議檢查:
- 性能優化
- 架構設計
- 文檔完整性
8.4 評論禮儀
❌ "這裡寫錯了"
✅ "這裡我理解是 xxx,對嗎?如果是 xxx 的話,建議用 yyy 方式"
❌ "變量名不好"
✅ "這個變量能不能叫 xxx,更清晰地表達它的用途?"
原則:
- 對事不對人
- 提問而非指責
- 給出建議而非要求
- 肯定好的做法
九、常用高級技巧
9.1 Bisect 二分查找 bug
# 開始 bisect
git bisect start
# 標記當前版本為壞
git bisect bad
# 標記某個已知好的版本
git bisect good v1.0.0
# Git 會自動切換到中間版本
# 測試後標記
git bisect good # 如果版本是好的
git bisect bad # 如果版本是壞的
# 重複直到找到引入 bug 的提交
# 結束 bisect
git bisect reset9.2 Blame 追溯修改
# 查看某文件每一行最後是誰修改的
git blame file.js
# 查看特定行範圍
git blame -L 10,50 file.js
# 顯示作者郵箱
git blame -e file.js9.3 Grep 搜索歷史
# 搜索所有提交中包含某關鍵詞的
git log -S "關鍵詞"
# 使用正則搜索
git log -G "正則表達式"
# 搜索提交信息
git log --grep="關鍵詞"9.4 Worktree 多分支同時工作
# 創建新的 worktree(在不同目錄同時工作在不同分支)
git worktree add ../project-feature feature-branch
# 列出所有 worktree
git worktree list
# 刪除 worktree
git worktree remove ../project-feature9.5 自定義別名
# 添加別名
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 了大文件
# 安裝 git-filter-repo
pip install git-filter-repo
# 從歷史中刪除文件
git filter-repo --path large-file.zip --invert-paths
# 強制推送
git push --force --all10.2 merge 衝突太多
# 使用 ours/theirs 策略
git merge main -X ours # 衝突時使用當前分支的
git merge main -X theirs # 衝突時使用對方的
# 或使用 rebase 逐個解決
git rebase main10.3 錯誤地 reset --hard
# 用 reflog 找回
git reflog
git reset --hard <hash>10.4 提交信息寫錯了
# 最近一個提交
git commit --amend -m "新信息"
# 更早的提交
git rebase -i HEAD~3
# 把 pick 改成 reword十一、總結
Git 高級技巧是團隊高效協作的基礎:
- 變基讓歷史更清晰,但不要在公共分支使用
- 儲藏幫你在分支間無縫切換
- cherry-pick選擇性同步提交
- 分支策略選擇適合團隊的工作流
- 代碼審查提升代碼質量和團隊成長
- reflog是你的救命稻草
🌿 好的 Git 工作流讓團隊協作如絲般順滑。
相關文章推薦: