fetch: add fetch.writeCommitGraph config setting

The commit-graph feature is now on by default, and is being
written during 'git gc' by default. Typically, Git only writes
a commit-graph when a 'git gc --auto' command passes the gc.auto
setting to actualy do work. This means that a commit-graph will
typically fall behind the commits that are being used every day.

To stay updated with the latest commits, add a step to 'git
fetch' to write a commit-graph after fetching new objects. The
fetch.writeCommitGraph config setting enables writing a split
commit-graph, so on average the cost of writing this file is
very small. Occasionally, the commit-graph chain will collapse
to a single level, and this could be slow for very large repos.

For additional use, adjust the default to be true when
feature.experimental is enabled.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Derrick Stolee 2019-09-02 19:22:02 -07:00 коммит произвёл Junio C Hamano
Родитель aaf633c2ad
Коммит 50f26bd035
6 изменённых файлов: 51 добавлений и 0 удалений

Просмотреть файл

@ -17,6 +17,14 @@ which can improve `git push` performance in repos with many files.
+ +
* `fetch.negotiationAlgorithm=skipping` may improve fetch negotiation times by * `fetch.negotiationAlgorithm=skipping` may improve fetch negotiation times by
skipping more commits at a time, reducing the number of round trips. skipping more commits at a time, reducing the number of round trips.
+
* `fetch.writeCommitGraph=true` writes a commit-graph after every `git fetch`
command that downloads a pack-file from a remote. Using the `--split` option,
most executions will create a very small commit-graph file on top of the
existing commit-graph file(s). Occasionally, these files will merge and the
write may take longer. Having an updated commit-graph file helps performance
of many Git commands, including `git merge-base`, `git push -f`, and
`git log --graph`.
feature.manyFiles:: feature.manyFiles::
Enable config options that optimize for repos with many files in the Enable config options that optimize for repos with many files in the

Просмотреть файл

@ -69,3 +69,13 @@ fetch.showForcedUpdates::
Set to false to enable `--no-show-forced-updates` in Set to false to enable `--no-show-forced-updates` in
linkgit:git-fetch[1] and linkgit:git-pull[1] commands. linkgit:git-fetch[1] and linkgit:git-pull[1] commands.
Defaults to true. Defaults to true.
fetch.writeCommitGraph::
Set to true to write a commit-graph after every `git fetch` command
that downloads a pack-file from a remote. Using the `--split` option,
most executions will create a very small commit-graph file on top of
the existing commit-graph file(s). Occasionally, these files will
merge and the write may take longer. Having an updated commit-graph
file helps performance of many Git commands, including `git merge-base`,
`git push -f`, and `git log --graph`. Defaults to false, unless
`feature.experimental` is true.

Просмотреть файл

@ -23,6 +23,7 @@
#include "packfile.h" #include "packfile.h"
#include "list-objects-filter-options.h" #include "list-objects-filter-options.h"
#include "commit-reach.h" #include "commit-reach.h"
#include "commit-graph.h"
#define FORCED_UPDATES_DELAY_WARNING_IN_MS (10 * 1000) #define FORCED_UPDATES_DELAY_WARNING_IN_MS (10 * 1000)
@ -1715,6 +1716,20 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
string_list_clear(&list, 0); string_list_clear(&list, 0);
prepare_repo_settings(the_repository);
if (the_repository->settings.fetch_write_commit_graph) {
int commit_graph_flags = COMMIT_GRAPH_SPLIT;
struct split_commit_graph_opts split_opts;
memset(&split_opts, 0, sizeof(struct split_commit_graph_opts));
if (progress)
commit_graph_flags |= COMMIT_GRAPH_PROGRESS;
write_commit_graph_reachable(get_object_directory(),
commit_graph_flags,
&split_opts);
}
close_object_store(the_repository->objects); close_object_store(the_repository->objects);
if (enable_auto_gc) { if (enable_auto_gc) {

Просмотреть файл

@ -49,10 +49,14 @@ void prepare_repo_settings(struct repository *r)
UPDATE_DEFAULT_BOOL(r->settings.index_version, 4); UPDATE_DEFAULT_BOOL(r->settings.index_version, 4);
UPDATE_DEFAULT_BOOL(r->settings.core_untracked_cache, UNTRACKED_CACHE_WRITE); UPDATE_DEFAULT_BOOL(r->settings.core_untracked_cache, UNTRACKED_CACHE_WRITE);
} }
if (!repo_config_get_bool(r, "fetch.writecommitgraph", &value))
r->settings.fetch_write_commit_graph = value;
if (!repo_config_get_bool(r, "feature.experimental", &value) && value) { if (!repo_config_get_bool(r, "feature.experimental", &value) && value) {
UPDATE_DEFAULT_BOOL(r->settings.pack_use_sparse, 1); UPDATE_DEFAULT_BOOL(r->settings.pack_use_sparse, 1);
UPDATE_DEFAULT_BOOL(r->settings.fetch_negotiation_algorithm, FETCH_NEGOTIATION_SKIPPING); UPDATE_DEFAULT_BOOL(r->settings.fetch_negotiation_algorithm, FETCH_NEGOTIATION_SKIPPING);
UPDATE_DEFAULT_BOOL(r->settings.fetch_write_commit_graph, 1);
} }
UPDATE_DEFAULT_BOOL(r->settings.fetch_write_commit_graph, 0);
/* Hack for test programs like test-dump-untracked-cache */ /* Hack for test programs like test-dump-untracked-cache */
if (ignore_untracked_cache_config) if (ignore_untracked_cache_config)

Просмотреть файл

@ -30,6 +30,7 @@ struct repo_settings {
int core_commit_graph; int core_commit_graph;
int gc_write_commit_graph; int gc_write_commit_graph;
int fetch_write_commit_graph;
int index_version; int index_version;
enum untracked_cache_setting core_untracked_cache; enum untracked_cache_setting core_untracked_cache;

Просмотреть файл

@ -570,6 +570,19 @@ test_expect_success 'LHS of refspec follows ref disambiguation rules' '
) )
' '
test_expect_success 'fetch.writeCommitGraph' '
git clone three write &&
(
cd three &&
test_commit new
) &&
(
cd write &&
git -c fetch.writeCommitGraph fetch origin &&
test_path_is_file .git/objects/info/commit-graphs/commit-graph-chain
)
'
# configured prune tests # configured prune tests
set_config_tristate () { set_config_tristate () {