git add 取り消しとは、index(ステージ)に載せた変更を外し、作業木の中身は残したまま add の前に戻す操作です。
- git restore --staged・git reset --・git checkout -- が、それぞれ index と作業木のどちらを戻すか
- index がリポジトリに 1 本しかないため、他の席の add が自分の commit に混ざった当社の記録
- 取り消しに頼らず、git commit にファイルを指定して撃つ形と、その時に踏んだ落とし穴
当社は 1 つのリポジトリを、複数の AIエージェント の席が同時に触っています。この頁は、その中で「add したつもりの無い物が commit に入った」「戻したつもりが staged のまま残った」記録を、git の公式の文書の定義と並べたものです。
git add を取り消す命令と、戻る場所の違い
git の公式の文書では、git restore は何も指定しなければ作業木を戻し、--staged を付けると index だけを HEAD の中身に戻します。git reset -- <path> は git add <path> の逆で、git restore --staged <path> と同じ働きです。
| 命令 | 何をするか(公式の文書) | 作業木の中身 | 当社で起きた事 |
|---|---|---|---|
git restore --staged <path> | index だけを戻す。戻す元は既定で HEAD | 残る | commit の直前に本数が合わない時、余計な物を外すのに使う(社の実測 2026-09-19) |
git reset -- <path> | 指定したファイルの staged の版を HEAD の版にする。index だけを更新し、HEAD と作業木は変えない。git add の逆 | 残る | post-commit で、作業木が HEAD と一致する写しだけを index から外すのに使った(社の実測 2026-09-29) |
git restore --staged --worktree <path> | index と作業木の両方を戻す | HEAD の版に戻る(編集は消える) | pre-commit で止められた後の 1 手の戻し方(社の実測 2026-10-09) |
git restore <path>(git checkout -- <path> と同じ向き) | 作業木だけを戻す。戻す元は既定で index | index の版に戻る | これだけで戻したつもりが、staged(M)が残った(社の実測 2026-10-09・2026-10-15) |
git commit -- <path>… | パスを渡すと --only が既定になり、他のパスに staged された中身を入れずに、渡したパスの作業木の中身で commit する | 残る | 他の席の add を混ぜないための当社の撃ち方(社の実測 2026-09-20) |
出典: git-restore https://git-scm.com/docs/git-restore ・git-reset https://git-scm.com/docs/git-reset ・git-commit https://git-scm.com/docs/git-commit (いずれも 2026-11-05 に確認)。「当社で起きた事」の列は社の実測(日付は各行)。
index は 1 本:13 本 add して commit したら 14 本入った
git の index はリポジトリに 1 本しかなく、同じ作業木を触る全ての席で共有されます。ある席が自分のファイルを 13 本 add して commit したところ、commit には 14 本入りました(社の実測 2026-09-19)。混ざったのは、別の席が add していたファイル(87 行追加・35 行削除)です(社の実測 2026-09-19)。
その席は commit の前に git status で「別席の物は未 staged」と確かめていました。確かめた後、commit までの間に別の席が staging したのです(社の実測 2026-09-19)。内容は 1 文字も失われておらず(git diff HEAD -- <道> が空)、別の席の仕事が自分の commit 文の下に付いただけでした。それでも、どの変更が誰の何のためかという記録は崩れます。
翌日には、別の席が add すらしていない編集が、他の席の commit に相乗りして入りました(社の実測 2026-09-20)。status で確かめてから撃つ形は、確かめた瞬間と撃つ瞬間の間が空く限り、同時に動く席がいれば守れません。
対策は 2 つにしました(社の実測 2026-09-19)。
- commit の直前に
git diff --cached --name-onlyの本数が自分の add した本数と一致することを門にする。違えばgit restore --stagedで外す git commit -m "…" -- <道を全部列挙>と道を書いて撃つ。index の状態に依らない
同じ index を共有する所に別の席の変更が載る話は、git stash と autostash の頁や、Claude Code を並列で動かす頁でも別の角度から扱っています。
取り消すより先に、git commit にファイルを指定する
相乗りの後の 4 本は、git add -- <道> の後に git commit -m … -- <道を全部列挙> で出しました(社の実測 2026-09-20)。今は社の決まりとして、次の形で撃ちます。
| 場面 | 撃ち方 | 撃った後に測る物 |
|---|---|---|
| 新しいファイルを含む | git add -- <道> → git commit -m "…" -- <道を全部列挙> | commit に入った本数が列挙した本数と一致する |
| 既にあるファイルだけ | add せずに git commit -m "…" -- <道> | 同上 |
git mv A B | git commit -m "…" -- A B(移す前と後の両方を書く) | git ls-tree -r HEAD -- A | wc -l が 0 |
| しない事 | git add -A・ディレクトリ単位の add | — |
出典: 社の実測 2026-09-18・2026-09-20 と、git-commit https://git-scm.com/docs/git-commit (2026-11-05 に確認)。
この形で撃った 2 回は、どちらも別の席が同時刻に commit している最中でしたが、相乗りは 0 でした(社の実測 2026-09-20)。公式の文書の通り、パスを渡した commit は他のパスに staged された中身を入れないので、他の席が index に何を載せていても自分の commit には入りません。
1 つ注意があります。-m "…" は -- より前に置きます。-- の後ろに書くと、メッセージがパス名として読まれて commit が落ちます(社の実測 2026-09-20)。
git mv をパスを限って commit すると、古い紙が 2 か所に残る
git mv A B の後、パスを B だけに限って commit したところ、「移す前の A を消す側」が staged のまま残り、古い紙がリポジトリの 2 か所に在る状態になりました。これを 3 回踏みました(社の実測 2026-09-18)。
git mv は「A を消す」と「B を足す」の 2 つの変更を index に載せます。パスを限った commit は渡したパスの分しか入れないので、B だけを書けば A の削除は index に置き去りです。直しは、パスに A と B の両方を書くこと、撃った後に git ls-tree -r HEAD -- A | wc -l が 0 であることを測ることです(社の実測 2026-09-18)。
git checkout -- だけでは戻らない:staged が残る
pre-commit の門に止められた後、git checkout -- <file> だけで戻したつもりの席がありました。ところが checkout が戻したのは「index に staged された版」から作業木への写しだけで、index の staged(M)は残りました(社の実測 2026-10-09・2026-10-15)。公式の文書でも、--staged を付けない restore は作業木を index の中身から戻すと書かれています。
残った staged は、その席の外にも響きました。
- 他の席の
pull --rebaseが通らなくなった(社の実測 2026-10-09) - 2 時間後に、別の席の autostash に巻き上げられた(社の実測 2026-10-15)
直し方は次のどちらかです(社の実測 2026-10-09)。
git restore --staged <path>→git checkout -- <path>の 2 手(先に index を外し、次に作業木を戻す)git restore --staged --worktree <path>の 1 手
確かめは git status --porcelain が 0 行であることです。「戻した」は、index と作業木の両方が空になってから言います。
pre-commit の hook が add した写しが、本物の index に古いまま残る
パスを限った commit(git commit -- <paths>)では、pre-commit の hook の中で git add した写しは一時の index にしか入りませんでした。commit には入るのに、本物の index には古い写しが残り、次の commit でその写しが巻き戻りました(社の実測 2026-09-29)。
直しは post-commit です。作業木が HEAD と一致する写しだけを git reset -- <path> して index を揃えました(社の実測 2026-09-29)。一致を比べるのは git hash-object です。git diff HEAD は index に無い新しいファイルを「消えた」と読むため、比べる道具に使えませんでした(社の実測 2026-09-29)。
index に残った古い物は、押し出す側で他の席の仕事を上書きする事故にも繋がります。push の守り方は git push --force-with-lease の頁にまとめています。
よくある質問
git add を取り消すには、どの命令を使う?
git restore --staged <path> を使います。index だけを HEAD の中身に戻し、作業木の編集は残ります。git reset -- <path> も同じ働きで、公式の文書では git add の逆と書かれています(git-restore・git-reset)。
git commit で特定のファイルだけを commit するには?
git commit -m "…" -- <path>… のようにパスを渡します。パスを渡すと --only が既定になり、他のパスに staged された中身は入りません(git-commit)。-m は -- より前に置きます。後ろだとメッセージがパス名として読まれて落ちます(社の実測 2026-09-20)。
git checkout -- で戻らないのはなぜ?
git checkout -- <file> は作業木を index の版から戻すだけで、index に staged された変更は残るからです。当社では staged が残り、他の席の pull --rebase が通らなくなりました(社の実測 2026-10-09)。git restore --staged --worktree <path> で両方を戻し、git status --porcelain が 0 行かを確かめます。
git の index は、作業する人ごとに別?
別ではありません。index はリポジトリに 1 本で、同じ作業木を触る全員で共有されます。当社では 13 本 add した commit に、別の席が add していた 1 本が混ざって 14 本入りました(社の実測 2026-09-19)。
git mv したファイルを commit する時の注意は?
パスを限って commit するなら、移す前(A)と移した後(B)の両方を書きます。B だけだと A を消す側が staged のまま残り、同じ物が 2 か所に残ります(社の実測 2026-09-18)。撃った後に git ls-tree -r HEAD -- A | wc -l が 0 かを測ります。
出典
- git-restore Documentation https://git-scm.com/docs/git-restore (2026-11-05 に確認)
- git-commit Documentation https://git-scm.com/docs/git-commit (2026-11-05 に確認)
- git-reset Documentation https://git-scm.com/docs/git-reset (2026-11-05 に確認)
- 社の実測 2026-09-18・2026-09-19・2026-09-20・2026-09-29・2026-10-09・2026-10-15
ブルーランプ 記事の編集部/更新日 2026-11-05