web-dev-qa-db-ja.com

gitインデックスには正確に何が含まれていますか?

Gitインデックスには正確に何が含まれており、どのコマンドを使用してインデックスのコンテンツを表示できますか?


更新

回答ありがとうございます。インデックスはステージング領域として機能し、コミットされるのは作業ツリーではなくインデックスにあることを知っています。インデックスオブジェクトの構成について知りたいだけです。ファイル名/ディレクトリ名のリスト、SHA-1ペア、仮想ツリーのようなものでしょうか?

Gitの用語では、インデックスの内容を一覧表示するために使用できるplumbingコマンドはありますか?

165
mochidino

ビットごとの分析

形式をよりよく理解し、いくつかのフィールドをより詳細に調査するために、少しテストを行うことにしました。

以下の結果は、Gitバージョン1.8.5.22.3で同じです。

TODOを使用して、不明または未発見のポイントをマークしました。これらのポイントを自由に補完してください。

他の人が述べたように、インデックスは標準のツリーオブジェクトとしてではなく、.git/indexの下に保存され、その形式はバイナリであり、次の場所に文書化されています: https://github.com/git/git/blob/master /Documentation/technical/index-format.txt

インデックスはコミットを作成するためのキャッシュであるため、インデックスを定義する主要な構造体は cache.h にあります。

セットアップ

以下を使用してテストリポジトリを開始すると:

git init
echo a > b
git add b
tree --charset=ascii

.gitディレクトリは次のようになります。

.git/objects/
|-- 78
|   `-- 981922613b2afb6025042ff6bd878ac1994e85
|-- info
`-- pack

そして、唯一のオブジェクトのコンテンツを取得する場合:

git cat-file -p 78981922613b2afb6025042ff6bd878ac1994e85

aを取得します。これは次のことを示しています。

  • indexは、git add bがblobオブジェクトを作成したため、ファイルの内容を指します
  • メタデータはツリーオブジェクトではなく、インデックスファイルに格納されます。これは、オブジェクトが1つしかなかったためです:通常のGitオブジェクトでは、ブロブメタデータはツリーに格納されます

hd分析

次に、インデックス自体を見てみましょう。

hd .git/index

与える:

00000000  44 49 52 43 00 00 00 02  00 00 00 01 54 09 76 e6  |DIRC.... ....T.v.|
00000010  1d 81 6f c6 54 09 76 e6  1d 81 6f c6 00 00 08 05  |..o.T.v. ..o.....|
00000020  00 e4 2e 76 00 00 81 a4  00 00 03 e8 00 00 03 e8  |...v.... ........|
00000030  00 00 00 02 78 98 19 22  61 3b 2a fb 60 25 04 2f  |....x.." a;*.`%./|
00000040  f6 bd 87 8a c1 99 4e 85  00 01 62 00 ee 33 c0 3a  |......N. ..b..3.:|
00000050  be 41 4b 1f d7 1d 33 a9  da d4 93 9a 09 ab 49 94  |.AK...3. ......I.|
00000060

次に、結論を出します。

  | 0           | 4            | 8           | C              |
  |-------------|--------------|-------------|----------------|
0 | DIRC        | Version      | File count  | ctime       ...| 0
  | ...         | mtime                      | device         |
2 | inode       | mode         | UID         | GID            | 2
  | File size   | Entry SHA-1                              ...|
4 | ...                        | Flags       | Index SHA-1 ...| 4
  | ...                                                       |

最初に、ヘッダーが定義されます: struct cache_header

  • 44 49 52 43DIRC。 TODO:なぜこれが必要なのですか?

  • 00 00 00 02:形式バージョン:2.インデックス形式は時間とともに進化しています。現在、最大4つのバージョンがあります。GitHubの異なるコンピューター間で共同作業を行う場合、裸のリポジトリはインデックスを保存しないため、インデックスの形式は問題になりません。クローン時に生成されます。

  • 00 00 00 01:インデックス上のファイルの数:1つだけ、b

次に、 struct cache_entry で定義されたインデックスエントリのリストを開始します。ここには1つしかありません。を含む:

  • 一連のファイルメタデータ:8バイトctime、8バイトmtime、次に4バイト:デバイス、iノード、モード、UID、GID。

    方法に注意してください:

    • ctimemtimeは、ファイルを変更していないため、期待どおり(54 09 76 e6 1d 81 6f c6)です

      最初のバイトは、16進数のエポックからの秒数です:

      date --date="@$(printf "%x" "540976e6")"
      

      与える:

      Fri Sep  5 10:40:06 CEST 2014
      

      これは、この例を作成したときです。

      次の4バイトはナノ秒です。

    • UIDとGIDは00 00 03 e8、16進数で1000です。これは、シングルユーザー設定の一般的な値です。

    ほとんどすべてがツリーオブジェクトに存在しないこのメタデータのすべてにより、Gitはコンテンツ全体を比較せずにファイルが迅速に変更されたかどうかを確認できます。

  • 行の先頭に3000 00 00 02:ファイルサイズ:2バイト(aおよびechoからの\n

  • 78 98 19 22 ... c1 99 4e 85:エントリの以前のコンテンツに対する20バイトのSHA-1。 有効なフラグを仮定した私の実験 に従って、それに続くフラグはこのSHA-1では考慮されないことに注意してください。

  • 2バイトのフラグ:00 01

    • 1ビット:有効なフラグを想定します。私の調査では、この名前の不適切なフラグは、git update-index --assume-unchangedがその状態を保存する場所であることを示しています。 https://stackoverflow.com/a/28657085/895245

    • 1ビットの拡張フラグ。拡張フラグが存在するかどうかを決定します。拡張フラグを持たないバージョン2では0でなければなりません。

    • マージ中に使用される2ビットのステージフラグ。ステージはman git-mergeに文書化されています:

      • 0:マージ競合ではない通常のファイル
      • 1:ベース
      • 2:私たちのもの
      • 3:彼らのもの

      マージの競合時には、1〜3のすべてのステージがインデックスに保存され、git checkout --oursなどの操作が可能になります。

      git addの場合、ステージ0がパスのインデックスに追加され、Gitは競合が解決済みとしてマークされたことを認識します。 TODO:これを確認してください。

    • 続くパスの12ビット長:0 01:パスがbであったため、1バイトのみ

  • 2バイトの拡張フラグ。 「拡張フラグ」が基本フラグに設定されている場合にのみ意味があります。 TODO。

  • 62(ASCII b):可変長パス。前のフラグで決定された長さ、ここでは1バイト、b

次に00:ゼロパディングの1〜8バイトが来るので、パスはnullで終了し、インデックスは8バイトの倍数で終わります。これは、インデックスバージョン4以前でのみ発生します。

拡張機能は使用されていません。 Gitは、ファイルにチェックサム用の十分なスペースがないため、これを認識しています。

最後に、インデックスのコンテンツに対して20バイトのチェックサムee 33 c0 3a .. 09 ab 49 94があります。

Gitインデックスは、作業ディレクトリとリポジトリの間のステージング領域です。インデックスを使用して、一緒にコミットする一連の変更を構築できます。コミットを作成すると、コミットされるのは現在のインデックスにあるものであり、作業ディレクトリにあるものではありません。

インデックス内の内容を確認するには、次のコマンドを発行します。

git status

Git statusを実行すると、ステージングされている(現在インデックスにある)ファイル、変更されているがまだステージングされていないファイル、および完全に追跡されていないファイルを確認できます。

this と読むことができます。 Google検索では多くのリンクが表示されますが、これはかなり十分なものです。

12
user225312

これがまさに必要なものです。このコマンドを使用してください。

$ビンウォークインデックス

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
1717          0x6B5           Unix path: /company/user/user/delete.php
1813          0x715           Unix path: /company/user/user/get.php
1909          0x775           Unix path: /company/user/user/post.php
2005          0x7D5           Unix path: /company/user/user/put.php
3373          0xD2D           Unix path: /urban-airship/channel/channel/post.php
3789          0xECD           Unix path: /urban-airship/named-user/named-user/post.php
3901          0xF3D           Unix path: /user/categories/categories/delete.php
4005          0xFA5           Unix path: /user/categories/categories/get.php
4109          0x100D          Unix path: /user/categories/categories/put.php
4309          0x10D5          Unix path: /user/favorites/favorites/delete.php
1
l h