status: advise to consider use of -u when read_directory takes too long

Introduce advice.statusUoption to suggest considering use of -u to strike different trade-off when it took more than 2 seconds to enumerate untracked/ignored files. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Mar 13, 2013 at 19:59 UTC 6a38ef2ced55f0a8a7967581934e40f79e1d8733
8 files changed +36
Documentation/config.txt
+4
@@ -163,6 +163,10 @@ advice.*::
163 state in the output of linkgit:git-status[1] and in
164 the template shown when writing commit messages in
165 linkgit:git-commit[1].
166 + statusUoption::
167 + Advise to consider using the `-u` option to linkgit:git-status[1]
168 + when the command takes more than 2 seconds to enumerate untracked
169 + files.
170 commitBeforeMerge::
171 Advice shown when linkgit:git-merge[1] refuses to
172 merge to avoid overwriting local changes.
advice.c
+2
@@ -5,6 +5,7 @@ int advice_push_non_ff_current = 1;
5 int advice_push_non_ff_default = 1;
6 int advice_push_non_ff_matching = 1;
7 int advice_status_hints = 1;
8 +int advice_status_u_option = 1;
9 int advice_commit_before_merge = 1;
10 int advice_resolve_conflict = 1;
11 int advice_implicit_identity = 1;
@@ -19,6 +20,7 @@ static struct {
20 { "pushnonffdefault", &advice_push_non_ff_default },
21 { "pushnonffmatching", &advice_push_non_ff_matching },
22 { "statushints", &advice_status_hints },
23 + { "statusuoption", &advice_status_u_option },
24 { "commitbeforemerge", &advice_commit_before_merge },
25 { "resolveconflict", &advice_resolve_conflict },
26 { "implicitidentity", &advice_implicit_identity },
advice.h
+1
@@ -8,6 +8,7 @@ extern int advice_push_non_ff_current;
8 extern int advice_push_non_ff_default;
9 extern int advice_push_non_ff_matching;
10 extern int advice_status_hints;
11 +extern int advice_status_u_option;
12 extern int advice_commit_before_merge;
13 extern int advice_resolve_conflict;
14 extern int advice_implicit_identity;
t/t7060-wtstatus.sh
+1
@@ -5,6 +5,7 @@ test_description='basic work tree status reporting'
5 . ./test-lib.sh
6
7 test_expect_success setup '
8 + git config --global advice.statusuoption false &&
9 test_commit A &&
10 test_commit B oneside added &&
11 git checkout A^0 &&
t/t7508-status.sh
+1
@@ -8,6 +8,7 @@ test_description='git status'
8 . ./test-lib.sh
9
10 test_expect_success 'status -h in broken repository' '
11 + git config --global advice.statusuoption false &&
12 mkdir broken &&
13 test_when_finished "rm -fr broken" &&
14 (
t/t7512-status-help.sh
+1
@@ -14,6 +14,7 @@ test_description='git status advices'
14 set_fake_editor
15
16 test_expect_success 'prepare for conflicts' '
17 + git config --global advice.statusuoption false &&
18 test_commit init main.txt init &&
19 git branch conflicts &&
20 test_commit on_master main.txt on_master &&
wt-status.c
+25
@@ -496,9 +496,14 @@ static void wt_status_collect_untracked(struct wt_status *s)
496 {
497 int i;
498 struct dir_struct dir;
499 + struct timeval t_begin;
500
501 if (!s->show_untracked_files)
502 return;
503 +
504 + if (advice_status_u_option)
505 + gettimeofday(&t_begin, NULL);
506 +
507 memset(&dir, 0, sizeof(dir));
508 if (s->show_untracked_files != SHOW_ALL_UNTRACKED_FILES)
509 dir.flags |=
@@ -528,6 +533,14 @@ static void wt_status_collect_untracked(struct wt_status *s)
533 }
534
535 free(dir.entries);
536 +
537 + if (advice_status_u_option) {
538 + struct timeval t_end;
539 + gettimeofday(&t_end, NULL);
540 + s->untracked_in_ms =
541 + (uint64_t)t_end.tv_sec * 1000 + t_end.tv_usec / 1000 -
542 + ((uint64_t)t_begin.tv_sec * 1000 + t_begin.tv_usec / 1000);
543 + }
544 }
545
546 void wt_status_collect(struct wt_status *s)
@@ -1011,6 +1024,18 @@ void wt_status_print(struct wt_status *s)
1024 wt_status_print_other(s, &s->untracked, _("Untracked files"), "add");
1025 if (s->show_ignored_files)
1026 wt_status_print_other(s, &s->ignored, _("Ignored files"), "add -f");
1027 + if (advice_status_u_option && 2000 < s->untracked_in_ms) {
1028 + status_printf_ln(s, GIT_COLOR_NORMAL, "");
1029 + status_printf_ln(s, GIT_COLOR_NORMAL,
1030 + _("It took %.2f seconds to enumerate untracked files."
1031 + " 'status -uno'"),
1032 + s->untracked_in_ms / 1000.0);
1033 + status_printf_ln(s, GIT_COLOR_NORMAL,
1034 + _("may speed it up, but you have to be careful not"
1035 + " to forget to add"));
1036 + status_printf_ln(s, GIT_COLOR_NORMAL,
1037 + _("new files yourself (see 'git help status')."));
1038 + }
1039 } else if (s->commitable)
1040 status_printf_ln(s, GIT_COLOR_NORMAL, _("Untracked files not listed%s"),
1041 advice_status_hints
wt-status.h
+1
@@ -69,6 +69,7 @@ struct wt_status {
69 struct string_list change;
70 struct string_list untracked;
71 struct string_list ignored;
72 + uint32_t untracked_in_ms;
73 };
74
75 struct wt_status_state {