バグがどこで混入したのか調べたい時など、一時的に過去のコミットに戻って作業したい場合があります。
その場合は次の git switch コマンドを使います。

一時的に過去のコミットに戻る:
git switch -d <コミット>

※ -d オプションは移動後の HEAD を「detached HEAD」という使い捨ての HEAD にするという意味

ところが、このコマンドはワーキングツリーとインデックスと HEAD の内容が一致していないとエラーが出て実行出来ない事があります。
そういう場合は次の様に stash 機能を使ってワーキングツリーとインデックスの内容を一時的に保存してから git switch を実行します。

一時的に過去のコミットに戻る(stash を使う場合):

ワーキングツリーとインデックスの内容を stash に一時保存する: git stash
過去のコミットに戻る: git switch -d <コミット>
過去に戻れたか確認: git log --all --oneline

例えば状態16から HEAD~2 に戻った状態が以下の状態17となります。
ワーキングツリーとインデックスの内容が元の状態 16 における HEAD~2 の内容に置き換わっていることに注目して下さい。
また元の状態 16 におけるワーキングツリーとインデックスの内容は stash に一時保存され、HEAD は detached HEAD になっています。


状態 17


ワーキングツリー
stash に一時保存されたワーキングツリー
hoge.txt
a
     
hoge.txt
ab
piyo.txt
A


インデックス
stash に一時保存されたインデックス
hoge.txt
ab
     
hoge.txt
ab
piyo.txt
A


ローカルリポジトリ「gitlocal」
本来のHEAD
hoge.txt
ab
"piyo.txtを削除(S16)"
 
hoge.txt
ab
piyo.txt
AB
"piyo.txtを更新(S9)"
(detached) HEAD
hoge.txt
ab
piyo.txt
A
"hoge.txtを更新(S8)"
HEAD~
hoge.txt
a
piyo.txt
A
"piyo.txtを追加(S5)"
HEAD~2
hoge.txt
a
"hoge.txtを追加(S4)"

何らかの作業が終わったら以下の手順で元の状態に戻すことが出来ます。
ただしファイルを更新した場合はエラーが出て戻る事が出来ないので、変更したファイルの内容をgit restoreコマンドで復元する必要があります。

元の状態に復帰する:


(ファイルを更新した場合) git restoreコマンドで更新したファイルを復元
元の HEAD に戻る: git switch -
(git stash を行った場合)は stash から内容を復元: git stash pop --index
元に戻れたか確認: git log --all --oneline

さて状態 17 の状態から上の作業を行うと次の状態18になります。
当然これは元の状態16と同じ状態です。


状態 18 ( = 状態16 )


ワーキングツリー
hoge.txt
a


インデックス
hoge.txt
ab


ローカルリポジトリ「gitlocal」
HEAD
hoge.txt
ab
"piyo.txtを削除(S16)"
HEAD~
hoge.txt
ab
piyo.txt
AB
"piyo.txtを更新(S9)"
HEAD~2
hoge.txt
ab
piyo.txt
A
"hoge.txtを更新(S8)"
HEAD~3
hoge.txt
a
piyo.txt
A
"piyo.txtを追加(S5)"
HEAD~4
hoge.txt
a
"hoge.txtを追加(S4)"