設定與組態
取得與建立專案
基本快照
分支與合併
分享與更新專案
檢查與比較
修補
除錯
電子郵件
外部系統
伺服器管理
指南
- gitattributes
- 命令列介面規範
- Git 日常使用
- 常見問題 (FAQ)
- 詞彙表
- 掛鉤 (Hooks)
- gitignore
- gitmodules
- 修訂版本 (Revisions)
- 子模組
- 教學
- 工作流程
- 所有指南...
管理
底層命令 (Plumbing Commands)
- 2.55.0 無變更
-
2.54.0
2026-04-20
- 2.53.0 無變更
-
2.52.0
2025-11-17
- 2.44.1 → 2.51.2 無變更
-
2.44.0
2024-02-23
- 2.43.1 → 2.43.7 無變更
-
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 計算。
CRC32 校驗和始終針對整個已封裝物件進行計算,包括標頭(n 位元組的類型和長度)、基礎物件名稱或偏移量(若有的話),以及整個壓縮後的物件。使用的 CRC32 演算法為 zlib 所採用的演算法。
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 無效。
物件編碼
與鬆散物件不同,已封裝物件沒有包含類型、大小和 NUL 位元組的前綴。這些是不必要的,因為它們可以由資料前方的 n 位元組類型和長度來確定,因此它們被從壓縮和差異化的資料中省略了。
物件 ID 的計算仍使用此字首,並視需要透過類型和長度重建該字首。
大小編碼
本文檔對非負整數使用以下「大小編碼」:從每個位元組中,取其七個最低有效位元來組成最終整數。只要最高有效位元 (MSB) 為 1,此過程就會繼續;MSB 為 0 的位元組提供最後七個位元。這些七位元區塊被串聯起來。後續的值權重較高。
此大小編碼不應與本文檔中也使用的「偏移量編碼」混淆。
當在封裝檔中編碼未差異化物件的大小時,該大小為未壓縮原始物件的大小。對於已差異化的物件,它是未壓縮差異檔的大小。基礎物件名稱或偏移量不包含在大小計算中。
差異化表示
從概念上講,只有四種物件類型:提交 (commit)、樹 (tree)、標籤 (tag) 和二進位物件 (blob)。然而為了節省空間,物件可以儲存為另一個「基礎 (base)」物件的「差異 (delta)」。這些表示形式被賦予了新的類型 ofs-delta 和 ref-delta,這僅在封裝檔案中有效。
ofs-delta 和 ref-delta 都儲存了應用於另一個物件(稱為基礎物件)以重建該物件的「差異」。兩者的區別在於,ref-delta 直接編碼基礎物件名稱。如果基礎物件位於同一個封裝檔中,ofs-delta 則會改為編碼基礎物件在封裝檔中的偏移量。
如果基礎物件位於同一個封裝檔中,它也可以是被差異化的。Ref-delta 也可以參照封裝檔之外的物件(即所謂的「瘦封裝檔」)。然而,當儲存在磁碟上時,為了避免循環依賴,封裝檔應是自包含的。
差異資料以基礎物件的大小和要重建物件的大小開始。這些大小使用上述的大小編碼進行編碼。差異資料的其餘部分是用於從基礎物件重建目標物件的指令序列。如果基礎物件是已差異化的,則必須先將其轉換為規範形式。每條指令都會將越來越多的資料附加到目標物件上,直到它完成為止。目前支援兩條指令:一條用於從來源物件複製位元組範圍,另一條用於插入嵌入在指令本身中的新資料。
每條指令長度可變。指令類型由第一個八位元組的第七個位元決定。以下圖表遵循 RFC 1951(Deflate 壓縮資料格式)中的慣例。
從基礎物件複製的指令
+----------+---------+---------+---------+---------+-------+-------+-------+ | 1xxxxxxx | offset1 | offset2 | offset3 | offset4 | size1 | size2 | size3 | +----------+---------+---------+---------+---------+-------+-------+-------+
這是用於從來源物件複製位元組範圍的指令格式。它編碼了複製的偏移量和複製的位元組數。偏移量和大小採用小端序。
所有偏移量和大小位元組均為可選的。這是為了在編碼小偏移量或小時減少指令大小。第一個八位元組中的前七個位元決定了接下來七個八位元組中的哪些存在。如果位元 0 被設定,則存在 offset1。如果位元 1 被設定,則存在 offset2,依此類推。
請注意,更緊湊的指令不會改變偏移量和大小編碼。例如,如果如下所示僅省略 offset2,offset3 仍然包含位元 16-23。即使它緊鄰 offset1,它也不會變成 offset2 並包含位元 8-15。
+----------+---------+---------+ | 10000101 | offset1 | offset3 | +----------+---------+---------+
在其最緊湊的形式中,此指令僅佔用一個位元組 (0x80),且偏移量和大小均被省略,它們將具有預設值 0。還有一個例外:大小 0 會自動轉換為 0x10000。
原始 (版本 1) pack-*.idx 檔案的格式如下
-
標頭由 256 個網路位元組序的 4 位元組整數組成。此表的第 N 個條目記錄了對應封裝檔中,其物件名稱的第一個位元組小於或等於 N 的物件數量。這稱為「一級扇出 (first-level fan-out)」表。
-
標頭後面是排序過的 24 位元組條目,封裝檔中每個物件一個條目。每個條目為
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:
-
一個 4 位元組的魔數 \377tOc,這是一個不合理的 fanout[0] 值。
-
一個 4 位元組的版本號 (= 2)
-
一個與 v1 相同的 256 條目扇出表。
-
一個已排序的物件名稱表。這些名稱被封裝在一起,沒有偏移量值,以減少針對特定物件名稱進行二元搜尋時的快取佔用。
-
一個已封裝物件資料的 4 位元組 CRC32 值表。這是 v2 新增的功能,以便在重新封裝期間可以將壓縮資料直接從封裝檔複製到封裝檔,而不會發生未檢測到的資料損壞。
-
一個 4 位元組偏移量值表(採用網路位元組序)。這些通常是 31 位元的封裝檔偏移量,但大偏移量會編碼為指向下一個表的索引,並將最高有效位元 (msbit) 設定為 1。
-
一個 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 位元組的雜湊函式識別碼 (= 1 代表 SHA-1,2 代表 SHA-256)。
-
一個索引位置表(每個已封裝物件一個,總計 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 位元組的雜湊函式識別碼 (= 1 代表 SHA-1,2 代表 SHA-256)。
-
一個 4 位元組無符號整數表。第 i 個值是對應封裝檔中第 i 個物件(依字典編碼索引順序)的修改時間 (mtime)。mtime 的計數單位為標準紀元秒。
-
一個結尾符,包含對應封裝檔案的校驗和,以及上述所有內容的校驗和(每個校驗和的長度根據指定的雜湊函式而定)。
multi-pack-index (MIDX) 檔案的格式如下
multi-pack-index 檔案參照多個封裝檔案和鬆散物件。
為了允許新增額外資料到 MIDX 的擴展,我們將主體組織成「區塊 (chunks)」,並在主體開頭提供一個查詢表。標頭包含特定的長度值,例如封裝檔數量、基礎 MIDX 檔案數量、雜湊長度和類型。
所有 4 位元組數字皆採用網路位元組序。
標頭 (HEADER)
4-byte signature:
The signature is: {'M', 'I', 'D', 'X'}
1-byte version number:
Git writes the version specified by the "midx.version"
configuration option, which defaults to 2. It recognizes
both versions 1 and 2.
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
區塊查詢 (CHUNK LOOKUP)
(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.
區塊資料 (CHUNK DATA)
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. Version 1 MIDXs are required to
list their packs in lexicographic order, but version 2 MIDXs may
list their packs in any arbitrary order.
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.
結尾符 (TRAILER)
Index checksum of the above contents.
multi-pack-index 反向索引
與基於封裝檔的反向索引類似,multi-pack-index 也可以用來產生反向索引。
此反向索引不是在偏移量、封裝檔和索引位置之間進行對映,而是在物件在 MIDX 中的位置,與該物件在 MIDX 所描述的虛擬封裝檔 (pseudo-pack) 中的位置之間進行對映(即多重封裝反向索引的第 i 個條目持有虛擬封裝順序中第 i 個物件的 MIDX 位置)。
為了釐清這些順序之間的差異,請考慮多重封裝可達性點陣圖(雖然目前尚未存在,但我們正朝此方向構建)。每個位元需要對應 MIDX 中的一個物件,因此我們需要一個從位元位置到 MIDX 位置的高效對映。
一種解決方案是讓位元佔用與 MIDX 儲存的 OID 排序索引中相同的位置。但由於 OID 本質上是隨機的,因此產生的可達性點陣圖將沒有局部性,從而導致壓縮效果不佳。(這就是為什麼單一封裝點陣圖為了相同的目的使用封裝順序,而不是 .idx 順序的原因。)
因此,我們希望基於封裝順序為整個 MIDX 定義一個排序,該排序具有更好的局部性(從而更有效地壓縮)。我們可以想像一個由 MIDX 中所有封裝檔串聯而成的虛擬封裝檔。例如,如果我們有一個包含三個封裝檔 (a, b, c) 的 MIDX,分別有 10、15 和 20 個物件,我們可以想像物件的排序如下
|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 只儲存一個指向該物件的指標(因此我們希望點陣圖中只有一個槽位)。
呼叫者可以透過依位元位置順序讀取物件來自行處理重複項,但這在物件數量上是線性的,對於普通的點陣圖查詢來說太昂貴了。建構反向索引可以解決這個問題,因為它是索引的邏輯逆運算,而該索引已經移除了重複項。但是,動態建構反向索引可能很昂貴。由於我們已經有了基於封裝檔的反向索引的磁碟格式,我們也為 MIDX 的虛擬封裝檔重複使用它。
MIDX 中的物件按照以下方式排序以組成虛擬封裝檔。讓 pack(o) 傳回 MIDX 選定 o 的封裝檔,並根據它們的數值 ID(由 MIDX 儲存)定義封裝檔的順序。讓 offset(o) 傳回 o 在 pack(o) 中的物件偏移量。然後,比較 o1 和 o2 如下
-
如果
pack(o1) 和pack(o2) 其中之一是首選的而另一個不是,則首選的排在前面。(這是一個細節,允許 MIDX 點陣圖決定封裝重用機制應該使用哪個封裝檔,因為它可以詢問 MIDX 位於位元位置 0 的物件包含在哪個封裝檔中)。
-
如果 pack(o1) ≠ pack(o2),則根據封裝檔 ID 以降序排列這兩個物件。
-
否則,
pack(o1)=pack(o2),物件將按封裝順序排序(即當且僅當 offset(o1) < offset(o2) 時,o1排在o2前面)。
簡而言之,MIDX 的虛擬封裝檔是 MIDX 所儲存封裝檔中物件的去重複串聯,按封裝順序排列,封裝檔按 MIDX 順序排列(首選封裝檔在前)。
MIDX 的反向索引儲存在 MIDX 內部的選用 RIDX 區塊中。
BTMP 區塊
已點陣圖化的封裝檔案 (BTMP) 區塊編碼了關於 multi-pack-index 可達性點陣圖中物件的額外資訊。回想一下,MIDX 中的物件為了可達性點陣圖而以「虛擬封裝 (pseudo-pack)」順序排列(見上文)。
從上面的例子中,假設我們有封裝檔 "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] 會執行「逐字 (verbatim)」重用,嘗試重用已點陣圖化或首選封裝檔案的區塊,而不是將物件新增到封裝清單中。
當從現有封裝檔中重用一個位元組區塊時,其中包含的任何物件都不需要新增到封裝清單中,從而節省了記憶體和 CPU 時間。但只有滿足以下條件時,才能重用現有封裝檔案中的區塊
-
該區塊僅包含呼叫者請求的物件(即不包含任何呼叫者未顯式或隱式要求的物件)。
-
所有以偏移量或參照差異儲存在非瘦封裝檔中的物件,也在產生的封裝檔中包含其基礎物件。
BTMP 區塊編碼了必要的資訊,以便如上所述在一組封裝檔案上實作多重封裝重用。具體而言,BTMP 區塊為 MIDX 中儲存的每個封裝檔案 p 編碼了三個資訊(均為網路位元組序的 32 位元無符號整數),如下所示
例如,對應於上述範例(包含封裝檔 "a"、"b" 和 "c")的 BTMP 區塊看起來會像
bitmap_pos |
bitmap_nr |
|
|---|---|---|
封裝檔案 "a" |
|
|
封裝檔案 "b" |
|
|
封裝檔案 "c" |
|
|
有了這些資訊,我們可以將每個封裝檔案視為可獨立重用的,就像在實作 BTMP 區塊之前對個別封裝檔案執行逐字封裝重用的方式一樣。
殘餘封裝檔 (cruft packs)
殘餘封裝檔功能提供了一種替代 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.
不可達物件不會立即移除,因為這樣做可能會與可能參照即將刪除物件的傳入推送 (push) 產生競爭。相反,這些不可達物件會儲存為鬆散物件,並保持該狀態直到它們超過過期視窗,此時它們會由 git-prune[1] 移除。
Git 必須將這些不可達物件以鬆散狀態儲存,以便追蹤它們的個別物件修改時間 (mtime)。如果這些不可達物件被寫入一個大的封裝檔,那麼重新整理該封裝檔(因為其中包含的一個物件被重寫)或建立一個新的不可達物件封裝檔,會導致封裝檔的 mtime 被更新,而其中的物件將永遠不會離開過期視窗。相反,物件被儲存為鬆散狀態以追蹤個別物件的 mtime,並避免所有殘餘物件同時被更新的情況。
當儲存庫中包含許多尚未離開寬限期的不可達物件時,這可能會導致不理想的情況。在 .git/objects 的分片中擁有大型目錄可能會導致儲存庫效能下降。但給定足夠多的不可達物件,這可能導致 inode 耗盡並降低整個系統的效能。由於我們永遠無法封裝這些物件,這些儲存庫通常會佔用大量的磁碟空間,因為我們只能對它們進行 zlib 壓縮,而無法將它們儲存在差異鏈中。
殘餘封裝檔
殘餘封裝檔透過在包含所有鬆散物件的單一封裝檔旁,在一個單獨的檔案中包含個別物件的 mtime,消除了以鬆散狀態儲存不可達物件的需求。
殘餘封裝檔由 git repack --cruft 在產生新封裝檔時寫入。git-pack-objects[1] 的 --cruft 選項。請注意,git repack --cruft 是一種經典的「全合一 (all-into-one)」重新封裝,這意味著產生的封裝檔中的所有內容都是可達的,而其他所有內容都是不可達的。一旦寫入,--cruft 選項會指示 git repack 產生另一個僅包含前一步驟中未封裝物件的封裝檔(這等同於將所有不可達物件封裝在一起)。此過程如下
-
列舉每個物件,將任何 (a) 不包含在保留封裝檔 (kept-pack) 中,且 (b) mtime 在寬限期內的物件標記為遍歷起點 (traversal tip)。
-
基於前一步收集的起點執行可達性遍歷,將沿途遇到的每個物件新增到封裝檔中。
-
將封裝檔寫出,連同記錄個別物件時間戳的
.mtimes檔案。
當指示編寫殘餘封裝檔時,此模式由 git-repack[1] 在內部呼叫。關鍵在於,核心中保留封裝檔的集合正是重新封裝不會刪除的封裝檔集合;換句話說,它們包含了儲存庫中所有可達的物件。
當儲存庫已經有一個殘餘封裝檔時,git repack --cruft 通常只會向其中新增物件。一個例外是當 git repack 被賦予 --cruft-expiration 選項時,這允許產生的殘餘封裝檔省略已過期的物件,而不是等待 git-gc[1] 稍後使這些物件過期。
通常由 git-gc[1] 負責移除已過期的不可達物件。
GIT
git[1] 套件的一部分