🗝️

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

2021/03/04に公開

みなさん、こんにちは! 今回も前回の続きで、コミットして行きまあ~す! 尚、git reset --soft , --mixed, --hard の動作の違いが、いまいちの理解度という方は、前回、前々回と、遡って学習してくださいね!

前回の記事は、こちら!

https://zenn.dev/shiozumi/articles/aafde127262c8a

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

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

前回の続き、git reset --mixed HEAD~ からの git add, git commit

$ git reset --mixed HEAD~

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

$ ls
README.md  a.txt  b.txt

$ echo "git reset --mixed head~" > b.txt

$ cat b.txt
git reset --mixed head~

$ git status
On branch tag0033
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)

$ git add b.txt
$ git commit -m " 3rd git reset --mixed head~"
[tag0033 6d4ae32]  3rd git reset --mixed head~
 1 file changed, 1 insertion(+)
 create mode 100644 b.txt
 
$ git log --oneline
6d4ae32 (HEAD -> tag0033)  3rd git reset --mixed head~
ce2321e 2nd add a.txt
53d39e0 1st

さあ、どうでしょうか? これだけ繰り返してやっていると、かなり慣れてきたと思います。
--soft --mixed[省略可] --hard の違いについても、もう大丈夫ですよね。冒頭でも述べましたけど、もし、まだ、理解度が曖昧だという方がいれば、前回、前々回と遡ってくださいね。そんな私も、こうやって、同じことを繰り返しながら、覚えているんですけどね。(爆笑)

git reset --soft HEAD~ からの git rm a.txt

こんどは、3rd コミットするときに、a.txt を削除してみます。

git reset --soft HEAD~

$ git rm a.txt
rm 'a.txt'
// 今度は、a.txt を削除してみましょう!

$ ls
README.md  b.txt

$ git status
On branch tag0033
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    a.txt
        new file:   b.txt

// --soft ですから、ステージングエリアの状態は、前回尾コミットのままです。
// 従って、b.txt の中身も変わらず、git reset --mixed head~ ですね。

$ git commit -m " 3rd git rm a.txt"
	
[tag0033 febd3e2]  3rd git rm a.txt
 2 files changed, 1 insertion(+), 1 deletion(-)
 delete mode 100644 a.txt
 create mode 100644 b.txt
// これで、3rd コミットでは、a.txtが削除されて、b.txtが追加れました。

$ git log --oneline
ac13f1d (HEAD -> tag0033)  3rd git rm a.txt
ce2321e 2nd add a.txt
53d39e0 1st

このような処理ですね!

コメント file1 file2 補足事項
3rd git rm a.txt README.md b.txt a.txtを削除して、b.txtを追加
2nd README.md a.txt a.txtを追加
1st README.md - README.mdを追加

a.txtが、Gitリポジトリから削除されたかの確認、前回のコミットHEAD~ と、今の直前のコミットHEADとの差分を見てみましょう!

$  git diff HEAD~ HEAD
diff --git a/a.txt b/a.txt
deleted file mode 100644
index eaa5fa8..0000000
--- a/a.txt
+++ /dev/null // <!-- /dev/null ファイルが削除されていますね。
@@ -1 +0,0 @@
-a.txt

// 以下、中略~

git log --name-status --oneline でも確認!

$  git log --name-status --oneline
ac13f1d (HEAD -> tag0033)  3rd git rm a.txt
D       a.txt  // <!-- a.txt が削除されていますね。
A       b.txt
ce2321e 2nd add a.txt
M       README.md
A       a.txt
53d39e0 1st
A       README.md
  1. A は、ファイルの追加
  2. D は、ファイルの削除
  3. M は、ファイル内容の変更

では、--worktreeで、a.txtを復元します!

a.txt は、現在のGitリポジトリからは、削除されてしまいましたが、前回、ひとつ前のコミットにはファイルがありますので、git restore --source=HEAD~ --worktree <FILE> で、取り出せますね。

git restore --source=HEAD~ --worktree a.txt

$ ls
README.md  a.txt  b.txt
// 無事、a.txt をリストアーできましたね。

$ git status -s
?? a.txt // <!-- ?? が赤色で表示されていますね!

$ git add a.txt // <!-- add して!

$ git commit --amend -C HEAD // <!-- 直近のコミットを上書き、コメントそのまま!

$ git diff HEAD~ HEAD a.txt // <!-- もう一度、diff で確認!
$
// はい! 何も差分がないので表示されませんね!

前回のコミットのGitリポジトリから、a.txt をリストアーして、addしてcommit
今回は、a.txtを編集しませんでしたが、編集するケースも、是非、お試しください。

2回目 --worktree --stagedで、a.txtを復元します!

今度は、git restore --source=HEAD~ --worktree --staged <FILE> で、ステージングエリアにも、a.txt を戻して、add なしで行きます!

$ git reset --hard ac13f1d
HEAD is now at ac13f1d  3rd git rm a.txt

$ git log --oneline
ac13f1d (HEAD -> tag0033)  3rd git rm a.txt
ce2321e 2nd add a.txt
53d39e0 1st
// これで、a.txt が削除された状態に戻りました!

// 今度は、--staged オプションを追加して、
// ステージングエリアにも、a.txt を戻してみましょう!
git restore --source=HEAD~ --worktree --staged a.txt

$ git status
On branch tag0033
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   a.txt

// ステージングにもリストアーしましたので、add は不要となりますね!

$ git commit --amend -C HEAD // <!-- 直近のコミットを上書き、コメントそのまま!
[tag0033 b735fe4]  3rd git rm a.txt
 Date: Thu Mar 4 12:39:54 2021 +0900
 1 file changed, 1 insertion(+)
 create mode 100644 b.txt

$ git diff HEAD~ HEAD a.txt // <!-- もう一度、diff で確認!
$
// はい! 何も差分がないので表示されませんね!

特に、a.txtを編集する必要が無いときは、こちらですね。

3回目! --staged のみで、a.txtを復元します!

今度は、git restore --source=HEAD~ --staged <FILE> で、ステージングエリアのみ、ワーキングディレクトリには、a.txt を戻さないやり方です!

$ git reset --hard ac13f1d
HEAD is now at ac13f1d  3rd git rm a.txt

$ ls
README.md  b.txt

$  git restore --source=HEAD~ --staged a.txt

$ ls
README.md  b.txt
// a.txt は、ワーキングディレクトリには、ありませんね!

$ git status
On branch tag0033
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   a.txt

// ご丁寧に、ステージングエリアからワーキングディレクトリに、
// リストアーしなさいと表示されています。

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    a.txt

git status -s
AD a.txt
// Aが緑、Dが赤い文字で、表示されていますね。
// 一体、これは、どうなるのかな?

a.txt は、以下のような状態ですね。

ワーキングディレクトリ ステージングエリア HEAD 直前コミット HEAD~ ※前回コミット
なし あり なし あり

この状態で、コミットしてみます!

$ git commit --amend -C HEAD  // <!-- 直近のコミットを上書き、コメントそのまま!

[tag0033 68d4c0f]  3rd git rm a.txt
 Date: Thu Mar 4 12:39:54 2021 +0900
 1 file changed, 1 insertion(+)
 create mode 100644 b.txt

$ git log --oneline
68d4c0f (HEAD -> tag0033)  3rd git rm a.txt
ce2321e 2nd add a.txt
53d39e0 1st

$ git status -s
 D a.txt
// Aの文字は消えて、Dの赤文字だけ残りましたね!

これで、a.txt は、以下のようになりました!

ワーキングディレクトリ ステージングエリア HEAD 直前コミット HEAD~ ※前回コミット
なし あり あり あり

一応、a.txt はコミットされましたね。Gitリポジトリーには、あるかどうか確かめてみましょう。git restore --source=HEAD --worktree a.txt で、取り出せれば、コミットされていることになりますね。[1]

git restore --source=HEAD --worktree a.txt

$ ls
README.md  a.txt  b.txt
// 無事、a.txt がリストアーされましたね。

$ git status
On branch tag0033
nothing to commit, working tree clean

これで、a.txt は、以下のようになりました!

ワーキングディレクトリ ステージングエリア HEAD HEAD~ ※前回コミット
あり あり あり あり

さあ、どうでしたか? 最後の3回目は、おまけ的に試してみましたけど、add して、ステージングエリアには登録したけど、間違って、rm コマンド[2]で、削除していまうと、同じようなケースになると思います。

最後に本日覚えたばかりのgit log --name-status

$  git log --name-status --oneline
68d4c0f (HEAD -> tag0033)  3rd git rm a.txt
A       b.txt
ce2321e 2nd add a.txt
M       README.md
A       a.txt
53d39e0 1st
A       README.md

// a.txt の内容が変化していないので、3rd コミットの欄には、
// 何も表示されていないので、ちょっとわかりづらいですけどね。(苦笑)

それでは、今回はここまで、お疲れ様でした!

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

脚注
  1. git reset --hard HEAD でも、a.txtを戻せます、、、というか、複数ファイルの時は、このコマンドは、便利ですよね。 ↩︎

  2. git rm ではなく、linux の rm コマンドの場合は、同じように、ワーキングディレクトリからは、a.txt が削除されて、ステージングエリアには、a.txt が残ります。 ↩︎

Discussion