Skip to content

Commit cdbd70c

Browse files
derrickstoleegitster
authored andcommitted
fetch: add --[no-]show-forced-updates argument
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a6a95cd commit cdbd70c

File tree

4 files changed

+51
-1
lines changed

4 files changed

+51
-1
lines changed

Documentation/config/fetch.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,8 @@ fetch.negotiationAlgorithm::
6363
Unknown values will cause 'git fetch' to error out.
6464
+
6565
See also the `--negotiation-tip` option for linkgit:git-fetch[1].
66+
67+
fetch.showForcedUpdates::
68+
Set to false to enable `--no-show-forced-updates` in
69+
linkgit:git-fetch[1] and linkgit:git-pull[1] commands.
70+
Defaults to true.

Documentation/fetch-options.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,19 @@ endif::git-pull[]
221221
When multiple `--server-option=<option>` are given, they are all
222222
sent to the other side in the order listed on the command line.
223223

224+
--show-forced-updates::
225+
By default, git checks if a branch is force-updated during
226+
fetch. This can be disabled through fetch.showForcedUpdates, but
227+
the --show-forced-updates option guarantees this check occurs.
228+
See linkgit:git-config[1].
229+
230+
--no-show-forced-updates::
231+
By default, git checks if a branch is force-updated during
232+
fetch. Pass --no-show-forced-updates or set fetch.showForcedUpdates
233+
to false to skip this check for performance reasons. If used during
234+
'git-pull' the --ff-only option will still check for forced updates
235+
before attempting a fast-forward update. See linkgit:git-config[1].
236+
224237
-4::
225238
--ipv4::
226239
Use IPv4 addresses only, ignoring IPv6 addresses.

builtin/fetch.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ enum {
3939
};
4040

4141
static int fetch_prune_config = -1; /* unspecified */
42+
static int fetch_show_forced_updates = 1;
4243
static int prune = -1; /* unspecified */
4344
#define PRUNE_BY_DEFAULT 0 /* do we prune by default? */
4445

@@ -79,6 +80,11 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
7980
return 0;
8081
}
8182

83+
if (!strcmp(k, "fetch.showforcedupdates")) {
84+
fetch_show_forced_updates = git_config_bool(k, v);
85+
return 0;
86+
}
87+
8288
if (!strcmp(k, "submodule.recurse")) {
8389
int r = git_config_bool(k, v) ?
8490
RECURSE_SUBMODULES_ON : RECURSE_SUBMODULES_OFF;
@@ -169,6 +175,8 @@ static struct option builtin_fetch_options[] = {
169175
OPT_STRING_LIST(0, "negotiation-tip", &negotiation_tip, N_("revision"),
170176
N_("report that we have only objects reachable from this object")),
171177
OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
178+
OPT_BOOL(0, "show-forced-updates", &fetch_show_forced_updates,
179+
N_("check for forced-updates on all updated branches")),
172180
OPT_END()
173181
};
174182

@@ -773,9 +781,10 @@ static int update_local_ref(struct ref *ref,
773781
return r;
774782
}
775783

776-
if (in_merge_bases(current, updated)) {
784+
if (!fetch_show_forced_updates || in_merge_bases(current, updated)) {
777785
struct strbuf quickref = STRBUF_INIT;
778786
int r;
787+
779788
strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
780789
strbuf_addstr(&quickref, "..");
781790
strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);

t/t5510-fetch.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,4 +978,27 @@ test_expect_success '--negotiation-tip limits "have" lines sent with HTTP protoc
978978
check_negotiation_tip
979979
'
980980

981+
test_expect_success '--no-show-forced-updates' '
982+
mkdir forced-updates &&
983+
(
984+
cd forced-updates &&
985+
git init &&
986+
test_commit 1 &&
987+
test_commit 2
988+
) &&
989+
git clone forced-updates forced-update-clone &&
990+
git clone forced-updates no-forced-update-clone &&
991+
git -C forced-updates reset --hard HEAD~1 &&
992+
(
993+
cd forced-update-clone &&
994+
git fetch --show-forced-updates origin 2>output &&
995+
test_i18ngrep "(forced update)" output
996+
) &&
997+
(
998+
cd no-forced-update-clone &&
999+
git fetch --no-show-forced-updates origin 2>output &&
1000+
! test_i18ngrep "(forced update)" output
1001+
)
1002+
'
1003+
9811004
test_done

0 commit comments

Comments
 (0)