
reset --hard 按下去的那一刻你會怕,但學完 reflog 你就不怕了。
先講結論
這篇講的是 Git 的「後悔藥」和「急救包」:版本回退讓你反悔、stash 讓你暫停手邊工作、cherry-pick 讓你精準搬運 commit、reflog 在你搞砸一切時救你一命。搭配 上篇的分支管理 一起服用。
reset 三兄弟:搞懂差別很重要
git reset --soft HEAD^ # 只回退 commit,暫存區和工作目錄都還在
git reset --mixed HEAD^ # 回退 commit + 暫存區,工作目錄還在(預設)
git reset --hard HEAD^ # 全部回退,什麼都不留白話翻譯:
--soft:拆掉 commit,但改的東西都還在暫存區,馬上可以重新 commit--mixed:拆掉 commit,改的東西退回工作目錄,需要重新 add--hard:核彈級操作,回退後什麼都不留。用之前三思
回退兩次?用 HEAD~2。回退到特定 commit?用 git reset --soft abc1234。
revert:公共分支上的安全撤銷
git revert commit-hash跟 reset 不同,revert 會產生一個「反向 commit」來撤銷指定的提交,不會重寫歷史。在公共分支上要撤銷東西,永遠用 revert 而不是 reset。
stash:臨時口袋
正在做一件事,還不想提交,但又要切換分支處理緊急問題?
git stash # 把當前進度塞進口袋
git stash save "描述訊息" # 帶備註的 stash
git stash list # 看口袋裡有什麼
git stash pop # 拿出來並刪除 stash
git stash apply stash@{1} # 拿出特定的 stash(不刪除)
git stash drop stash@{1} # 丟掉特定的 stash實際場景:你在開發新功能,老闆突然說線上有 bug 要修。
git stash save "開發到一半的新功能"
git checkout main
git checkout -b hotfix/urgent-bug
# 修 bug、提交、合併...
git checkout feature-branch
git stash pop # 回來繼續cherry-pick:精準搬運
git cherry-pick commit-hash從另一個分支挑一個 commit 搬到當前分支。比如同事在 A 分支修了一個 bug,你的 B 分支也需要這個修復,直接 cherry-pick 過來就好,不用合併整個分支。
reflog:Git 的黑盒子
git reflog即使你用 reset --hard 搞砸了什麼,reflog 通常還能救你一命。它記錄了你做過的所有 Git 操作,包括那些「已經消失」的 commit。
找到你要回去的那個點,然後 git reset --hard <hash> 就能回去了。所以嚴格來說,在 Git 裡幾乎沒有什麼是真正不可逆的。
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 管理。
好用的檢視指令
git log --graph --oneline --all # 漂亮的分支圖
git diff --staged # 看暫存區裡改了什麼在提交前跑一下 git diff --staged 檢查內容,是個好習慣。
學完這篇和 上篇,你的 Git 功力已經超過大部分初階工程師了。但別驕傲,Git 的坑永遠比你想像的深。問問那些 force push 到 main 的人就知道了。
延伸閱讀
- 進階 Git 指令(上) — 分支管理與合併衝突
- Merge vs Rebase — 深入了解兩種合併策略
- GitHub Flow — 更簡潔的工作流程
- Release 管理 — 版本發佈的完整流程
- CommitLint 規範 — 讓你的 commit message 更規範