reset: warn when refresh_index() takes more than 2 seconds

refresh_index() is done after a reset command as an optimization. Because it can be an expensive call, warn the user if it takes more than 2 seconds and tell them how to avoid it using the --quiet command line option or reset.quiet config setting. Signed-off-by: Ben Peart <benpeart@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ben Peart committed Oct 23, 2018 at 15:04 UTC 649bf3a42f344e71b1b5a7f562576f911a1f7423
4 files changed +20 -1
Documentation/config.txt
+4
@@ -333,6 +333,10 @@ advice.*::
333 commitBeforeMerge::
334 Advice shown when linkgit:git-merge[1] refuses to
335 merge to avoid overwriting local changes.
336 + resetQuiet::
337 + Advice to consider using the `--quiet` option to linkgit:git-reset[1]
338 + when the command takes more than 2 seconds to enumerate unstaged
339 + changes after reset.
340 resolveConflict::
341 Advice shown by various commands when conflicts
342 prevent the operation from being performed.
advice.c
+2
@@ -12,6 +12,7 @@ int advice_push_needs_force = 1;
12 int advice_status_hints = 1;
13 int advice_status_u_option = 1;
14 int advice_commit_before_merge = 1;
15 +int advice_reset_quiet_warning = 1;
16 int advice_resolve_conflict = 1;
17 int advice_implicit_identity = 1;
18 int advice_detached_head = 1;
@@ -65,6 +66,7 @@ static struct {
66 { "statusHints", &advice_status_hints },
67 { "statusUoption", &advice_status_u_option },
68 { "commitBeforeMerge", &advice_commit_before_merge },
69 + { "resetQuiet", &advice_reset_quiet_warning },
70 { "resolveConflict", &advice_resolve_conflict },
71 { "implicitIdentity", &advice_implicit_identity },
72 { "detachedHead", &advice_detached_head },
advice.h
+1
@@ -12,6 +12,7 @@ extern int advice_push_needs_force;
12 extern int advice_status_hints;
13 extern int advice_status_u_option;
14 extern int advice_commit_before_merge;
15 +extern int advice_reset_quiet_warning;
16 extern int advice_resolve_conflict;
17 extern int advice_implicit_identity;
18 extern int advice_detached_head;
builtin/reset.c
+13 -1
@@ -25,6 +25,8 @@
25 #include "submodule.h"
26 #include "submodule-config.h"
27
28 +#define REFRESH_INDEX_DELAY_WARNING_IN_MS (2 * 1000)
29 +
30 static const char * const git_reset_usage[] = {
31 N_("git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"),
32 N_("git reset [-q] [<tree-ish>] [--] <paths>..."),
@@ -377,9 +379,19 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
379 int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
380 if (read_from_tree(&pathspec, &oid, intent_to_add))
381 return 1;
380 - if (!quiet && get_git_work_tree())
382 + if (!quiet && get_git_work_tree()) {
383 + uint64_t t_begin, t_delta_in_ms;
384 +
385 + t_begin = getnanotime();
386 refresh_index(&the_index, flags, NULL, NULL,
387 _("Unstaged changes after reset:"));
388 + t_delta_in_ms = (getnanotime() - t_begin) / 1000000;
389 + if (advice_reset_quiet_warning && t_delta_in_ms > REFRESH_INDEX_DELAY_WARNING_IN_MS) {
390 + printf(_("\nIt took %.2f seconds to enumerate unstaged changes after reset. You can\n"
391 + "use '--quiet' to avoid this. Set the config setting reset.quiet to true\n"
392 + "to make this the default.\n"), t_delta_in_ms / 1000.0);
393 + }
394 + }
395 } else {
396 int err = reset_index(&oid, reset_type, quiet);
397 if (reset_type == KEEP && !err)