]> git.ipfire.org Git - thirdparty/git.git/commitdiff
status: add --[no-]ahead-behind to status and commit for V2 format.
authorJeff Hostetler <jeffhost@microsoft.com>
Tue, 9 Jan 2018 18:50:16 +0000 (18:50 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 24 Jan 2018 21:48:38 +0000 (13:48 -0800)
Teach "git status" and "git commit" to accept "--no-ahead-behind"
and "--ahead-behind" arguments to request quick or full ahead/behind
reporting.

When "--no-ahead-behind" is given, the existing porcelain V2 line
"branch.ab +x -y" is replaced with a new "branch.ab +? -?" line.
This indicates that the branch and its upstream are or are not equal
without the expense of computing the full ahead/behind values.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-status.txt
builtin/commit.c
remote.c
remote.h
t/t7064-wtstatus-pv2.sh
wt-status.c
wt-status.h

index 81cab9aefb014690d93f9602ebebc9058c3d168e..b6ec10bf32769ce63de9ff3c93b2cc097ad0e0fb 100644 (file)
@@ -130,6 +130,11 @@ ignored, then the directory is not shown, but all contents are shown.
        without options are equivalent to 'always' and 'never'
        respectively.
 
+--ahead-behind::
+--no-ahead-behind::
+       Display or do not display detailed ahead/behind counts for the
+       branch relative to its upstream branch.  Defaults to true.
+
 <pathspec>...::
        See the 'pathspec' entry in linkgit:gitglossary[7].
 
index 8a877014145435516930c787dec37b8c4ac3da90..bfcb88f2915e12fd10b1ed5e53f2aa904e66780e 100644 (file)
@@ -1151,6 +1151,9 @@ 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 (s->ahead_behind_flags == AHEAD_BEHIND_UNSPECIFIED)
+               s->ahead_behind_flags = AHEAD_BEHIND_FULL;
 }
 
 static int parse_and_validate_options(int argc, const char *argv[],
@@ -1365,6 +1368,8 @@ int cmd_status(int argc, const char **argv, const char *prefix)
                         N_("show branch information")),
                OPT_BOOL(0, "show-stash", &s.show_stash,
                         N_("show stash information")),
+               OPT_BOOL(0, "ahead-behind", &s.ahead_behind_flags,
+                        N_("compute full ahead/behind values")),
                { OPTION_CALLBACK, 0, "porcelain", &status_format,
                  N_("version"), N_("machine-readable output"),
                  PARSE_OPT_OPTARG, opt_parse_porcelain },
@@ -1648,6 +1653,8 @@ 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, "ahead-behind", &s.ahead_behind_flags,
+                        N_("compute full ahead/behind values")),
                OPT_SET_INT(0, "porcelain", &status_format,
                            N_("machine-readable output"), STATUS_FORMAT_PORCELAIN),
                OPT_SET_INT(0, "long", &status_format,
index 29d47a5852b3d732b27da6260c7ffe3185aa23c1..e514536afe5d7962ec41b5c68f3653a768bca810 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -2058,6 +2058,8 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
                return 0;
        if (abf == AHEAD_BEHIND_QUICK)
                return 1;
+       if (abf != AHEAD_BEHIND_FULL)
+               BUG("stat_tracking_info: invalid abf '%d'", abf);
 
        /* Run "rev-list --left-right ours...theirs" internally... */
        argv_array_push(&argv, ""); /* ignored */
index 80240f0ada6176d1370cc4ae7f3e4a753fb7efe7..0a6e770c9ebaa85a8d400924c644a76eb87f04ee 100644 (file)
--- a/remote.h
+++ b/remote.h
@@ -259,8 +259,9 @@ enum match_refs_flags {
 
 /* Flags for --ahead-behind option. */
 enum ahead_behind_flags {
-       AHEAD_BEHIND_QUICK = 0,  /* just eq/neq reporting */
-       AHEAD_BEHIND_FULL  = 1,  /* traditional a/b reporting */
+       AHEAD_BEHIND_UNSPECIFIED = -1,
+       AHEAD_BEHIND_QUICK       =  0,  /* just eq/neq reporting */
+       AHEAD_BEHIND_FULL        =  1,  /* traditional a/b reporting */
 };
 
 /* Reporting of tracking info */
index e319fa2e8470791340a479989a81d934b79405da..8f795327a00f6c1b751b82e7e395c8387543d388 100755 (executable)
@@ -390,6 +390,68 @@ test_expect_success 'verify upstream fields in branch header' '
        )
 '
 
+test_expect_success 'verify --[no-]ahead-behind with V2 format' '
+       git checkout master &&
+       test_when_finished "rm -rf sub_repo" &&
+       git clone . sub_repo &&
+       (
+               ## Confirm local master tracks remote master.
+               cd sub_repo &&
+               HUF=$(git rev-parse HEAD) &&
+
+               # Confirm --no-ahead-behind reports traditional branch.ab with 0/0 for equal branches.
+               cat >expect <<-EOF &&
+               # branch.oid $HUF
+               # branch.head master
+               # branch.upstream origin/master
+               # branch.ab +0 -0
+               EOF
+
+               git status --no-ahead-behind --porcelain=v2 --branch --untracked-files=all >actual &&
+               test_cmp expect actual &&
+
+               # Confirm --ahead-behind reports traditional branch.ab with 0/0.
+               cat >expect <<-EOF &&
+               # branch.oid $HUF
+               # branch.head master
+               # branch.upstream origin/master
+               # branch.ab +0 -0
+               EOF
+
+               git status --ahead-behind --porcelain=v2 --branch --untracked-files=all >actual &&
+               test_cmp expect actual &&
+
+               ## Test non-equal ahead/behind.
+               echo xyz >file_xyz &&
+               git add file_xyz &&
+               git commit -m xyz &&
+
+               HUF=$(git rev-parse HEAD) &&
+
+               # Confirm --no-ahead-behind reports branch.ab with ?/? for non-equal branches.
+               cat >expect <<-EOF &&
+               # branch.oid $HUF
+               # branch.head master
+               # branch.upstream origin/master
+               # branch.ab +? -?
+               EOF
+
+               git status --no-ahead-behind --porcelain=v2 --branch --untracked-files=all >actual &&
+               test_cmp expect actual &&
+
+               # Confirm --ahead-behind reports traditional branch.ab with 1/0.
+               cat >expect <<-EOF &&
+               # branch.oid $HUF
+               # branch.head master
+               # branch.upstream origin/master
+               # branch.ab +1 -0
+               EOF
+
+               git status --ahead-behind --porcelain=v2 --branch --untracked-files=all >actual &&
+               test_cmp expect actual
+       )
+'
+
 test_expect_success 'create and add submodule, submodule appears clean (A. S...)' '
        git checkout master &&
        git clone . sub_repo &&
index 1137f27aa6c5c49ce8935b39f3b3799fbcaf9b37..7a560c16a7861197a5baad51d07086993fffcc43 100644 (file)
@@ -136,6 +136,7 @@ void wt_status_prepare(struct wt_status *s)
        s->ignored.strdup_strings = 1;
        s->show_branch = -1;  /* unspecified */
        s->show_stash = 0;
+       s->ahead_behind_flags = AHEAD_BEHIND_UNSPECIFIED;
        s->display_comment_prefix = 0;
 }
 
@@ -1883,18 +1884,19 @@ static void wt_porcelain_print(struct wt_status *s)
  *
  *    <upstream> ::= the upstream branch name, when set.
  *
- *       <ahead> ::= integer ahead value, when upstream set
- *                   and the commit is present (not gone).
- *
- *      <behind> ::= integer behind value, when upstream set
- *                   and commit is present.
+ *       <ahead> ::= integer ahead value or '?'.
  *
+ *      <behind> ::= integer behind value or '?'.
  *
  * The end-of-line is defined by the -z flag.
  *
  *                 <eol> ::= NUL when -z,
  *                           LF when NOT -z.
  *
+ * When an upstream is set and present, the 'branch.ab' line will
+ * be printed with the ahead/behind counts for the branch and the
+ * upstream.  When AHEAD_BEHIND_QUICK is requested and the branches
+ * are different, '?' will be substituted for the actual count.
  */
 static void wt_porcelain_v2_print_tracking(struct wt_status *s)
 {
@@ -1934,15 +1936,25 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
                /* Lookup stats on the upstream tracking branch, if set. */
                branch = branch_get(branch_name);
                base = NULL;
-               ab_info = (stat_tracking_info(branch, &nr_ahead, &nr_behind,
-                                             &base, AHEAD_BEHIND_FULL) >= 0);
+               ab_info = stat_tracking_info(branch, &nr_ahead, &nr_behind,
+                                            &base, s->ahead_behind_flags);
                if (base) {
                        base = shorten_unambiguous_ref(base, 0);
                        fprintf(s->fp, "# branch.upstream %s%c", base, eol);
                        free((char *)base);
 
-                       if (ab_info)
-                               fprintf(s->fp, "# branch.ab +%d -%d%c", nr_ahead, nr_behind, eol);
+                       if (ab_info > 0) {
+                               /* different */
+                               if (nr_ahead || nr_behind)
+                                       fprintf(s->fp, "# branch.ab +%d -%d%c",
+                                               nr_ahead, nr_behind, eol);
+                               else
+                                       fprintf(s->fp, "# branch.ab +? -?%c",
+                                               eol);
+                       } else if (!ab_info) {
+                               /* same */
+                               fprintf(s->fp, "# branch.ab +0 -0%c", eol);
+                       }
                }
        }
 
index fe27b465e220bb720dfd0b4d52ddeae74a942707..b91267455b9b9aa0b4673ce7c6206166a9abc885 100644 (file)
@@ -5,6 +5,7 @@
 #include "string-list.h"
 #include "color.h"
 #include "pathspec.h"
+#include "remote.h"
 
 struct worktree;
 
@@ -86,6 +87,7 @@ struct wt_status {
        int show_branch;
        int show_stash;
        int hints;
+       enum ahead_behind_flags ahead_behind_flags;
 
        enum wt_status_format status_format;
        unsigned char sha1_commit[GIT_MAX_RAWSZ]; /* when not Initial */