開発ブログ

WWWクリエイターズが送る、Git, CSS, HTML, コマンドライン、Macの便利機能など、開発に関する役立ち情報発信します。気まぐれに更新。

git add の取り消し方法、徹底まとめ。

最終更新:2017-06-13 by Joe

git add してしまったファイルを取り消しするgit コマンドです。

整然と、意図をもってコミットを作成して履歴を育てて行くには、git addによるインデックスの作り方を覚えておくことは、すごく重要です。今まで「なんとなく」できていたのですが、仕様に関する理解がぼんやりだったので、今回は深掘りしてしっかり理解し、まとめました。

git add したファイルを取り消すコマンド

全てのファイルのaddを一括で取り消す

git add したファイルの変更内容を、インデックスから削除します。

git resetに、HEADと指定するか、もしくは引数なしでデフォルトでHEADを指定した事になります。作業ツリーの状態はそのままで、インデックスへaddした変更が、元の状態に戻ります。必要なファイルをaddし直して下さい。

ちなみに、インデックスから変更を取り除くことを「unstage(アンステージ)」と呼びます。インデックスに入れることを「stage(ステージ)」と呼ぶ動作の逆を行うことを意味します。

ファイル(フォルダ)を限定してaddを取り消す

特定のファイルのみ、変更内容をインデックスから削除します。こちらも作業ツリーはそのままです。

<path>と書いたのは、フォルダを指定することで、フォルダ配下のすべてのファイルを指定できるからです。これはaddのときも一緒ですね。

これらの操作を「git addの取り消し」と呼ぶよりは、「インデックスを、HEADのコミット状態にリセットする」と言った方が誤解が少なく、イメージもしやすいかもしれません。

さて、以下、このgit resetの動作について、詳しく見ていきます。

git reset についてちゃんと理解しよう!

git reset は何するのか?

git reset は「現在のブランチの先頭(とブランチ履歴)」と「インデックスの状態」を、指定されたコミットに強制的に書き換えます。

HEADは通常、現在のブランチの先頭コミットを参照していますので、「git reset HEAD」と、HEADの指している状態へのリセットに施す事により、インデックスの状態がコミットのと同じ状態になる、すなわち、もとに戻る、というわけです。

(実際は「git reset」とコミット指定を省略すると、デフォルトでHEADとなります。)

※git reset(モード指定なし)は作業ツリーには何もしません。モードの詳細は後述。

git resetは、「git addの取り消し」ではない

注意が必要なのが、例えば「最後のcommitから2回以上のaddした。」という場合、1回目の変更含めて、すべてリセットされてしまいます。ですので、本当の意味での、「git addコマンドの実行1回分の取り消し」はgitでは不可能です。

git では一般的に、コミットしたり、stashしていない変更内容は、一度失われると取り返せません。

HEAD以外のコミットにresetする場面

git resetは、引数で「HEAD」以外のコミットを指定できます。このような別のコミットの指定を行う場合、git reset の代表的な3種類のモードを使い分けるケースが多いです。

git resetのモード

冒頭の「取り消し」の操作で使ったのは、引数なしのmixedモードでした。

モード指定 動作
git reset –soft 現在のbranchの先頭だけをリセット。(インデックスはそのまま)
git reset
(git reset –mixed)
現在のbranchの先頭と、インデックスをリセット
git reset –hard 現在のbranchの先頭、インデックスも作業ツリーも全部リセット

git reset –softはいつ使うの?

例えば、最新のコミットの内容をちょっとだけ修正したい時にgit reset –soft HEAD^ とすると、直前のgit インデックスには最新の変更を取り出して、それがまだコミットされていない状態に戻れます。

もし「デバッグコード削除し忘れ」の修正であれば、あとはコードを削除してgit commit を実行するだけでコミットをやり直せます。逆に、それ以外の用途は、あまり思いつきません。

git reset はいつ使うの?

上述のaddの取り消しの例など、addをやり直すなど、コミットを作っている最中に使うかもしれません。

git rest –hard はいつ使うの?

例えば、「ローカルブランチをリモートブランチで強制上書きする」などする時に、一撃必殺技的に使うことが多いです。ローカルブランチの歴史もろとも、不要なものを全部消し去って、特定の基準点に一気に帰りたい時、ということだと思います。とにかく、インデックス、作業ツリーの状態を無視して(変更があろうがなかろうが吹き飛ばして)origin/masterと同じ状態を作り出します。脅威の–hardです。

git resetについて、より詳しくは、こちらをご覧下さい:

addしたファイルとHEADの差分を確認するコマンド

最後におまけコーナーです。

addしたり、resetしたりしていると「いまインデックスがどんな状態か」わかりにくくなりそうですが、下記が差分を見るコマンドです。–cachedにより、普段は作業ツリーを対象としているdiffの振る舞いを、インデックスへ変更することができるのでした。

diffの振る舞いについては、「git diff を攻略!よく使う便利オプションのまとめ、完全版。」に詳しくまとめたので、ぜひご覧下さい。

参考リンク

git addも、git resetもだいたいマニュアルには書いてありますね。読みにくいのが難。

git commit の取り消し走査に関しては、こちらを御覧ください

 

以上となります。

それでは、楽しいgit ライフを。