🗝️

Gitコマンド入門::add,reset,rm,status,log「第三十二回」

2021/03/04に公開

みなさん、こんにちは! 今回もコミットを修正して行きますよ。前回は、git commit --amend コマンドで、最新のコミットに対して、上書き修正するやり方でしたね。今日は、git reset コマンドで、まずは、最新のコミットを消して、そして、コミットを通常のように追加する方式を、試して行きたいと思います!

前回の記事は、こちら!

https://zenn.dev/shiozumi/articles/63a686eb69e205

git本家本元の情報はこちらから!

https://git-scm.com/book/ja/v2

git reset --soft は、どんな時に使うのか?

git reset も、ここまで何回か取り上げてきましたけど、一番、分かりやすいのが、
git reset --hard ですね。 これは、もう任意の地点に自由に移動できるという、スーパー優れモノでした。git reflog コマンドと併用して使えば、最強コマンドタッグです!

そして、その次に学習したのは、git reset --mixed [--mixedは、省略可] コマンドでした。そして、これは、git add の取り消し、つまるところ、ステージングエリアを元に戻す。もとに戻すのは、Gitリポジトリから、ステージングエリアにファイル[1]をコピーすることでしたね。 そして今回は、git reset --soft から学習してみたいと思いますよ!

復習も兼ねて、こちらの一覧から!

Option Working Directory Stagin Area 補足事項
--hard 上書き変更 上書き変更 Gitリポジトリのファイルで更新
--mixed 何もしない 上書き変更 指定しない場合も、--mixed 同様
--soft 何もしない 何もしない ヘッダーの位置だけ移動
  1. --hard は、任意の位置にヘッダーを移動して、ワーキングディレクトリとステージングエリアも、Gitリポジトリの内容で更新します。

  2. --mixed は、ワーキングディレクトリの変更はせずに、ステージングエリアのみ、Gitリポジトリの内容で更新します。これを、add の取り消しとして使っています。

  3. --soft は、任意の位置にヘッダーを移動するだけで、ワーキングディレクトリとステージングエリアは、何も変更せずに、そのままとなります。

--soft は、rebase -i にも似ている?

コミットをまとめる、squash や、drop のような使い方にもなりますね。ファイルの状態は、最新のままとなり、HEADだけ自由に移動できますからね。要するに、その間にあるコミットが、不要なれば、スパッと! 全てカット出来てしまうので、rebase よりも確実、簡単にコミット削除が出来てしまいますからね。 とは、いいつつも、まずは、利用頻度の多そうな、git reset --soft HEAD^ から!

git reset --soft HEAD~ 直前のコミットをリセット!

$ git log --oneline
ceff847 (HEAD -> tag0032, tag: v.0032, origin/main, origin/HEAD) 3rd add b.txt
ce2321e 2nd add a.txt
53d39e0 1st

$ git reset --soft HEAD^

$ git log --oneline
ce2321e (HEAD -> tag0032) 2nd add a.txt
53d39e0 1st

// HEADを移動するだけで、ワーキングディレクトリ、
// ステージングエリアには、影響を与えません。
// 3つのファイルが存在していますね。
$ ls
README.md  a.txt  b.txt

// status で確認すると、b.txt が new file として認識されています。
// 要するに、b.txt を、add して、コミットする前の状態ですね。
$ git status
On branch tag0032
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   b.txt

git reset --mixed HEAD~ 直前のコミットをリセットして、さらに、add も取り消し!

次は、--soft から、--mixed に変えて実行してみましょう。まずは、その前に、ヘッダーを元に戻してから、以下の3つあたりが、候補でしょうか? 勿論、4つ目の、git reflog でもOKですよ!

  1. git reset --hard ORIG_HEAD[2]
  2. git reset --hard v.0032 // タグ名を指定
  3. git reset --hard ceff847 // 勿論、ハッシュ値でも!
  4. git reflog | grep "reset: moving to v.0032" // 一度、reflog で検索してから、HEAD@{xx} を指定して実行。git reset --hard HEAD@{xx}[3]
$ git reset --hard v.0032

// これで、元に戻りましたね!
$ git log --oneline
ceff847 (HEAD -> tag0032, tag: v.0032, origin/main, origin/HEAD) 3rd add b.txt
ce2321e 2nd add a.txt
53d39e0 1st

// では、直前のコミットをリセット
// さらに、ステージングエリアを元に戻すので、add 取り消しです。
$ git reset --mixed HEAD~

// ステータスコマンドで確認
// b.txt が、add する前の状態に戻りましたね。

$ git status
On branch tag0032
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        b.txt

nothing added to commit but untracked files present (use "git add" to track)

// HEADも、直前に戻りました。
$ git log --oneline
ce2321e (HEAD -> tag0032) 2nd add a.txt
53d39e0 1st

git reset --hard HEAD~ 直前のコミットをリセットして、さらに、ワーキングディレクトリも、ステージングエリアも、全て無かった状態、初期状態に戻す![4]

$ git reset --hard v.0032

// これで、元に戻りましたね!
$ git log --oneline
ceff847 (HEAD -> tag0032, tag: v.0032, origin/main, origin/HEAD) 3rd add b.txt
ce2321e 2nd add a.txt
53d39e0 1st

// では、直前のコミットをリセット
// さらに、ワーキングディレクトリも、ステージングエリアも元に戻します!
$ git reset --hard HEAD~

// ステータスコマンドで確認
// ワーキングディレクトリもクリーン:working tree clean
// ステージングエリアも何もなし:nothing to commit
$ git status
On branch tag0032
nothing to commit, working tree clean

// 勿論、b.txt も、消えてますね!
$ ls
README.md  a.txt

// HEADも、直前に戻りました。
$ git log --oneline
ce2321e (HEAD -> tag0032) 2nd add a.txt
53d39e0 1st

// では、元に戻して!
$ git reset --hard v.0032
HEAD is now at ceff847 3rd add b.txt

// はい! b.txt も無事復活です!
$ ls
README.md  a.txt  b.txt

今回のまとめ!

  1. --hard は、HEADを任意の位置に移動して、ワーキングディレクトリ、ステージングエリアの両方を初期化する。初期化とは、HEADの指している、Gitリポジトリから、コミットされているファイルを全てコピーすることですね。結果、status コマンドでは、nothing to commit, working tree clean と表示される!

  2. --mixed は、HEADを任意の位置に移動して、ステージングエリアのみ、HEADの指しているGitリポジトリから、ファイルを複製する。結果、add を取り消した状態に戻る。status コマンドでは、ファイル名が赤い文字で表記される。git status -s では、?? と表記される。以後、コミットするには、git add b.txt してから、git commit -m "任意のコメント"となる。

  3. --soft は、HEADを任意の位置に移動するのみ、ワーキングディレクトリ、ステージングエリアには、影響を与えません。つまり、git commit -m の直前の状態に戻ます。status コマンドでは、ファイル名が緑色の文字で表記される。git status -s では、Aと表記される。以後、コミットするには、git commit -m "任意のコメント"のみでOK!

次回は、今回の続きで、git commit しま~す! それでは、今回はここまで、お疲れ様でした!

https://zenn.dev/shiozumi/articles/ff20b8e1a0d894
https://twitter.com/esmile2013

脚注
  1. ファイルは、単体でも、複数でも可能です。 ↩︎

  2. ORIG_HEADは、直前のHEADの意味になります。 ↩︎

  3. xx は、検索結果の数値が入ります。 ↩︎

  4. 言い回しは、なかなか難しいと思うこの頃ですが、もうすこし正しく表現するならば、指定したHEADのコミット直後の環境状態にするって事ですね。だから、ワーキングディレクトリ、ステージングエリアも、ファイルが最新のコミットの内容に設定される訳です。 ↩︎

Discussion