status: warn when a/b calculation takes too long
[gitweb.git] / wt-status.c
index f4fa98263857015b3d86e05df42e59591e74109a..d4e45f9e6a94d6d59536f5e9e29f3bc238733e63 100644 (file)
@@ -17,6 +17,9 @@
 #include "utf8.h"
 #include "worktree.h"
 #include "lockfile.h"
+#include "sequencer.h"
+
+#define AB_DELAY_WARNING_IN_MS (2 * 1000)
 
 static const char cut_line[] =
 "------------------------ >8 ------------------------\n";
@@ -1084,14 +1087,29 @@ static void wt_longstatus_print_tracking(struct wt_status *s)
        struct branch *branch;
        char comment_line_string[3];
        int i;
+       uint64_t t_begin = 0;
 
        assert(s->branch && !s->is_initial);
        if (!skip_prefix(s->branch, "refs/heads/", &branch_name))
                return;
        branch = branch_get(branch_name);
+
+       t_begin = getnanotime();
+
        if (!format_tracking_info(branch, &sb, s->ahead_behind_flags))
                return;
 
+       if (advice_status_ahead_behind_warning &&
+           s->ahead_behind_flags == AHEAD_BEHIND_FULL) {
+               uint64_t t_delta_in_ms = (getnanotime() - t_begin) / 1000000;
+               if (t_delta_in_ms > AB_DELAY_WARNING_IN_MS) {
+                       strbuf_addf(&sb, _("\n"
+                                          "It took %.2f seconds to compute the branch ahead/behind values.\n"
+                                          "You can use '--no-ahead-behind' to avoid this.\n"),
+                                   t_delta_in_ms / 1000.0);
+               }
+       }
+
        i = 0;
        if (s->display_comment_prefix) {
                comment_line_string[i++] = comment_line_char;
@@ -1214,7 +1232,9 @@ static void abbrev_sha1_in_line(struct strbuf *line)
        int i;
 
        if (starts_with(line->buf, "exec ") ||
-           starts_with(line->buf, "x "))
+           starts_with(line->buf, "x ") ||
+           starts_with(line->buf, "label ") ||
+           starts_with(line->buf, "l "))
                return;
 
        split = strbuf_split_max(line, ' ', 3);
@@ -1386,12 +1406,22 @@ static void show_rebase_in_progress(struct wt_status *s,
 static void show_cherry_pick_in_progress(struct wt_status *s,
                                         const char *color)
 {
-       status_printf_ln(s, color, _("You are currently cherry-picking commit %s."),
-                       find_unique_abbrev(&s->state.cherry_pick_head_oid, DEFAULT_ABBREV));
+       if (is_null_oid(&s->state.cherry_pick_head_oid))
+               status_printf_ln(s, color,
+                       _("Cherry-pick currently in progress."));
+       else
+               status_printf_ln(s, color,
+                       _("You are currently cherry-picking commit %s."),
+                       find_unique_abbrev(&s->state.cherry_pick_head_oid,
+                                          DEFAULT_ABBREV));
+
        if (s->hints) {
                if (has_unmerged(s))
                        status_printf_ln(s, color,
                                _("  (fix conflicts and run \"git cherry-pick --continue\")"));
+               else if (is_null_oid(&s->state.cherry_pick_head_oid))
+                       status_printf_ln(s, color,
+                               _("  (run \"git cherry-pick --continue\" to continue)"));
                else
                        status_printf_ln(s, color,
                                _("  (all conflicts fixed: run \"git cherry-pick --continue\")"));
@@ -1404,12 +1434,21 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
 static void show_revert_in_progress(struct wt_status *s,
                                    const char *color)
 {
-       status_printf_ln(s, color, _("You are currently reverting commit %s."),
-                        find_unique_abbrev(&s->state.revert_head_oid, DEFAULT_ABBREV));
+       if (is_null_oid(&s->state.revert_head_oid))
+               status_printf_ln(s, color,
+                       _("Revert currently in progress."));
+       else
+               status_printf_ln(s, color,
+                       _("You are currently reverting commit %s."),
+                       find_unique_abbrev(&s->state.revert_head_oid,
+                                          DEFAULT_ABBREV));
        if (s->hints) {
                if (has_unmerged(s))
                        status_printf_ln(s, color,
                                _("  (fix conflicts and run \"git revert --continue\")"));
+               else if (is_null_oid(&s->state.revert_head_oid))
+                       status_printf_ln(s, color,
+                               _("  (run \"git revert --continue\" to continue)"));
                else
                        status_printf_ln(s, color,
                                _("  (all conflicts fixed: run \"git revert --continue\")"));
@@ -1580,6 +1619,7 @@ void wt_status_get_state(struct repository *r,
 {
        struct stat st;
        struct object_id oid;
+       enum replay_action action;
 
        if (!stat(git_path_merge_head(r), &st)) {
                wt_status_check_rebase(NULL, state);
@@ -1597,7 +1637,15 @@ void wt_status_get_state(struct repository *r,
                state->revert_in_progress = 1;
                oidcpy(&state->revert_head_oid, &oid);
        }
-
+       if (!sequencer_get_last_command(r, &action)) {
+               if (action == REPLAY_PICK) {
+                       state->cherry_pick_in_progress = 1;
+                       oidcpy(&state->cherry_pick_head_oid, &null_oid);
+               } else {
+                       state->revert_in_progress = 1;
+                       oidcpy(&state->revert_head_oid, &null_oid);
+               }
+       }
        if (get_detached_from)
                wt_status_get_detached_from(r, state);
 }
@@ -2045,9 +2093,7 @@ static void wt_porcelain_v2_submodule_state(
 /*
  * Fix-up changed entries before we print them.
  */
-static void wt_porcelain_v2_fix_up_changed(
-       struct string_list_item *it,
-       struct wt_status *s)
+static void wt_porcelain_v2_fix_up_changed(struct string_list_item *it)
 {
        struct wt_status_change_data *d = it->util;
 
@@ -2107,7 +2153,7 @@ static void wt_porcelain_v2_print_changed_entry(
        char submodule_token[5];
        char sep_char, eol_char;
 
-       wt_porcelain_v2_fix_up_changed(it, s);
+       wt_porcelain_v2_fix_up_changed(it);
        wt_porcelain_v2_submodule_state(d, submodule_token);
 
        key[0] = d->index_status ? d->index_status : '.';