Skip to content

Commit

Permalink
fetch: only run 'gc' once when fetching multiple remotes
Browse files Browse the repository at this point in the history
In multiple remotes mode, git-fetch is launched for n-1 remotes and the
last remote is handled by the current process. Each of these processes
will in turn run 'gc' at the end.

This is not really a problem because even if multiple 'gc --auto' is run
at the same time we still handle it correctly. It does show multiple
"auto packing in the background" messages though. And we may waste some
resources when gc actually runs because we still do some stuff before
checking the lock and moving it to background.

So let's try to avoid that. We should only need one 'gc' run after all
objects and references are added anyway. Add a new option --no-auto-gc
that will be used by those n-1 processes. 'gc --auto' will always run on
the main fetch process (*).

(*) even if we fetch remotes in parallel at some point in future, this
    should still be fine because we should "join" all those processes
    before this step.

Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]>
Acked-by: Jeff King <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
pclouds authored and gitster committed Jun 20, 2019
1 parent b697d92 commit c3d6b70
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 8 deletions.
4 changes: 4 additions & 0 deletions Documentation/fetch-options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ ifndef::git-pull[]
Allow several <repository> and <group> arguments to be
specified. No <refspec>s may be specified.

--[no-]auto-gc::
Run `git gc --auto` at the end to perform garbage collection
if needed. This is enabled by default.

-p::
--prune::
Before fetching, remove any remote-tracking references that no
Expand Down
17 changes: 11 additions & 6 deletions builtin/fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ static int prune_tags = -1; /* unspecified */

static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity, deepen_relative;
static int progress = -1;
static int enable_auto_gc = 1;
static int tags = TAGS_DEFAULT, unshallow, update_shallow, deepen;
static int max_children = 1;
static enum transport_family family;
Expand Down Expand Up @@ -169,6 +170,8 @@ static struct option builtin_fetch_options[] = {
OPT_STRING_LIST(0, "negotiation-tip", &negotiation_tip, N_("revision"),
N_("report that we have only objects reachable from this object")),
OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
OPT_BOOL(0, "auto-gc", &enable_auto_gc,
N_("run 'gc --auto' after fetching")),
OPT_END()
};

Expand Down Expand Up @@ -1424,7 +1427,7 @@ static int fetch_multiple(struct string_list *list)
return errcode;
}

argv_array_pushl(&argv, "fetch", "--append", NULL);
argv_array_pushl(&argv, "fetch", "--append", "--no-auto-gc", NULL);
add_options_to_argv(&argv);

for (i = 0; i < list->nr; i++) {
Expand Down Expand Up @@ -1674,11 +1677,13 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)

close_all_packs(the_repository->objects);

argv_array_pushl(&argv_gc_auto, "gc", "--auto", NULL);
if (verbosity < 0)
argv_array_push(&argv_gc_auto, "--quiet");
run_command_v_opt(argv_gc_auto.argv, RUN_GIT_CMD);
argv_array_clear(&argv_gc_auto);
if (enable_auto_gc) {
argv_array_pushl(&argv_gc_auto, "gc", "--auto", NULL);
if (verbosity < 0)
argv_array_push(&argv_gc_auto, "--quiet");
run_command_v_opt(argv_gc_auto.argv, RUN_GIT_CMD);
argv_array_clear(&argv_gc_auto);
}

return result;
}
7 changes: 5 additions & 2 deletions t/t5514-fetch-multiple.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,12 @@ test_expect_success 'git fetch --multiple (two remotes)' '
git remote rm origin &&
git remote add one ../one &&
git remote add two ../two &&
git fetch --multiple one two &&
GIT_TRACE=1 git fetch --multiple one two 2>trace &&
git branch -r > output &&
test_cmp ../expect output)
test_cmp ../expect output &&
grep "built-in: git gc" trace >gc &&
test_line_count = 1 gc
)
'

test_expect_success 'git fetch --multiple (bad remote names)' '
Expand Down

0 comments on commit c3d6b70

Please sign in to comment.