許可画面の判定表 — 見るだけ・注意・危険

Claude Code が打った Git のコマンド延べ約14,000回のうち、約8,200回は status・diff・log・show の見るだけのコマンドでした。残りの中に、ごくたまに、許可すると取り戻せないものが混ざります。この回では、第1部〜第3部のコマンドを安全(見るだけ)・注意・危険の3段に分けた判定表にまとめ、危険の段のコマンドで何が消えるのかを1コマンドずつ確かめます。最後に、迷ったときに許可の前に打つ安全策を見ます。

画面の見方
  • 上のターミナルは、実際に打ったときと同じ出力です(Git は英語で答えます)
  • 下の中で起きていることは、Git の中の何が変わったかを図にしたものです。丸がコミット、黒い札がブランチ、ピンクの札が HEAD です
  • 図の下に並ぶ3つの箱は作業ツリー・ステージ・HEAD のコミット(1-1 3つの場所)、その下は退避(stash)の棚です
  • 右の説明をスクロールして読み進めると、左のターミナルでコマンドが1つずつ打たれます。→ キーでも1つずつ進みます(← で1つ戻ります。スマホでは「次へ」ボタン)。最後まで進んでから → を押すと次の区間へ移ります。黄色く光っているのが、そのコマンドで変わった場所です

1. 3段の決め方 — 何が消えうるか、取り戻せるか

許可するかどうかは、何が消えうるかと消えたら取り戻せるかの2つで決めます。

  • 安全 見るだけ。手元のブランチ・ファイル・GitHub のどれも変えない。そのまま許可してよい
  • 注意 手元や GitHub が変わる。消えうるのはコミット済みのものだけ。何が変わるかを読んでから許可する
  • 危険 コミットしていない変更か、GitHub の歴史が消える。消えるものを逃がしてから許可する

分かれ目は、消えるものがコミットになっていたかどうかです。3-4 reflogで見たとおり、reflog(HEAD が通った場所の記録)はコミットを覚えているので、付箋から外れたコミットも reflog が残る間は辿り直せます。ステージや作業ツリーにだけあった変更、一度も add していないファイルは、どこにも記録されません。GitHub にだけあったコミットも、手元の reflog には出てきません。

これまでの回の表で「消えうるもの」がなしだった git add や git switch も、手元を変えるので、この回では注意の一番軽いところに置きます。git fetch は手元の写しの origin/main を動かすだけなので、見るだけの仲間です(2-3)。

2. 判定表

コマンドの欄は git の後ろの部分です。同じ段の中では、上ほど軽いものです。

判定コマンド何が起きるか消えうるもの取り戻せるか
安全status diff log show branch(名前なし)reflog stash list worktree list clean -n見るだけなし—
fetch / fetch -q手元の写し(origin/main)だけを動かすなし—
注意add commit revert merge pull --ff-only stash stash pop push記録を足す・付箋を進める(push は GitHub 側)・書きかけを棚へ出し入れするなし—
switch / checkout ブランチ / branch -d乗り換える・取り込み済みの付箋を剥がす。危ないときは止まるなし—
restore --staged ファイル / reset -q HEAD ファイルadd を取り消すadd の後に書き換えていたら、add した時点の版ふつうは作業ツリーに新しい版が残る
merge --abort / rebase --abort始める前に戻すコンフリクトを直しかけた中身戻らない
worktree add / worktree remove作業ツリーを増やす・片付ける。書きかけがあれば remove は止まるdetached HEAD の作業ツリーで作り、付箋を貼っていないコミット手元の reflog に残らない(4-3)
checkout コミットID / reset --soft HEAD~1 / reset HEAD~1 / commit --amend / rebase / pull --rebase付箋を動かす・コミットを作り直す付箋から外れたコミットreflog で戻せる
push --force-with-lease手元の写しが GitHub の今と同じときだけ付け替える直前に fetch していると、GitHub にだけあるコミット手元にはない(3-3)
branch -D確かめずに付箋を剥がすそのブランチにしか無いコミットへの道筋reflog が残る間は戻せる
stash drop退避を1つ、戻さずに捨てるまだ戻していない、その書きかけ出力に出る ID を控えていれば git stash apply ID で戻せる(1-7 stash)
危険reset --hard(行き先なし・HEAD~1・origin/main なども)ステージと作業ツリーを行き先の中身で上書き未コミットの変更すべて戻らない(外れたコミットは reflog)
checkout -- ファイル / checkout ファイル / restore ファイルそのファイルの作業ツリーをステージの中身で上書きそのファイルの未 add の変更戻らない
checkout HEAD -- ファイル / checkout -f ブランチ / switch -f ブランチステージと作業ツリーを HEAD や乗り換え先の中身で上書きそのファイル(-f はすべて)の未コミットの変更戻らない
clean -f / clean -fd追跡していないファイル(-d はフォルダも)を消す一度も add していないファイル戻らない
stash clear退避の棚を空にする棚にある、まだ戻していない書きかけすべてほぼ戻らない
worktree remove --force作業ツリーのフォルダを書きかけごと消すその作業ツリーの未コミットの変更と追跡していないファイル戻らない(4-3)
push --force / push -f確かめずに GitHub 側の付箋を付け替えるGitHub にだけあるコミット手元にはない(3-3)
reflog expire --expire=now --all / gc --prune=nowreflog と、辿れないコミットを今すぐ片付ける付箋から外れたコミットすべて戻らない

危険の段の大半は、作業ツリーやステージを上書きするコマンドです。付箋やコミットを動かすだけのものは、reflog が後ろで支えるので注意の段に収まります。ここから、危険の段の代表を動かしてみます。

3. git reset --hard — 書きかけがまとめて消える

1-5 resetで見たとおり、--hard はステージと作業ツリーを行き先の中身で上書きします。「いったんきれいにしてやり直します」や、2台で作業していて「GitHub に合わせます」(git reset --hard origin/main)と言うときに出てくる形です。

git reset --hard — 書きかけがまとめて消える

  1. 許可画面に git reset --hard が出たら、許可する前にまず git status を見ます。modified: todo.txt が書きかけ、Untracked files の draft.txt は一度も add していないファイルです。

    $ git status
    On branch main
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
    	modified:   todo.txt
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    	draft.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")
  2. git diff で、書きかけの中身を確かめます。+バターを買う の1行が、これから消えうるものです。

    $ git diff
    diff --git a/todo.txt b/todo.txt
    --- a/todo.txt
    +++ b/todo.txt
    +バターを買う
  3. 書きかけを add して、ステージに載せておきます。コミットはしていません。

    $ git add todo.txt
  4. 行き先を書かない git reset --hard は、付箋を動かさずに、ステージと作業ツリーを HEAD の中身で上書きします。HEAD is now at e5c0a62 パンを追加 は「HEAD のコミットの中身に戻した」という意味です。

    $ git reset --hard
    HEAD is now at e5c0a62 パンを追加
  5. 「バターを買う」が消えました。add してステージに載せていても、--hard はステージごと上書きします。

    $ cat todo.txt
    牛乳を買う
    卵を買う
    パンを買う
  6. 一度も add していない draft.txt は残っています。reset --hard は、Git が追跡していないファイルには手を出しません。

    $ git status
    On branch main
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    	draft.txt
    
    nothing added to commit but untracked files present (use "git add" to track)
  7. 増えたのは reset: moving to HEAD の1行で、指しているのは元と同じ e5c0a62 です。reflog はコミットの記録なので、コミットしていない「バターを買う」はどの行にもありません。これが「危険」の段に入る理由です。

    $ git reflog -2
    e5c0a62 (HEAD -> main) HEAD@{0}: reset: moving to HEAD
    e5c0a62 HEAD@{1}: commit: パンを追加

守られるのはコミットになったものだけで、add は守りになりません。一度も add していないファイルは対象外で、それを消すのは 5 節の git clean です。

4. checkout -- ファイル と restore — 1ファイルの書きかけが消える

Claude Code が打った git checkout 56回のうち、44回が git checkout -- ファイル でした。1-4 checkoutで見たとおり、ファイル名が付いた checkout はファイルを戻す仕事をします。git restore ファイル も同じ仕事です。

checkout -- ファイル と restore — 1ファイルの書きかけが消える

  1. notes.txt と todo.txt の2つに、書きかけがあります。

    $ git status
    On branch main
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
    	modified:   notes.txt
    	modified:   todo.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")
  2. notes.txt の「卵は10個入り」まで add して、ステージに載せます。

    $ git add notes.txt
  3. add したあとで、notes.txt にもう1行書き足します。この「牛乳は低脂肪」は、まだ作業ツリーにしかありません。

    $ echo "牛乳は低脂肪" >> notes.txt
  4. git checkout -- ファイル は、そのファイルの作業ツリーを ステージの中身 で上書きします。Updated 1 path from the index の the index がステージのことです。

    $ git checkout -- notes.txt
    Updated 1 path from the index
  5. add した「卵は10個入り」は残り、add していない「牛乳は低脂肪」だけが消えました。消えるのは そのファイルの未 add の変更 です。

    $ cat notes.txt
    特売は水曜
    卵は10個入り
  6. git restore ファイル も同じ動きで、何も出力しません。todo.txt の「バターを買う」は一度も add していないので、丸ごと消えました。

    $ git restore todo.txt
  7. 残っているのは、ステージに載せた notes.txt の変更だけです。

    $ git status
    On branch main
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
    	modified:   notes.txt
    
  8. HEAD を挟むと、ステージと作業ツリーの両方を HEAD のコミットの中身 で上書きします。出力の from e5c0a62 が、HEAD のコミットです。

    $ git checkout HEAD -- notes.txt
    Updated 1 path from e5c0a62
  9. add した「卵は10個入り」も消え、working tree clean になりました。どのコマンドも HEAD を動かさないので、reflog にも何も残りません。

    $ git status
    On branch main
    nothing to commit, working tree clean

何も挟まなければステージの中身で、HEAD を挟むと HEAD の中身で上書きします。-- は省けるので、checkout の後ろにファイル名があれば危険の側と覚えておきます。

5. git clean — 追跡していないファイルが消える

git clean は、追跡していないファイル(git status の Untracked files に並ぶもの)を消します。試しに作ったファイルの片付けに使いますが、自分が作ったばかりのファイルも同じく消えます。

git clean — 追跡していないファイルが消える

  1. Untracked files に、一度も add していない recipe.txt と scratch.txt があります。todo.txt には書きかけがあります。

    $ git status
    On branch main
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
    	modified:   todo.txt
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    	recipe.txt
    	scratch.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")
  2. git clean は、追跡していないファイルを消すコマンドです。-f が無いと refusing to clean(消すのを断ります)と止まり、何も消しません。

    $ git clean
    fatal: clean.requireForce is true and -f not given: refusing to clean
  3. -n は、消すものを見せるだけです。Would remove の行が、-f を付けたら消えるファイルです。

    $ git clean -n
    Would remove recipe.txt
    Would remove scratch.txt
  4. recipe.txt は残したいので、add して追跡に入れます。

    $ git add recipe.txt
  5. もう一度見ると、Would remove は scratch.txt だけになりました。

    $ git clean -n
    Would remove scratch.txt
  6. -f で本当に消します。Removing scratch.txt と出て、作業ツリーから無くなりました。

    $ git clean -f
    Removing scratch.txt
  7. add した recipe.txt と、追跡している todo.txt の書きかけは残っています。消えた scratch.txt は一度も add していないので、Git のどこにも中身が残っていません。

    $ git status
    On branch main
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
    	new file:   recipe.txt
    
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
    	modified:   todo.txt
    

reset や checkout で消えた書きかけは、少なくとも前の版がコミットに残っています。追跡していないファイルは、Git が一度も中身を受け取っていません。だから Git も -f が無いと動きません。clean -f を見たら、先に git clean -n を頼んでください。git stash は追跡していないファイルを退避しないので、clean の前の守りになりません(1-7)。

6. git branch -D — 付箋は剥がれても、コミットは戻せる

git branch -D は確かめずにブランチを消すので、危険に見えます。この表では注意の段の一番重いところに置きました。消すのは付箋で、コミットではないからです。

git branch -D — 付箋は剥がれても、コミットは戻せる

  1. 献立を試しに書くブランチ menu を作って乗ります。

    $ git switch -c menu
    Switched to a new branch 'menu'
  2. 新しいファイル menu.txt を作ります。

    $ echo "月曜はカレー" > menu.txt
  3. ステージに載せます。

    $ git add menu.txt
  4. menu だけが1つ先へ進みました。「献立を書く」は、menu の付箋からしか辿れません。

    $ git commit -m "献立を書く"
    [menu d24492c] 献立を書く
     1 file changed, 1 insertion(+)
     create mode 100644 menu.txt
  5. main に戻ります。

    $ git switch main
    Switched to branch 'main'
  6. 小文字の -d は、main に取り込まれていないコミットがあると not fully merged で止まります。hint は「本当に消すなら -D で」と言っています。

    $ git branch -d menu
    error: the branch 'menu' is not fully merged
    hint: If you are sure you want to delete it, run 'git branch -D menu'
  7. 大文字の -D は、確かめずに付箋を剥がします。「献立を書く」は薄くなりました。(was d24492c) が、剥がす前に指していたコミットです。

    $ git branch -D menu
    Deleted branch menu (was d24492c).
  8. HEAD の reflog には、menu にいたときの commit: 献立を書く が HEAD@{1} として残っています。コミットしたものは、reflog が残っている間は辿れます。

    $ git reflog -3
    e5c0a62 (HEAD -> main) HEAD@{0}: checkout: moving from menu to main
    d24492c HEAD@{1}: commit: 献立を書く
    e5c0a62 HEAD@{2}: checkout: moving from main to menu
  9. そこに同じ名前の付箋を貼り直します。今いる main には触りません。

    $ git branch menu HEAD@{1}
  10. 「献立を書く」が戻りました。だから -D は、書きかけを消すコマンドとは分けて「注意」の段に置きます。

    $ git log --oneline --all
    d24492c (menu) 献立を書く
    e5c0a62 (HEAD -> main) パンを追加
    8b41d07 卵を追加
    3f2a9c1 牛乳を追加

剥がした付箋のコミットはコミット済みなので、HEAD の reflog が残る間は辿り直せます(3-4)。ただし reflog は時間がたつと片付けられるので、許可する前に git log --oneline ブランチ名 -3 で中身を見ておくと確実です。

7. GitHub の歴史が消える — push --force

もう1種類の危険が、GitHub 側の歴史が消えるものです。git push --force は GitHub 側の付箋を手元の位置へ付け替えるので、もう1台の PC が push したコミットが外れます。GitHub にだけあったコミットは、手元のどの reflog にも出てきません。Windows と Mac の2台で使っていると、Mac の push を Windows からの force push で消すことが起こりえます(3-3)。main への --force は許可せず、作業ブランチなら --force-with-lease に変えてもらいます。

並行セッションで使う git worktree remove --force(実測25回)も危険の段です。作業ツリーを書きかけごと消します。仕組みは次の回で見ます。

8. 迷ったときの安全策 — 先に逃がしてから許可する

危険の段のコマンドでも、Claude Code が打とうとする理由はたいてい正しいものです。困るのは、そのついでに自分の書きかけまで消えることです。許可する前に、書きかけを逃がしておきます。

危険なコマンドの前に、書きかけを退避する

  1. Claude Code が、直前のコミット バターを追加 を取り消すために git reset --hard HEAD~1 の許可を求めてきた場面です。まず、取り消すコミットが一番上にあるのを確かめます。

    $ git log --oneline -3
    71d9b3e (HEAD -> main) バターを追加
    e5c0a62 パンを追加
    8b41d07 卵を追加
  2. notes.txt に自分の書きかけがあります。このまま --hard を許可すると、これも消えます。

    $ git status
    On branch main
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
    	modified:   notes.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")
  3. 許可する前に、書きかけを 退避の棚 にしまいます。

    $ git stash
    Saved working directory and index state WIP on main: 71d9b3e バターを追加
  4. working tree clean になりました。これで --hard が上書きしても、消える書きかけはありません。

    $ git status
    On branch main
    nothing to commit, working tree clean
  5. ここで許可します。main の付箋が パンを追加 に戻り、作業ツリーもその中身になりました。

    $ git reset --hard HEAD~1
    HEAD is now at e5c0a62 パンを追加
  6. 退避した書きかけを戻します。Dropped refs/stash@{0} は、戻したので棚から外した、という意味です。

    $ git stash pop
    On branch main
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
    	modified:   notes.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")
    Dropped refs/stash@{0} (7cfbe44288cbee281ae388b9dddf5da565048dae)
  7. 「卵は10個入り」が戻ってきました。

    $ cat notes.txt
    特売は水曜
    卵は10個入り
  8. 取り消した バターを追加 は、HEAD@{1} の 71d9b3e として残っています。コミットしたものは reflog から、書きかけは棚から、どちらも戻せる状態で危険なコマンドを通せました。

    $ git reflog -2
    e5c0a62 (HEAD -> main) HEAD@{0}: reset: moving to HEAD~1
    71d9b3e HEAD@{1}: commit: バターを追加

stash の代わりに、仮のコミットで逃がしてもかまいません。コミットになっていれば、付箋から外れても reflog から拾えます。clean の前は git clean -n、branch -D の前は git log、force push の前は git fetch と git status で、消えるものを先に見ます。

9. Claude Code の許可画面で見かけたら

許可画面では、コマンドの名前より先に付いている印を見ます。

見る場所例判定と、何のしるしか
--hardreset --hard危険 ステージと作業ツリーを上書きする
--force / -fpush --force / clean -f / worktree remove --force危険 止まるはずの安全装置を外す
-- や後ろのファイル名checkout -- todo.txt / restore todo.txt危険 そのファイルの書きかけを捨てる
drop / clear / --prunestash clear / gc --prune=now危険 取り戻すための控えを捨てる
大文字の -Dbranch -D注意 確かめずに付箋を剥がす

印が無く、status・diff・log・show・fetch で始まるものは見るだけです。確認を省く設定にしてよいのは、この安全の段だけです。危険の段は、許可する前に git status を自分の目で見ると決めておけば、取り戻せないものを消す場面はまず起きません。

まとめ

  • 許可の判断は「何が消えうるか」と「消えたら取り戻せるか」で決める。reflog が覚えているのはコミットだけ
  • 安全は見るだけ(fetch を含む)。注意は変わるが、消えうるのはコミット済みのものだけ。危険は未コミットの変更か、GitHub の歴史が消える
  • 危険の代表は reset --hard・checkout -- ファイル・restore ファイル・clean -f・stash clear・worktree remove --force・push --force。branch -D は付箋だけなので注意
  • 迷ったら git status → stash か仮のコミット → 許可。clean は -n で先に見る

次の回では、Claude Code が並行してセッションを走らせるときに使う git worktree を扱います。1つのリポジトリに作業ツリーと HEAD をいくつも持たせる仕組みをコミットグラフで見て、この表で危険の段に置いた git worktree remove --force で何が消えるのかを確かめます。