git resetの使い方!ステージのリセット・コミットの取り消し

git Git

gitコマンドのgit resetの使い方について書いています。
git resetコマンドを使用すると、ステージエリアに追加された状態をリセットしてくれます。
また、リポジトリにコミットされた任意の履歴まで、ソースコードを戻すことが可能です。

最初に解説を書いて、最後に動作をまとめていますので、コマンドのみ確認したい方はそちらを参照ください。
公式のドキュメントがこちらになります。

Gitのバージョン2.32.0を使って、動作を確認しています。

git resetコマンドでステージを取り消す

git resetコマンドを使用して、git addでステージエリアに乗せたファイルをリセットします。
ファイルパスを渡さずに、そのまま使用すると全てのファイルがステージエリアからリセットされて、git add前の状態になります。

$ git reset

ファイルパスを指定して、git resetを使用すると、そのファイルだけステージエリアから解除された状態になります。

$ git reset ./test.js

それでは実際に使用して、動作を確認します。

全てのファイルをステージする(add)前の状態に戻す

2つのファイル(test.js, test2.js)を変更と新規ファイル(test3.js)をひとつ作成して、git addコマンドでステージしました。
git statusコマンドで確認すると、下記のように3つのファイルが、ステージされてコミット前の状態になっています。

% git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   test.js
        modified:   test2.js
        new file:   test3.js

git resetコマンドを使用すると、git addしたファイルが全て解除されます。
実際に使用すると、下記のようになりました。

$ git reset
Unstaged changes after reset:
M       test.js
M       test2.js

git statusコマンドで確認すると、ステージエリアから解除されたことが確認できました。

% git status
On branch main
Your branch is up to date with 'origin/main'.

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:   test.js
        modified:   test2.js

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        test3.js

指定したファイルのみステージする(add)前の状態に戻す

ファイルを指定すると、指定したファイルのみステージする前の状態に戻せます。
先ほどと同じように、3つのファイルをgit addコマンドでステージエリアに追加しました。

git statusコマンドで確認すると、先ほどと同様の状態です。

$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   test.js
        modified:   test2.js
        new file:   test3.js

test2.jsのみステージエリアから解除してみます。

$ git reset test2.js
Unstaged changes after reset:
M       test2.js

test2.jsのみ解除できたことが確認できました。
git statusコマンドで確認すると、下記のようにtest2.jsのみステージエリアから解除された状態です。

$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   test.js
        new file:   test3.js

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:   test2.js

git resetコマンドでコミット履歴を戻す

git resetコマンドでコミット履歴を戻す場合には、下記のようにコミット番号と合わせて使ったり、HEADを指定して使うことが可能です。
下記のように、コミット番号を指定して実行します。

$ git reset d8dcc0ce05338712c892f5465e052ff00e017c81

もしくはHEADを指定して、実行します。(HEADは現在のブランチの最新のコミット位置です)

$ git reset HEAD^

それではsoft・hard・mixedオプションについて、それぞれ解説していきます。
オプションを指定せずに、上記のようにgit resetのみで使用した場合は、デフォルトで--mixedが使用されます。

softオプションを使う

git resetに--softオプションを使うと、コミットしていたファイルや変更内容を残して、指定したコミット履歴まで戻ることができます。
残したファイルはステージングエリアに乗せている状態になります。

実際に使用してみます。現在下記のようにコミット履歴があるリポジトリです。

$ git log
commit 16f8af891861bc23cea47827e9f9fe5f16037b22 (HEAD -> main)
Author: yasuaki0206 <testhoge@example.com>
Date:   Sat May 14 16:31:05 2022 +0900

    add test outputs

commit d8dcc0ce05338712c892f5465e052ff00e017c81 (origin/main, origin/HEAD)
Merge: 58b91cf 03154cc
Author: yasuaki0206 <testhoge@example.com>
Date:   Tue May 3 20:57:15 2022 +0900

    merge branch test

commit 58b91cf4d3c2466f95cc96b62c0f82bcd5bbc07d
Author: yasuaki0206 <testhoge@example.com>
Date:   Tue May 3 20:35:14 2022 +0900

    add output message123

git resetコマンドで、ひとつ前のコミットに戻します。
ひとつ前のコミット番号を指定して、下記のように実行しました。

$ git reset --soft d8dcc0ce05338712c892f5465e052ff00e017c81

そうすると、最新のコミット履歴が消えて、ひとつ前の状態に戻ります。
最新のコミットで、コミットしていたファイルや更新内容はそのまま残って、ステージに乗った状態になっています。

コミット履歴を確認すると、指定したコミット履歴が最新になっています。

$ git log
commit d8dcc0ce05338712c892f5465e052ff00e017c81 (HEAD -> main, origin/main, origin/HEAD)
Merge: 58b91cf 03154cc
Author: yasuaki0206 <testhoge@example.com>
Date:   Tue May 3 20:57:15 2022 +0900

    merge branch test

commit 58b91cf4d3c2466f95cc96b62c0f82bcd5bbc07d
Author: yasuaki0206 <testhoge@example.com>
Date:   Tue May 3 20:35:14 2022 +0900

    add output message123

git statusコマンドで、ステージの状態を確認すると、ファイルが残ってステージエリアに乗った状態になっています。

$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   test.js

hardオプションを使う

git resetに--hardオプションを使うと、コミットしたファイル全て削除して、指定した履歴まで戻ります。

実際に使用して、指定したコミット履歴まで戻ってみます。
git logで確認すると、履歴は下記のようになっています。

$ git log   
commit 517b12e88a0029bf45aa412ff7b3ee95a268a203 (HEAD -> main)
Author: yasuaki0206 <testhoge@example.com>
Date:   Sat May 14 19:26:16 2022 +0900

    add test outputs

commit d8dcc0ce05338712c892f5465e052ff00e017c81 (origin/main, origin/HEAD)
Merge: 58b91cf 03154cc
Author: yasuaki0206 <testhoge@example.com>
Date:   Tue May 3 20:57:15 2022 +0900

    merge branch test

commit 58b91cf4d3c2466f95cc96b62c0f82bcd5bbc07d
Author: yasuaki0206 <testhoge@example.com>
Date:   Tue May 3 20:35:14 2022 +0900

    add output message123

git resetでhardオプションを指定して、先ほどと同様にひとつ前のコミットを指定してみます。

$ git reset --hard d8dcc0ce05338712c892f5465e052ff00e017c81
HEAD is now at d8dcc0c merge branch test

実行すると、「merge branch test」のコミットまで戻ったことが確認できました。
コミットされていたファイルや変更箇所は削除されます。

ファイルを変更して、コミットしていましたがgit statusコマンドで確認すると、下記のように変更ファイルがないことになっています。

$ git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

mixedオプションを使う

git resetに--mixedオプションを使用します。
このオプションを使うと、コミットしたファイルや変更内容は残したままで、ステージエリアから解除した状態になります。
git resetコマンドでオプションを指定しない場合は、このオプションがデフォルトで使用されます。

実際に使用して、指定したコミット履歴まで戻ってみます。
履歴は下記の状態です。

$ git log                                                   
commit c64032412152504ee3c7629b3415e690fedf4208 (HEAD -> main)
Author: yasuaki0206 <testhoge@example.com>
Date:   Sat May 14 19:51:13 2022 +0900

    add test outputs

commit d8dcc0ce05338712c892f5465e052ff00e017c81 (origin/main, origin/HEAD)
Merge: 58b91cf 03154cc
Author: yasuaki0206  <testhoge@example.com>
Date:   Tue May 3 20:57:15 2022 +0900

    merge branch test

commit 58b91cf4d3c2466f95cc96b62c0f82bcd5bbc07d
Author: yasuaki0206 <testhoge@example.com>
Date:   Tue May 3 20:35:14 2022 +0900

    add output message123

git resetでmixedオプションを指定して、同様にひとつ前のコミットを指定してみます。

$ git reset --mixed d8dcc0ce05338712c892f5465e052ff00e017c81
Unstaged changes after reset:
M       test.js

使用すると、コミット履歴が指定位置まで戻って、変更したファイルがステージングエリアに乗っていない状態になります。
git logコマンドを使用すると、下記のように最新のコミットが指定コミットまで戻っていることが確認できました。

commit d8dcc0ce05338712c892f5465e052ff00e017c81 (HEAD -> main, origin/main, origin/HEAD)
Merge: 58b91cf 03154cc
Author: yasuaki0206 <testhoge@example.com>
Date:   Tue May 3 20:57:15 2022 +0900

    merge branch test

commit 58b91cf4d3c2466f95cc96b62c0f82bcd5bbc07d
Author: yasuaki0206 <testhoge@example.com>
Date:   Tue May 3 20:35:14 2022 +0900

    add output message123

git statusコマンドを使用すると、下記のように変更したファイルは残っていますが、ステージングエリアに乗っていないことが確認できました。

$ git status
On branch main
Your branch is up to date with 'origin/main'.

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:   test.js

git resetコマンドの動作まとめ

解説したgit resetコマンドの内容をまとめてみました。

ステージエリアから解除する

コミット前のステージエリアから解除する場合です。
下記でステージされているファイルを全て解除できます。

$ git reset

指定したファイルのみ解除するには、ファイルパスを渡します。

$ git reset filepath

コミット履歴を戻す

コミット履歴を戻すにはコミット番号を指定します。

softオプション

下記のように使用すると、指定されたコミット番号まで戻ります。
コミットで更新したファイルや新規ファイルは、ステージエリアに残ります。

$ git reset --soft <コミット番号>

hardオプション

hardオプションがsoftオプションと違うのは、更新したファイルや新規ファイルが無くなることです。
下記のように使用すると、指定したコミット番号まで履歴が戻ります。

コミットしたファイルは全て破棄されます。

$ git reset --hard <コミット番号>

mixedオプション

mixedオプションを使用すると、ステージエリアから解除した状態でコミット履歴を戻します。
下記のように使用すると、指定したコミット番号まで履歴を戻して、ステージエリアからも解除します。

ファイルはステージされていない状態で残ります。

$ git reset --mixed <コミット番号>

コメント

タイトルとURLをコピーしました