Git日常開發中,我們經常需要撤銷一些錯誤操作,比如提交了錯誤代碼、誤刪了文件等。Git提供了git reset、git revert和git restore三個常用工具,它們功能相似但適用場景差異很大,初學者很容易混淆。下面我們詳細總結它們的區別,幫你在不同場景下正確選擇。
一、git reset:“硬刪”歷史的分支指針調整¶
1. 基本概念¶
git reset主要用於調整分支指針的指向,並選擇性丟棄部分提交的修改。它會“移動”分支指針到過去的某個提交,相當於“刪除”指針後的提交(若不保留)。
通俗比喻:你在書架上按順序放了A→B→C三本書(C是最新),reset就是直接把指針撥到B的位置,C看起來“消失”了(但實際可能還在,只是指針不指向它)。
2. 語法與模式¶
# 語法:git reset [模式] <目標版本>
# 模式:--mixed(默認)、--soft、--hard
--mixed(默認):
回退分支指針,並將暫存區重置到目標版本,工作區文件保留修改。
例子:回退到上一個提交(HEAD~1)
git reset HEAD~1 # 等價於 git reset --mixed HEAD~1
執行後:分支指針到A,暫存區是A的狀態,工作區保留C的修改(未暫存)。
--soft:
只回退分支指針,暫存區和工作區完全保留修改。
例子:回退到2個提交前,保留中間修改
git reset --soft HEAD~2
執行後:分支指針到A,暫存區和工作區仍有B、C的修改(可重新提交)。
--hard:
徹底丟棄目標版本之後的所有修改(分支指針、暫存區、工作區全部回退),最危險!
例子:回退到3個提交前,徹底刪除中間修改
git reset --hard HEAD~3
執行後:分支指針、暫存區、工作區均回到目標版本,後續提交的內容永久丟失。
3. 適用場景¶
- 本地未推送的快速回退:比如剛提交了錯誤代碼但還沒推到遠程,想立即回退到之前版本。
- 分支指針需要調整:比如團隊成員共用分支時,快速修正分支錯誤節點。
⚠️ 注意:若已推送的提交用reset --hard,會破壞團隊其他人的歷史,此時嚴禁使用!
二、git revert:“貼便籤”的歷史記錄保留¶
1. 基本概念¶
git revert會創建一個新提交,內容是“反向修改”之前某個提交的代碼,原提交歷史完整保留。
通俗比喻:你在紙上寫了錯誤的公式(B),然後在下面寫一個“修正公式”(D),原錯誤公式(B)仍存在,但D的存在讓所有人都知道哪裏錯了。
2. 語法與用法¶
# 撤銷最近1個提交(創建新提交)
git revert HEAD~1
# 撤銷指定提交(通過提交哈希)
git revert a1b2c3d # 假設a1b2c3d是要撤銷的提交哈希
3. 核心特點¶
- 歷史完整:不會刪除原提交,而是新增一個“撤銷提交”,所有人的本地倉庫都能同步到正確歷史。
- 安全回滾:即使已推送到遠程,
revert也能安全回滾,避免破壞團隊歷史。
4. 適用場景¶
- 已推送到遠程的分支回滾:比如線上環境發現bug,是由遠程分支的舊提交導致的,此時必須用
revert(reset會污染歷史)。 - 多人協作項目:需同步所有團隊成員的歷史,避免代碼衝突。
三、git restore:“恢復文件”的精準操作¶
1. 基本概念¶
git restore(Git 2.23+新增)專注於恢復文件到特定狀態(工作區或暫存區),不調整分支指針,完全聚焦於文件操作。
通俗比喻:你不小心把文件灑了,restore就是從“歷史備份”(如某個提交的版本)中把文件重新拿回來,既不影響其他文件,也不修改分支結構。
2. 語法與用法¶
# 1. 撤銷暫存區(恢復文件到工作區)
git restore --staged <文件名>
# 2. 恢復文件到歷史版本(工作區)
git restore --source=HEAD~1 <文件名> # 從HEAD~1版本恢復<文件名>
3. 常見場景¶
- 撤銷暫存區操作:比如誤
git add了一個文件,想回到未暫存狀態:
git restore --staged sensitive.txt # 撤銷對sensitive.txt的暫存
- 恢復單個文件到歷史版本:比如只修改了
app.js的錯誤內容,需回退到昨天的版本:
git restore --source=2023-10-01 app.js # 從指定日期的提交恢復app.js
4. 適用場景¶
- 單文件快速修正:不需要回退整個分支,僅恢復某一個文件的內容。
- 替代舊命令:
git checkout -- <文件>現在用git restore <文件>更明確,功能一致但語義更清晰。
四、三者核心區別與選擇¶
| 命令 | 核心操作 | 歷史完整性 | 適用場景 | 風險程度 |
|---|---|---|---|---|
reset |
調整分支指針,丟棄提交 | 不完整(丟棄部分歷史) | 本地未推送的快速回退 | 高(--hard易丟數據) |
revert |
創建新提交,反向撤銷 | 完整(新增撤銷提交) | 已推送的遠程分支回滾 | 低 |
restore |
恢復文件到特定狀態 | 不影響分支 | 單個文件回退/撤銷暫存 | 低 |
決策口訣:
- 本地未推、分支混亂 → reset(選--mixed保留修改,--hard徹底回退)
- 遠程已推、歷史要留 → revert(新增撤銷提交,同步團隊)
- 單個文件、恢復操作 → restore(精準恢復,不碰分支)
總結¶
Git撤銷操作的核心是“場景匹配”:reset像“物理刪除”歷史(危險),revert像“文明記錄”錯誤(安全),restore像“文件急救”(精準)。根據提交是否已推送、是否影響團隊協作,選擇合適的工具,就能高效解決回滾需求,避免踩坑!