はじめに
git commitを取り消すメモ。 ほとんど手順メモ程度な感じ+他記事で使うスニペット記事。
とはいえ、数あるgit便利コマンドの中で毎回使うものではないけど
いざって時に役立つ、もしくは、困るのは取り消し系のコマンドですよね。
補足
他の取り消しもぱっと見たい自分用にまとめたので参考までに。
アジェンダ
git reset
でgit commitを取り消すgit revert
でgit commitを取り消すgit commit
でgit commitを取り消す- それぞれやってみる
git reset
、git revert
、git commit
のそれぞれのコマンド例と
やってみた操作ログ的なものは一緒にすると長くなりそうだったので、
やってみた系は最後にまとめました。
1. git reset
でgit commitを取り消す
git reset
でgit commit
を取り消します。
git add
の取り消しにも使えるので便利ですね。
しかし使い方が若干違うのでこちらと比べて見てみるとよりわかりやすいかもしれません。 →【git】git addを取り消す
コマンド例
このログの状態のときを例とします
※ git logを確認 $ git log --oneline 49a715d commit sample2 693755b commit sample 8189e9c Initial commit
2つ前のcommitを取り消し
つまり8189e9c Initial commit
だけの状態にするコマンドは
いつくかありますがこんな感じです。
※ 2つ前のcommitを取り消し $ git reset --soft HEAD^^ ※ 2つ前のcommitを取り消し $ git reset --soft HEAD~2 ※ 最初のコミットに戻す(2つぶんコミット取り消し) $ git reset --soft 8189e9c
ポイント
HEADを使うと^^
であれ~2
であれ2つ前までのcommitを取り消す、という感じですが、
commitハッシュを用いると3つ前の8189e9cを使うところは気をつけたいですね。
また、ポイントはオプションの--soft
と--hard
の違い、そしてHEAD
についてでしょうか。
--soft
と--hard
の違い
違いを簡単にまとめるとこんな感じです。
--soft
... commitだけを取り消したい--hard
... commit取り消し + ワークディレクトリの内容も書き換え
HEAD
HEADの後ろについては2つだけ覚えればたいていことたります。
HEAD^
...HEAD
+^
で直前のcommitを表すHEAD~{n}
...HEAD
+~{n}
で{n}こ前のcommitを表すつまり
HEAD^^
=HEAD~2
ってことですね。
2. git revert
でgit commitを取り消す
git revert
を使うと、
指定したcommitを打ち消すようなcommitを行います。
逆向きのcommitというらいしですが、戻した履歴も残す取り消しな感じです。
追加したものは無かったことに、消したものは復活し、変更したものは変更を元にもどすそんな感じですね。
コマンド例
※ git logを確認 $ git log --oneline 693755b commit sample 8189e9c Initial commit ※ 1つ前のcommitハッシュを指定 ※ エディタが開かれるのでとりあえずそのまま保存して終了でrevert確定 $ git revert 693755b ※ git logを確認 $ git log --oneline 567254a Revert "commit sample" 693755b commit sample 8189e9c Initial commit
ポイント
ログには戻したという履歴も残ります。
上記の例で言うと戻すのを戻すという操作を行いたい場合
567254a
を指定して再度revertすることもできます。
3. git commit
でgit commitを取り消す
git commit
で取り消すというよりは、直前のcommitに上書きするといった感じです。
直前にcommitしたものに修正が足りなかった場合や、
余分にファイルをcommitしてしまった場合などに
それらを正しい状態に直して直前のcommitに無理やり入れる感じです。
コマンド例
※ git logを確認 $ git log --oneline 2ed0aab commit sample 8189e9c Initial commit ※ 足りなかった修正を加える ※ 余分なファイルを`git rm ファイル`で消す ※ などをここで行ったと仮定 ※ --amendする $ git commit --amend ※ 正しい状態を入れつつ、直前のcommitに取り込んで新しいcommitハッシュを振りなおす $ git log --oneline 0c91475 commit sample 8189e9c Initial commit
ポイント
- commitしたけど実は修正が漏れていた
- 余分なファイルをcommitしてしまった
などはよくありがちなので、その際にresetでいったん戻してから再度全部commitしなおすとかしなくて良いので楽ですね。
4. それぞれやってみる
前提条件として、
git reset
、git revert
、git commit
をやってみる前に
それぞれこの状態だったと仮定して進めます。
それぞれをやる前の初期状態
※ ログ確認 $ git log --oneline 8189e9c Initial commit ※ README.mdのみaddもcommitもしてある状態 $ ls -al drwxr-xr-x 15 hoge hoge 510 6 7 04:25 .git -rw-r--r-- 1 hoge hoge 18 6 6 15:08 README.md ※ ログ確認 $ git log --oneline 8189e9c Initial commit ※ 新規のファイルを追加・修正した状態 $ tree . ├── README.md ├── img │ └── sample.png └── index.html ※ statusを確認 ※ index.htmlとimgディレクトリはまだaddもしていない状態 $ git status Your branch is up-to-date with 'origin/master'. Untracked files: (use "git add <file>..." to include in what will be committed) img/ index.html nothing added to commit but untracked files present (use "git add" to track)
git reset
git reset --softの確認
※ すべてadd $ git add . ※ commit $ git commit -m 'commit sample' ※ ログを確認 $ git log --oneline 98232e3 commit sample 8189e9c Initial commit ※ 直前のcommitを取り消し $ git reset --soft HEAD^ ※ ログとファイルの確認 ※ commitログは最初のだけになる ※ ファイル類はそのまま $ git log --oneline 8189e9c Initial commit $ ls -l -rw-r--r-- 1 hoge hoge 18 6 6 15:08 README.md drwxr-xr-x 3 hoge hoge 102 6 6 15:14 img -rw-r--r-- 1 hoge hoge 83 6 6 15:14 index.html ※ statusを確認 ※ addされる前に戻るわけではなく、addはした状態になっている $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: img/sample.png new file: index.html
ポイント
この後の--hard
と比べるとわかりやすいのですが
ファイルは残っていますがaddされる前に戻るわけでは無い
と言った感じです。
git reset --hardの確認
※ すべてadd $ git add . ※ commit $ git commit -m 'commit sample' ※ ログを確認 $ git log --oneline 10e0dcd commit sample 8189e9c Initial commit ※ 直前のcommitを取り消し $ git reset --hard HEAD^ ※ ログとファイルの確認 ※ commitログは最初のだけになる ※ 変更や新たに追加したファイル類も消える $ git log --oneline 8189e9c Initial commit $ ls -l -rw-r--r-- 1 hoge hoge 18 6 6 15:08 README.md
ポイント
--soft
と比べるとわかりやすく、変更や追加したファイルも消えてしまいます。
git reset --soft コミットハッシュの確認
HEAD指定と違ってどれを取り消すか、ではなくどこまで戻るか、なので
最初に間違った指定もしてみます。
※ すべてadd $ git add . ※ commit $ git commit -m 'commit sample' ※ ログを確認 $ git log --oneline b869e93 commit sample 8189e9c Initial commit ※ 直前のcommitハッシュを指定してみる $ git reset --soft b869e93 ※ ログとstatusの確認 ※ 直前のcommitハッシュを指定しても何も変わっていない $ git log --oneline b869e93 commit sample 8189e9c Initial commit $ git status On branch master Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working directory clean ※ 戻りたいコミットハッシュを指定してみる $ git reset --soft 8189e9c ※ ログとファイルの確認 ※ コミットハッシュ指定の場合は'どこまで'戻りたいかで指定 ※ HEADと違い、'どれを'り消すかではない $ git log --oneline 8189e9c Initial commit $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: img/sample.png new file: index.html
ポイント
HEAD指定はどれを
取り消すか
コミットハッシュ指定はどこまで
戻るかのような感じで覚えると良さそうです。
git revert
revertのサンプルとしては直前のrevertを2回やってみます。
ログとファイルがどんな感じになるかに注目するとわかりやすいかと思います。
※ すべてadd $ git add . ※ commit $ git commit -m 'commit sample' ※ ログを確認 $ git log --oneline 1fe0f69 commit sample 8189e9c Initial commit ※ 直前のコミットハッシュを指定してrevert $ git revert 1fe0f69 ※ ログとファイルを確認 ※ "commit sample"というコミットハッシュをrevertしたよ、と出る ※ 指定したコミットハッシュで追加したファイルや変更もなかったことになる $ git log --oneline ef9e453 Revert "commit sample" 1fe0f69 commit sample 8189e9c Initial commit ※ ファイルを確認 $ ls -l -rw-r--r-- 1 hoge hoge 18 6 7 05:18 README.md ※ 再度、直前のコミットハッシュを指定してrevert ※ 直前のコミット=revertしたコミットハッシュ $ git revert ef9e453 ※ ログとファイルを確認 ※ revertをrevertすると、なかったことになったファイルも戻る $ git log --oneline b058b30 Revert "Revert "commit sample"" ef9e453 Revert "commit sample" 1fe0f69 commit sample 8189e9c Initial commit $ ls -l -rw-r--r-- 1 hoge hoge 18 6 7 05:18 README.md drwxr-xr-x 3 hoge hoge 102 6 7 06:05 img -rw-r--r-- 1 hoge hoge 83 6 7 06:05 index.html
ポイント
revertすると取り消すという意味合いのログも残る上に、
revert自体も戻すことができるので便利です。
git commit
index.htmlという余分なファイルをcommitしてしまった
と仮定して
既に行ったcommitに対してindex.htmlを無しの状態にしてみます。
※ すべてadd $ git add . ※ commit $ git commit -m 'commit sample' ※ ログを確認 $ git log --oneline e102d17 commit sample 8189e9c Initial commit ※ index.htmlを消す $ git rm index.html ※ git commit --amendしてログを確認する ※ git commit した場合は消したというコミットログが残るが ※ --ammendの場合は新しくcommitハッシュを作り直して直前のコミットを上書きする $ git commit --amend $ git log --oneline 9ea5842 commit sample 8189e9c Initial commit
ポイント
あえて消したログを残したい場合は
git commit -m 'remove file'
と通常通り行っても良いですね。
補足
resetに関してはこのあたりも参考に
→マージ後のreset HEAD^は危険だった
まとめ
取り消し系の操作はいざそのときになると慌てて出てこなかったりするので
何回か練習して覚えたいですね。\(^o^)/