gitのキャッシュ? ステージ? インデックス?

  • 「キャッシュにインデックスが残っている」
  • 「キャッシュを削除する」

とかの言葉を見かけた。コマンドラインは:

# ファイル全体のキャッシュ削除
$ git rm -r --cached .
  • コメント文言「ファイル全体」は「すべてのファイル」の意味。日本語が不正確で困る。
  • 「キャッシュ削除の際、ファイルを削除しているわけではないのでご安心を。」
  • だが、--cached を忘れると、とんでもないことになる
  • rm -r . のようなコマンド実行は、一日考えて翌日にするほうがいい。

「キャッシュ」という言葉が出てきたのは、コマンドのオプション --cached のせいだろうが、https://stackoverflow.com/questions/64308136/what-is-git-cache-and-what-is-stored-in-the-git-cache によると:

The expression the cache, and the spelling of the flag as --cached, is one of those[歴史的な用語]. The most modern term for this entity is the staging area, which reflects how you use it, but the most common term in Git for this entity is the index.

So, in general, if someone or something mentions the index, the staging area, or the cache, they probably mean the same thing:

  • git rm --cached でキャッシュ〈cache〉という文言を使う。
  • Git自身のメッセージで "staged content" という文言がある。
  • ファイル名は ./.git/index
  • cache = staging area = index

その他の有用な情報と知見:

  • git rev-parse --git-dir で、gitのリポジトリディレクトリが分かる。通常は ./.git
  • 環境変数 $GIT_INDEX_FILE でインデックスファイルを指定できる。
  • git rm --cached は、indexファイルを削除しない。
  • リポジトリがベアかどうかは git config --get core.bare
  • git ls-files でファイルをリストできる(詳細後述)
  • git ls-files --stage でインデックス内部を見ると、ステージされたファイル〈staged files〉だけではなくて、カレントコミットのファイルツリーが持つすべてのファイル=blobオブジェクトがリストされる。
  • index内容と概念的なステージングエリアは違うかも知れない。
  • indexエントリーには、 mode bits, object name and stage number が記録されている(後述)

https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables を調べてみると:

  • GIT_DIR is the location of the .git folder. If this isn’t specified, Git walks up the directory tree until it gets to ~ or /, looking for a .git directory at every step.
  • GIT_WORK_TREE is the location of the root of the working directory for a non-bare repository. If --git-dir or GIT_DIR is specified but none of --work-tree, GIT_WORK_TREE or core.worktree is specified, the current working directory is regarded as the top level of your working tree.
  • GIT_INDEX_FILE is the path to the index file (non-bare repositories only).

git ls-files に関して:

  • カレントコミット〈HEAD参照先〉のファイルツリーが持つすべてのファイルをリストするには、git ls-files
  • index内に記録されているすべてのファイルをリストするには git ls-files --stage
  • デバッグ情報は git ls-files --debug

mode bits は:

32-bit mode, split into (high to low bits)

4-bit object type
valid values in binary are 1000 (regular file), 1010 (symbolic link)
and 1110 (gitlink)

3-bit unused

9-bit unix permission. Only 0755 and 0644 are valid for regular files.
Symbolic links and gitlinks have value 0 in this field.

UNIXパーミッションは:

The following flags are defined for the st_mode field:

S_IFMT 0170000 bit mask for the file type bit fields
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
S_ISUID 0004000 set UID bit
S_ISGID 0002000 set-group-ID bit (see below)
S_ISVTX 0001000 sticky bit (see below)
S_IRWXU 00700 mask for file owner permissions
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 mask for group permissions
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permi

staging number は:

Normally, only 0 is used since this represents the state of the current working tree. However, if a merge conflict arises, then the index is used to disambiguate the state of the files at each level. If you have a conflict, then stage 0 is used to represent the current working tree, stage 1 is used for your change, then stage 2 and 3 for the other differences.