fetch: add --[no-]show-forced-updates argument
authorDerrick Stolee <dstolee@microsoft.com>
Tue, 18 Jun 2019 20:25:26 +0000 (13:25 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 21 Jun 2019 16:38:29 +0000 (09:38 -0700)
After updating a set of remove refs during a 'git fetch', we walk the
commits in the new ref value and not in the old ref value to discover
if the update was a forced update. This results in two things happening
during the command:

1. The line including the ref update has an additional "(forced-update)"
marker at the end.

2. The ref log for that remote branch includes a bit saying that update
is a forced update.

For many situations, this forced-update message happens infrequently, or
is a small bit of information among many ref updates. Many users ignore
these messages, but the calculation required here slows down their fetches
significantly. Keep in mind that they do not have the opportunity to
calculate a commit-graph file containing the newly-fetched commits, so
these comparisons can be very slow.

Add a '--[no-]show-forced-updates' option that allows a user to skip this
calculation. The only permanent result is dropping the forced-update bit
in the reflog.

Include a new fetch.showForcedUpdates config setting that allows this
behavior without including the argument in every command. The config
setting is overridden by the command-line arguments.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config/fetch.txt
Documentation/fetch-options.txt
builtin/fetch.c
t/t5510-fetch.sh
index cbfad6cdbb38edec5633144af499cf63e2828dee..ba890b5884fc3496e6529cb8e1f41ad7dd9748f4 100644 (file)
@@ -63,3 +63,8 @@ fetch.negotiationAlgorithm::
        Unknown values will cause 'git fetch' to error out.
 +
 See also the `--negotiation-tip` option for linkgit:git-fetch[1].
+
+fetch.showForcedUpdates::
+       Set to false to enable `--no-show-forced-updates` in
+       linkgit:git-fetch[1] and linkgit:git-pull[1] commands.
+       Defaults to true.
index 91c47752ecdc9c77f660ec1b67bb9b1f393c3cb7..5801d23ae4dffcefe758534d4fb354f62a883ad7 100644 (file)
@@ -221,6 +221,19 @@ endif::git-pull[]
        When multiple `--server-option=<option>` are given, they are all
        sent to the other side in the order listed on the command line.
 
+--show-forced-updates::
+       By default, git checks if a branch is force-updated during
+       fetch. This can be disabled through fetch.showForcedUpdates, but
+       the --show-forced-updates option guarantees this check occurs.
+       See linkgit:git-config[1].
+
+--no-show-forced-updates::
+       By default, git checks if a branch is force-updated during
+       fetch. Pass --no-show-forced-updates or set fetch.showForcedUpdates
+       to false to skip this check for performance reasons. If used during
+       'git-pull' the --ff-only option will still check for forced updates
+       before attempting a fast-forward update. See linkgit:git-config[1].
+
 -4::
 --ipv4::
        Use IPv4 addresses only, ignoring IPv6 addresses.
index 4ba63d5ac642844832a5c832cea93ddf99507764..571c2552181d485f73731538712508fc119dbbd0 100644 (file)
@@ -39,6 +39,7 @@ enum {
 };
 
 static int fetch_prune_config = -1; /* unspecified */
+static int fetch_show_forced_updates = 1;
 static int prune = -1; /* unspecified */
 #define PRUNE_BY_DEFAULT 0 /* do we prune by default? */
 
@@ -79,6 +80,11 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
                return 0;
        }
 
+       if (!strcmp(k, "fetch.showforcedupdates")) {
+               fetch_show_forced_updates = git_config_bool(k, v);
+               return 0;
+       }
+
        if (!strcmp(k, "submodule.recurse")) {
                int r = git_config_bool(k, v) ?
                        RECURSE_SUBMODULES_ON : RECURSE_SUBMODULES_OFF;
@@ -169,6 +175,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, "show-forced-updates", &fetch_show_forced_updates,
+                N_("check for forced-updates on all updated branches")),
        OPT_END()
 };
 
@@ -773,9 +781,10 @@ static int update_local_ref(struct ref *ref,
                return r;
        }
 
-       if (in_merge_bases(current, updated)) {
+       if (!fetch_show_forced_updates || in_merge_bases(current, updated)) {
                struct strbuf quickref = STRBUF_INIT;
                int r;
+
                strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
                strbuf_addstr(&quickref, "..");
                strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
index e98d90dd9baf644bf2013aea51a91eab4e9ef73c..139f7106f78177ed4a1355dda463b7b69b2d839f 100755 (executable)
@@ -978,4 +978,27 @@ test_expect_success '--negotiation-tip limits "have" lines sent with HTTP protoc
        check_negotiation_tip
 '
 
+test_expect_success '--no-show-forced-updates' '
+       mkdir forced-updates &&
+       (
+               cd forced-updates &&
+               git init &&
+               test_commit 1 &&
+               test_commit 2
+       ) &&
+       git clone forced-updates forced-update-clone &&
+       git clone forced-updates no-forced-update-clone &&
+       git -C forced-updates reset --hard HEAD~1 &&
+       (
+               cd forced-update-clone &&
+               git fetch --show-forced-updates origin 2>output &&
+               test_i18ngrep "(forced update)" output
+       ) &&
+       (
+               cd no-forced-update-clone &&
+               git fetch --no-show-forced-updates origin 2>output &&
+               ! test_i18ngrep "(forced update)" output
+       )
+'
+
 test_done