git commitをやり直しする&取り消しする(「get commit --amend」と「git reset」)
git commitを実行あとでコミットをやり直したり、コミット自体を取り消す方法です。
直前にしたコミットをやり直す(git commit --amend)
直前にしたコミットをやり直す場合、「git commit --amend」を使用します。
例えば、直前のコミットログが以下のような状態だったとします。
実は直前のコミットに含めるべきであった「hoge.txt」が含まれていませんでした。
コミットログ(git commit --amend 実行前)
$ git log commit cca638b48b4c8be7ad5432f7882497534b04e2b4 Author: mrgoofy <hogehoge@example.com> Date: Wed Sep 8 23:03:57 2010 +0900 2nd Commit.-> New Add File : bar.txt
この直前のコミットに対して新たにファイルを追加してコミットをやり直すには、
- いつも通り git add でファイルを追加
- git commit --amend で直前のコミットをやり直す
という流れになります。
git add した後に git commit --amend
$ git add hoge.txt $ git commit --amend -m "2nd Commit.-> New Add File : bar.txt & hoge.txt" [master 325e5d3] 2nd Commit.-> New Add File : bar.txt & hoge.txt 2 files changed, 10 insertions(+), 0 deletions(-) create mode 100755 bar.txt create mode 100755 hoge.txt
git logを見てみると、コミットコメントも書き換わった形でコミットのやり直しが出来ています。
ただ、よく見ると「commit」の部分のIDが前のコミットのモノとは違うものになっています。
コミットログ(git commit --amend 実行後)
$ git log commit 325e5d3f193d1e7ceb57d718a15c4b28360c1bf9 Author: mrgoofy <hogehoge@example.com> Date: Wed Sep 8 23:03:57 2010 +0900 2nd Commit.-> New Add File : bar.txt & hoge.txt
「git commit --amend」を使用した場合、元のコミットを上書きするのではなく、元のコミットを無効にして、新たなコミットを作るという動作になります。
------o (325e5d3f1) -> やり直したコミット / -----o-------o (cca638b48) -> 間違ったコミット : コミット自体は残るが無効とされる
コミット自体を取り消したい場合
コミット自体を取り消しする(なかった事にする)には、「git reset」を使います。
「git reset」には「git reset --soft」と「git reset --hard」の2種類があります。
- 「git reset --soft」 → ワークディレクトリの内容はそのままでコミットだけを取り消す。
- 「git reset --hard」 → コミット取り消した上でワークディレクトリの内容も書き換える。
「git reset --soft」を使用する
「git reset --soft」は、ワークディレクトリの内容はそのままでコミットだけを取り消したい場合に使用します。
例えば、以下のような2件のコミットログのあるリポジトリに対して、「git reset --soft」をしてみます。
ワークディレクトリには「bar.txt」と「foo.txt」の2ファイルが存在しています。
コミットログ(git reset --soft 実行前)
$ git log commit abf80570906a5b8a1db8efdb0041d774f782bf8f Author: mrgoofy <hogehoge@example.com> Date: Wed Sep 8 23:05:54 2010 +0900 2nd Commit.-> New Add File : bar.txt commit a532d5a9ce88ddeaa0d521c13b05deb89b247bc2 Author: mrgoofy <hogehoge@example.com> Date: Wed Sep 8 23:05:23 2010 +0900 1st Commit.-> New Add File : foo.txt
ワークディレクトリ(git reset --soft 実行前)
$ ls -l total 2 -rwxr-xr-x+ 1 goofy なし 16 2010-09-08 23:05 bar.txt -rwxr-xr-x+ 1 goofy なし 15 2010-09-08 23:05 foo.txt
git reset --soft を実行
「git reset --soft HEAD^」の「HEAD^」はひとつ前のコミットの意味になるので、ここでは直前のコミットである「abf8057090 2nd Commit.…」を取り消すことになります。
$ git reset --soft HEAD^
コミットログ(git reset --soft 実行後)
コミットログから「abf805709 2nd Commit.…」が消えています。
$ git log commit a532d5a9ce88ddeaa0d521c13b05deb89b247bc2 Author: mrgoofy <hogehoge@example.com> Date: Wed Sep 8 23:05:23 2010 +0900 1st Commit.-> New Add File : foo.txt
ワークディレクトリ(git reset --soft 実行後)
「bar.txt」と「foo.txt」の2ファイルが存在したままで、「git reset --soft」実行前の状態がそのまま保持されています。
$ ls -l total 2 -rwxr-xr-x+ 1 goofy なし 16 2010-09-08 23:05 bar.txt -rwxr-xr-x+ 1 goofy なし 15 2010-09-08 23:05 foo.txt
「git reset --hard」を使用する
「git reset --hard」は、コミット取り消した上でワークディレクトリの内容も書き換えたい場合に使用します。
先程の「git reset --soft」で使用したディレクトリと同じ状態で試してみます。
コミットログ(git reset --hard 実行前)
$ git log commit abf80570906a5b8a1db8efdb0041d774f782bf8f Author: mrgoofy <hogehoge@example.com> Date: Wed Sep 8 23:05:54 2010 +0900 2nd Commit.-> New Add File : bar.txt commit a532d5a9ce88ddeaa0d521c13b05deb89b247bc2 Author: mrgoofy <hogehoge@example.com> Date: Wed Sep 8 23:05:23 2010 +0900 1st Commit.-> New Add File : foo.txt
ワークディレクトリ(git reset --hard 実行前)
$ ls -l total 2 -rwxr-xr-x+ 1 goofy なし 16 2010-09-08 23:05 bar.txt -rwxr-xr-x+ 1 goofy なし 15 2010-09-08 23:05 foo.txt
git reset --hard を実行
先程と同じく「HEAD^」で、直前のコミットの「abf8057090 2nd Commit.…」を取り消します。
$ git reset --hard HEAD^ HEAD is now at a532d5a 1st Commit.-> New Add File : foo.txt
コミットログ(git reset --hard 実行後)
「git reset --soft」の時と同様にコミットログから「abf805709 2nd Commit.…」が消えています。
$ git log commit a532d5a9ce88ddeaa0d521c13b05deb89b247bc2 Author: mrgoofy <hogehoge@example.com> Date: Wed Sep 8 23:05:23 2010 +0900 1st Commit.-> New Add File : foo.txt
ワークディレクトリ(git reset --hard 実行後)
「bar.txt」が削除され「foo.txt」のみが存在している状態になっています。
「git reset --hard」を実行した場合、ワークディレクトリについてもコミットを取り消した状態(今回の場合「a532d5a 1st Commit.…」)に戻されます。
$ ls -l total 1 -rwxr-xr-x+ 1 goofy なし 15 2010-09-08 23:05 foo.txt
今回参考にしたページ
Gitを使いこなすための20のコマンド - SourceForge.JP
http://sourceforge.jp/magazine/09/03/16/0831212/3
Gitの取消練習 - sinkin' in the rain
http://tsukamoto.tumblr.com/post/267736584