Git を1からやり直す(リセット編)

Gitを1からやり直す(目次)

リセットすると履歴が消えてしまうので、使うときは注意する!

リセット

git reset は、HEADを移動させるコマンド。コミットの指定方法やHEADについては後述。

コマンド 動作など
git reset コミット 指定したコミットをHEADにする。作業ツリーはリセット前HEADの内容に
git reset --hard コミット 指定したコミットをHEADにしてインデックスと作業ツリーも同じに
git reset --soft コミット 指定したコミットをHEADにする。インデックスと作業ツリーはリセット前HEADの内容に

以下のように、コミットを指定しなければ変更を破棄することができる。上のコマンドでHEADを指定しているのと同じ。

コマンド 動作など
git reset --hard インデックスと作業ツリーをHEADと同じ状態にする(最新コミット後の修正を破棄)

通常書かないが、オプションのデフォルトは--mixed。つまり$ git reset$ git reset --mixed HEAD ということ。

コミットの指定方法

$ git reset コミット などのコマンドで「コミット」をどう指定するか。

HEADで指定

HEAD は現在のコミットを指すポインタのようなものだ。コミットすると、そこを親として新しいコミット(子コミット)ができ、HEADが子コミットに移る。

HEAD の1つ前のコミットは HEAD^ または HEAD~1

HEAD の2つ前のコミットは HEAD^^ または HEAD~2

3つ前はHEAD~3、4つ前はHEAD~4、と数字を増やしていける。


(例1)現在のコミットと1つ前のコミットの差を見たい

$ git diff HEAD^ HEAD または $ git diff HEAD~1 HEAD


(例2)2つ前のコミットをHEADにしてそれより後のコミットはなかったことにしたい

$ git reset --hard HEAD^^ または $ git reset --hard HEAD~2

具体的な例はこちら(間違ってmasterにpushした話)。

ちなみに、HEADエイリアス@@^のように書ける。

ブランチ名で指定

ブランチ名がmasterだとすると、masterはその一連の履歴という意味で使われることが多いが、masterブランチの先端のコミットという意味もある。HEADと同じように、ブランチの先端を指すポインタのようなものだ。

masterブランチの先端のコミットは master

masterブランチの先端の1つ前のコミットは master^ または master~1

masterブランチの先端の2つ前のコミットは master^^ または master~2

3つ前はmaster~3、4つ前はmaster~4、と数字を増やしていけるのも HEAD と同様。

つまり、masterブランチの先端にHEADがある場合、master^HEAD^は同じコミットを指す。HEADの(例1)と(例2)のHEADはそのままブランチ名に置き換えることができる。

コミットのハッシュで指定

コミットを特定するためにコミットのハッシュ(コミットIDなどと呼ばれることもある)を使うこともできる。

ハッシュの確認方法
$ git log
commit ed4ef63cc7ebf7e13ea544aded5383a1d7982ce2 (HEAD -> master, origin/master)
Author: masuyama13 <example@gmail.com>
Date:   Sun Jul 5 17:02:59 2020 +0900

    English追加

$ git logすると表示される commit の横の ed4ef63cc7ebf7e13ea544aded5383a1d7982ce2 がコミットのハッシュ。かなり長いが、リポジトリ内で一意になるところまで書けばOK。

git log--oneline オプションをつけると、ハッシュは先頭の7桁だけ表示される。通常は7桁もあればコミットを特定できると思われる。

$ git log --oneline
ed4ef63 (HEAD -> master, origin/master) English追加
a67591b READMEに"▲▲▲▲"追加
4d7d34c READMEに"〇〇〇〇"追加
22b74e1 README作成

(例3)現在のコミットed4ef63 と1つ前のコミット a67591b の違いを見たい

$ git diff a67591b ed4ef63


(例4)2つ前のコミット4d7d34cをHEADにしてそれより後のコミットはなかったことにしたい

$ git reset 4d7d34c

(例3)(例4)のいずれもHEADを使った(例1)(例2)と同じ結果になる。

間違ってリセットしたとき

リセットの取り消し。でも間違えないように気をつける。

$ git reset --hard ORIG_HEAD

リセットを使わずに直近のコミットをやり直す

コミットメッセージの入力ミスや add し忘れたファイルがあったときに使える。

コマンド 動作など
git commit --amend 直近のコミットをやり直す。コミットIDは変わる

Git - 作業のやり直し

リセットに似ている revert についてはこちらの記事


(参考資料)わかる Git