设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
-
2.52.0
2025-11-17
- 2.50.1 → 2.51.2 无更改
-
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子命令相同的配置更新,然后更新后台调度程序,使其每小时运行一次gitmaintenancerun--scheduled。 - stop
-
停止后台维护计划。当前仓库不会从维护仓库列表中移除,以便将来可以重新启动后台维护。
- register
-
初始化 Git 配置值,以便任何计划的维护都将在此仓库上开始运行。这会将仓库添加到当前用户全局配置中的
maintenance.repo配置变量,或者添加到 --config-file 选项指定的配置中,并为maintenance.<task>.schedule启用一些推荐的配置值。启用的任务是可以在后台运行而不会中断前台进程的。register子命令还会将maintenance.strategy配置值设置为incremental,如果该值尚未设置。incremental策略对每个维护任务使用以下计划-
gc: 已禁用。 -
commit-graph: 每小时。 -
prefetch: 每小时。 -
loose-objects: 每天。 -
incremental-repack: 每天。
gitmaintenanceregister还会通过在当前仓库中设置maintenance.auto=false来禁用前台维护。此配置设置将在gitmaintenanceunregister命令之后保留。 -
- unregister
-
从后台维护中移除当前仓库。这只会将仓库从已配置列表中移除。它不会停止后台维护进程的运行。
unregister子命令如果在当前仓库尚未注册时会报告错误。使用--force选项在当前仓库未注册时也返回成功。
任务
- commit-graph
-
commit-graph作业以增量方式更新commit-graph文件,然后验证写入的数据是否正确。增量写入可以与并发 Git 进程安全地运行,因为它不会使前一个commit-graph-chain文件中的.graph文件过期。它们将在稍后的运行中根据过期延迟被删除。 - prefetch
-
prefetch任务会使用所有已注册远程的最新对象更新对象目录。对于每个远程,都会运行一个gitfetch命令。配置的 refspec 被修改为将所有请求的 refs 放置在refs/prefetch/下。此外,标签不会被更新。这样做是为了避免干扰远程跟踪分支。最终用户期望这些 refs 在他们发起 fetch 之前保持不变。然而,使用 prefetch 任务,完成后续真实 fetch 所需的对象将已经被获取,从而使真实 fetch 速度更快。在理想情况下,它只会更新一批远程跟踪分支而无需任何对象传输。
可以使用
remote.<name>.skipFetchAll配置来排除某个远程不被预取。 - gc
-
清理不必要的文件并优化本地仓库。“GC”代表“垃圾回收”,但此任务执行许多较小的任务。此任务可能对大型仓库来说开销很大,因为它会将所有 Git 对象重新打包到一个 pack-file 中。在某些情况下,它也可能具有破坏性,因为它会删除过时的数据。有关 Git 中垃圾回收的更多详细信息,请参阅 git-gc[1]。
- loose-objects
-
loose-objects作业清理松散对象并将其放入 pack-file 中。为了防止并发 Git 命令的竞态条件,它遵循一个两步过程。首先,它删除已存在于 pack-file 中的任何松散对象;并发 Git 进程将检查 pack-file 以获取对象数据,而不是松散对象。其次,它创建一个新的 pack-file(以“loose-”开头),其中包含一批松散对象。批次大小默认为五万个对象,以防止作业在具有大量松散对象的仓库上花费太长时间。使用
maintenance.loose-objects.batchSize配置选项可以调整此大小,包括设置为0以移除限制。gc任务仅在未被 pack-file 重新添加时,才将不可达对象写入松散对象以供后续步骤清理;因此,不建议同时启用loose-objects和gc任务。 - incremental-repack
-
incremental-repack作业使用multi-pack-index功能重新打包对象目录。为了防止并发 Git 命令的竞态条件,它遵循一个两步过程。首先,它调用gitmulti-pack-indexexpire来删除multi-pack-index文件未引用的 pack-file。其次,它调用gitmulti-pack-indexrepack来选择几个小的 pack-file 并将它们重新打包成一个更大的 pack-file,然后更新引用这些小 pack-file 的multi-pack-index条目,使其引用新的 pack-file。这会为下一次运行gitmulti-pack-indexexpire做好删除这些小 pack-file 的准备。小 pack-file 的选择使得大 pack-file 的预期大小至少等于批次大小;有关repack子命令的--batch-size选项,请参阅 git-multi-pack-index[1]。默认批次大小为零,这是一个特殊情况,它会尝试将所有 pack-file 打包成一个 pack-file。 - 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-file 数量超过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子命令结合使用时,指定用于运行gitmaintenancerun的每小时、每天和每周执行的调度程序。 <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 再次启动定时器,因此任何自定义都应通过创建 drop-in 文件来完成,即在 ~/.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
-
此布尔配置选项控制某些命令在执行正常工作后是否运行
gitmaintenancerun--auto。默认为 true。 - maintenance.autoDetach
-
许多 Git 命令在将数据写入仓库后会触发自动维护。此布尔配置选项控制此自动维护是在前台进行,还是维护进程将分离并继续在后台运行。
如果未设置,则将使用
gc.autoDetach的值作为回退。如果两者都未设置,则默认为 true,这意味着维护进程将分离。 - maintenance.strategy
-
此字符串配置选项提供了一种指定仓库维护的几种推荐策略的方法。这会影响在
gitmaintenancerun期间运行的任务,前提是没有提供--task=<task> 参数。此设置会影响手动维护、自动维护以及计划维护。运行的任务可能因维护类型而异。可以通过设置
maintenance.<task>.enabled和maintenance.<task>.schedule来进一步调整维护策略。如果设置了这些值,则将使用它们而不是maintenance.strategy提供的默认值。可能的策略包括
-
none:此策略意味着根本不运行任何任务。这是计划维护的默认策略。 -
gc:此策略运行gc任务。这是手动维护的默认策略。 -
geometric:此策略执行 packfile 的几何重新打包并将辅助数据结构保持最新。该策略使 reflog 中的数据过期,并删除无法再找到的工作区。当几何重新打包策略决定进行一次性全部打包时,该策略会为所有不可达对象生成一个 cruft pack。已成为 cruft pack 一部分的不可达对象将被过期。这种重新打包策略是
gc策略的完整替代品,推荐用于大型仓库。 -
incremental:此设置优化了执行小型维护活动,这些活动不会删除任何数据。这不会计划gc任务,但会每小时运行prefetch和commit-graph任务,每天运行loose-objects和incremental-repack任务,每周运行pack-refs任务。手动仓库维护使用gc任务。
-
- maintenance.<task>.enabled
-
此布尔配置选项控制当
gitmaintenancerun没有指定--task选项时,名称为 <task> 的维护任务是否运行。如果存在--task选项,则忽略这些配置值。默认情况下,只有maintenance.gc.enabled为 true。 - maintenance.<task>.schedule
-
此配置选项控制给定 <task> 是否在
gitmaintenancerun--schedule=<frequency> 命令期间运行。该值必须是“hourly”、“daily”或“weekly”之一。 - maintenance.commit-graph.auto
-
此整数配置选项控制
commit-graph任务在gitmaintenancerun--auto中运行的频率。如果为零,则commit-graph任务不会与--auto选项一起运行。负值将强制任务每次都运行。否则,正值表示当不在 commit-graph 文件中的可达提交数量至少等于maintenance.commit-graph.auto的值时,命令应运行。默认值为 100。 - maintenance.loose-objects.auto
-
此整数配置选项控制
loose-objects任务在gitmaintenancerun--auto中运行的频率。如果为零,则loose-objects任务不会与--auto选项一起运行。负值将强制任务每次都运行。否则,正值表示当松散对象数量至少等于maintenance.loose-objects.auto的值时,命令应运行。默认值为 100。 - maintenance.loose-objects.batchSize
-
此整数配置选项控制在
loose-objects任务期间写入 packfile 的松散对象的最大数量。默认值为五万。使用值0表示无限制。 - maintenance.incremental-repack.auto
-
此整数配置选项控制作为
git maintenance run --auto的一部分运行incremental-repack任务的频率。如果为零,则incremental-repack任务将不会与--auto选项一起运行。负值将强制任务每次都运行。否则,正值表示当不在 multi-pack-index 中的 pack-files 数量至少为maintenance.incremental-repack.auto的值时,应运行该命令。默认值为 10。 - maintenance.geometric-repack.auto
-
此整数配置选项控制作为
git maintenance run --auto的一部分运行geometric-repack任务的频率。如果为零,则geometric-repack任务将不会与--auto选项一起运行。负值将强制任务每次都运行。否则,正值表示当存在需要合并在一起以保持几何级数的 packfiles 时,或者当至少有这么多松散对象将被写入新的 packfile 时,应运行该命令。默认值为 100。 - maintenance.geometric-repack.splitFactor
-
此整数配置选项控制用于几何级数的因子。有关更多详细信息,请参阅 git-repack[1] 中的
--geometric=选项。默认为2。 - maintenance.reflog-expire.auto
-
此整数配置选项控制作为
git maintenance run --auto的一部分运行reflog-expire任务的频率。如果为零,则reflog-expire任务将不会与--auto选项一起运行。负值将强制任务每次都运行。否则,正值表示当 "HEAD" reflog 中过期的 reflog 条目数量至少为maintenance.loose-objects.auto的值时,应运行该命令。默认值为 100。 - maintenance.rerere-gc.auto
-
此整数配置选项控制作为
git maintenance run --auto的一部分运行rerere-gc任务的频率。如果为零,则rerere-gc任务将不会与--auto选项一起运行。负值将强制任务每次都运行。否则,任何正值表示当 "rr-cache" 目录存在且至少有一个条目时,该命令将运行,无论其是否过时。此启发式方法将来可能会得到改进。默认值为 1。 - maintenance.worktree-prune.auto
-
此整数配置选项控制作为
git maintenance run --auto的一部分运行worktree-prune任务的频率。如果为零,则worktree-prune任务将不会与--auto选项一起运行。负值将强制任务每次都运行。否则,正值表示当可修剪的工作树数量超过该值时,应运行该命令。默认值为 1。