Git
English ▾ トピック ▾ 最新バージョン ▾ gitformat-pack は 2.44.0 で最後に更新されました

名前

gitformat-pack - Gitパック形式

概要

$GIT_DIR/objects/pack/pack-.{pack,idx}
$GIT_DIR/objects/pack/pack-.rev
$GIT_DIR/objects/pack/pack-*.mtimes
$GIT_DIR/objects/pack/multi-pack-index

説明

Gitパック形式は、Gitが主要なリポジトリデータのほとんどを保存する方法です。リポジトリのライフサイクル全体で、ルーズオブジェクト(もしあれば)と小さいパックは、より大きいパックに統合されます。git-gc[1]およびgit-pack-objects[1]を参照してください。

パック形式は、たとえばgitprotocol-v2[5]のように、オーバーザワイヤーでも使用され、gitformat-bundle[5]の場合のように、他のコンテナ形式の一部でもあります。

チェックサムとオブジェクトID

従来のSHA-1を使用するリポジトリでは、以下に記載されているパックチェックサム、インデックスチェックサム、およびオブジェクトID(オブジェクト名)はすべてSHA-1を使用して計算されます。同様に、SHA-256リポジトリでは、これらの値はSHA-256を使用して計算されます。

pack-*.packファイルは次の形式です

  • ヘッダーは先頭に現れ、次の内容で構成されます

    4-byte signature:
        The signature is: {'P', 'A', 'C', 'K'}
       4-byte version number (network byte order):
    Git currently accepts version number 2 or 3 but
           generates version 2 only.
    4-byte number of objects contained in the pack (network byte order)
    Observation: we cannot have more than 4G versions ;-) and
    more than 4G objects in a pack.
  • ヘッダーの後には、多数のオブジェクトエントリが続きます。各エントリは次のようになります

    (undeltified representation)
    n-byte type and length (3-bit type, (n-1)*7+4-bit length)
    compressed data
       (deltified representation)
       n-byte type and length (3-bit type, (n-1)*7+4-bit length)
       base object name if OBJ_REF_DELTA or a negative relative
    offset from the delta object's position in the pack if this
    is an OBJ_OFS_DELTA object
       compressed delta data
    Observation: the length of each object is encoded in a variable
    length format and is not constrained to 32-bit or anything.
  • トレーラーは上記のすべてのパックチェックサムを記録します。

オブジェクトタイプ

有効なオブジェクトタイプは次のとおりです

  • OBJ_COMMIT (1)

  • OBJ_TREE (2)

  • OBJ_BLOB (3)

  • OBJ_TAG (4)

  • OBJ_OFS_DELTA (6)

  • OBJ_REF_DELTA (7)

タイプ5は将来の拡張のために予約されています。タイプ0は無効です。

サイズエンコーディング

このドキュメントでは、非負の整数の次の「サイズエンコーディング」を使用します。各バイトから、最小有効ビットの7つを使用して、結果の整数を形成します。最上位ビットが1である限り、このプロセスは継続します。MSBが0のバイトは、最後の7ビットを提供します。7ビットチャンクは連結されます。後の値はより重要です。

このサイズエンコーディングは、このドキュメントでも使用されている「オフセットエンコーディング」と混同しないでください。

デルタ表現

概念的には、オブジェクトタイプはcommit、tree、tag、blobの4つしかありません。ただし、スペースを節約するために、オブジェクトは別の「ベース」オブジェクトの「デルタ」として格納できます。これらの表現には、ofs-deltaおよびref-deltaという新しいタイプが割り当てられます。これは、パックファイルでのみ有効です。

ofs-deltaとref-deltaの両方が、オブジェクトを再構築するために別のオブジェクト(ベースオブジェクトと呼ばれる)に適用される「デルタ」を格納します。それらの違いは、ref-deltaがベースオブジェクト名を直接エンコードすることです。ベースオブジェクトが同じパックにある場合、ofs-deltaは代わりにパック内のベースオブジェクトのオフセットをエンコードします。

ベースオブジェクトが同じパック内にある場合、デルタ化することもできます。Ref-deltaは、パック外のオブジェクト(いわゆる「シンパック」)を参照することもできます。ただし、ディスクに保存する場合、パックは循環依存を避けるために自己完結型である必要があります。

デルタデータは、ベースオブジェクトのサイズと再構築されるオブジェクトのサイズから始まります。これらのサイズは、上記のサイズエンコーディングを使用してエンコードされます。デルタデータの残りは、ベースオブジェクトからオブジェクトを再構築する命令のシーケンスです。ベースオブジェクトがデルタ化されている場合は、最初に正規形式に変換する必要があります。各命令は、完了するまで、ますます多くのデータをターゲットオブジェクトに追加します。これまでにサポートされている命令は2つあります。1つはソースオブジェクトからバイト範囲をコピーするため、もう1つは命令自体に埋め込まれた新しいデータを挿入するためのものです。

各命令は可変長です。命令タイプは、最初のオクテットの7番目のビットによって決定されます。次の図は、RFC 1951(Deflate圧縮データ形式)の規則に従います。

ベースオブジェクトからコピーする命令

+----------+---------+---------+---------+---------+-------+-------+-------+
| 1xxxxxxx | offset1 | offset2 | offset3 | offset4 | size1 | size2 | size3 |
+----------+---------+---------+---------+---------+-------+-------+-------+

これは、ソースオブジェクトからバイト範囲をコピーする命令形式です。コピー元のオフセットとコピーするバイト数をエンコードします。オフセットとサイズはリトルエンディアン順です。

すべてのオフセットバイトとサイズバイトはオプションです。これは、小さいオフセットまたはサイズをエンコードするときに命令サイズを縮小するためです。最初のオクテットの最初の7ビットは、次の7つのオクテットのどれが存在するかを決定します。ビット0が設定されている場合、offset1が存在します。ビット1が設定されている場合、offset2が存在します。以下同様です。

よりコンパクトな命令を使用しても、オフセットとサイズのエンコーディングは変わらないことに注意してください。たとえば、以下のようにoffset2のみが省略されている場合、offset3には引き続きビット16〜23が含まれます。offset2にはならず、offset1のすぐ隣にある場合でも、ビット8〜15が含まれます。

+----------+---------+---------+
| 10000101 | offset1 | offset3 |
+----------+---------+---------+

最もコンパクトな形式では、この命令はオフセットとサイズが省略された1バイト(0x80)のみを使用します。これにより、デフォルト値はゼロになります。もう1つの例外があります。サイズゼロは自動的に0x10000に変換されます。

新しいデータを追加する命令

+----------+============+
| 0xxxxxxx |    data    |
+----------+============+

これは、ベースオブジェクトなしでターゲットオブジェクトを構築する命令です。次のデータがターゲットオブジェクトに追加されます。最初のオクテットの最初の7ビットは、バイト単位のデータサイズを決定します。サイズはゼロ以外である必要があります。

予約された命令

+----------+============
| 00000000 |
+----------+============

これは、将来の拡張のために予約された命令です。

元の(バージョン1)pack-*.idxファイルは次の形式です

  • ヘッダーは、256個の4バイトのネットワークバイトオーダー整数で構成されています。このテーブルのN番目のエントリは、対応するパック内のオブジェクトの数を記録します。オブジェクト名の最初のバイトはN以下です。これは、第1レベルのファンアウトテーブルと呼ばれます。

  • ヘッダーの後に、ソートされた24バイトのエントリが続きます。パック内のオブジェクトごとに1つのエントリがあります。各エントリは

    4-byte network byte order integer, recording where the
    object is stored in the packfile as the offset from the
    beginning.
    one object name of the appropriate size.
  • ファイルはトレーラーで終了します

    A copy of the pack checksum at the end of the corresponding
    packfile.
    Index checksum of all of the above.

パックIdxファイル

	--  +--------------------------------+
fanout	    | fanout[0] = 2 (for example)    |-.
table	    +--------------------------------+ |
	    | fanout[1]                      | |
	    +--------------------------------+ |
	    | fanout[2]                      | |
	    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
	    | fanout[255] = total objects    |---.
	--  +--------------------------------+ | |
main	    | offset                         | | |
index	    | object name 00XXXXXXXXXXXXXXXX | | |
table	    +--------------------------------+ | |
	    | offset                         | | |
	    | object name 00XXXXXXXXXXXXXXXX | | |
	    +--------------------------------+<+ |
	  .-| offset                         |   |
	  | | object name 01XXXXXXXXXXXXXXXX |   |
	  | +--------------------------------+   |
	  | | offset                         |   |
	  | | object name 01XXXXXXXXXXXXXXXX |   |
	  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   |
	  | | offset                         |   |
	  | | object name FFXXXXXXXXXXXXXXXX |   |
	--| +--------------------------------+<--+
trailer	  | | packfile checksum              |
	  | +--------------------------------+
	  | | idxfile checksum               |
	  | +--------------------------------+
          .-------.
                  |
Pack file entry: <+
    packed object header:
1-byte size extension bit (MSB)
       type (next 3 bit)
       size0 (lower 4-bit)
       n-byte sizeN (as long as MSB is set, each 7-bit)
	size0..sizeN form 4+7+7+..+7 bit integer, size0
	is the least significant part, and sizeN is the
	most significant part.
    packed object data:
       If it is not DELTA, then deflated bytes (the size above
	is the size before compression).
If it is REF_DELTA, then
  base object name (the size above is the
	size of the delta data that follows).
         delta data, deflated.
If it is OFS_DELTA, then
  n-byte offset (see below) interpreted as a negative
	offset from the type-byte of the header of the
	ofs-delta entry (the size above is the size of
	the delta data that follows).
  delta data, deflated.
  offset encoding:
n bytes with MSB set in all but the last one.
The offset is then the number constructed by
concatenating the lower 7 bit of each byte, and
for n >= 2 adding 2^7 + 2^14 + ... + 2^(7*(n-1))
to the result.

バージョン2のpack-*.idxファイルは、4 GiBを超えるパックをサポートし、

have some other reorganizations.  They have the format:
  • ありえないファンアウト[0]値である4バイトのマジックナンバー\377tOc

  • 4バイトのバージョン番号(= 2)

  • v1と同様の256エントリのファンアウトテーブル。

  • ソートされたオブジェクト名のテーブル。これらは、特定のオブジェクト名のバイナリ検索のキャッシュフットプリントを削減するために、オフセット値なしで一緒にパックされます。

  • パックされたオブジェクトデータの4バイトのCRC32値のテーブル。これはv2の新機能であるため、再パッケージ化中に検出されないデータ破損なしに、圧縮データをパックからパックに直接コピーできます。

  • 4バイトのオフセット値(ネットワークバイトオーダー)。これらは通常、31ビットのパックファイルオフセットですが、大きなオフセットはmsbitセットを持つ次のテーブルへのインデックスとしてエンコードされます。

  • 8バイトのオフセットエントリのテーブル(2 GiB未満のパックファイルの場合は空)。パックファイルは、使用頻度の高いオブジェクトが先頭になるように編成されているため、ほとんどのオブジェクト参照はこのテーブルを参照する必要はありません。

  • v1パックファイルと同じトレーラー

    A copy of the pack checksum at the end of the
    corresponding packfile.
    Index checksum of all of the above.

pack-*.revファイルは次の形式です

  • 4バイトのマジックナンバー0x52494458RIDX)。

  • 4バイトのバージョン識別子(= 1)。

  • 4バイトのハッシュ関数識別子(SHA-1の場合は1、SHA-256の場合は2)。

  • パックファイル内の対応するオフセットでソートされた、インデックス位置のテーブル(パックされたオブジェクトごとに1つ、合計num_objects個、それぞれネットワークバイトオーダーの4バイト符号なし整数)。

  • トレーラー。以下を含む。

    checksum of the corresponding packfile, and
    a checksum of all of the above.

すべての4バイト数値はネットワークバイトオーダーです。

pack-*.mtimes ファイルの形式は次のとおりです。

すべての4バイト数値はネットワークバイトオーダーです。

  • 4バイトのマジックナンバー 0x4d544d45 (MTME)。

  • 4バイトのバージョン識別子(= 1)。

  • 4バイトのハッシュ関数識別子(SHA-1の場合は1、SHA-256の場合は2)。

  • 4バイト符号なし整数のテーブル。i番目の値は、対応するパック内のi番目のオブジェクトの最終更新時刻(mtime)であり、辞書式順序(インデックス)で並んでいます。mtimeは標準エポック秒をカウントします。

  • トレーラー。対応するパックファイルのチェックサムと、上記のすべて(それぞれ、指定されたハッシュ関数に応じた長さを持つ)のチェックサムを含みます。

マルチパックインデックス(MIDX)ファイルの形式は次のとおりです。

マルチパックインデックスファイルは、複数のパックファイルとルーズオブジェクトを参照します。

MIDXに追加のデータを追加する拡張を可能にするために、本体を「チャンク」に整理し、本体の先頭にルックアップテーブルを提供します。ヘッダーには、パック数、ベースMIDXファイル数、ハッシュ長、タイプなどの特定の長さの値が含まれています。

すべての4バイト数値はネットワークバイトオーダーです。

ヘッダー

4-byte signature:
    The signature is: {'M', 'I', 'D', 'X'}
1-byte version number:
    Git only writes or recognizes version 1.
1-byte Object Id Version
    We infer the length of object IDs (OIDs) from this value:
	1 => SHA-1
	2 => SHA-256
    If the hash type does not match the repository's hash algorithm,
    the multi-pack-index file should be ignored with a warning
    presented to the user.
1-byte number of "chunks"
1-byte number of base multi-pack-index files:
    This value is currently always zero.
4-byte number of pack files

チャンクルックアップ

(C + 1) * 12 bytes providing the chunk offsets:
    First 4 bytes describe chunk id. Value 0 is a terminating label.
    Other 8 bytes provide offset in current file for chunk to start.
    (Chunks are provided in file-order, so you can infer the length
    using the next chunk position if necessary.)
The CHUNK LOOKUP matches the table of contents from
the chunk-based file format, see gitformat-chunk[5].
The remaining data in the body is described one chunk at a time, and
these chunks may be given in any order. Chunks are required unless
otherwise specified.

チャンクデータ

Packfile Names (ID: {'P', 'N', 'A', 'M'})
    Store the names of packfiles as a sequence of NUL-terminated
    strings. There is no extra padding between the filenames,
    and they are listed in lexicographic order. The chunk itself
    is padded at the end with between 0 and 3 NUL bytes to make the
    chunk size a multiple of 4 bytes.
Bitmapped Packfiles (ID: {'B', 'T', 'M', 'P'})
    Stores a table of two 4-byte unsigned integers in network order.
    Each table entry corresponds to a single pack (in the order that
    they appear above in the `PNAM` chunk). The values for each table
    entry are as follows:
    - The first bit position (in pseudo-pack order, see below) to
      contain an object from that pack.
    - The number of bits whose objects are selected from that pack.
OID Fanout (ID: {'O', 'I', 'D', 'F'})
    The ith entry, F[i], stores the number of OIDs with first
    byte at most i. Thus F[255] stores the total
    number of objects.
OID Lookup (ID: {'O', 'I', 'D', 'L'})
    The OIDs for all objects in the MIDX are stored in lexicographic
    order in this chunk.
Object Offsets (ID: {'O', 'O', 'F', 'F'})
    Stores two 4-byte values for every object.
    1: The pack-int-id for the pack storing this object.
    2: The offset within the pack.
	If all offsets are less than 2^32, then the large offset chunk
	will not exist and offsets are stored as in IDX v1.
	If there is at least one offset value larger than 2^32-1, then
	the large offset chunk must exist, and offsets larger than
	2^31-1 must be stored in it instead. If the large offset chunk
	exists and the 31st bit is on, then removing that bit reveals
	the row in the large offsets containing the 8-byte offset of
	this object.
[Optional] Object Large Offsets (ID: {'L', 'O', 'F', 'F'})
    8-byte offsets into large packfiles.
[Optional] Bitmap pack order (ID: {'R', 'I', 'D', 'X'})
    A list of MIDX positions (one per object in the MIDX, num_objects in
    total, each a 4-byte unsigned integer in network byte order), sorted
    according to their relative bitmap/pseudo-pack positions.

トレーラー

Index checksum of the above contents.

マルチパックインデックスのリバースインデックス

パックベースのリバースインデックスと同様に、マルチパックインデックスもリバースインデックスを生成するために使用できます。

オフセット、パック、およびインデックス位置間のマッピングではなく、このリバースインデックスは、MIDX内のオブジェクトの位置と、MIDXが記述する疑似パック内のオブジェクトの位置の間をマッピングします(つまり、マルチパックリバースインデックスのi番目のエントリは、疑似パック順のi番目のオブジェクトのMIDX位置を保持します)。

これらの順序付けの違いを明確にするために、マルチパック到達可能性ビットマップ(まだ存在しませんが、ここで構築しようとしているものです)を考えてみましょう。各ビットはMIDX内のオブジェクトに対応する必要があるため、ビット位置からMIDX位置への効率的なマッピングが必要です。

1つの解決策は、ビットがMIDXによって保存されたoidソートされたインデックス内の同じ位置を占めるようにすることです。しかし、oidは事実上ランダムであるため、結果として得られる到達可能性ビットマップは局所性がなくなり、圧縮が悪くなります。(これが、シングルパックビットマップが同じ目的のために、.idx順序ではなく、パック順序を使用する理由です。)

そのため、局所性がはるかに優れている(したがって、より効率的に圧縮される)パック順序に基づいて、MIDX全体の順序付けを定義したいと思います。MIDX内のすべてのパックの連結によって作成された疑似パックと考えることができます。たとえば、それぞれ10、15、20個のオブジェクトを持つ3つのパック(a、b、c)を含むMIDXがある場合、オブジェクトの順序は次のようになります。

|a,0|a,1|...|a,9|b,0|b,1|...|b,14|c,0|c,1|...|c,19|

パックの順序付けはMIDXのパックリストによって定義され、各パック内のオブジェクトの順序付けは実際のパックファイル内の順序と同じです。

パックのリストとオブジェクトの数を与えられれば、その疑似パック順序をナイーブに再構築できます(たとえば、位置27のオブジェクトは、パック「a」と「b」が25個のスロットを消費したため、(c、1)である必要があります)。しかし、落とし穴があります。オブジェクトはパック間で重複する可能性があり、その場合、MIDXはオブジェクトへのポインターを1つだけ保存します(したがって、ビットマップにスロットを1つだけ必要とします)。

呼び出し元は、ビット位置の順序でオブジェクトを読み取ることで、重複を自分で処理できますが、これはオブジェクトの数に対して線形であり、通常のビットマップルックアップには高価すぎます。リバースインデックスを構築することで解決します。これは、インデックスの論理的な逆であり、そのインデックスはすでに重複を削除しているからです。ただし、リバースインデックスをその場で構築するのはコストがかかる可能性があります。パックベースのリバースインデックスのオンディスク形式がすでにあるため、MIDXの疑似パックにもそれを再利用しましょう。

MIDXのオブジェクトは、疑似パックをつなぎ合わせるために、次のように順序付けられます。pack(o)は、MIDXによってoが選択されたパックを返し、パックの順序は(MIDXによって保存された)数値IDに基づいて定義します。offset(o)は、pack(o)内のoのオブジェクトオフセットを返します。次に、o1o2を次のように比較します。

  • pack(o1)pack(o2)のいずれかが優先され、もう一方が優先されない場合、優先される方が最初にソートされます。

    (これは、MIDXビットマップが、パック再利用メカニズムで使用する必要があるパックを決定できるようにする詳細です。ビット位置0のオブジェクトを含むパックをMIDXに問い合わせることができます)。

  • pack(o1) ≠ pack(o2)の場合、パックIDに基づいて2つのオブジェクトを降順にソートします。

  • それ以外の場合、pack(o1) = pack(o2)であり、オブジェクトはパック順にソートされます(つまり、offset(o1) < offset(o2)の場合にのみ、o1o2より前にソートされます)。

要するに、MIDXの疑似パックは、MIDXによって保存されたパック内のオブジェクトの重複が排除された連結であり、パック順にレイアウトされ、パックはMIDX順に配置されます(優先パックが最初に配置されます)。

MIDXのリバースインデックスは、MIDX内のオプションのRIDXチャンクに格納されます。

BTMPチャンク

ビットマップ化されたパックファイル(BTMP)チャンクは、マルチパックインデックスの到達可能性ビットマップ内のオブジェクトに関する追加情報をエンコードします。MIDXのオブジェクトは、到達可能性ビットマップのために「疑似パック」順(上記を参照)に配置されていることを思い出してください。

上記の例から、「a」、「b」、「c」のパックがあり、それぞれ10、15、20個のオブジェクトがあるとします。疑似パック順では、それらは次のように配置されます。

|a,0|a,1|...|a,9|b,0|b,1|...|b,14|c,0|c,1|...|c,19|

シングルパックビットマップ(または、優先パック付きのマルチパック到達可能性ビットマップ)を操作する場合、git-pack-objects[1]は、「逐語的」な再利用を実行し、オブジェクトをパッキングリストに追加するのではなく、ビットマップ化されたパックファイルまたは優先パックファイルのチャンクを再利用しようとします。

既存のパックからバイトのチャンクが再利用される場合、そこに含まれるオブジェクトはパッキングリストに追加する必要がなく、メモリとCPU時間を節約できます。ただし、既存のパックファイルからのチャンクは、次の条件が満たされた場合にのみ再利用できます。

  • チャンクには、呼び出し元によって要求されたオブジェクトのみが含まれます(つまり、呼び出し元が明示的または暗黙的に要求しなかったオブジェクトは含まれません)。

  • オフセットまたは参照デルタとして非シンパックに格納されているすべてのオブジェクトには、結果のパックにベースオブジェクトも含まれます。

BTMPチャンクは、上記のようにパックファイルのセットに対するマルチパック再利用を実装するために必要な情報をエンコードします。具体的には、BTMPチャンクは、MIDXに格納されている各パックファイルpに対して、3つの情報(すべてネットワークバイトオーダーの32ビット符号なし整数)を次のようにエンコードします。

bitmap_pos

pからのオブジェクトによって占有される、マルチパックインデックスの到達可能性ビットマップ内の最初のビット位置(疑似パック順)。

bitmap_nr

そのパックpからのオブジェクトをエンコードするビット位置の数(bitmap_posの位置を含む)。

たとえば、上記の例(パック「a」、「b」、「c」)に対応するBTMPチャンクは次のようになります。

bitmap_pos bitmap_nr

パックファイル「a」

0

10

パックファイル「b」

10

15

パックファイル「c」

25

20

この情報があれば、各パックファイルを、BTMPチャンクの実装前に個々のパックで実行されていた逐語的なパック再利用と同じ方法で、個別に再利用可能として扱うことができます。

クラフトパック

クラフトパック機能は、到達不能なオブジェクトを削除するGitの従来のメカニズムに代わるものを提供します。このドキュメントでは、Gitのプルーニングメカニズムと、代わりにクラフトパックを使用して同じことを実現する方法の概要を説明します。

背景

リポジトリから到達不能なオブジェクトを削除するために、Gitはgit repack -Adを提供しています(git-repack[1]を参照)。ドキュメントから引用すると

[...] unreachable objects in a previous pack become loose, unpacked objects,
instead of being left in the old pack. [...] loose unreachable objects will be
pruned according to normal expiry rules with the next 'git gc' invocation.

到達不能なオブジェクトは、削除されようとしているオブジェクトを参照する可能性のある着信プッシュと競合する可能性があるため、すぐには削除されません。代わりに、これらの到達不能なオブジェクトはルーズオブジェクトとして保存され、有効期限ウィンドウよりも古くなるまでそのままになり、その時点でgit-prune[1]によって削除されます。

Gitは、オブジェクトごとのmtimeを追跡するために、これらの到達不能なオブジェクトをルーズに保存する必要があります。これらの到達不能なオブジェクトが1つの大きなパックに書き込まれた場合、(その中に含まれるオブジェクトが再書き込みされたために)そのパックを更新するか、到達不能なオブジェクトの新しいパックを作成すると、パックのmtimeが更新され、その中のオブジェクトは有効期限ウィンドウから出ることはありません。代わりに、個々のオブジェクトmtimeを追跡し、すべてのクラフトオブジェクトが一度に更新される状況を回避するために、オブジェクトはルーズに保存されます。

これにより、リポジトリに猶予期間を過ぎていない多くの到達不能なオブジェクトが含まれている場合、望ましくない状況が発生する可能性があります。.git/objectsのシャードに大きなディレクトリがあると、リポジトリのパフォーマンスが低下する可能性があります。しかし、十分な数の到達不能なオブジェクトがあると、inodeの枯渇につながり、システム全体のパフォーマンスが低下する可能性があります。これらのオブジェクトをパックすることはできないため、これらのリポジトリはディスクスペースを大量に消費することがよくあります。zlibで圧縮することはできますが、デルタチェーンに格納することはできないためです。

クラフトパック

クラフトパックは、すべてのルーズオブジェクトを含む単一のパックとともに、オブジェクトごとのmtimeを別のファイルに含めることで、到達不能なオブジェクトをルーズな状態で保存する必要性を排除します。

クラフトパックは、新しいパックを生成するときにgit repack --cruftによって書き込まれます。git-pack-objects[1]--cruftオプションです。git repack --cruftは、古典的なオールインワンのリパックであり、結果のパック内のすべてが到達可能であり、それ以外のすべてが到達不能であることを意味することに注意してください。書き込まれると、--cruftオプションは、git repackに前のステップでパックされていないオブジェクトのみを含む別のパックを生成するように指示します(これは、すべての到達不能なオブジェクトを一緒にパックすることと同じです)。これは次のように進みます。

  1. すべてのオブジェクトを列挙し、(a)維持されたパックに含まれていない、かつ(b)そのmtimeが猶予期間内であるオブジェクトを走査チップとしてマークします。

  2. 前のステップで収集されたチップに基づいて到達可能性走査を実行し、途中のすべてのオブジェクトをパックに追加します。

  3. パックと、オブジェクトごとのタイムスタンプを記録する.mtimesファイルを書き出します。

このモードは、cruftパックを書き込むように指示された場合に、git-repack[1]によって内部的に呼び出されます。重要なのは、コア内で保持されるパックのセットが、リパックによって削除されないパックのセットと正確に一致するということです。言い換えれば、それらはリポジトリの到達可能なオブジェクトをすべて含んでいるということです。

リポジトリにすでにcruftパックが存在する場合、通常、git repack --cruft はオブジェクトをそれに追加するだけです。ただし、git repack--cruft-expiration オプションが指定された場合は例外で、生成されたcruftパックは、後で git-gc[1] がそれらのオブジェクトを期限切れにするのを待つ代わりに、期限切れのオブジェクトを省略することができます。

期限切れの到達不能なオブジェクトを削除する責任を通常負うのは、git-gc[1] です。

代替案

この設計に対する注目すべき代替案は次のとおりです。

  • オブジェクトごとのmtimeデータの場所。

mtimeデータの場所については、.idx形式を複雑にすることを避けるため、パックに関連付けられた新しい補助ファイルが選択されました。.idx形式がオプションのデータチャンクをサポートするようになった場合、.mtimes形式を.idx自体に統合することが理にかなうかもしれません。

GIT

git[1] スイートの一部

scroll-to-top