Merge branch 'jh/status-no-ahead-behind'
"git status" can spend a lot of cycles to compute the relation between the current branch and its upstream, which can now be disabled with "--no-ahead-behind" option. * jh/status-no-ahead-behind: status: support --no-ahead-behind in long format status: update short status to respect --no-ahead-behind status: add --[no-]ahead-behind to status and commit for V2 format. stat_tracking_info: return +1 when branches not equal
This commit is contained in:
commit
4094e47fd2
@ -130,6 +130,11 @@ ignored, then the directory is not shown, but all contents are shown.
|
|||||||
without options are equivalent to 'always' and 'never'
|
without options are equivalent to 'always' and 'never'
|
||||||
respectively.
|
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>...::
|
<pathspec>...::
|
||||||
See the 'pathspec' entry in linkgit:gitglossary[7].
|
See the 'pathspec' entry in linkgit:gitglossary[7].
|
||||||
|
|
||||||
|
@ -609,7 +609,7 @@ static void report_tracking(struct branch_info *new_branch_info)
|
|||||||
struct strbuf sb = STRBUF_INIT;
|
struct strbuf sb = STRBUF_INIT;
|
||||||
struct branch *branch = branch_get(new_branch_info->name);
|
struct branch *branch = branch_get(new_branch_info->name);
|
||||||
|
|
||||||
if (!format_tracking_info(branch, &sb))
|
if (!format_tracking_info(branch, &sb, AHEAD_BEHIND_FULL))
|
||||||
return;
|
return;
|
||||||
fputs(sb.buf, stdout);
|
fputs(sb.buf, stdout);
|
||||||
strbuf_release(&sb);
|
strbuf_release(&sb);
|
||||||
|
@ -1061,6 +1061,9 @@ static void finalize_deferred_config(struct wt_status *s)
|
|||||||
s->show_branch = status_deferred_config.show_branch;
|
s->show_branch = status_deferred_config.show_branch;
|
||||||
if (s->show_branch < 0)
|
if (s->show_branch < 0)
|
||||||
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[],
|
static int parse_and_validate_options(int argc, const char *argv[],
|
||||||
@ -1277,6 +1280,8 @@ int cmd_status(int argc, const char **argv, const char *prefix)
|
|||||||
N_("show branch information")),
|
N_("show branch information")),
|
||||||
OPT_BOOL(0, "show-stash", &s.show_stash,
|
OPT_BOOL(0, "show-stash", &s.show_stash,
|
||||||
N_("show stash information")),
|
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,
|
{ OPTION_CALLBACK, 0, "porcelain", &status_format,
|
||||||
N_("version"), N_("machine-readable output"),
|
N_("version"), N_("machine-readable output"),
|
||||||
PARSE_OPT_OPTARG, opt_parse_porcelain },
|
PARSE_OPT_OPTARG, opt_parse_porcelain },
|
||||||
@ -1437,6 +1442,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
|||||||
OPT_SET_INT(0, "short", &status_format, N_("show status concisely"),
|
OPT_SET_INT(0, "short", &status_format, N_("show status concisely"),
|
||||||
STATUS_FORMAT_SHORT),
|
STATUS_FORMAT_SHORT),
|
||||||
OPT_BOOL(0, "branch", &s.show_branch, N_("show branch information")),
|
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,
|
OPT_SET_INT(0, "porcelain", &status_format,
|
||||||
N_("machine-readable output"), STATUS_FORMAT_PORCELAIN),
|
N_("machine-readable output"), STATUS_FORMAT_PORCELAIN),
|
||||||
OPT_SET_INT(0, "long", &status_format,
|
OPT_SET_INT(0, "long", &status_format,
|
||||||
|
@ -1249,8 +1249,8 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
|
|||||||
if (atom->u.remote_ref.option == RR_REF)
|
if (atom->u.remote_ref.option == RR_REF)
|
||||||
*s = show_ref(&atom->u.remote_ref.refname, refname);
|
*s = show_ref(&atom->u.remote_ref.refname, refname);
|
||||||
else if (atom->u.remote_ref.option == RR_TRACK) {
|
else if (atom->u.remote_ref.option == RR_TRACK) {
|
||||||
if (stat_tracking_info(branch, &num_ours,
|
if (stat_tracking_info(branch, &num_ours, &num_theirs,
|
||||||
&num_theirs, NULL)) {
|
NULL, AHEAD_BEHIND_FULL) < 0) {
|
||||||
*s = xstrdup(msgs.gone);
|
*s = xstrdup(msgs.gone);
|
||||||
} else if (!num_ours && !num_theirs)
|
} else if (!num_ours && !num_theirs)
|
||||||
*s = "";
|
*s = "";
|
||||||
@ -1267,8 +1267,8 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
|
|||||||
free((void *)to_free);
|
free((void *)to_free);
|
||||||
}
|
}
|
||||||
} else if (atom->u.remote_ref.option == RR_TRACKSHORT) {
|
} else if (atom->u.remote_ref.option == RR_TRACKSHORT) {
|
||||||
if (stat_tracking_info(branch, &num_ours,
|
if (stat_tracking_info(branch, &num_ours, &num_theirs,
|
||||||
&num_theirs, NULL))
|
NULL, AHEAD_BEHIND_FULL) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!num_ours && !num_theirs)
|
if (!num_ours && !num_theirs)
|
||||||
|
50
remote.c
50
remote.c
@ -2022,16 +2022,23 @@ int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compare a branch with its upstream, and save their differences (number
|
* Lookup the upstream branch for the given branch and if present, optionally
|
||||||
* of commits) in *num_ours and *num_theirs. The name of the upstream branch
|
* compute the commit ahead/behind values for the pair.
|
||||||
* (or NULL if no upstream is defined) is returned via *upstream_name, if it
|
*
|
||||||
* is not itself NULL.
|
* If abf is AHEAD_BEHIND_FULL, compute the full ahead/behind and return the
|
||||||
|
* counts in *num_ours and *num_theirs. If abf is AHEAD_BEHIND_QUICK, skip
|
||||||
|
* the (potentially expensive) a/b computation (*num_ours and *num_theirs are
|
||||||
|
* set to zero).
|
||||||
|
*
|
||||||
|
* The name of the upstream branch (or NULL if no upstream is defined) is
|
||||||
|
* returned via *upstream_name, if it is not itself NULL.
|
||||||
*
|
*
|
||||||
* Returns -1 if num_ours and num_theirs could not be filled in (e.g., no
|
* Returns -1 if num_ours and num_theirs could not be filled in (e.g., no
|
||||||
* upstream defined, or ref does not exist), 0 otherwise.
|
* upstream defined, or ref does not exist). Returns 0 if the commits are
|
||||||
|
* identical. Returns 1 if commits are different.
|
||||||
*/
|
*/
|
||||||
int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
|
int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
|
||||||
const char **upstream_name)
|
const char **upstream_name, enum ahead_behind_flags abf)
|
||||||
{
|
{
|
||||||
struct object_id oid;
|
struct object_id oid;
|
||||||
struct commit *ours, *theirs;
|
struct commit *ours, *theirs;
|
||||||
@ -2059,11 +2066,15 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
|
|||||||
if (!ours)
|
if (!ours)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
*num_theirs = *num_ours = 0;
|
||||||
|
|
||||||
/* are we the same? */
|
/* are we the same? */
|
||||||
if (theirs == ours) {
|
if (theirs == ours)
|
||||||
*num_theirs = *num_ours = 0;
|
|
||||||
return 0;
|
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... */
|
/* Run "rev-list --left-right ours...theirs" internally... */
|
||||||
argv_array_push(&argv, ""); /* ignored */
|
argv_array_push(&argv, ""); /* ignored */
|
||||||
@ -2079,8 +2090,6 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
|
|||||||
die("revision walk setup failed");
|
die("revision walk setup failed");
|
||||||
|
|
||||||
/* ... and count the commits on each side. */
|
/* ... and count the commits on each side. */
|
||||||
*num_ours = 0;
|
|
||||||
*num_theirs = 0;
|
|
||||||
while (1) {
|
while (1) {
|
||||||
struct commit *c = get_revision(&revs);
|
struct commit *c = get_revision(&revs);
|
||||||
if (!c)
|
if (!c)
|
||||||
@ -2096,20 +2105,22 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
|
|||||||
clear_commit_marks(theirs, ALL_REV_FLAGS);
|
clear_commit_marks(theirs, ALL_REV_FLAGS);
|
||||||
|
|
||||||
argv_array_clear(&argv);
|
argv_array_clear(&argv);
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return true when there is anything to report, otherwise false.
|
* Return true when there is anything to report, otherwise false.
|
||||||
*/
|
*/
|
||||||
int format_tracking_info(struct branch *branch, struct strbuf *sb)
|
int format_tracking_info(struct branch *branch, struct strbuf *sb,
|
||||||
|
enum ahead_behind_flags abf)
|
||||||
{
|
{
|
||||||
int ours, theirs;
|
int ours, theirs, sti;
|
||||||
const char *full_base;
|
const char *full_base;
|
||||||
char *base;
|
char *base;
|
||||||
int upstream_is_gone = 0;
|
int upstream_is_gone = 0;
|
||||||
|
|
||||||
if (stat_tracking_info(branch, &ours, &theirs, &full_base) < 0) {
|
sti = stat_tracking_info(branch, &ours, &theirs, &full_base, abf);
|
||||||
|
if (sti < 0) {
|
||||||
if (!full_base)
|
if (!full_base)
|
||||||
return 0;
|
return 0;
|
||||||
upstream_is_gone = 1;
|
upstream_is_gone = 1;
|
||||||
@ -2123,10 +2134,17 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb)
|
|||||||
if (advice_status_hints)
|
if (advice_status_hints)
|
||||||
strbuf_addstr(sb,
|
strbuf_addstr(sb,
|
||||||
_(" (use \"git branch --unset-upstream\" to fixup)\n"));
|
_(" (use \"git branch --unset-upstream\" to fixup)\n"));
|
||||||
} else if (!ours && !theirs) {
|
} else if (!sti) {
|
||||||
strbuf_addf(sb,
|
strbuf_addf(sb,
|
||||||
_("Your branch is up to date with '%s'.\n"),
|
_("Your branch is up to date with '%s'.\n"),
|
||||||
base);
|
base);
|
||||||
|
} else if (abf == AHEAD_BEHIND_QUICK) {
|
||||||
|
strbuf_addf(sb,
|
||||||
|
_("Your branch and '%s' refer to different commits.\n"),
|
||||||
|
base);
|
||||||
|
if (advice_status_hints)
|
||||||
|
strbuf_addf(sb, _(" (use \"%s\" for details)\n"),
|
||||||
|
"git status --ahead-behind");
|
||||||
} else if (!theirs) {
|
} else if (!theirs) {
|
||||||
strbuf_addf(sb,
|
strbuf_addf(sb,
|
||||||
Q_("Your branch is ahead of '%s' by %d commit.\n",
|
Q_("Your branch is ahead of '%s' by %d commit.\n",
|
||||||
|
12
remote.h
12
remote.h
@ -258,10 +258,18 @@ enum match_refs_flags {
|
|||||||
MATCH_REFS_FOLLOW_TAGS = (1 << 3)
|
MATCH_REFS_FOLLOW_TAGS = (1 << 3)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Flags for --ahead-behind option. */
|
||||||
|
enum ahead_behind_flags {
|
||||||
|
AHEAD_BEHIND_UNSPECIFIED = -1,
|
||||||
|
AHEAD_BEHIND_QUICK = 0, /* just eq/neq reporting */
|
||||||
|
AHEAD_BEHIND_FULL = 1, /* traditional a/b reporting */
|
||||||
|
};
|
||||||
|
|
||||||
/* Reporting of tracking info */
|
/* Reporting of tracking info */
|
||||||
int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
|
int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
|
||||||
const char **upstream_name);
|
const char **upstream_name, enum ahead_behind_flags abf);
|
||||||
int format_tracking_info(struct branch *branch, struct strbuf *sb);
|
int format_tracking_info(struct branch *branch, struct strbuf *sb,
|
||||||
|
enum ahead_behind_flags abf);
|
||||||
|
|
||||||
struct ref *get_local_heads(void);
|
struct ref *get_local_heads(void);
|
||||||
/*
|
/*
|
||||||
|
@ -146,6 +146,48 @@ test_expect_success 'status -s -b (diverged from upstream)' '
|
|||||||
test_i18ncmp expect actual
|
test_i18ncmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
cat >expect <<\EOF
|
||||||
|
## b1...origin/master [different]
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'status -s -b --no-ahead-behind (diverged from upstream)' '
|
||||||
|
(
|
||||||
|
cd test &&
|
||||||
|
git checkout b1 >/dev/null &&
|
||||||
|
git status -s -b --no-ahead-behind | head -1
|
||||||
|
) >actual &&
|
||||||
|
test_i18ncmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
cat >expect <<\EOF
|
||||||
|
On branch b1
|
||||||
|
Your branch and 'origin/master' have diverged,
|
||||||
|
and have 1 and 1 different commits each, respectively.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'status --long --branch' '
|
||||||
|
(
|
||||||
|
cd test &&
|
||||||
|
git checkout b1 >/dev/null &&
|
||||||
|
git status --long -b | head -3
|
||||||
|
) >actual &&
|
||||||
|
test_i18ncmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
cat >expect <<\EOF
|
||||||
|
On branch b1
|
||||||
|
Your branch and 'origin/master' refer to different commits.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'status --long --branch --no-ahead-behind' '
|
||||||
|
(
|
||||||
|
cd test &&
|
||||||
|
git checkout b1 >/dev/null &&
|
||||||
|
git status --long -b --no-ahead-behind | head -2
|
||||||
|
) >actual &&
|
||||||
|
test_i18ncmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
cat >expect <<\EOF
|
cat >expect <<\EOF
|
||||||
## b5...brokenbase [gone]
|
## b5...brokenbase [gone]
|
||||||
EOF
|
EOF
|
||||||
|
@ -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...)' '
|
test_expect_success 'create and add submodule, submodule appears clean (A. S...)' '
|
||||||
git checkout master &&
|
git checkout master &&
|
||||||
git clone . sub_repo &&
|
git clone . sub_repo &&
|
||||||
|
41
wt-status.c
41
wt-status.c
@ -136,6 +136,7 @@ void wt_status_prepare(struct wt_status *s)
|
|||||||
s->ignored.strdup_strings = 1;
|
s->ignored.strdup_strings = 1;
|
||||||
s->show_branch = -1; /* unspecified */
|
s->show_branch = -1; /* unspecified */
|
||||||
s->show_stash = 0;
|
s->show_stash = 0;
|
||||||
|
s->ahead_behind_flags = AHEAD_BEHIND_UNSPECIFIED;
|
||||||
s->display_comment_prefix = 0;
|
s->display_comment_prefix = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1032,7 +1033,7 @@ static void wt_longstatus_print_tracking(struct wt_status *s)
|
|||||||
if (!skip_prefix(s->branch, "refs/heads/", &branch_name))
|
if (!skip_prefix(s->branch, "refs/heads/", &branch_name))
|
||||||
return;
|
return;
|
||||||
branch = branch_get(branch_name);
|
branch = branch_get(branch_name);
|
||||||
if (!format_tracking_info(branch, &sb))
|
if (!format_tracking_info(branch, &sb, s->ahead_behind_flags))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -1793,7 +1794,7 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
|
|||||||
const char *base;
|
const char *base;
|
||||||
char *short_base;
|
char *short_base;
|
||||||
const char *branch_name;
|
const char *branch_name;
|
||||||
int num_ours, num_theirs;
|
int num_ours, num_theirs, sti;
|
||||||
int upstream_is_gone = 0;
|
int upstream_is_gone = 0;
|
||||||
|
|
||||||
color_fprintf(s->fp, color(WT_STATUS_HEADER, s), "## ");
|
color_fprintf(s->fp, color(WT_STATUS_HEADER, s), "## ");
|
||||||
@ -1819,7 +1820,9 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
|
|||||||
|
|
||||||
color_fprintf(s->fp, branch_color_local, "%s", branch_name);
|
color_fprintf(s->fp, branch_color_local, "%s", branch_name);
|
||||||
|
|
||||||
if (stat_tracking_info(branch, &num_ours, &num_theirs, &base) < 0) {
|
sti = stat_tracking_info(branch, &num_ours, &num_theirs, &base,
|
||||||
|
s->ahead_behind_flags);
|
||||||
|
if (sti < 0) {
|
||||||
if (!base)
|
if (!base)
|
||||||
goto conclude;
|
goto conclude;
|
||||||
|
|
||||||
@ -1831,12 +1834,14 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
|
|||||||
color_fprintf(s->fp, branch_color_remote, "%s", short_base);
|
color_fprintf(s->fp, branch_color_remote, "%s", short_base);
|
||||||
free(short_base);
|
free(short_base);
|
||||||
|
|
||||||
if (!upstream_is_gone && !num_ours && !num_theirs)
|
if (!upstream_is_gone && !sti)
|
||||||
goto conclude;
|
goto conclude;
|
||||||
|
|
||||||
color_fprintf(s->fp, header_color, " [");
|
color_fprintf(s->fp, header_color, " [");
|
||||||
if (upstream_is_gone) {
|
if (upstream_is_gone) {
|
||||||
color_fprintf(s->fp, header_color, LABEL(N_("gone")));
|
color_fprintf(s->fp, header_color, LABEL(N_("gone")));
|
||||||
|
} else if (s->ahead_behind_flags == AHEAD_BEHIND_QUICK) {
|
||||||
|
color_fprintf(s->fp, header_color, LABEL(N_("different")));
|
||||||
} else if (!num_ours) {
|
} else if (!num_ours) {
|
||||||
color_fprintf(s->fp, header_color, LABEL(N_("behind ")));
|
color_fprintf(s->fp, header_color, LABEL(N_("behind ")));
|
||||||
color_fprintf(s->fp, branch_color_remote, "%d", num_theirs);
|
color_fprintf(s->fp, branch_color_remote, "%d", num_theirs);
|
||||||
@ -1905,18 +1910,19 @@ static void wt_porcelain_print(struct wt_status *s)
|
|||||||
*
|
*
|
||||||
* <upstream> ::= the upstream branch name, when set.
|
* <upstream> ::= the upstream branch name, when set.
|
||||||
*
|
*
|
||||||
* <ahead> ::= integer ahead value, when upstream set
|
* <ahead> ::= integer ahead value or '?'.
|
||||||
* and the commit is present (not gone).
|
|
||||||
*
|
|
||||||
* <behind> ::= integer behind value, when upstream set
|
|
||||||
* and commit is present.
|
|
||||||
*
|
*
|
||||||
|
* <behind> ::= integer behind value or '?'.
|
||||||
*
|
*
|
||||||
* The end-of-line is defined by the -z flag.
|
* The end-of-line is defined by the -z flag.
|
||||||
*
|
*
|
||||||
* <eol> ::= NUL when -z,
|
* <eol> ::= NUL when -z,
|
||||||
* LF when NOT -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)
|
static void wt_porcelain_v2_print_tracking(struct wt_status *s)
|
||||||
{
|
{
|
||||||
@ -1956,14 +1962,25 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
|
|||||||
/* Lookup stats on the upstream tracking branch, if set. */
|
/* Lookup stats on the upstream tracking branch, if set. */
|
||||||
branch = branch_get(branch_name);
|
branch = branch_get(branch_name);
|
||||||
base = NULL;
|
base = NULL;
|
||||||
ab_info = (stat_tracking_info(branch, &nr_ahead, &nr_behind, &base) == 0);
|
ab_info = stat_tracking_info(branch, &nr_ahead, &nr_behind,
|
||||||
|
&base, s->ahead_behind_flags);
|
||||||
if (base) {
|
if (base) {
|
||||||
base = shorten_unambiguous_ref(base, 0);
|
base = shorten_unambiguous_ref(base, 0);
|
||||||
fprintf(s->fp, "# branch.upstream %s%c", base, eol);
|
fprintf(s->fp, "# branch.upstream %s%c", base, eol);
|
||||||
free((char *)base);
|
free((char *)base);
|
||||||
|
|
||||||
if (ab_info)
|
if (ab_info > 0) {
|
||||||
fprintf(s->fp, "# branch.ab +%d -%d%c", nr_ahead, nr_behind, eol);
|
/* 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "string-list.h"
|
#include "string-list.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "pathspec.h"
|
#include "pathspec.h"
|
||||||
|
#include "remote.h"
|
||||||
|
|
||||||
struct worktree;
|
struct worktree;
|
||||||
|
|
||||||
@ -87,6 +88,7 @@ struct wt_status {
|
|||||||
int show_branch;
|
int show_branch;
|
||||||
int show_stash;
|
int show_stash;
|
||||||
int hints;
|
int hints;
|
||||||
|
enum ahead_behind_flags ahead_behind_flags;
|
||||||
|
|
||||||
enum wt_status_format status_format;
|
enum wt_status_format status_format;
|
||||||
unsigned char sha1_commit[GIT_MAX_RAWSZ]; /* when not Initial */
|
unsigned char sha1_commit[GIT_MAX_RAWSZ]; /* when not Initial */
|
||||||
|
Loading…
Reference in New Issue
Block a user