设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
- 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。