This patch attempts to advertise -uno to the users who tolerate slow
"git status" on large repositories (or slow machines/disks). The 2
seconds limit is quite arbitrary but is probably long enough to start
using -uno.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 Documentation/config.txt |  4 ++++
 advice.c                 |  2 ++
 advice.h                 |  1 +
 t/t7060-wtstatus.sh      |  2 ++
 t/t7508-status.sh        |  4 ++++
 t/t7512-status-help.sh   |  1 +
 wt-status.c              | 20 +++++++++++++++++++-
 wt-status.h              |  1 +
 8 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index bbba728..e91d06f 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -178,6 +178,10 @@ advice.*::
                the template shown when writing commit messages in
                linkgit:git-commit[1], and in the help message shown
                by linkgit:git-checkout[1] when switching branch.
+       statusUno::
+               If collecting untracked files in linkgit:git-status[1]
+               takes more than 2 seconds, hint the user that the option
+               `-uno` could be used to stop collecting untracked files.
        commitBeforeMerge::
                Advice shown when linkgit:git-merge[1] refuses to
                merge to avoid overwriting local changes.
diff --git a/advice.c b/advice.c
index 780f58d..72b5c66 100644
--- a/advice.c
+++ b/advice.c
@@ -8,6 +8,7 @@ int advice_push_already_exists = 1;
 int advice_push_fetch_first = 1;
 int advice_push_needs_force = 1;
 int advice_status_hints = 1;
+int advice_status_uno = 1;
 int advice_commit_before_merge = 1;
 int advice_resolve_conflict = 1;
 int advice_implicit_identity = 1;
@@ -25,6 +26,7 @@ static struct {
        { "pushfetchfirst", &advice_push_fetch_first },
        { "pushneedsforce", &advice_push_needs_force },
        { "statushints", &advice_status_hints },
+       { "statusuno", &advice_status_uno },
        { "commitbeforemerge", &advice_commit_before_merge },
        { "resolveconflict", &advice_resolve_conflict },
        { "implicitidentity", &advice_implicit_identity },
diff --git a/advice.h b/advice.h
index fad36df..d7e03be 100644
--- a/advice.h
+++ b/advice.h
@@ -11,6 +11,7 @@ extern int advice_push_already_exists;
 extern int advice_push_fetch_first;
 extern int advice_push_needs_force;
 extern int advice_status_hints;
+extern int advice_status_uno;
 extern int advice_commit_before_merge;
 extern int advice_resolve_conflict;
 extern int advice_implicit_identity;
diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh
index f4f38a5..dd340d5 100755
--- a/t/t7060-wtstatus.sh
+++ b/t/t7060-wtstatus.sh
@@ -5,6 +5,7 @@ test_description='basic work tree status reporting'
 . ./test-lib.sh
 
 test_expect_success setup '
+       git config advice.statusuno false &&
        test_commit A &&
        test_commit B oneside added &&
        git checkout A^0 &&
@@ -46,6 +47,7 @@ test_expect_success 'M/D conflict does not segfault' '
        (
                cd mdconflict &&
                git init &&
+               git config advice.statusuno false
                test_commit initial foo "" &&
                test_commit modify foo foo &&
                git checkout -b side HEAD^ &&
diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index a79c032..9d6e4db 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -8,11 +8,13 @@ test_description='git status'
 . ./test-lib.sh
 
 test_expect_success 'status -h in broken repository' '
+       git config advice.statusuno false &&
        mkdir broken &&
        test_when_finished "rm -fr broken" &&
        (
                cd broken &&
                git init &&
+               git config advice.statusuno false &&
                echo "[status] showuntrackedfiles = CORRUPT" >>.git/config &&
                test_expect_code 129 git status -h >usage 2>&1
        ) &&
@@ -25,6 +27,7 @@ test_expect_success 'commit -h in broken repository' '
        (
                cd broken &&
                git init &&
+               git config advice.statusuno false &&
                echo "[status] showuntrackedfiles = CORRUPT" >>.git/config &&
                test_expect_code 129 git commit -h >usage 2>&1
        ) &&
@@ -780,6 +783,7 @@ test_expect_success 'status refreshes the index' '
 test_expect_success 'setup status submodule summary' '
        test_create_repo sm && (
                cd sm &&
+               git config advice.statusuno false &&
                >foo &&
                git add foo &&
                git commit -m "Add foo"
diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index d2da89a..033a1b3 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -14,6 +14,7 @@ test_description='git status advice'
 set_fake_editor
 
 test_expect_success 'prepare for conflicts' '
+       git config advice.statusuno false &&
        test_commit init main.txt init &&
        git branch conflicts &&
        test_commit on_master main.txt on_master &&
diff --git a/wt-status.c b/wt-status.c
index ef405d0..6fde08b 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -540,7 +540,16 @@ void wt_status_collect(struct wt_status *s)
                wt_status_collect_changes_initial(s);
        else
                wt_status_collect_changes_index(s);
-       wt_status_collect_untracked(s);
+       if (s->show_untracked_files && advice_status_uno) {
+               struct timeval tv1, tv2;
+               gettimeofday(&tv1, NULL);
+               wt_status_collect_untracked(s);
+               gettimeofday(&tv2, NULL);
+               s->untracked_in_ms =
+                       (uint64_t)tv2.tv_sec * 1000 + tv2.tv_usec / 1000 -
+                       ((uint64_t)tv1.tv_sec * 1000 + tv1.tv_usec / 1000);
+       } else
+               wt_status_collect_untracked(s);
 }
 
 static void wt_status_print_unmerged(struct wt_status *s)
@@ -1097,6 +1106,15 @@ void wt_status_print(struct wt_status *s)
                wt_status_print_other(s, &s->untracked, _("Untracked files"), 
"add");
                if (s->show_ignored_files)
                        wt_status_print_other(s, &s->ignored, _("Ignored 
files"), "add -f");
+               if (advice_status_uno && s->untracked_in_ms > 2000) {
+                       status_printf_ln(s, GIT_COLOR_NORMAL,
+                                        _("It took %.2f seconds to collect 
untracked files."),
+                                        (float)s->untracked_in_ms / 1000);
+                       status_printf_ln(s, GIT_COLOR_NORMAL,
+                                        _("If it happens often, you may want 
to use option -uno"));
+                       status_printf_ln(s, GIT_COLOR_NORMAL,
+                                        _("to speed up by stopping displaying 
untracked files"));
+               }
        } else if (s->commitable)
                status_printf_ln(s, GIT_COLOR_NORMAL, _("Untracked files not 
listed%s"),
                        advice_status_hints
diff --git a/wt-status.h b/wt-status.h
index 81e1dcf..74208c0 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -69,6 +69,7 @@ struct wt_status {
        struct string_list change;
        struct string_list untracked;
        struct string_list ignored;
+       uint32_t untracked_in_ms;
 };
 
 struct wt_status_state {
-- 
1.8.1.2.536.gf441e6d

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to