コードの履歴管理ツールGitを使っていると、ファイルを編集したけど、その内容を全て削除したい、git addしてステージングしたけど、コミットはせずに全ての変更内容をなかったことにしたい(直近のコミットの状態に戻したい)ということがあります。
ここでは、そんな、コミット前の作業を削除する方法についてまとめています。
git checkout .(ドット)がどんな処理をしているかについても解説しています。
ファイルの変更・修正内容を削除する方法
修正を加えたファイルの変更や修正内容を削除して、直近のコミットの状態に戻す方法は、どのファイルを戻すかによって、主に次の2つがあります。
git addしたファイルも全て元に戻す
git addしたファイルも全て元に戻すには以下のコマンドを実行します。
git reset --hard HEAD
git resetは指定したコミットに戻るためのコマンドです。
オプションに「–hard」をつけることで変更内容を全て削除することができます。
戻りたいコミットで現在のブランチが指している最新のコミットを表す「HEAD」を指定することで、直近のコミットの状態に戻すことができます。
なお、「HEAD」を「@」にしても同じ処理になります。
git reset --hard @
git addする前の変更を全て元に戻す
git addしたものはそのままで、git addする前の変更を全て元に戻したい場合は「git checkout」を使います。
git checkout .
これで、git add前のすべてのファイルを直近のコミットの状態にするコマンドです。
以下で「git checkout .」の詳細について解説しています。
git checkout . (ドット)の意味は何か?
git checkoutは何をしているか?
git checkout
はブランチ名を指定して、ブランチを切り替えるときに使うのが一般的です。
このためgit checkoutはブランチを指定したり切り替えるコマンドだと思っている人がいますが、本質的には違います。
git checkout ブランチ名
としたとき、裏側で行われている処理は、指定したブランチが指しているコミットに移動するという処理です。
すなわちコミットを指定しているということです。
特定のファイルのみ、指定したコミットの状態に戻す
git checkoutは指定したコミットに移動する処理であるため、移動したいコミットとファイルパスを指定することで、指定したファイルのみ、指定したコミットの状態に戻すことができます。
$ git checkout <コミット> <ファイル or ディレクトリパス>
なお、ファイルパスは相対パスで記述でき、ワイルドカード「*」も使えます。
また、ファイルではなくディレクトリを指定することもできます。ディレクトリを指定した場合は、そのディレクトリ配下のファイルが全て、指定したコミットの状態に戻ります。
実例:ファイルを指定
$ git checkout f7325fc test.txt
Updated 1 path from the index
実例:ワイルドカードを使って指定
「st.tx」という文字列を含むすべてのディレクトリやファイルを対象にしたい場合は以下のようにします。
$ git checkout f7325fc *st.tx*
Updated 1 path from 024ecc9
コミットを指定しない場合
git checkoutではコミットを指定せずに、ファイルパスやディレクトリパスだけを指定する記述もあります。
その場合、コミットは最新のコミットを指しているのと同じになります。
$ git checkout <ファイル or ディレクトリパス>
この使い方で、現在のディレクトリを指す「.」を指定すると、現在のディレクトリにある全てのファイルが、直近のコミットの状態に戻ります。
$ git checkout .
このため、「git checkout .」とすることで、コミット前の編集した内容を全て削除することができます。
「git checkout .」の実例
例えば、以下のようにgit add済みのファイル「resources/views/index.blade.php」と、ステージ前の変更を加えたファイル「app/Http/Controllers/UserController.php」があるとします。
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: resources/views/index.blade.php
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: app/Http/Controllers/UserController.php
この状態で「git checkout .」します。
$ git checkout .
Updated 1 path from the index
再度git statusで状態を確認します。
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: resources/views/index.blade.php
git add 前の「app/Http/Controllers/UserController.php」の変更内容が消えて、git add後の「resources/views/index.blade.php」のみになったことがわかります。
git checkout .やgit reset –hardでUntracked filesは消せない
Untracked filesは消せない
新規作成でgit addも何もしていないファイルはGitが未追跡なので、git checkout .
やgit reset --hard HEAD
で戻すことができません。
「git status」で確認すると「Untracked files」(未追跡ファイル)と表示されるファイルです。
実例
例えば以下のように、ステージング済みのファイル「text.txt」と未追跡のファイル「app/assets/stylesheets/articles.scss」があるとします。
#状態確認
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: test.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
app/assets/stylesheets/articles.scss
このファイルに、「git reset –hard @」を実行して、全ての変更を削除します。
$ git reset --hard @
HEAD is now at 9aa0fb6 [A]test.txt3
再度、git statusをして状態を確認します。
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
app/assets/stylesheets/articles.scss
nothing added to commit but untracked files present (use "git add" to track)
git addしたファイルは削除されていることがわかりますが、「Untracked files」がそのまま残っています。
未追跡ファイル(Untracked files)を削除する方法
未追跡ファイルは、git clean
で削除することができます。
未追跡のファイルを削除する方法
$ git clean -f
未追跡のディレクトリを削除する方法
$ git clean -df
実例(未追跡ファイルやディレクトリの削除)
例えば以下のように「Untracked files」に複数のファイルとディレクトリがあるとします。
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
app/assets/stylesheets/articles2.scss
app/assets/stylesheets/test.scss
app/views/articles2/
app/views/test/
nothing added to commit but untracked files present (use "git add" to track)
この状態で「git clean -f」を実行します。
$ git clean -f
Removing app/assets/stylesheets/articles2.scss
Removing app/assets/stylesheets/test.scss
すると、未追跡のファイルだけ削除されたことがわかります。
未追跡のディレクトリはそのまま残っている状態です。
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
app/views/articles2/
app/views/test/
nothing added to commit but untracked files present (use "git add" to track)
未追跡のディレクトリを削除するためには、git cleanコマンドで「-df」オプションを実行します。
$ git clean -df
Removing app/views/articles2/
Removing app/views/test/
すると、ディレクトリも削除できました。
git statusで確認すると完全にクリーンになっていることがわかります。
$ git status
On branch master
nothing to commit, working tree clean