2020 年 9 月更新:您不必只运行git gc --auto
作为自动保存脚本的一部分。
老人 ”gc
“ 现在可以被新的取代git maintenance run --auto
.
它可以显示它正在做什么。
With Git 2.29 (Q4 2020), A "git gc"(man)'s big brother has been introduced to take care of more repository maintenance tasks, not limited to the object database cleaning.
See commit 25914c4, commit 4ddc79b, commit 916d062, commit 65d655b, commit d7514f6, commit 090511b, commit 663b2b1, commit 3103e98, commit a95ce12, commit 3ddaad0, commit 2057d75 (17 Sep 2020) by Derrick Stolee (derrickstolee).
(Merged by Junio C Hamano -- gitster -- in commit 48794ac, 25 Sep 2020)
maintenance:创建基本维护运行程序
Helped-by: Jonathan Nieder
Signed-off-by: Derrick Stolee
内置的“gc”是我们当前自动维护存储库的入口点。这一工具可以执行许多操作,例如:
- 重新打包存储库,
- 包装参考文献,以及
- 重写提交图文件。
顾名思义,它执行“垃圾收集”,这意味着几个不同的事情,并且某些用户可能不希望使用此重写整个对象数据库的操作。
创建一个新的 'maintenance
' 内置命令将成为更通用的命令。
首先,它只支持 'run
' 子命令,但稍后将扩展以添加用于在后台安排维护的子命令。
目前,'maintenance
'内置的是一个薄垫片'gc
' 内置。
事实上,唯一的选择是“--auto
' 切换,直接传递给 'gc
' 内置。
当前的更改与这个简单的操作隔离,以防止在添加新内置函数的所有样板中丢失更有趣的逻辑。
Use existing builtin/gc.c file because we want to share code between the two builtins.
It is possible that we will have 'maintenance
' replace the 'gc
' builtin entirely at some point, leaving 'git gc(man)' as an alias for some specific arguments to 'git maintenance run
'.
创建一个新的test_subcommand
帮助器允许我们测试某个子命令是否运行。它需要存储GIT_TRACE2_EVENT
登录到一个文件中。
否定模式可用,将在以后的测试中使用。
(最后一部分是确定新的方法git maintainance run --auto
做某事)
git maintenance
现在包含在其man page:
git 维护(1)
NAME
git-maintenance
- 运行任务来优化 Git 存储库数据
SYNOPSIS
[verse]
'git maintenance' run [<options>]
描述
运行任务来优化 Git 存储库数据,加快其他 Git 命令的速度
并减少存储库的存储要求。
添加存储库数据的 Git 命令,例如git add
or git fetch
,
针对响应式用户体验进行了优化。这些命令不采取
是时候优化 Git 数据了,因为这种优化会随着整个系统的扩展而扩展
存储库的大小,而这些用户命令各自执行相对
小动作。
The git maintenance
命令为如何优化提供了灵活性
Git 存储库。
子命令
run
运行一项或多项维护任务。
TASKS
gc
清理不必要的文件并优化本地存储库。 “GC”
代表“垃圾收集”,但此任务执行许多操作
较小的任务。对于大型存储库来说,此任务可能会很昂贵,
因为它将所有 Git 对象重新打包到一个包文件中。还可以
在某些情况下会造成破坏,因为它会删除陈旧的数据。看git gc有关 Git 中垃圾收集的更多详细信息。
OPTIONS
--auto
当与run
子命令,运行维护任务
仅当满足某些阈值时。例如,gc
任务
当松散对象的数量超过存储的数量时运行
在里面gc.auto
配置设置,或者当包文件的数量
超过gc.autoPackLimit
配置设置。
maintenance: 代替run_auto_gc()
Signed-off-by: Derrick Stolee
The run_auto_gc()
method is used in several places to trigger a check for repo maintenance after some Git commands, such as 'git commit'(man) or 'git fetch'(man).
To allow for extra customization of this maintenance activity, replace the 'git gc --auto [--quiet](man)' call with one to 'git maintenance run --auto [--quiet](man)'.
As we extend the maintenance builtin with other steps, users will be able to select different maintenance activities.
Rename run_auto_gc()
to run_auto_maintenance()
更清楚地了解此调用中发生的情况,并公开当前差异中的所有调用者。重写方法以使用结构体child_process
稍微简化调用。
Since 'git fetch'(man) already allows disabling the 'git gc --auto'(man) subprocess, add an equivalent option with a different name to be more descriptive of the new behavior: '--[no-]maintenance
'.
fetch-options
现在包含在其man page:
Run git maintenance run --auto
最后执行自动
如果需要的话,存储库维护。 (--[no-]auto-gc
是同义词。)
默认情况下启用此功能。
git clone
现在包含在其man page:
它会自动调用git maintenance run --auto
. (See
git maintenance.)
另外,您的保存脚本将能够使git maintenance
做的比git gc
曾经可以,感谢tasks.
maintenance: 添加 --task 选项
Signed-off-by: Derrick Stolee
用户可能只想按特定顺序运行某些维护任务。
Add the --task=<task>
选项,它允许用户指定要运行的任务的有序列表。但是,这些不能多次运行。
这是我们的数组的位置maintenance_task
指针变得至关重要。我们可以根据任务顺序对指针数组进行排序,但我们不想移动结构数据本身以保留哈希图引用。我们使用 hashmap 将 --task= 参数匹配到任务结构数据中。
请记住,'enabled
' 的成员maintenance_task
struct 是未来的占位符 'maintenance.<task>.enabled
' 配置选项。因此,我们使用 'enabled
' 成员指定当用户未指定任何任务时运行哪些任务--task=<task>
论据。
The 'enabled
' 成员应该被忽略,如果--task=<task>
出现。
git maintenance
现在包含在其man page:
运行一项或多项维护任务。如果有一个或多个--task=<task>
指定选项,然后这些任务在提供的中运行
命令。否则,只有gc
任务已运行。
git maintenance
现在包含在其man page:
--task=<task>
如果此选项被指定一次或多次,则仅运行
按指定顺序执行指定任务。请参阅“任务”部分
对于已接受的名单<task>
values.
And:
maintenance:创建维护..启用配置
Signed-off-by: Derrick Stolee
Currently, a normal run of "git maintenance run"(man) will only run the 'gc
' task, as it is the only one enabled.
This is mostly for backwards-compatible reasons since "git maintenance run --auto"(man) commands replaced previous "git gc --auto
" commands after some Git processes.
用户可以通过调用“git maintenance run --task=<task>
“ 直接地。
允许用户使用 config 自定义自动运行哪些步骤。这 'maintenance.<task>.enabled
' 选项然后可以打开这些其他任务(或关闭 'gc
' task).
git config
现在包含在其man page:
maintenance.<task>.enabled
该布尔配置选项控制是否执行维护任务
有名字<task>
当没有时运行--task
选项指定为git maintenance run
。如果出现以下情况,这些配置值将被忽略--task
选项存在。
默认情况下,仅maintenance.gc.enabled
是真的。
git maintenance
现在包含在其man page:
运行一项或多项维护任务。如果有一个或多个--task
选项
指定后,这些任务将按该顺序运行。否则,
任务由以下因素决定maintenance.<task>.enabled
配置选项是正确的。
默认情况下,仅maintenance.gc.enabled
是真的。
git maintenance
现在也包括在其man page:
If no --task=<task>
指定了参数,那么只有带有maintenance.<task>.enabled
配置为true
被考虑。
另一种方式来了解是否是新的git maintenance run
目前正在做的事情就是检查锁(.git/maintenance.lock
file):
maintenance:锁定对象目录
Signed-off-by: Derrick Stolee
Performing maintenance on a Git repository involves writing data to the .git
directory, which is not safe to do with multiple writers attempting the same operation.
Ensure that only one 'git maintenance'(man) process is running at a time by holding a file-based lock.
简单来说就是存在.git/maintenance.lock
文件将妨碍将来的维护。该锁永远不会被提交,因为它不代表有意义的数据。相反,它只是一个占位符。
If the lock file already exists, then no maintenance tasks are attempted. This will become very important later when we implement the 'prefetch
' task, as this is our stop-gap from creating a recursive process loop between 'git fetch'(man) ' and 'git maintenance run --auto(man).
您还可以检查是否git gc
/git maintenance
will必须做任何事。
With Git 2.29 (Q4 2020), A "git gc"(man) 's big brother has been introduced to take care of more repository maintenance tasks, not limited to the object database cleaning.
See commit 25914c4, commit 4ddc79b, commit 916d062, commit 65d655b, commit d7514f6, commit 090511b, commit 663b2b1, commit 3103e98, commit a95ce12, commit 3ddaad0, commit 2057d75 (17 Sep 2020) by Derrick Stolee (derrickstolee).
(Merged by Junio C Hamano -- gitster -- in commit 48794ac, 25 Sep 2020)
maintenance: 使用指针来检查--auto
Signed-off-by: Derrick Stolee
The 'git maintenance run(man) ' command has an '--auto' option. This is used by other Git commands such as 'git commit(man) ' or 'git fetch(man) ' to check if maintenance should be run after adding data to the repository.
Previously, this --auto
option was only used to add the argument to the 'git gc'(man) command as part of the 'gc
' task.
We will be expanding the other tasks to perform a check to see if they should do work as part of the --auto
flag, when they are enabled by config.
-
First, update the 'gc' task to perform the auto check inside the maintenance process.
This prevents running an extra 'git gc --auto'(man) command when not needed.
It also shows a model for other tasks.
-
其次,使用 'auto_condition
'函数指针作为我们是否启用维护任务的信号'--auto
'.
例如,我们不想在“--auto
' 模式,这样函数指针将保留NULL
.
We continue to pass the '--auto' option to the 'git gc'(man) command when necessary, because of the gc.autoDetach
config option changes behavior.
Likely, we will want to absorb the daemonizing behavior implied by gc.autoDetach
as a maintenance.autoDetach
config option.
为了说明什么git maintenance
会那么做git gc
won't:
maintenance: 添加提交图任务
Signed-off-by: Derrick Stolee
The first new task in the 'git maintenance(man) ' builtin is the 'commit-graph
' task.
This updates the commit-graph file incrementally with the command
git commit-graph write --reachable --split
通过使用“编写增量提交图文件--split
“我们可以选择尽量减少此次操作的干扰。
默认行为是合并图层,直到新的“顶部”图层小于下面图层大小的一半。这在大多数情况下提供快速写入,较长的写入遵循幂律分布。
最重要的是,并发 Git 进程只会在很短的时间内查看提交图链文件,因此当我们尝试替换该文件时,它们很可能不会持有该文件的句柄。 (这仅在 Windows 上重要。)
如果并发进程读取旧的提交图链文件,但我们的作业使某些.graph
文件,然后这些进程将看到一条警告消息(但不会失败)。将来的更新可以避免这种情况--expire-time
编写提交图时的参数。
git maintenance
现在包含在其man page:
commit-graph
The commit-graph
工作更新commit-graph
增量文件,
然后验证写入的数据是否正确。
增量式
write 可以安全地与并发 Git 进程一起运行,因为它
不会过期.graph
之前的文件commit-graph-chain
文件。它们将被稍后基于运行的
关于过期延迟。
And:
maintenance:添加自动条件commit-graph
task
Signed-off-by: Derrick Stolee
Instead of writing a new commit-graph
in every 'git maintenance run --auto'(man) process (when maintenance.commit-graph.enabled
is configured to be true
), only write when there are "enough" commits not in a commit-graph
file.
该计数由控制maintenance.commit-graph.auto
配置选项。
要计算计数,请使用从每个 ref 开始的深度优先搜索,并使用SEEN
flag.
如果此计数达到限制,则提前终止并开始任务。
否则,此操作将剥离每个引用并解析它指向的提交。如果这些都在commit-graph
,那么这通常是一个非常快的操作。
拥有许多引用的用户可能会感到速度变慢,因此可以考虑将其限制更新为非常小。负值将强制该步骤每次都运行。
git config
现在包含在其man page:
maintenance.commit-graph.auto
这个整数配置选项控制频率commit-graph
任务
应该作为一部分运行git maintenance run --auto
.
- 如果为零,则
commit-graph
任务将不会运行--auto
option.
- 负值将强制任务每次都运行。
- 否则,正值意味着该命令应在以下数量时运行:
不在提交图文件中的可到达提交至少是
的价值
maintenance.commit-graph.auto
.
默认值为 100。
With Git 2.30 (Q1 2021), the test-coverage enhancement of running commit-graph
task "git maintenance"(man) as needed led to discovery and fix of a bug.
See commit d334107 (12 Oct 2020), and commit 8f80180 (08 Oct 2020) by Derrick Stolee (derrickstolee).
(Merged by Junio C Hamano -- gitster -- in commit 0be2d65, 02 Nov 2020)
maintenance:测试提交图自动条件
Signed-off-by: Derrick Stolee
自动条件为commit-graph
维护任务遍历 refs 寻找不在commit-graph
file.
这是添加在4ddc79b2 ("maintenance
:为提交图任务添加自动条件”,2020-09-17,Git v2.29.0-rc0 --merge列于第 17 批)但未经测试。
此更改的最初目标是通过添加测试来证明该功能正常工作。然而,有一个相差一的错误导致了基本测试maintenance.commit-graph.auto=1
在应该起作用的时候却失败了。
微妙之处在于,如果裁判提示不在commit-graph
,那么我们就不会将其添加到总数中。在测试中,我们看到自上次提交图写入以来我们只添加了一次提交,因此自动条件会说没有什么可做的。
修复方法很简单:添加对commit-graph
位置以查看尖端不在commit-graph
在开始步行之前归档。由于这是在添加到 DFS 堆栈之前发生的,因此我们不需要清除(当前为空的)提交列表。
This does add some extra complexity for the test, because we also want to verify that the walk along the parents actually does some work. This means we need to add at least two commits in a row without writing the commit-graph
. However, we also need to make sure no additional refs are pointing to the middle of this list or else the for_each_ref()
in should_write_commit_graph()
might visit these commits as tips instead of doing a DFS walk. Hence, the last two commits are added with "git commit"(man) instead of "test_commit"
.
With Git 2.30 (Q1 2021), "git maintenance(man) run/start/stop" needed to be run in a repository to hold the lockfile they use, but didn't make sure they are actually in a repository, which has been corrected.
See commit 0a1f2d0 (08 Dec 2020) by Josh Steadmon (steadmon).
See commit e72f7de (26 Nov 2020) by Rafael Silva (raffs).
(Merged by Junio C Hamano -- gitster -- in commit f2a75cb, 08 Dec 2020)
maintenance:修复没有存储库时的 SEGFAULT
Signed-off-by: Rafael Silva
Reviewed-by: Derrick Stolee
The "git maintenance run git"(man) and "git maintenance start/stop
" commands holds a file-based lock at the .git/maintenance.lock
and .git/schedule.lock
respectively.
These locks are used to ensure only one maintenance process is executed at the time as both operations involves writing data into the repository.
锁定文件的路径是使用构建的"
the_repository->对象->odb->路径” that results in SEGFAULT when we have no repository available as `"`the_repository->objects->odb"
被设定为NULL
.
让我们教一下维护命令的使用RUN_SETUP
选项将提供验证并在存储库外部运行时失败。因此修复了所有三个操作的 SEGFAULT 并使所有子命令的行为一致。
设置RUN_SETUP
鉴于“注册”和“取消注册”也需要在存储库内执行,还为所有子命令提供相同的保护。
此外,让我们删除由“注册”和“取消注册”实现的本地验证,因为新选项不再需要此操作。