セットアップと設定
プロジェクトの取得と作成
基本的なスナップショット取得
ブランチとマージ
プロジェクトの共有と更新
検査と比較
パッチ適用
デバッグ
メール
外部システム
サーバー管理
ガイド
- gitattributes
- コマンドラインインターフェースの慣例
- 日常のGit
- よくある質問 (FAQ)
- 用語集
- フック
- gitignore
- gitmodules
- リビジョン
- サブモジュール
- チュートリアル
- ワークフロー
- すべてのガイド...
管理
プラミングコマンド
- 2.44.1 → 2.49.0 変更なし
-
2.44.0
2024-02-23
- 2.43.1 → 2.43.6 変更なし
-
2.43.0
2023-11-20
- 2.41.1 → 2.42.4 変更なし
-
2.41.0
2023-06-01
- 2.38.1 → 2.40.4 変更なし
-
2.38.0
2022-10-02
概要
$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ビットのチャンクは連結されます。後の値はより重要です。
このサイズエンコーディングは、このドキュメントでも使用されている「オフセットエンコーディング」と混同しないでください。
デルタ化表現
概念的には、コミット、ツリー、タグ、ブロブの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が含まれます。offset1のすぐ隣にあっても、offset2になってビット8-15が含まれることはありません。
+----------+---------+---------+ | 10000101 | offset1 | offset3 | +----------+---------+---------+
最もコンパクトな形式では、この命令はオフセットとサイズの両方が省略された状態で1バイト(0x80)しか占有せず、デフォルト値はゼロになります。もう1つの例外として、サイズゼロは自動的に0x10000に変換されます。
オリジナル(バージョン1)のpack-*.idxファイルは以下のフォーマットを持っています
-
ヘッダーは、256個の4バイトのネットワークバイトオーダー整数で構成されています。このテーブルのN番目のエントリは、対応するパック内のオブジェクトの数を記録しており、そのオブジェクト名の最初のバイトがN以下であるものの数です。これは*ファーストレベル・ファンアウト*テーブルと呼ばれます。
-
ヘッダーの後にはソートされた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.
パックインデックスファイル
-- +--------------------------------+ 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ビットのパックファイルオフセットですが、大きなオフセットは最上位ビットが設定された次のテーブルへのインデックスとしてエンコードされます。
-
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バイトのマジックナンバー *0x52494458* (*RIDX*)。
-
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位置への効率的なマッピングが必要です。
一つの解決策は、MIDXが格納するOIDでソートされたインデックス内でビットが同じ位置を占めるようにすることです。しかし、OIDは実質的にランダムであるため、結果として得られる到達可能性ビットマップには局所性がなく、したがって圧縮効率が悪くなります。(これが、シングルパックビットマップが同じ目的で.idx順ではなくパック順を使用する理由です。)
そこで、パックの順序に基づいてMIDX全体の順序を定義したいと考えています。これははるかに優れた局所性(したがって、より効率的に圧縮)を持ちます。MIDX内のすべてのパックを連結して作成された擬似パックを考えることができます。例えば、3つのパック(a、b、c)があり、それぞれ10、15、20のオブジェクトを持つMIDXがあった場合、オブジェクトの順序は次のようになります。
|a,0|a,1|...|a,9|b,0|b,1|...|b,14|c,0|c,1|...|c,19|
ここで、パックの順序はMIDXのパックリストによって定義され、各パック内のオブジェクトの順序は実際のパックファイル内の順序と同じです。
パックのリストとそれらのオブジェクト数があれば、その擬似パックの順序を素朴に再構築できます(例:位置27のオブジェクトは(c,1)であるはずです。なぜならパック「a」と「b」が25スロットを消費したからです)。しかし、注意点があります。オブジェクトはパック間で重複する可能性があり、その場合MIDXはオブジェクトへのポインタを1つしか保存しません(したがって、ビットマップには1つのスロットしか必要ありません)。
呼び出し元は、ビット位置の順序でオブジェクトを読み取ることで重複を自分で処理できますが、それはオブジェクトの数に比例し、通常のビットマップルックアップには費用がかかりすぎます。逆インデックスを構築することでこれを解決できます。それはインデックスの論理的な逆であり、そのインデックスはすでに重複を排除しているからです。しかし、その場で逆インデックスを構築するのは費用がかかる場合があります。パックベースの逆インデックスのディスク上のフォーマットがすでに存在するため、MIDXの擬似パックにもそれを再利用しましょう。
MIDXからのオブジェクトは、擬似パックを構成するために次のように順序付けられます。`pack(o)` がMIDXによって `o` が選択されたパックを返し、数値ID(MIDXによって格納される)に基づいてパックの順序を定義するとします。`offset(o)` が `pack(o)` 内の `o` のオブジェクトオフセットを返すとします。次に、`o1` と `o2` を次のように比較します。
-
`pack(o1)` と `pack(o2)` の一方が優先され、もう一方がそうでない場合、優先される方が先にソートされます。
(これは、MIDXビットマップがパック再利用メカニズムによってどのパックを使用すべきかを決定できるようにする詳細です。なぜなら、ビット位置0にあるオブジェクトを含むパックをMIDXに問い合わせることができるからです。)
-
`pack(o1) ≠ pack(o2)` の場合、パックIDに基づいて2つのオブジェクトを降順にソートします。
-
それ以外の場合、`pack(o1) = pack(o2)` であり、オブジェクトはパック順にソートされます(つまり、`offset(o1) < offset(o2)` の場合にのみ `o1` は `o2` より先にソートされます)。
要するに、MIDXの擬似パックは、MIDXによって格納されたパック内のオブジェクトの重複排除された連結であり、パック順に配置され、パックはMIDX順(優先パックが最初に来る)に並べられています。
MIDXの逆インデックスは、MIDX自体のオプションの *RIDX* チャンクに格納されます。
`BTMP` チャンク
Bitmapped Packfiles (`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ビット符号なし整数)をエンコードします。
例えば、上記の例(パック「a」、「b」、「c」を含む)に対応する `BTMP` チャンクは次のようになります。
bitmap_pos |
bitmap_nr |
|
---|---|---|
パックファイル「a」 |
|
|
パックファイル「b」 |
|
|
パックファイル「c」 |
|
|
この情報が整っていれば、`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` に、前のステップでパックされなかったオブジェクトのみを含む別のパックを生成するよう指示します(これは、すべての到達不能なオブジェクトをまとめてパックすることに相当します)。これは次のように進行します。
-
すべてのオブジェクトを列挙し、(a)保持パックに含まれていない、かつ(b)mtimeが猶予期間内であるオブジェクトをトラバーサルヒントとしてマークします。
-
前のステップで収集されたヒントに基づいて到達可能性トラバーサルを実行し、その過程ですべてのオブジェクトをパックに追加します。
-
パックと、オブジェクトごとのタイムスタンプを記録する `.mtimes` ファイルを書き出します。
このモードは、クラフトパックを書き込むよう指示されたときに、git-repack[1] によって内部的に呼び出されます。重要なことに、コア内の保持されているパックのセットは、再パックによって削除されないパックのセットと全く同じです。言い換えれば、それらはリポジトリの到達可能なすべてのオブジェクトを含んでいます。
リポジトリがすでにクラフトパックを持っている場合、`git repack --cruft` は通常、オブジェクトをそこに追加するだけです。これには例外があり、`git repack` に `--cruft-expiration` オプションが与えられた場合です。このオプションを使用すると、生成されるクラフトパックは、git-gc[1] が後でこれらのオブジェクトを期限切れにするのを待つのではなく、期限切れのオブジェクトを省略できます。
通常、期限切れの到達不能なオブジェクトを削除する責任を負うのはgit-gc[1]です。
GIT
git[1] スイートの一部