Skip to content

Commit cde9a64

Browse files
committed
Merge branch 'ds/fetch-disable-force-notice'
"git fetch" and "git pull" reports when a fetch results in non-fast-forward updates to let the user notice unusual situation. The commands learned "--no-shown-forced-updates" option to disable this safety feature. * ds/fetch-disable-force-notice: pull: add --[no-]show-forced-updates passthrough fetch: warn about forced updates in branch listing fetch: add --[no-]show-forced-updates argument
2 parents 3418622 + 3883c55 commit cde9a64

File tree

8 files changed

+88
-1
lines changed

8 files changed

+88
-1
lines changed

Documentation/config/advice.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ advice.*::
44
can tell Git that you do not need help by setting these to 'false':
55
+
66
--
7+
fetchShowForcedUpdates::
8+
Advice shown when linkgit:git-fetch[1] takes a long time
9+
to calculate forced updates after ref updates, or to warn
10+
that the check is disabled.
711
pushUpdateRejected::
812
Set this variable to 'false' if you want to disable
913
'pushNonFFCurrent',

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
@@ -225,6 +225,19 @@ endif::git-pull[]
225225
When multiple `--server-option=<option>` are given, they are all
226226
sent to the other side in the order listed on the command line.
227227

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

advice.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "color.h"
44
#include "help.h"
55

6+
int advice_fetch_show_forced_updates = 1;
67
int advice_push_update_rejected = 1;
78
int advice_push_non_ff_current = 1;
89
int advice_push_non_ff_matching = 1;
@@ -60,6 +61,7 @@ static struct {
6061
const char *name;
6162
int *preference;
6263
} advice_config[] = {
64+
{ "fetchShowForcedUpdates", &advice_fetch_show_forced_updates },
6365
{ "pushUpdateRejected", &advice_push_update_rejected },
6466
{ "pushNonFFCurrent", &advice_push_non_ff_current },
6567
{ "pushNonFFMatching", &advice_push_non_ff_matching },

advice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "git-compat-util.h"
55

6+
extern int advice_fetch_show_forced_updates;
67
extern int advice_push_update_rejected;
78
extern int advice_push_non_ff_current;
89
extern int advice_push_non_ff_matching;

builtin/fetch.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include "list-objects-filter-options.h"
2525
#include "commit-reach.h"
2626

27+
#define FORCED_UPDATES_DELAY_WARNING_IN_MS (10 * 1000)
28+
2729
static const char * const builtin_fetch_usage[] = {
2830
N_("git fetch [<options>] [<repository> [<refspec>...]]"),
2931
N_("git fetch [<options>] <group>"),
@@ -39,6 +41,8 @@ enum {
3941
};
4042

4143
static int fetch_prune_config = -1; /* unspecified */
44+
static int fetch_show_forced_updates = 1;
45+
static uint64_t forced_updates_ms = 0;
4246
static int prune = -1; /* unspecified */
4347
#define PRUNE_BY_DEFAULT 0 /* do we prune by default? */
4448

@@ -80,6 +84,11 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
8084
return 0;
8185
}
8286

87+
if (!strcmp(k, "fetch.showforcedupdates")) {
88+
fetch_show_forced_updates = git_config_bool(k, v);
89+
return 0;
90+
}
91+
8392
if (!strcmp(k, "submodule.recurse")) {
8493
int r = git_config_bool(k, v) ?
8594
RECURSE_SUBMODULES_ON : RECURSE_SUBMODULES_OFF;
@@ -172,6 +181,8 @@ static struct option builtin_fetch_options[] = {
172181
OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
173182
OPT_BOOL(0, "auto-gc", &enable_auto_gc,
174183
N_("run 'gc --auto' after fetching")),
184+
OPT_BOOL(0, "show-forced-updates", &fetch_show_forced_updates,
185+
N_("check for forced-updates on all updated branches")),
175186
OPT_END()
176187
};
177188

@@ -710,6 +721,7 @@ static int update_local_ref(struct ref *ref,
710721
enum object_type type;
711722
struct branch *current_branch = branch_get(NULL);
712723
const char *pretty_ref = prettify_refname(ref->name);
724+
int fast_forward = 0;
713725

714726
type = oid_object_info(the_repository, &ref->new_oid, NULL);
715727
if (type < 0)
@@ -784,9 +796,18 @@ static int update_local_ref(struct ref *ref,
784796
return r;
785797
}
786798

787-
if (in_merge_bases(current, updated)) {
799+
if (fetch_show_forced_updates) {
800+
uint64_t t_before = getnanotime();
801+
fast_forward = in_merge_bases(current, updated);
802+
forced_updates_ms += (getnanotime() - t_before) / 1000000;
803+
} else {
804+
fast_forward = 1;
805+
}
806+
807+
if (fast_forward) {
788808
struct strbuf quickref = STRBUF_INIT;
789809
int r;
810+
790811
strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
791812
strbuf_addstr(&quickref, "..");
792813
strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
@@ -982,6 +1003,17 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
9821003
" 'git remote prune %s' to remove any old, conflicting "
9831004
"branches"), remote_name);
9841005

1006+
if (advice_fetch_show_forced_updates) {
1007+
if (!fetch_show_forced_updates) {
1008+
warning(_("Fetch normally indicates which branches had a forced update, but that check has been disabled."));
1009+
warning(_("To re-enable, use '--show-forced-updates' flag or run 'git config fetch.showForcedUpdates true'."));
1010+
} else if (forced_updates_ms > FORCED_UPDATES_DELAY_WARNING_IN_MS) {
1011+
warning(_("It took %.2f seconds to check forced updates. You can use '--no-show-forced-updates'\n"),
1012+
forced_updates_ms / 1000.0);
1013+
warning(_("or run 'git config fetch.showForcedUpdates false' to avoid this check.\n"));
1014+
}
1015+
}
1016+
9851017
abort:
9861018
strbuf_release(&note);
9871019
free(url);

builtin/pull.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ static char *opt_update_shallow;
128128
static char *opt_refmap;
129129
static char *opt_ipv4;
130130
static char *opt_ipv6;
131+
static int opt_show_forced_updates = -1;
131132

132133
static struct option pull_options[] = {
133134
/* Shared options */
@@ -240,6 +241,8 @@ static struct option pull_options[] = {
240241
OPT_PASSTHRU('6', "ipv6", &opt_ipv6, NULL,
241242
N_("use IPv6 addresses only"),
242243
PARSE_OPT_NOARG),
244+
OPT_BOOL(0, "show-forced-updates", &opt_show_forced_updates,
245+
N_("check for forced-updates on all updated branches")),
243246

244247
OPT_END()
245248
};
@@ -549,6 +552,10 @@ static int run_fetch(const char *repo, const char **refspecs)
549552
argv_array_push(&args, opt_ipv4);
550553
if (opt_ipv6)
551554
argv_array_push(&args, opt_ipv6);
555+
if (opt_show_forced_updates > 0)
556+
argv_array_push(&args, "--show-forced-updates");
557+
else if (opt_show_forced_updates == 0)
558+
argv_array_push(&args, "--no-show-forced-updates");
552559

553560
if (repo) {
554561
argv_array_push(&args, repo);

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)