🗂

【Git】なんとなくでやってたGitの動きを追ってみた(メモ書き)

2021/12/20に公開

Gitの追跡管理の仕組み

作業ディレクトリとリポジトリの差分検知で実現している。それを確認するためにローカルでリポジトリを作成してみる。

$ mkdir tuto // tutoディレクトリを作成
$ cd tuto // tutoディレクトリへ移動
$ git init // リポジトリを作成

ちなみにリポジトリとは.gitディレクトリのこと。「.」が頭につくファイルは隠しファイルなので普通は見ることができない。「ls -a」コマンドで確認できる。

$ pwd
/i/workspace/tuto
$ ls -a
./  ../  .git/

確かに.gitファイルがある。
Gitの追跡管理はこのリポジトリと作業ディレクトリの差分によって管理される。
作業ディレクトリとは、.gitディレクトリがあるディレクトリのこと。今は、tutoディレクトリが作業ディレクトリに当たる。
今はtutoディレクトリが空なので、追跡管理するものがない。
次はファイルを作成してみる。

$ echo "2020/12/20" > firstFile.txt // firstFile.txtを作成する。

ここでgit statusを実行。

$ git status
On branch master

No commits yet

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

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

Untracked filesとしてfirstFile.txtが表示されている。これは追跡できていないファイルがあるということ。つまり、リポジトリが把握していないファイルが作業ディレクトリにあると教えてくれている。
さきほど記載した通り追跡管理はリポジトリと作業ディレクトリの差分によって行われる。現状、リポジトリが追跡すべきファイルを知らないので、差分検知もくそもない。
リポジトリに登録するにはgit addを使う。

$ git add firstFile.txt
warning: LF will be replaced by CRLF in firstFile.txt.
The file will have its original line endings in your working directory

$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   firstFile.txt

git addによってリポジトリにfirstFile.txtがコピーされた。
git addされたfirstFile.txtははじめてリポジトリにコピーされたため、new fileとなっている。
ではfirstFile.txtに新たな行を加えてみる。

$ vi firstFile.txt

そしてgit statusをしてみる。

$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   firstFile.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:   firstFile.txt

先ほどと同じ、firstFile.txtがコミットすべき変更であると認識されていることがわかる。
さらに下を見ていくと「modified: firstFile.txt」とある。
これは、リポジトリに先ほど登録したfirstFile.txtと比較したところ、変更がありそうだぞということをお知らせしてくれている。

これを新たにgit add する。

$ git add .
warning: LF will be replaced by CRLF in firstFile.txt.
The file will have its original line endings in your working directory

$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   firstFile.txt

すると「modified: firstFile.txt」が消えたことがわかる。
このように作業ディレクトリの内容をgit addでリポジトリにコピーすることで差分がなくなっていることがわかる。
では、commitしてからstatusしていく。

$ git commit -m "はじめてのコミット"
[master (root-commit) 84c0793] はじめてのコミット
 1 file changed, 3 insertions(+)
 create mode 100644 firstFile.txt

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

コミットされるとリポジトリ(ステージ)の内容を記録する。これで作業ディレクトリとリポジトリの内容が完全に一致する。git statusの実行結果の通り、作業ディレクトリは変更も新規ファイルもない綺麗な状態になる。

この状態からviで追記するとリポジトリの内容(先ほどコミットした内容)と作業ディレクトリを比較して差分を検知する。modifiedと表示されるので、git addを実行。
そしてgit statusをすると。。。

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   firstFile.txt

コミットすべき変更のあとに「modified: firstFile.txt」と表示される。先ほどはnew fileだった部分だ。これは、リポジトリの中に記録されたfirstFileがあるからmodifiedになっている。つまり、commitすべき変更の部分でのメッセージはリポジトリの中に記録されているコミットと比較してmodifiedと表示しているということになる。
整理すると次のようになる。

// ステージとコミットの内容の比較
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   firstFile.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:   firstFile.txt

Discussion