設定和配置
獲取和建立專案
基本快照
分支與合併
共享和更新專案
檢查和比較
打補丁
除錯
電子郵件
外部系統
伺服器管理
指南
管理
底層命令
- 2.50.1 無更改
-
2.50.0
2025-06-16
- 2.47.2 → 2.49.1 無更改
-
2.47.1
2024-11-25
-
2.47.0
2024-10-06
- 2.46.3 → 2.46.4 無更改
-
2.46.2
2024-09-23
- 2.43.1 → 2.46.1 無更改
-
2.43.0
2023-11-20
- 2.39.1 → 2.42.4 無更改
-
2.39.0
2022-12-12
- 2.38.1 → 2.38.5 無更改
-
2.38.0
2022-10-02
- 2.36.1 → 2.37.7 無更改
-
2.36.0
2022-04-18
- 2.34.1 → 2.35.8 無更改
-
2.34.0
2021-11-15
- 2.32.1 → 2.33.8 無更改
-
2.32.0
2021-06-06
- 2.31.1 → 2.31.8 無更改
-
2.31.0
2021-03-15
- 2.30.2 → 2.30.9 無變化
-
2.30.1
2021-02-08
-
2.30.0
2020-12-27
- 2.29.1 → 2.29.3 無更改
-
2.29.0
2020-10-19
概要
git maintenance run [<options>] git maintenance start [--scheduler=<scheduler>] git maintenance (stop|register|unregister) [<options>]
描述
執行任務以最佳化 Git 倉庫資料,從而加快其他 Git 命令的速度並減少倉庫的儲存需求。
新增倉庫資料的 Git 命令,例如 git
add
或 git
fetch
,都經過最佳化以提供響應迅速的使用者體驗。這些命令不會花費時間來最佳化 Git 資料,因為此類最佳化與倉庫的完整大小成比例,而這些使用者命令每次執行相對較小的操作。
git
maintenance
命令為如何最佳化 Git 倉庫提供了靈活性。
子命令
- run
-
執行一個或多個維護任務。如果指定了一個或多個
--task
選項,則這些任務將按指定順序執行。否則,任務由哪些maintenance.
<task>.enabled
配置選項為 true 來決定。預設情況下,只有maintenance.gc.enabled
為 true。 - start
-
開始在當前倉庫上執行維護。這會執行與
register
子命令相同的配置更新,然後更新後臺排程程式以每小時執行git
maintenance
run
--scheduled
。 - stop
-
停止後臺維護計劃。當前倉庫不會從維護的倉庫列表中移除,以防以後重新啟動後臺維護。
- register
-
初始化 Git 配置值,以便任何計劃的維護都將在該倉庫上執行。這會將倉庫新增到當前使用者的全域性配置中的
maintenance.repo
配置變數,或由 --config-file 選項指定的配置中,併為maintenance.
<task>.schedule
啟用一些推薦的配置值。啟用的任務可以安全地在後臺執行,而不會干擾前臺程序。如果
maintenance.strategy
配置值未事先設定,register
子命令還會將其設定為incremental
。incremental
策略為每個維護任務使用以下計劃:-
gc
: 停用。 -
commit-graph
: 每小時。 -
prefetch
: 每小時。 -
loose-objects
: 每天。 -
incremental-repack
: 每天。
git
maintenance
register
還將透過在當前倉庫中設定maintenance.auto
=
false
來停用前臺維護。此配置設定在git
maintenance
unregister
命令之後仍將保留。 -
- unregister
-
從後臺維護中移除當前倉庫。這僅將倉庫從配置列表中移除。它不會停止後臺維護程序的執行。
如果當前倉庫尚未註冊,
unregister
子命令將報告錯誤。即使當前倉庫未註冊,也可以使用--force
選項返回成功。
任務
- commit-graph
-
commit-graph
任務會增量更新commit-graph
檔案,然後驗證寫入的資料是否正確。增量寫入可以安全地與併發 Git 程序一起執行,因為它不會使之前commit-graph-chain
檔案中的.graph
檔案過期。它們將根據過期延遲在稍後執行時被刪除。 - prefetch
-
prefetch
任務使用所有註冊遠端倉庫的最新物件更新物件目錄。對於每個遠端倉庫,都會執行git
fetch
命令。配置的 refspec 會被修改,以便將所有請求的引用放置在refs/prefetch/
中。此外,標籤不會被更新。這樣做是為了避免中斷遠端跟蹤分支。終端使用者希望這些引用保持不變,除非他們發起獲取操作。但是,透過預取任務,完成後續實際獲取所需的物件將已被獲取,從而使實際獲取更快。在理想情況下,它將僅僅是更新一組遠端跟蹤分支,而無需任何物件傳輸。
remote.
<name>.skipFetchAll
配置可用於將特定遠端倉庫排除在預取之外。 - gc
-
清理不必要的檔案並最佳化本地倉庫。“GC”代表“垃圾回收”,但此任務執行許多較小的任務。對於大型倉庫而言,此任務可能開銷較大,因為它會將所有 Git 物件重新打包到一個 pack 檔案中。在某些情況下,它也可能具有破壞性,因為它會刪除陳舊資料。有關 Git 中垃圾回收的更多詳細資訊,請參閱 git-gc[1]。
- loose-objects
-
loose-objects
任務清理鬆散物件並將其放入 pack 檔案中。為了防止與併發 Git 命令發生競爭條件,它遵循兩步過程。首先,它刪除 pack 檔案中已存在的任何鬆散物件;併發 Git 程序將檢查 pack 檔案中的物件資料,而不是鬆散物件。其次,它建立一個新的 pack 檔案(以“loose-”開頭),其中包含一批鬆散物件。批處理大小預設為五萬個物件,以防止任務在包含許多鬆散物件的倉庫上花費太長時間。使用
maintenance.loose-objects.batchSize
配置選項調整此大小,包括值0
以取消限制。gc
任務將不可達物件作為鬆散物件寫入,以便僅在它們未被重新新增到 pack 檔案中時才在後續步驟中清理;因此,不建議同時啟用loose-objects
和gc
任務。 - incremental-repack
-
incremental-repack
任務使用multi-pack-index
功能重新打包物件目錄。為了防止與併發 Git 命令發生競爭條件,它遵循兩步過程。首先,它呼叫git
multi-pack-index
expire
來刪除未被multi-pack-index
檔案引用的 pack 檔案。其次,它呼叫git
multi-pack-index
repack
來選擇幾個小的 pack 檔案並將它們重新打包成一個更大的檔案,然後更新引用小 pack 檔案的multi-pack-index
條目以引用新的 pack 檔案。這為在下一次執行git
multi-pack-index
expire
時刪除這些小 pack 檔案做準備。小 pack 檔案的選擇使得大 pack 檔案的預期大小至少是批處理大小;有關repack
子命令的--batch-size
選項,請參閱 git-multi-pack-index[1]。預設的批處理大小為零,這是一個特殊情況,它嘗試將所有 pack 檔案重新打包到一個 pack 檔案中。 - pack-refs
-
pack-refs
任務收集鬆散的引用檔案並將它們收集到一個檔案中。這會加快需要遍歷許多引用的操作。有關更多資訊,請參閱 git-pack-refs[1]。 - reflog-expire
-
reflog-expire
任務刪除 reflog 中早於過期閾值的所有條目。有關更多資訊,請參閱 git-reflog[1]。 - rerere-gc
-
rerere-gc
任務呼叫垃圾回收以清理 rerere 快取中的陳舊條目。有關更多資訊,請參閱 git-rerere[1]。 - worktree-prune
-
worktree-prune
任務刪除陳舊或損壞的工作區。有關更多資訊,請參閱 git-worktree[1]。
選項
- --auto
-
與
run
子命令結合使用時,僅當滿足某些閾值時才執行維護任務。例如,當鬆散物件的數量超過gc.auto
配置設定中儲存的數量時,或者當 pack 檔案數量超過gc.autoPackLimit
配置設定時,gc
任務會執行。與--schedule
選項不相容。 - --schedule
-
與
run
子命令結合使用時,僅當滿足某些時間條件時才執行維護任務,具體由每個 <task> 的maintenance.
<task>.schedule
配置值指定。此配置值指定自該任務上次執行以來(根據maintenance.
<task>.lastRun
配置值)的秒數。被測試的任務是那些由--task=
<task> 選項提供的任務,或者那些maintenance.
<task>.enabled
設定為 true 的任務。 - --quiet
-
不透過
stderr
報告進度或其他資訊。 - --task=<task>
-
如果指定此選項一次或多次,則僅按指定順序執行指定任務。如果未指定
--task=
<task> 引數,則僅考慮將maintenance.
<task>.enabled
配置為true
的任務。有關接受的 <task> 值列表,請參閱任務部分。 - --scheduler=auto|crontab|systemd-timer|launchctl|schtasks
-
與
start
子命令結合使用時,指定用於執行git
maintenance
run
的每小時、每天和每週執行的排程程式。<scheduler> 的可能值為auto
、crontab
(POSIX)、systemd-timer
(Linux)、launchctl
(macOS) 和schtasks
(Windows)。當指定auto
時,將使用適當的平臺特定排程程式;在 Linux 上,如果可用則使用systemd-timer
,否則使用crontab
。預設為auto
。
故障排除
git
maintenance
命令旨在簡化倉庫維護模式,同時最大限度地減少 Git 命令期間的使用者等待時間。提供了各種配置選項,允許自定義此過程。預設維護選項側重於即使在大型倉庫上也能快速完成的操作。
使用者可能會發現某些情況下,計劃的維護任務沒有按預期頻繁執行。每個 git
maintenance
run
命令都會鎖定倉庫的物件資料庫,這會阻止其他併發的 git
maintenance
run
命令在同一倉庫上執行。如果沒有這種保護措施,相互競爭的程序可能會使倉庫處於不可預測的狀態。
後臺維護計劃每小時執行 git
maintenance
run
程序。每次執行都會執行“每小時”任務。在午夜,該程序還會執行“每日”任務。在每週的第一天的午夜,該程序還會執行“每週”任務。一個單獨的程序會遍歷每個已註冊的倉庫,執行該頻率下計劃的任務。這些程序針對每個客戶端安排在小時的隨機分鐘執行,以分散多個客戶端可能產生的負載(例如來自預取)。根據註冊倉庫的數量和大小,此過程可能需要一個多小時。在這種情況下,多個 git
maintenance
run
命令可能同時在同一倉庫上執行,在物件資料庫鎖上發生衝突。這導致其中一個任務無法執行。
如果您發現某些維護視窗需要一個多小時才能完成,那麼請考慮降低維護任務的複雜性。例如,gc
任務比 incremental-repack
任務慢得多。然而,這會以略大的物件資料庫為代價。考慮將開銷更大的任務安排為不那麼頻繁地執行。
專家使用者可以考慮使用與透過 git
maintenance
start
和 Git 配置選項提供的計劃不同的計劃來安排自己的維護任務。這些使用者應該瞭解物件資料庫鎖以及併發 git
maintenance
run
命令的行為方式。此外,git
gc
命令不應與 git
maintenance
run
命令結合使用。git
gc
修改物件資料庫,但不會像 git
maintenance
run
那樣獲取鎖。如果可能,請使用 git
maintenance
run
--task=gc
而不是 git
gc
。
以下部分描述了透過 git
maintenance
start
執行後臺維護的機制以及如何自定義它們。
POSIX 系統上的後臺維護
在 POSIX 系統上排程後臺任務的標準機制是 cron(8)。此工具根據給定的計劃執行命令。透過執行 crontab
-l
可以找到當前使用者計劃任務列表。git
maintenance
start
寫入的計劃類似於這樣
# BEGIN GIT MAINTENANCE SCHEDULE # The following schedule was created by Git # Any edits made in this region might be # replaced in the future by a Git command. 0 1-23 * * * "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=hourly 0 0 * * 1-6 "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=daily 0 0 * * 0 "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=weekly # END GIT MAINTENANCE SCHEDULE
註釋用作標記 Git 寫入的計劃的區域。此區域內的任何修改都將被 git
maintenance
stop
完全刪除或被 git
maintenance
start
覆蓋。
crontab
條目指定 git
可執行檔案的完整路徑,以確保執行的 git
命令與發出 git
maintenance
start
時使用的命令相同,而不受 PATH
的影響。如果同一使用者使用多個 Git 可執行檔案執行 git
maintenance
start
,則僅使用最新的可執行檔案。
這些命令使用 git
for-each-repo
--config=maintenance.repo
在 maintenance.repo
多值配置選項中列出的每個倉庫上執行 git
maintenance
run
--schedule=
<frequency>。這些通常從使用者特定的全域性配置中載入。git
maintenance
程序然後使用 maintenance.
<task>.schedule
配置選項,確定每個 <frequency> 下配置為在每個倉庫上執行的維護任務。這些值從全域性或倉庫配置值中載入。
如果配置值不足以實現您所需的後臺維護計劃,那麼您可以建立自己的計劃。如果您執行 crontab
-e
,則編輯器將載入您使用者特定的 cron
計劃。在該編輯器中,您可以新增自己的計劃行。您可以從調整前面列出的預設計劃開始,或者閱讀 crontab(5) 文件以瞭解高階排程技術。請務必使用預設計劃中的完整路徑和 --exec-path
技術,以確保您在計劃中執行正確的二進位制檔案。
Linux Systemd 系統上的後臺維護
雖然 Linux 支援 cron
,但根據發行版的不同,cron
可能是一個可選包,不一定安裝。在現代 Linux 發行版上,systemd 定時器正在取代它。
如果使用者 systemd 定時器可用,它們將作為 cron
的替代品。
在這種情況下,git
maintenance
start
將建立使用者 systemd 定時器單元並啟動定時器。透過執行 systemctl
--user
list-timers
可以找到當前使用者計劃任務列表。git
maintenance
start
寫入的定時器類似於這樣
$ systemctl --user list-timers NEXT LEFT LAST PASSED UNIT ACTIVATES Thu 2021-04-29 19:00:00 CEST 42min left Thu 2021-04-29 18:00:11 CEST 17min ago git-maintenance@hourly.timer git-maintenance@hourly.service Fri 2021-04-30 00:00:00 CEST 5h 42min left Thu 2021-04-29 00:00:11 CEST 18h ago git-maintenance@daily.timer git-maintenance@daily.service Mon 2021-05-03 00:00:00 CEST 3 days left Mon 2021-04-26 00:00:11 CEST 3 days ago git-maintenance@weekly.timer git-maintenance@weekly.service
每個 --schedule=
<frequency> 選項都會註冊一個定時器。
systemd 單元的定義可以在以下檔案中檢視
~/.config/systemd/user/git-maintenance@.timer ~/.config/systemd/user/git-maintenance@.service ~/.config/systemd/user/timers.target.wants/git-maintenance@hourly.timer ~/.config/systemd/user/timers.target.wants/git-maintenance@daily.timer ~/.config/systemd/user/timers.target.wants/git-maintenance@weekly.timer
git
maintenance
start
將覆蓋這些檔案並再次使用 systemctl
--user
啟動定時器,因此任何自定義都應透過建立放置檔案(即 ~/.config/systemd/user/git-maintenance@.service.d
目錄中以 .conf
結尾的檔案)來完成。
git
maintenance
stop
將停止使用者 systemd 定時器並刪除上述檔案。
有關更多詳細資訊,請參閱 systemd.timer
(5
)。
macOS 系統上的後臺維護
雖然 macOS 技術上支援 cron
,但使用 crontab
-e
需要提升的許可權,並且執行的程序沒有完整的使用者上下文。如果沒有完整的使用者上下文,Git 及其憑證助手將無法訪問儲存的憑證,因此某些維護任務將無法執行。
相反,git
maintenance
start
與 launchctl
工具互動,這是在 macOS 中安排定時任務的推薦方式。透過 git
maintenance
(start
|stop
) 安排維護需要一些僅在 macOS 10.11 或更高版本中可用的 launchctl
功能。
您的使用者特定計劃任務以 XML 格式的 .plist
檔案儲存在 ~/Library/LaunchAgents/
中。您可以使用以下命令檢視當前註冊的任務
$ ls ~/Library/LaunchAgents/org.git-scm.git* org.git-scm.git.daily.plist org.git-scm.git.hourly.plist org.git-scm.git.weekly.plist
每個 --schedule=
<frequency> 選項都會註冊一個任務。要檢視 XML 格式如何描述每個計劃,請在編輯器中開啟其中一個 .plist
檔案,並檢查 <key>StartCalendarInterval</key> 元素後面的 <array> 元素。
git
maintenance
start
將覆蓋這些檔案並再次使用 launchctl
註冊任務,因此任何自定義都應透過建立具有不同名稱的自己的 .plist
檔案來完成。類似地,git
maintenance
stop
命令將使用 launchctl
登出任務並刪除 .plist
檔案。
要對後臺任務進行更高階的自定義,請參閱 launchctl.plist(5) 以獲取更多資訊。
Windows 系統上的後臺維護
Windows 不支援 cron
,而是有自己的後臺任務排程系統。git
maintenance
start
命令使用 schtasks
命令向該系統提交任務。您可以使用任務計劃程式應用程式檢查所有後臺任務。Git 新增的任務名稱形式為 Git
Maintenance
(<frequency>)。任務計劃程式 GUI 有檢查這些任務的方法,但您也可以將任務匯出到 XML 檔案並在其中檢視詳細資訊。
請注意,由於 Git 是一個控制檯應用程式,這些後臺任務會建立一個對當前使用者可見的控制檯視窗。這可以透過在任務計劃程式中選擇“無論使用者是否登入都執行”選項手動更改。此更改需要輸入密碼,這就是 git
maintenance
start
預設不選擇它的原因。
如果您想自定義後臺任務,請重新命名任務,以便將來呼叫 git
maintenance
(start
|stop
) 時不會覆蓋您的自定義任務。
配置
本節中以下所有內容均從 git-config[1] 文件中選擇性地包含。內容與彼處相同:
- maintenance.auto
-
此布林配置選項控制某些命令在完成其正常工作後是否執行
git
maintenance
run
--auto
。預設為 true。 - maintenance.autoDetach
-
許多 Git 命令在將資料寫入倉庫後會觸發自動維護。此布林配置選項控制此自動維護是應在前臺進行,還是維護程序應分離並在後臺繼續執行。
如果未設定,則使用
gc.autoDetach
的值作為備用。如果兩者都未設定,則預設為 true,這意味著維護程序將分離。 - maintenance.strategy
-
此字串配置選項提供了一種指定後臺維護的幾種推薦計劃之一的方法。這僅影響在
git
maintenance
run
--schedule=X
命令期間執行哪些任務,前提是沒有提供--task=
<task> 引數。此外,如果設定了maintenance.
<task>.schedule
配置值,則使用該值而不是maintenance.strategy
提供的值。可能的策略字串包括-
none
: 此預設設定意味著在任何計劃下都不執行任務。 -
incremental
: 此設定優化了執行不刪除任何資料的小型維護活動。它不安排gc
任務,但每小時執行prefetch
和commit-graph
任務,每天執行loose-objects
和incremental-repack
任務,每週執行pack-refs
任務。
-
- maintenance.<task>.enabled
-
此布林配置選項控制當未向
git
maintenance
run
指定--task
選項時,是否執行名稱為 <task> 的維護任務。如果存在--task
選項,則這些配置值將被忽略。預設情況下,只有maintenance.gc.enabled
為 true。 - maintenance.<task>.schedule
-
此配置選項控制給定的 <task> 是否在
git
maintenance
run
--schedule=
<frequency> 命令期間執行。該值必須是“hourly”、“daily”或“weekly”之一。 - maintenance.commit-graph.auto
-
此整數配置選項控制
commit-graph
任務作為git
maintenance
run
--auto
的一部分應該執行的頻率。如果為零,則commit-graph
任務將不會與--auto
選項一起執行。負值將強制任務每次都執行。否則,正值意味著當不在 commit-graph 檔案中的可達提交數量至少為maintenance.commit-graph.auto
的值時,命令應執行。預設值為 100。 - maintenance.loose-objects.auto
-
此整數配置選項控制
loose-objects
任務作為git
maintenance
run
--auto
的一部分應該執行的頻率。如果為零,則loose-objects
任務將不會與--auto
選項一起執行。負值將強制任務每次都執行。否則,正值意味著當鬆散物件的數量至少為maintenance.loose-objects.auto
的值時,命令應執行。預設值為 100。 - maintenance.loose-objects.batchSize
-
此整數配置選項控制在
loose-objects
任務期間寫入 pack 檔案中的鬆散物件的最大數量。預設值為五萬。使用值0
表示沒有限制。 - maintenance.incremental-repack.auto
-
此整數配置選項控制
incremental-repack
任務作為git
maintenance
run
--auto
的一部分應該執行的頻率。如果為零,則incremental-repack
任務將不會與--auto
選項一起執行。負值將強制任務每次都執行。否則,正值意味著當不在多 pack 索引中的 pack 檔案數量至少為maintenance.incremental-repack.auto
的值時,命令應執行。預設值為 10。 - maintenance.reflog-expire.auto
-
此整數配置選項控制
reflog-expire
任務作為git
maintenance
run
--auto
的一部分應該執行的頻率。如果為零,則reflog-expire
任務將不會與--auto
選項一起執行。負值將強制任務每次都執行。否則,正值意味著當“HEAD”reflog 中過期的 reflog 條目數量至少為maintenance.loose-objects.auto
的值時,命令應執行。預設值為 100。 - maintenance.rerere-gc.auto
-
此整數配置選項控制
rerere-gc
任務作為git
maintenance
run
--auto
的一部分應該執行的頻率。如果為零,則rerere-gc
任務將不會與--auto
選項一起執行。負值將強制任務每次都執行。否則,任何正值都意味著當“rr-cache”目錄存在且至少包含一個條目時(無論其是否陳舊)命令都將執行。此啟發式方法可能會在將來進行改進。預設值為 1。 - maintenance.worktree-prune.auto
-
此整數配置選項控制
worktree-prune
任務作為git
maintenance
run
--auto
的一部分應該執行的頻率。如果為零,則worktree-prune
任務將不會與--auto
選項一起執行。負值將強制任務每次都執行。否則,正值意味著當可修剪的工作區數量超過該值時,命令應執行。預設值為 1。