Git でコミットを取り消す・修正する方法 (git reset と git commit --amend)

git commit を行った直後に、間違えたファイルをコミットしてしまっていたり、コミットのメッセージに誤字があったりといった間違いに気が付き、コミットを取り消したいことがあります。 そうした場合には git resetgit commit --amend を利用してコミットを取り消すことができます。

コミットを取り消し、コミット直前の状態に戻す。

直前のコミットを取り消し、単純に取り消しコミット直前の状態に戻したい場合にはgit resetを--soft オプションと共に使います。

git reset --soft HEAD@{1}

解説

  • git reset --softは作業ツリー(現在のファイルの状態)とインデックス(git add されたファイルの状態)の状態を保ったまま HEAD を指定したコミット(今回の場合はHEAD@{1})に移動させます。
  • HEAD@{1}は HEAD が今のコミットに移動する前に指していたコミットを意味するので、今回の場合は間違えて行ったコミットのひとつ前のコミットを表します。

    • HEADの 1 番目の親(マージコミットでなければ単に親)を表すHEAD^ (あるいはHEAD^1) でHEAD@{1}を代用することもできます。
    • あるいはHEAD~ (== HEAD~1)で代用することも可能です。
    • @{1}, ^, ~については Git 公式のドキュメントが分かりやすいのでよく分かってない場合は参考にして下さい。
    • ORIG_HEADHEAD@{1}と(ほぼ?)同じものを指すので ORIG_HEAD でも代用できます。
  • そのためgit reset --soft HEAD@{1}によってgit commitを行う直前の状態に戻すことができます。
  • 修正を行って、直したファイルをgit addして改めて正しいコミットをやり直します。

    • コミットメッセージなどを取り消したコミットから再利用したい場合は git commit -c HEAD@{1}とします。
    • -cオプションで指定したコミットからメッセージなどをコピーした上でエディタが立ち上がります。
    • git reset後はHEAD@{1}は reset で取り消されたコミットを指しています。

一連の流れをコマンドで書くと以下のようになります。

$ git commit -m "間違ったコミット"
$ git reset --soft HEAD@{1}
<< 修正作業 >>
<< 修正したファイルをgit add >>
$ git add ...
<< コミットやり直し >>
$ git commit -m "正しいコミット"

直前のコミットを修正してやり直す

直前に行ったコミットを修正したい場合には git commit --amend を使うとgit reset --softを使った場合よりも手順が若干シンプルになります。amend は改正するとか修正するという意味です。

git commit --amendを行うと直前の修正したいコミットと、新しいコミットを合わせて 1 つのコミットにしてレポジトリにコミットされます。直前のコミットはなかったことになります。git commit --amend-mでコミットメッセージを付けずに実行すると直前のコミットからメッセージをコピーしてくれます(-cと同じ挙動)。一連の流れは以下のようになります。

$ git commit -m "間違ったコミット"
<< 修正作業 >>
<< 修正したファイル・足し忘れたファイルをgit add >>
$ git add <files>
<< 間違えてたしたファイルをgit rm >>
$ git rm --cached <files>
<< コミットやり直し >>
$ git commit --amend

git commit --amendは上で最初に紹介したgit reset --soft HEAD@{1}git commitを使った修正方法を短縮したものです。

最終更新: 3/9/2017