Ordinary (long) status shows information about bisect, revert, am,
rebase, cherry-pick in progress, and so does git-prompt.sh. status
--short currently shows none of this information.

Introduce an `--inprogress` argument to git status so that, when used with
`--short --branch`, in-progress information is shown next to the branch
information. Just like `--branch`, this comes with a config option.

The wording for the in-progress information is taken over from
git-prompt.sh.

Signed-off-by: Michael J Gruber <g...@grubix.eu>
---
When used with --porcelain, this gives an easy way to amend the 
powerline-gitstatus
prompt for example (in use locally here), and certainly others.

I don't touch --porcelain=v2 - that one reads in-progress state but does not 
seem
to display it. I don't know which parts are supposed to be stable for v2. 

 Documentation/config.txt     |  4 +++
 Documentation/git-status.txt |  5 ++++
 builtin/commit.c             | 13 ++++++++++
 t/t7512-status-help.sh       | 58 ++++++++++++++++++++++++++++++++++++++++----
 wt-status.c                  | 32 +++++++++++++++++++++---
 wt-status.h                  |  1 +
 6 files changed, 105 insertions(+), 8 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 475e874d51..3adc65f9d3 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2957,6 +2957,10 @@ status.branch::
        Set to true to enable --branch by default in linkgit:git-status[1].
        The option --no-branch takes precedence over this variable.
 
+status.inprogress::
+       Set to true to enable --inprogress by default in linkgit:git-status[1].
+       The option --no-inprogress takes precedence over this variable.
+
 status.displayCommentPrefix::
        If set to true, linkgit:git-status[1] will insert a comment
        prefix before each output line (starting with
diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt
index ba873657cf..4fac073247 100644
--- a/Documentation/git-status.txt
+++ b/Documentation/git-status.txt
@@ -32,6 +32,11 @@ OPTIONS
 --branch::
        Show the branch and tracking info even in short-format.
 
+-p::
+--inprogress::
+       When showing branch and tracking info in short-format,
+       show in-progress information (BISECTING, MERGING etc.), too.
+
 --porcelain[=<version>]::
        Give the output in an easy-to-parse format for scripts.
        This is similar to the short output, but will remain stable
diff --git a/builtin/commit.c b/builtin/commit.c
index 4e288bc513..6176dd2c2f 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1105,8 +1105,10 @@ static const char *read_commit_message(const char *name)
 static struct status_deferred_config {
        enum wt_status_format status_format;
        int show_branch;
+       int show_inprogress;
 } status_deferred_config = {
        STATUS_FORMAT_UNSPECIFIED,
+       -1, /* unspecified */
        -1 /* unspecified */
 };
 
@@ -1133,6 +1135,10 @@ static void finalize_deferred_config(struct wt_status *s)
                s->show_branch = status_deferred_config.show_branch;
        if (s->show_branch < 0)
                s->show_branch = 0;
+       if (use_deferred_config && s->show_inprogress < 0)
+               s->show_inprogress = status_deferred_config.show_inprogress;
+       if (s->show_inprogress < 0)
+               s->show_inprogress = 0;
 }
 
 static int parse_and_validate_options(int argc, const char *argv[],
@@ -1291,6 +1297,10 @@ static int git_status_config(const char *k, const char 
*v, void *cb)
                status_deferred_config.show_branch = git_config_bool(k, v);
                return 0;
        }
+       if (!strcmp(k, "status.inprogress")) {
+               status_deferred_config.show_inprogress = git_config_bool(k, v);
+               return 0;
+       }
        if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
                s->use_color = git_config_colorbool(k, v);
                return 0;
@@ -1339,6 +1349,8 @@ int cmd_status(int argc, const char **argv, const char 
*prefix)
                            N_("show status concisely"), STATUS_FORMAT_SHORT),
                OPT_BOOL('b', "branch", &s.show_branch,
                         N_("show branch information")),
+               OPT_BOOL('p', "inprogress", &s.show_inprogress,
+                        N_("show in-progress information")),
                { OPTION_CALLBACK, 0, "porcelain", &status_format,
                  N_("version"), N_("machine-readable output"),
                  PARSE_OPT_OPTARG, opt_parse_porcelain },
@@ -1612,6 +1624,7 @@ int cmd_commit(int argc, const char **argv, const char 
*prefix)
                OPT_SET_INT(0, "short", &status_format, N_("show status 
concisely"),
                            STATUS_FORMAT_SHORT),
                OPT_BOOL(0, "branch", &s.show_branch, N_("show branch 
information")),
+               OPT_BOOL(0, "inprogress", &s.show_inprogress, N_("show 
in-progress information")),
                OPT_SET_INT(0, "porcelain", &status_format,
                            N_("machine-readable output"), 
STATUS_FORMAT_PORCELAIN),
                OPT_SET_INT(0, "long", &status_format,
diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index 458608cc1e..103e006249 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -74,7 +74,6 @@ test_expect_success 'prepare for rebase conflicts' '
 
 
 test_expect_success 'status when rebase in progress before resolving 
conflicts' '
-       test_when_finished "git rebase --abort" &&
        ONTO=$(git rev-parse --short HEAD^^) &&
        test_must_fail git rebase HEAD^ --onto HEAD^^ &&
        cat >expected <<EOF &&
@@ -96,6 +95,15 @@ EOF
        test_i18ncmp expected actual
 '
 
+test_expect_success 'short status when rebase in progress' '
+       test_when_finished "git rebase --abort" &&
+       cat >expected <<EOF &&
+## HEAD (no branch); REBASE-m
+UU main.txt
+EOF
+       git status --untracked-files=no --short --branch --inprogress >actual &&
+       test_i18ncmp expected actual
+'
 
 test_expect_success 'status when rebase in progress before rebase --continue' '
        git reset --hard rebase_conflicts &&
@@ -133,7 +141,6 @@ test_expect_success 'prepare for rebase_i_conflicts' '
 
 
 test_expect_success 'status during rebase -i when conflicts unresolved' '
-       test_when_finished "git rebase --abort" &&
        ONTO=$(git rev-parse --short rebase_i_conflicts) &&
        LAST_COMMIT=$(git rev-parse --short rebase_i_conflicts_second) &&
        test_must_fail git rebase -i rebase_i_conflicts &&
@@ -159,6 +166,16 @@ EOF
        test_i18ncmp expected actual
 '
 
+test_expect_success 'short status during rebase -i when conflicts unresolved' '
+       test_when_finished "git rebase --abort" &&
+       cat >expected <<EOF &&
+## HEAD (no branch); REBASE-i
+UU main.txt
+EOF
+       git status --untracked-files=no --short --branch --inprogress >actual &&
+       test_i18ncmp expected actual
+'
+
 
 test_expect_success 'status during rebase -i after resolving conflicts' '
        git reset --hard rebase_i_conflicts_second &&
@@ -613,7 +630,6 @@ test_expect_success 'prepare am_session' '
 
 test_expect_success 'status in an am session: file already exists' '
        git checkout -b am_already_exists &&
-       test_when_finished "rm Maildir/* && git am --abort" &&
        git format-patch -1 -oMaildir &&
        test_must_fail git am Maildir/*.patch &&
        cat >expected <<\EOF &&
@@ -629,6 +645,14 @@ EOF
        test_i18ncmp expected actual
 '
 
+test_expect_success 'short status in an am session: file already exists' '
+       test_when_finished "rm Maildir/* && git am --abort" &&
+       cat >expected <<\EOF &&
+## am_already_exists; AM
+EOF
+       git status --untracked-files=no --short --branch --inprogress >actual &&
+       test_i18ncmp expected actual
+'
 
 test_expect_success 'status in an am session: file does not exist' '
        git reset --hard am_session &&
@@ -681,7 +705,6 @@ test_expect_success 'status when bisecting' '
        test_commit one_bisect main.txt one &&
        test_commit two_bisect main.txt two &&
        test_commit three_bisect main.txt three &&
-       test_when_finished "git bisect reset" &&
        git bisect start &&
        git bisect bad &&
        git bisect good one_bisect &&
@@ -697,6 +720,14 @@ EOF
        test_i18ncmp expected actual
 '
 
+test_expect_success 'short status when bisecting' '
+       test_when_finished "git bisect reset" &&
+       cat >expected <<EOF &&
+## HEAD (no branch); BISECTING
+EOF
+       git status --untracked-files=no --short --branch --inprogress >actual &&
+       test_i18ncmp expected actual
+'
 
 test_expect_success 'status when rebase conflicts with statushints disabled' '
        git reset --hard master &&
@@ -736,7 +767,6 @@ test_expect_success 'prepare for cherry-pick conflicts' '
 
 
 test_expect_success 'status when cherry-picking before resolving conflicts' '
-       test_when_finished "git cherry-pick --abort" &&
        test_must_fail git cherry-pick cherry_branch_second &&
        TO_CHERRY_PICK=$(git rev-parse --short CHERRY_PICK_HEAD) &&
        cat >expected <<EOF &&
@@ -756,6 +786,15 @@ EOF
        test_i18ncmp expected actual
 '
 
+test_expect_success 'short status when cherry-picking before resolving 
conflicts' '
+       test_when_finished "git cherry-pick --abort" &&
+       cat >expected <<EOF &&
+## cherry_branch; CHERRY-PICKING
+UU main.txt
+EOF
+       git status --untracked-files=no --short --branch --inprogress >actual &&
+       test_i18ncmp expected actual
+'
 
 test_expect_success 'status when cherry-picking after resolving conflicts' '
        git reset --hard cherry_branch &&
@@ -827,6 +866,15 @@ EOF
        test_i18ncmp expected actual
 '
 
+test_expect_success 'short status while reverting commit (conflicts)' '
+       cat >expected <<EOF &&
+## master; REVERTING
+UU to-revert.txt
+EOF
+       git status --untracked-files=no --short --branch --inprogress >actual &&
+       test_i18ncmp expected actual
+'
+
 test_expect_success 'status while reverting commit (conflicts resolved)' '
        echo reverted >to-revert.txt &&
        git add to-revert.txt &&
diff --git a/wt-status.c b/wt-status.c
index 308cf3779e..f4606d27c8 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1715,6 +1715,7 @@ static void wt_shortstatus_other(struct string_list_item 
*it,
 static void wt_shortstatus_print_tracking(struct wt_status *s)
 {
        struct branch *branch;
+       struct wt_status_state state;
        const char *header_color = color(WT_STATUS_HEADER, s);
        const char *branch_color_local = color(WT_STATUS_LOCAL_BRANCH, s);
        const char *branch_color_remote = color(WT_STATUS_REMOTE_BRANCH, s);
@@ -1738,7 +1739,7 @@ static void wt_shortstatus_print_tracking(struct 
wt_status *s)
        if (!strcmp(s->branch, "HEAD")) {
                color_fprintf(s->fp, color(WT_STATUS_NOBRANCH, s), "%s",
                              LABEL(N_("HEAD (no branch)")));
-               goto conclude;
+               goto inprogress;
        }
 
        skip_prefix(branch_name, "refs/heads/", &branch_name);
@@ -1749,7 +1750,7 @@ static void wt_shortstatus_print_tracking(struct 
wt_status *s)
 
        if (stat_tracking_info(branch, &num_ours, &num_theirs, &base) < 0) {
                if (!base)
-                       goto conclude;
+                       goto inprogress;
 
                upstream_is_gone = 1;
        }
@@ -1760,7 +1761,7 @@ static void wt_shortstatus_print_tracking(struct 
wt_status *s)
        free((char *)base);
 
        if (!upstream_is_gone && !num_ours && !num_theirs)
-               goto conclude;
+               goto inprogress;
 
        color_fprintf(s->fp, header_color, " [");
        if (upstream_is_gone) {
@@ -1779,6 +1780,31 @@ static void wt_shortstatus_print_tracking(struct 
wt_status *s)
        }
 
        color_fprintf(s->fp, header_color, "]");
+
+ inprogress:
+       if (!s->show_inprogress)
+               goto conclude;
+       memset(&state, 0, sizeof(state));
+       wt_status_get_state(&state,
+                           s->branch && !strcmp(s->branch, "HEAD"));
+       if (state.merge_in_progress)
+               color_fprintf(s->fp, header_color, "; %s", 
LABEL(N_("MERGING")));
+       else if (state.am_in_progress)
+               color_fprintf(s->fp, header_color, "; %s", LABEL(N_("AM")));
+       else if (state.rebase_in_progress)
+               color_fprintf(s->fp, header_color, "; %s", 
LABEL(N_("REBASE-m")));
+       else if (state.rebase_interactive_in_progress)
+               color_fprintf(s->fp, header_color, "; %s", 
LABEL(N_("REBASE-i")));
+       else if (state.cherry_pick_in_progress)
+               color_fprintf(s->fp, header_color, "; %s", 
LABEL(N_("CHERRY-PICKING")));
+       else if (state.revert_in_progress)
+               color_fprintf(s->fp, header_color, "; %s", 
LABEL(N_("REVERTING")));
+       if (state.bisect_in_progress)
+               color_fprintf(s->fp, header_color, "; %s", 
LABEL(N_("BISECTING")));
+       free(state.branch);
+       free(state.onto);
+       free(state.detached_from);
+
  conclude:
        fputc(s->null_termination ? '\0' : '\n', s->fp);
 }
diff --git a/wt-status.h b/wt-status.h
index 54fec77032..8f6c9e0e62 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -77,6 +77,7 @@ struct wt_status {
        unsigned colopts;
        int null_termination;
        int show_branch;
+       int show_inprogress;
        int hints;
 
        enum wt_status_format status_format;
-- 
2.12.2.739.gfc3eb97820

Reply via email to