下拉重新整理
tech 公開 git git-reset version-control vibe-coding dhh beginner

git reset 白話說明:commit 是存檔,reset 是讀檔重來

以「打電動存檔/讀檔」的比喻,用最簡單的方式解釋 git reset 的原理——commit 就是按一次存檔點,reset 就是放棄目前進度、倒回某個存檔點。對應 DHH 談 vibe coding「不會難過地用 git reset 把幾千行沖進馬桶」的情境:因為有存檔點當安全網,丟掉實驗的成本幾乎是零,才敢大膽亂試。含 --hard 與 --soft 差異、常用指令、以及「先 commit 再放心 reset」的關鍵前提。

| 匯入於 2026-06-15 |

這頁回答一個常見問題:DHH 在談 vibe-coding-criticality-spectrum 時說,他敢叫 AI 一口氣寫幾千行、
覺得不對就git reset 把它們「沖進馬桶」也不心疼——這裡的 git reset 到底在做什麼?
用最白話的方式說明。

全景圖解

git-reset-rpg-infographic.jpg

整張圖一次看懂:上排是「冒險中 → 存檔(commit) → 讀檔(reset) → 放棄進度丟掉變更」的打電動比喻;
中排對比 reset --soft(回到存檔點但變更保留在暫存區與工作區)與 reset --hard(回到存檔點並清空暫存區與工作區);
下排是常用指令(git log --onelinereset --soft/--hard <commit>reset --hard HEAD~1)。

一句話比喻

Git 就像打電動會存檔。每次 git commit 就是按一次存檔點

git reset = 讀取舊存檔、放棄目前進度,把專案倒回到你選的那個存檔點。

DHH 的情境拆解

  1. 他叫 AI 一口氣 vibe code 出幾千行——這些還沒存檔(還沒 commit),只是「目前畫面上的改動」。
  2. 看一看覺得方向不對。
  3. 一行 git reset --hard,就倒回最後一個存檔點,那幾千行瞬間蒸發,專案乾乾淨淨,像沒發生過。

這就是「不會難過地把幾千行沖進馬桶」的意思:有存檔點當安全網,丟掉實驗的成本幾乎是零,
所以才敢大膽亂試多種可能。這也呼應 dhh-basecamp5-vibe-coding-rails-future 裡 vibe coding 的精神。

心智模型圖

flowchart LR
    A[存檔點 A<br/>commit] --> B[存檔點 B<br/>commit]
    B --> W[目前畫面上的改動<br/>AI 寫的幾千行<br/>未 commit]
    W -. git reset --hard B .-> B
    style W stroke-dasharray: 5 5

reset --hard B = 回到存檔點 B,把 B 之後那些「還沒存檔的實驗」全部丟掉。

稍微具體一點:兩種味道

git reset <存檔點> 主要兩種:

  • git reset --hard <存檔點>連同你畫面上的改動一起丟掉,徹底回到那個存檔點的樣子。 (DHH 沖馬桶講的就是這個)
  • git reset --soft <存檔點> — 只把「存檔指標」往回移,但改動還留在畫面上, 給你重新整理、再存一次。

最常用的兩個指令

# 倒回上一個存檔點,丟掉之後所有改動(畫面回到最後一次 commit 的乾淨狀態)
git reset --hard HEAD

# 再往前倒一個 commit
git reset --hard HEAD~1
  • HEAD = 「目前所在的存檔點」。
  • ~1 = 「往前一個」,~2 就是往前兩個,以此類推。

一個要小心的點(也是 DHH 玩法的前提)

--hard 丟掉的是還沒 commit 的東西,丟了通常救不回來

所以這套「大膽亂試」成立的關鍵前提是:

真正想留的進度,要先 git commit(先存檔)。

這樣 reset --hard 沖掉的永遠只是「存檔之後的實驗」,不會誤傷你珍惜的成果。
換句話說:勤存檔,才能放心讀檔重來。

總結

commit 是存檔,reset --hard 是讀檔重來。
先養成勤 commit 的習慣,就能像 DHH 一樣,把 AI 寫壞的幾千行一鍵沖掉而不心疼。

延伸閱讀

© 2025-2026 Nickle Cheng Built with Ruby Ruby on Rails