
深入淺出進階 Git 指令:分支管理、合併策略與版本還原全攻略
如果你已經掌握了 Git 基本指令,那恭喜你,你已經可以用 Git 做日常的版本管理了。但是,真實世界的開發可沒那麼簡單,對吧?
這篇文章要介紹一些常用的進階 Git 指令,主要涵蓋分支管理、合併衝突、版本回退等操作。這些指令在日常開發中超實用,學會了能讓你更有效率地管理版本控制,也能讓你在團隊協作時更得心應手。
flowchart TB subgraph 分支管理 A[查看分支 branch -a] --> B[創建分支 checkout -b] B --> C[重命名 branch -m] B --> D[刪除 branch -d/-D] B --> E[推送 push origin] end subgraph 合併與衝突 F[merge] --> G[--no-ff 保持歷史] F --> H[解決衝突 mergetool] F --> I[放棄合併 --abort] end subgraph 還原與重置 J[reset --soft] --> K[保留暫存區] L[reset --mixed] --> M[保留工作目錄] N[reset --hard] --> O[全部回退] P[revert] --> Q[生成新提交] end
分支管理
查看所有分支
git branch -a這條指令會列出所有本地和遠端的分支。想知道你的 repo 裡到底有多少分支?跑一下就知道了。
顯示分支詳細信息
git branch -vv這會顯示每個分支的最新提交以及追蹤的遠端分支,超方便用來了解每個分支的狀態。特別是當你同時在好幾個分支上工作的時候,這個指令簡直是救命恩人。
創建並切換到新分支
git checkout -b new-branch-name這條指令會創建一個新的分支並立即切換到該分支,方便快速開始新功能的開發。基本上每天開工第一件事就是開個新分支。
刪除本地分支
git branch -d branch-name如果該分支有未合併的變更,可以強制刪除:
git branch -D branch-name記住,小寫 -d 是安全刪除(會檢查有沒有未合併的東西),大寫 -D 是強制刪除(不管三七二十一直接砍)。平時用 -d 就好,除非你很確定要放棄那個分支上的所有工作。
重命名分支
git branch -m new-branch-name這會把當前分支重命名。打錯分支名稱的時候特別好用。
推送新分支到遠端
git push origin new-branch-name把本地新分支推送到遠端倉庫,這樣團隊成員就能看到並使用你的分支了。
合併與衝突解決
合併分支
git merge branch-name把指定分支合併到當前分支。
使用 --no-ff 保持合併歷史
git merge --no-ff branch-name這樣可以保留合併歷史,便於追蹤分支的合併情況。什麼意思呢?預設的 merge 如果可以 fast-forward 就不會產生合併 commit,加了 --no-ff 會強制產生一個合併 commit,讓你的 git log 更清楚地看到「這裡合併了一個分支進來」。
想深入了解 merge 和 rebase 的差別?看看 Merge vs Rebase 的差異與應用。
解決合併衝突
當合併出現衝突時,Git 會標記出衝突部分。別慌,手動解決後再提交就好了:
git add conflicted-file
git commit使用合併工具自動解決衝突
git mergetool這會啟動你配置的合併工具,幫助你更直觀地解決衝突。VS Code 的內建合併工具就很好用。
放棄合併
git merge --abort如果合併過程不如預期,或者衝突太多你暫時不想處理,用這個指令直接放棄合併,回到合併前的狀態。沒什麼好丟臉的,策略性撤退也是一種智慧。
還原與重置
還原單個文件
git checkout -- filename這會把文件還原到上次提交的狀態。注意,這個操作是不可逆的,還原後你的修改就找不回來了。
回退提交
如果你需要撤銷最近的提交,但保留變更,可以用:
git reset --soft HEAD^如果要撤銷最近兩次提交:
git reset --soft HEAD~2如果要徹底撤銷變更並回到提交前的狀態(小心使用!):
git reset --hard HEAD^重置的影響
這三個模式的差別搞清楚很重要:
--soft:只回退提交,保留暫存區和工作目錄的變更。就像是把 commit 拆開來,但你改的東西都還在。--mixed(默認):回退提交並重置暫存區,但保留工作目錄的變更。改的東西還在,但需要重新git add。--hard:回退提交並重置暫存區和工作目錄,所有未提交的變更將被刪除。這個最危險,用之前三思!
還原遠端提交
git revert commit-hash這會生成一個新的提交來撤銷指定的提交,而且不會影響提交歷史。這是在公共分支上撤銷變更最安全的方式,因為它不會重寫歷史。
進階的 rebase 操作
交互式 rebase
git rebase -i HEAD~3這可以讓你重新排序、修改或合併最近的提交,保持提交歷史的整潔。比如你連續做了三個小 commit,想合併成一個有意義的 commit,就可以用這個。
解決 rebase 衝突
- 當出現衝突時,手動編輯衝突文件以解決問題。
- 添加解決後的文件:
git add conflicted-file- 繼續 rebase:
git rebase --continuerebase vs merge
- Rebase:重寫提交歷史,使歷史更線性,適合在私有分支上使用。
- Merge:保留分支歷史,適合在公共分支上使用,能清楚看到分支的合併點。
選擇合適的方法取決於團隊的工作流程和需求。這部分內容在 Merge vs Rebase 的差異與應用 有更詳細的說明。
其他進階操作
cherry-pick 指定提交
git cherry-pick commit-hash選擇一個提交並把它應用到當前分支。適用於你想從一個分支挑選特定變更到另一個分支的情況。比如同事在 A 分支上修了一個 bug,你的 B 分支也需要這個修復,就可以直接 cherry-pick 過來。
stash 暫存進階用法
保存帶有訊息的 stash
git stash save "描述訊息"查看所有 stash 條目
git stash list應用特定 stash
git stash apply stash@{index}彈出 stash(應用並刪除)
git stash pop刪除特定 stash
git stash drop stash@{index}stash 就像是一個臨時的「口袋」,你可以把還沒做完的東西先塞進口袋裡,等處理完其他事情再拿出來繼續做。
reflog 檢查所有 Git 操作
git reflog顯示你所有 Git 操作的歷史記錄,方便查找回退點。即使你用 reset --hard 搞砸了什麼,reflog 通常還能救你一命。它就像是 Git 的「黑盒子」,記錄了你做過的所有操作。
log --graph 視覺化提交歷史
git log --graph --oneline --all這會顯示一個圖形化的提交歷史,方便理解分支和合併的過程。在終端機裡看到漂亮的分支圖,感覺就很 pro 對吧?
diff --staged 比較已暫存的文件變更
git diff --staged比較已經 git add 到暫存區的變更。在提交前跑一下這個指令檢查內容,是個好習慣。
tag 標記版本
創建輕量標籤
git tag v1.0.0創建註釋標籤
git tag -a v1.0.0 -m "Release version 1.0.0"推送標籤
git push origin v1.0.0標籤通常用在版本發佈的時候,讓你能快速找到某個版本對應的程式碼。更多關於版本發佈的內容,可以看 Release 管理。
實際案例
多人協作中的 rebase 使用
在多人協作的專案中,使用 rebase 可以保持提交歷史的整潔。例如,當你在功能分支上工作,需要把最新的 main 分支變更整合過來,可以用:
git checkout feature-branch
git rebase main這樣可以把 feature-branch 的提交基於最新的 main 分支,避免不必要的合併提交。
使用 stash 管理臨時變更
當你正在處理一個功能,但需要切換到另一個分支修復緊急問題,可以用 stash 暫存當前變更:
git stash save "正在開發新功能"
git checkout urgent-fix
# 修復問題並提交
git checkout feature-branch
git stash pop這樣可以方便地在不同任務間切換,而不會丟失未完成的工作。
延伸閱讀
- Git 基本指令 — 需要複習基礎的話回去看看
- Merge vs Rebase — 深入了解兩種合併策略的差異
- Git Flow — 結構化的分支管理模型
- GitHub Flow — 更簡潔的工作流程
- Release 管理 — 版本發佈的完整流程
- CommitLint 規範 — 讓你的 commit message 更規範