git reset
について、わからないことが多かったので、まとめました。
中でも、よく使うコマンドである、以下について、実験的に調べたことをまとめました。
間違いなどがありましたら、ご指摘いただけるとありがたいです。
git reset [ --soft | --hard ] [ HEAD | HEAD^ ]
結論
結論から書くと、このような挙動となる。
git reset オプション HEAD
オプション | コミットされたもの | ステージングされたもの | ワークツリーで変更されたもの | ワークツリーで新規に追加されたもの |
---|---|---|---|---|
--soft | 変化なし | 変化なし | 変化なし | 変化なし |
オプションなし | 変化なし | ワークツリーへ移動する。 | 変化なし | 変化なし |
--hard | 変化なし | 変更が削除される。 | 変更が削除される。 | 変化なし |
git reset オプション HEAD^
オプション | コミットされたもの | ステージングされたもの | ワークツリーで変更されたもの | ワークツリーで新規に追加されたもの |
---|---|---|---|---|
--soft | ステージングされた状態に戻る。 | 変化なし | 変化なし | 変化なし |
オプションなし | ワークツリーへ移動する。 | ワークツリーへ移動する。 | 変化なし | 変化なし |
--hard | 変更が削除される。 | 変更が削除される。 | 変更が削除される。 | 変化なし |
言葉の説明
オプション( --soft と --hard )
どのくらいresetするかの度合いを決めるもの。
hard
> オプションなし
> --soft
の順に、resetの度合いが大きい。
オプションをつけていない時は、--soft
と--hard
の間みたいな挙動となる。言葉からイメージしやすい。
HEAD と HEAD^
HEAD
最新のコミットの状態。
HEAD^
最新から一個前のコミットの状態。
以下で、実際にコマンドをうって、git reset
の挙動を確かめる。見るだけではよく理解できない箇所もあるかと思いますので、一緒にターミナルで実行してみてください。
ワークツリー、インデックス、ステージング
ワークツリーで、ファイルを変更したり新規に追加したりする。
git add
をすると、ワークツリーで変更されたものがステージングされ、インデックスへ移動する。
git add
をすると、ステージングされインデックスにあるものが、コミットされる。
準備
こちらの4つのファイルを準備する。
commit.txt
: コミットされたもの
staging.txt
: ステージングされたもの
modified.txt
: ワークツリーで変更されたもの
untracked.txt
: ワークツリーで新規に追加されたもの
コミットされたもの | ステージングされたもの | ワークツリー | |
---|---|---|---|
コマンドを打つ前 | commit.txt | staging.txt | modified.txt, untracked.txt |
ここで、modified.txt
は、新規に追加されたものではなく、変更を加えられたものにしたいため、予め準備のためにcommitしてから、変更を加える。
# modified.txt
touch modified.txt
git add modified.txt
git commit -m 'modified.txtをコミット'
echo 'modified.txtを変更する' > modified.txt
# commit.txt
touch commit.txt
git add commit.txt
git commit -m 'commit.txtをコミット'
# staging.txt
touch staging.txt
git add staging.txt
# untracked.txt
touch untracked.txt
git status
して、状況を確認。
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: staging.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: modified.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
untracked.txt
また、git log
して、コミット状況を確認。
commit 875f4d280c450dcddfd3e799448c33cb07215854 (HEAD -> master)
Author: host <host@gmail.com>
Date: Sun Aug 9 23:03:39 2020 +0900
commit.txtをコミット
commit bb977083c0aa34911e9dd517f274b15378c64cfe
Author: host <host@gmail.com>
Date: Sun Aug 9 23:03:15 2020 +0900
modified.txtをコミット
この状況から、以下の6条件でのgit reset
を行う。それぞれのコマンドを打つ前の状態は、上の状態に統一している。
git reset オプション HEAD
1. git reset --soft HEAD
これは何も変わらない。
||コミットされたもの|ステージングされたもの|ワークツリー|
|---|---|---|---|---|
|コマンドを打つ前|commit.txt|staging.txt|modified.txt, untracked.txt|
|コマンドを打った後|commit.txt|staging.txt|modified.txt, untracked.txt|
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: staging.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: modified.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
untracked.txt
2. git reset HEAD
ステージングされていた、staging.txt
がインデックスからワークツリーへ移動。
||コミットされたもの|ステージングされたもの|ワークツリー|
|---|---|---|---|---|
|コマンドを打つ前|commit.txt|staging.txt|modified.txt, untracked.txt|
|コマンドを打った後|commit.txt||modified.txt, untracked.txt, staging.txt|
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: modified.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
staging.txt
untracked.txt
3. git reset --hard HEAD
ステージングされていたstaging.txt
の変更が削除される!!
ワークツリーのmodified.txt
の変更が削除される!!
ただし、ワークツリーに新規追加されたuntracked.txt
はそのまま残る。
||コミットされたもの|ステージングされたもの|ワークツリー|
|---|---|---|---|---|
|コマンドを打つ前|commit.txt|staging.txt|modified.txt, untracked.txt|
|コマンドを打った後|commit.txt||untracked.txt|
Untracked files:
(use "git add <file>..." to include in what will be committed)
untracked.txt
git reset オプション HEAD^
1. git reset --soft HEAD^
コミットしたはずのcommit.txt
が、ステージングされた状態に戻る。
||コミットされたもの|ステージングされたもの|ワークツリー|
|---|---|---|---|---|
|コマンドを打つ前|commit.txt|staging.txt|modified.txt, untracked.txt|
|コマンドを打った後||staging.txt, commit.txt|modified.txt, untracked.txt|
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: commit.txt
new file: staging.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: modified.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
untracked.txt
2. git reset HEAD^
コミットしたはずのcommit.txt
が、ワークツリーへ移動。
ステージングされていた、staging.txt
がインデックスからワークツリーへ移動。
||コミットされたもの|ステージングされたもの|ワークツリー|
|---|---|---|---|---|
|コマンドを打つ前|commit.txt|staging.txt|modified.txt, untracked.txt|
|コマンドを打った後|||modified.txt, untracked.txt, staging.txt, commit.txt|
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: modified.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
commit.txt
staging.txt
untracked.txt
3. git reset --hard HEAD^
コミットしたはずのcommit.txt
の変更が、削除される。
ステージングされていたstaging.txt
の変更が削除される!!
ワークツリーのmodified.txt
の変更が削除される!!
ただし、ワークツリーに新規追加されたuntrached.txt
はそのまま残る。
||コミットされたもの|ステージングされたもの|ワークツリー|
|---|---|---|---|---|
|コマンドを打つ前|commit.txt|staging.txt|modified.txt, untracked.txt|
|コマンドを打った後|||untracked.txt|
Untracked files:
(use "git add <file>..." to include in what will be committed)
untracked.txt