簡體中文 ▾ 主題 ▾ 最新版本 ▾ git-gc 最後更新於 2.49.0

名稱

git-gc - 清理不必要的檔案並最佳化本地倉庫

概要

git gc [--aggressive] [--auto] [--[no-]detach] [--quiet] [--prune=<date> | --no-prune] [--force] [--keep-largest-pack]

描述

在當前倉庫中執行多項內務管理任務,例如壓縮檔案修訂(以減少磁碟空間和提高效能)、移除可能由先前呼叫 git add 建立的不可達物件、打包引用、修剪引用日誌、rerere 元資料或過時的裸工作目錄。也可能更新輔助索引,如提交圖。

當執行建立物件的常見“瓷器命令”(porcelain operations)時,它們會檢查倉庫自上次維護以來是否已大幅增長,如果是,則自動執行 git gc。有關如何停用此行為,請參閱下面的 gc.auto

手動執行 git gc 通常只在以下情況需要:在不定期執行此類“瓷器命令”的情況下向倉庫新增物件,進行一次性倉庫最佳化,或者例如清理次優的大量匯入。有關匯入情況的更多詳細資訊,請參閱 git-fast-import[1] 中的“PACKFILE OPTIMIZATION”部分。

選項

--aggressive

通常 git gc 執行速度非常快,同時提供良好的磁碟空間利用率和效能。此選項將使 git gc 更積極地最佳化倉庫,代價是花費更多時間。此最佳化的效果大部分是持久的。有關詳細資訊,請參閱下面的“AGGRESSIVE”部分。

--auto

使用此選項,git gc 會檢查是否需要任何內務管理;如果不需要,則退出而不執行任何工作。

有關此啟發式方法的工作原理,請參閱下面“CONFIGURATION”部分中的 gc.auto 選項。

一旦內務管理因超出 gc.autogc.autoPackLimit 等配置選項的限制而觸發,所有其他內務管理任務(例如 rerere、工作目錄、引用日誌…​)也將被執行。

--[no-]detach

如果系統支援,則在後臺執行。此選項會覆蓋 gc.autoDetach 配置。

--[no-]cruft

在過期不可達物件時,將它們單獨打包成一個冗餘包(cruft pack),而不是將它們儲存為鬆散物件。--cruft 預設開啟。

--max-cruft-size=<n>

將不可達物件打包到冗餘包中時,限制新冗餘包的大小最多為 <n> 位元組。此選項會覆蓋透過 gc.maxCruftSize 配置指定的任何值。有關更多資訊,請參閱 git-repack[1]--max-cruft-size 選項。

--expire-to=<dir>

將不可達物件打包到冗餘包中時,將包含已修剪物件(如果有)的冗餘包寫入目錄 <dir>。此選項僅在與 --cruft 一起使用時才有效。有關更多資訊,請參閱 git-repack[1]--expire-to 選項。

--prune=<date>

修剪早於指定日期的鬆散物件(預設為兩週前,可透過配置變數 gc.pruneExpire 覆蓋)。--prune=now 會修剪所有鬆散物件,無論其建立時間,如果另一個程序同時寫入倉庫,會增加損壞的風險;請參閱下面的“NOTES”。--prune 預設開啟。

--no-prune

不修剪任何鬆散物件。

--quiet

禁止所有進度報告。

--force

即使此倉庫上可能正在執行另一個 git gc 例項,也強制執行 git gc

--keep-largest-pack

除了最大的非冗餘包、任何帶有 .keep 檔案的包以及任何冗餘包外,所有包都將合併為一個包。使用此選項時,gc.bigPackThreshold 將被忽略。

AGGRESSIVE

當提供 --aggressive 選項時,git-repack[1] 將被呼叫並帶有 -f 標誌,這反過來會將 --no-reuse-delta 傳遞給 git-pack-objects[1]。這將丟棄任何現有的增量並重新計算它們,代價是花費更多的時間進行重新打包。

這種效果大部分是持久的,例如當包和鬆散物件合併到另一個包中時,該包中現有的增量可能會被重用,但在各種情況下,我們也可能會從較新的包中選擇一個次優的增量。

此外,提供 --aggressive 將調整傳遞給 git-repack[1]--depth--window 選項。請參閱下面的 gc.aggressiveDepthgc.aggressiveWindow 設定。透過使用更大的視窗大小,我們更有可能找到更優的增量。

在給定倉庫上不進行定製效能基準測試的情況下使用此選項可能不值得。它會花費大量時間,並且產生的空間/增量最佳化可能不值得。對於大多數使用者及其倉庫來說,根本不使用此選項是正確的權衡。

配置

本節中以下所有內容均從 git-config[1] 文件中選擇性地包含。內容與彼處相同:

gc.aggressiveDepth

git gc --aggressive 使用的增量壓縮演算法中的深度引數。這預設為 50,這是不使用 --aggressive--depth 選項的預設值。

有關更多詳細資訊,請參閱 git-repack[1]--depth 選項的文件。

gc.aggressiveWindow

git gc --aggressive 使用的增量壓縮演算法中的視窗大小引數。這預設為 250,這是一個比預設 --window 10 更激進的視窗大小。

有關更多詳細資訊,請參閱 git-repack[1]--window 選項的文件。

gc.auto

當倉庫中的鬆散物件數量大約超過此值時,git gc --auto 將對其進行打包。一些“瓷器命令”會使用此命令不時執行輕量級垃圾回收。預設值為 6700。

將其設定為 0 不僅會停用基於鬆散物件數量的自動打包,還會停用 git gc --auto 否則會用來確定是否有工作要做的任何其他啟發式方法,例如 gc.autoPackLimit

gc.autoPackLimit

當倉庫中未標記 *.keep 檔案的包數量超過此值時,git gc --auto 會將它們合併為一個更大的包。預設值為 50。設定為 0 會停用此功能。將 gc.auto 設定為 0 也會停用此功能。

請參閱下面的 gc.bigPackThreshold 配置變數。使用時,它將影響自動包限制的工作方式。

gc.autoDetach

如果系統支援,則使 git gc --auto 立即返回並在後臺執行。預設值為 true。此配置變數作為 maintenance.autoDetach 未設定時的備用選項。

gc.bigPackThreshold

如果非零,當執行 git gc 時,所有大於此限制的非冗餘包都將被保留。這與 --keep-largest-pack 非常相似,只是所有符合閾值的非冗餘包都會被保留,而不僅僅是最大的包。預設為零。支援常見的單位字尾 k、m 或 g。

請注意,如果保留的包數量超過 gc.autoPackLimit,此配置變數將被忽略,除了基本包之外的所有包都將被重新打包。在此之後,包的數量應低於 gc.autoPackLimit,並且 gc.bigPackThreshold 應該再次受到尊重。

如果執行 git repack 所需的估計記憶體不可用且未設定 gc.bigPackThreshold,則最大的包也將被排除(這相當於執行 git gc 時帶有 --keep-largest-pack)。

gc.writeCommitGraph

如果為 true,則在執行 git-gc[1] 時 gc 將重寫提交圖檔案。當使用 git gc --auto 時,如果需要內務管理,提交圖將更新。預設值為 true。有關詳細資訊,請參閱 git-commit-graph[1]

gc.logExpiry

如果檔案 gc.log 存在,則 git gc --auto 將列印其內容並以狀態零退出而不是執行,除非該檔案早於 gc.logExpiry。預設值為 "1.day"。有關指定其值的更多方法,請參閱 gc.pruneExpire

gc.packRefs

在倉庫中執行 git pack-refs 會導致 Git 1.5.1.2 之前的版本無法透過 HTTP 等啞傳輸克隆。此變數決定 git gc 是否執行 git pack-refs。這可以設定為 notbare 以在所有非裸倉庫中啟用,也可以設定為布林值。預設值為 true

gc.cruftPacks

將不可達物件儲存在冗餘包中(參見 git-repack[1]),而不是作為鬆散物件儲存。預設值為 true

gc.maxCruftSize

重新打包時限制新冗餘包的大小。當與 --max-cruft-size 一起指定時,命令列選項優先。請參閱 git-repack[1]--max-cruft-size 選項。

gc.pruneExpire

當執行 git gc 時,它將呼叫 prune --expire 2.weeks.ago(如果透過 gc.cruftPacks--cruft 使用冗餘包,則呼叫 repack --cruft --cruft-expiration 2.weeks.ago)。使用此配置變數覆蓋寬限期。“now”值可用於停用此寬限期並始終立即修剪不可達物件,或“never”可用於抑制修剪。此功能有助於在 git gc 與另一個寫入倉庫的程序併發執行時防止損壞;請參閱 git-gc[1] 的“NOTES”部分。

gc.worktreePruneExpire

當執行 git gc 時,它會呼叫 git worktree prune --expire 3.months.ago。此配置變數可用於設定不同的寬限期。“now”值可用於停用寬限期並立即修剪 $GIT_DIR/worktrees,或“never”可用於抑制修剪。

gc.reflogExpire
gc.<pattern>.reflogExpire

git reflog expire 會移除早於此時間的引用日誌條目;預設為 90 天。“now”值會立即過期所有條目,“never”會完全抑制過期。在中間帶有“<pattern>”(例如“refs/stash”)的設定僅適用於匹配該模式的引用。

gc.reflogExpireUnreachable
gc.<pattern>.reflogExpireUnreachable

git reflog expire 會移除早於此時間且無法從當前 HEAD 訪問的引用日誌條目;預設為 30 天。“now”值會立即過期所有條目,“never”會完全抑制過期。在中間帶有“<pattern>”(例如“refs/stash”)的設定僅適用於匹配該模式的引用。

這些型別的條目通常是使用 git commit --amendgit rebase 產生的,並且是修改或變基發生之前的提交。由於這些更改不屬於當前專案,大多數使用者會希望更快地使其過期,這就是為什麼預設值比 gc.reflogExpire 更激進的原因。

gc.recentObjectsHook

在考慮是否移除物件時(無論是生成冗餘包還是將不可達物件儲存為鬆散物件),使用 shell 執行指定的命令。將其輸出解釋為 Git 將視為“最新”的物件 ID,無論其建立時間如何。透過將其修改時間視為“現在”,輸出中提及的任何物件(及其後代)都將保留,無論其真實建立時間如何。

輸出必須每行包含一個十六進位制物件 ID,不能包含其他任何內容。在倉庫中找不到的物件將被忽略。支援多個鉤子,但所有鉤子都必須成功退出,否則操作(無論是生成冗餘包還是解包不可達物件)將被中止。

gc.repackFilter

重新打包時,使用指定的過濾器將某些物件移動到單獨的 packfile 中。請參閱 git-repack[1]--filter=<filter-spec> 選項。

gc.repackFilterTo

重新打包並使用過濾器時,請參閱 gc.repackFilter,指定的位置將用於建立包含過濾掉的物件的 packfile。警告: 指定的位置應可訪問,例如使用 Git 備用機制,否則倉庫可能會被 Git 視為損壞,因為它可能無法訪問該 packfile 中的物件。請參閱 git-repack[1]--filter-to=<dir> 選項和 gitrepository-layout[5]objects/info/alternates 部分。

gc.rerereResolved

當執行 git rerere gc 時,您之前解決的衝突合併記錄將保留此天數。您也可以使用更具可讀性的“1.month.ago”等。預設值為 60 天。請參閱 git-rerere[1]

gc.rerereUnresolved

當執行 git rerere gc 時,您尚未解決的衝突合併記錄將保留此天數。您也可以使用更具可讀性的“1.month.ago”等。預設值為 15 天。請參閱 git-rerere[1]

注意事項

git gc 會非常努力地不刪除倉庫中任何地方引用的物件。特別是,它不僅會保留您當前分支和標籤集引用的物件,還會保留索引、遠端跟蹤分支、引用日誌(可能引用稍後修改或回溯的分支中的提交)以及 refs/* 名稱空間中的所有其他物件。請注意,附加到物件的註釋(透過 git notes 建立的註釋)不會有助於保持物件的存活。如果您期望某些物件被刪除但它們沒有,請檢查所有這些位置並確定在您的情況下刪除這些引用是否有意義。

另一方面,當 git gc 與另一個程序同時執行時,存在刪除該程序正在使用但尚未建立引用的物件的風險。這可能只會導致另一個程序失敗,或者如果另一個程序稍後新增對已刪除物件的引用,則可能會損壞倉庫。Git 有兩個顯著緩解此問題的功能

  1. 任何修改時間比 --prune 日期新的物件都將被保留,以及從它可達的所有物件。

  2. 大多數向資料庫新增物件的操作會在物件已存在時更新其修改時間,以便應用 #1。

然而,這些功能未能提供完整的解決方案,因此併發執行命令的使用者必須承受一定的損壞風險(實踐中這種風險似乎很低)。

鉤子

git gc --auto 命令將執行 pre-auto-gc 鉤子。有關更多資訊,請參閱 githooks[5]

GIT

Git[1] 套件的一部分

scroll-to-top