🗝️

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

2021/03/02に公開

みなさんこんにちは! 前回は、addの動作説明でしたけど、結局、git add コマンドの実行はせずに、話題が膨らんで終わってしまいました~(苦笑) ということで、今日は実際にコマンドをバシバシ叩いて、前へ前へ進んできますよ!

前回の記事は、こちら!

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

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

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

初期状態は、この表のようなイメージです。

Untracked ワーキングディレクトリ ステージングエリア Gitリポジトリ
a.txt
- README.md README.md README.md

a.txt を、git add しましょう!

$ git status -s
?? a.txt  // <!-- ?は赤色になっています。

$ git add a.txt

git status -s
A  a.txt  // <!-- Aは、緑色

その前に、README.mdを、viエディターで更新して、git statusの -s を省いて実行してみましょう!

cat README.md
# A+ // <!-- 私は、+ を最後に一文字追加しました。

$ 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)
        new file:   a.txt

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:   README.md
  1. new file: a.txt となっています。
  2. README.md の内容を更新したので、modified になりましたね。

では、いよいよ、git add . ピリオドは、複数ファイルを指定するワイルドカードですね。

$ git add .  // <!-- ピリオドは、README.md と、a.txt の両方です!

$ 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:   README.md
        new file:   a.txt

// これで、READMD.md と、a.txt がステージングエリアに登録されました。

現状は、このような状態ですね。

Untracked ワーキングディレクトリ ステージングエリア Gitリポジトリ
- a.txt a.txt -
- README.md(+)[1] README.md(+) README.md

git diff で確認!

$ git diff
$
// なにも表示されず・・・

ワーキングディレクトリと、ステージングエリアとの差分なので、add した直後の場合は、当然ですが、何も差分はありません。

git diff は、3方向で比較が可能!

  1. git diff //ワーキングディレクトリと、ステージングエリアの差分
  2. git diff --cached or --staged //ステージングエリアとGitリポジトリの差分
  3. git diff HEAD //ワーキングディレクトリとGitリポジトリの差分

git diff --cached or --staged

$ git diff --cached

diff --git a/README.md b/README.md
index 7f3b95d..6b52fb3 100644
--- a/README.md // <!-- Gitリポジトリ
+++ b/README.md // <!-- ステージングエリア
@@ -1 +1 @@
-# A
+# A+

diff --git a/a.txt b/a.txt
new file mode 100644
index 0000000..5622c8c
--- /dev/null // <!-- Gitリポジトリ ※ファイルが無いので、/dev/null
+++ b/a.txt   // <!-- ステージングエリア
@@ -0,0 +1 @@
+a.txt

ステージングエリアと、Gitリポジトリの差分表示ですね。気づいて欲しいところとしては、a.txt ファイルは、まだ一度もコミットしていませんから、当然Gitリポジトリには、ファイルが無いので、/dev/nullとなっています。尚、正しくは、git diff HEAD --cachedですね。HEADが省略されています。従って、HEAD^ などを指定すれば、以前のコミットとの比較も可能です。

git reset or git restore --staged .

さあ~ いよいよ本番ですね。第二回に行き詰ってクラッシュしたときから、今はなんともう既に、第二十九回ですからね。そして、やっとここで解決しますよ!(笑)ではさっそく、git reset からどうぞ!

$ git reset

Unstaged changes after reset:
M       README.md

$ 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:   README.md

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

no changes added to commit (use "git add" and/or "git commit -a")

README.md は、Changes not staged for commit:欄で、modifiedと認識されています。又、a.txtは、Untracked files:の欄に移り、初期状態として認識されましたね。

Untracked ワーキングディレクトリ ステージングエリア Gitリポジトリ
a.txt
- README.md(+) README.md README.md

このような状態です。尚、git reset は、省略系で、正しくは、git reset --mixed となります。この --mixed って何を意味していいるのか、やや理解に苦しみますが、まずは、ステージングエリアをクリアする。クリアーというのは、空にするのではなく、Gitリポジトリにあるファイルを、ステージングエリアに複製コピーして、add処理もリセットするということですね。そして、a.txtの場合は、ステージングエリアに複製コピーしてしようとしても、Gitリポジトリには、ファイルがありませんから、ステージングエリアは、空になります。そして、Untracked管理外にまで、処理を元に戻すのでしょう。

git add . してからの git restore --staged .

$ git add .

$ 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:   README.md
        new file:   a.txt

git restore --staged .

$ 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:   README.md

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

no changes added to commit (use "git add" and/or "git commit -a")

restore も、reset と全く同じ動作になりましたね。git restore --staged . は、省略系で、正しくは、git restore --source=HEAD --staged . となり、HEAD を指定すれば、Gitリポジトリの任意のコミット場所から、ファイルをステージングエリアに複製コピーできます。

今回のまとめ

  1. git reset で、git add の取り消しが可能![2]
  2. git restore --staged . でも、同じように可能![3]

実際の処理は、Gitリポジトリから、ステージングエリアへの複製コピーです。従って、ワーキングディレクトリと、ステージングエリアとの差分が発生します。さらに、Gitリポジトリにコミットされていない、a.txtの場合は、管理下からも外して、Untracked となりますね。

$ git status -s
 M README.md  // <!-- M は赤色
?? a.txt      // <!-- ?? は赤色 

$ git add .   // もう一度、add 

$ git status -s
M  README.md // <!-- M は緑色
A  a.txt     // <!-- A は緑色

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

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

脚注
  1. (+)マークは、ファイル変更を意味しています。つまり、Gitリポジトリとは、異なるという意味です。 ↩︎

  2. git reset ピリオド無しでも、git reset . ピリオド有りでも、どちらも可能! ↩︎

  3. git restore --staged . は、ピリオドか、ファイル名を指定しないと、エラーになります。 ↩︎

Discussion