Skip to content

Commit c97c42a

Browse files
jeffhostetlerdscho
authored andcommitted
stat_tracking_info: return +1 when branches not equal
Extend stat_tracking_info() to return +1 when branches are not equal and to take a new "enum ahead_behind_flags" argument to allow skipping the (possibly expensive) ahead/behind computation. This will be used in the next commit to allow "git status" to avoid full ahead/behind calculations for performance reasons. Signed-off-by: Jeff Hostetler <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 6514021 commit c97c42a

File tree

4 files changed

+36
-20
lines changed

4 files changed

+36
-20
lines changed

ref-filter.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,8 +1249,8 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
12491249
if (atom->u.remote_ref.option == RR_REF)
12501250
*s = show_ref(&atom->u.remote_ref.refname, refname);
12511251
else if (atom->u.remote_ref.option == RR_TRACK) {
1252-
if (stat_tracking_info(branch, &num_ours,
1253-
&num_theirs, NULL)) {
1252+
if (stat_tracking_info(branch, &num_ours, &num_theirs,
1253+
NULL, AHEAD_BEHIND_FULL) < 0) {
12541254
*s = xstrdup(msgs.gone);
12551255
} else if (!num_ours && !num_theirs)
12561256
*s = "";
@@ -1267,8 +1267,8 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
12671267
free((void *)to_free);
12681268
}
12691269
} else if (atom->u.remote_ref.option == RR_TRACKSHORT) {
1270-
if (stat_tracking_info(branch, &num_ours,
1271-
&num_theirs, NULL))
1270+
if (stat_tracking_info(branch, &num_ours, &num_theirs,
1271+
NULL, AHEAD_BEHIND_FULL) < 0)
12721272
return;
12731273

12741274
if (!num_ours && !num_theirs)

remote.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,16 +2007,23 @@ int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid)
20072007
}
20082008

20092009
/*
2010-
* Compare a branch with its upstream, and save their differences (number
2011-
* of commits) in *num_ours and *num_theirs. The name of the upstream branch
2012-
* (or NULL if no upstream is defined) is returned via *upstream_name, if it
2013-
* is not itself NULL.
2010+
* Lookup the upstream branch for the given branch and if present, optionally
2011+
* compute the commit ahead/behind values for the pair.
2012+
*
2013+
* If abf is AHEAD_BEHIND_FULL, compute the full ahead/behind and return the
2014+
* counts in *num_ours and *num_theirs. If abf is AHEAD_BEHIND_QUICK, skip
2015+
* the (potentially expensive) a/b computation (*num_ours and *num_theirs are
2016+
* set to zero).
2017+
*
2018+
* The name of the upstream branch (or NULL if no upstream is defined) is
2019+
* returned via *upstream_name, if it is not itself NULL.
20142020
*
20152021
* Returns -1 if num_ours and num_theirs could not be filled in (e.g., no
2016-
* upstream defined, or ref does not exist), 0 otherwise.
2022+
* upstream defined, or ref does not exist). Returns 0 if the commits are
2023+
* identical. Returns 1 if commits are different.
20172024
*/
20182025
int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
2019-
const char **upstream_name)
2026+
const char **upstream_name, enum ahead_behind_flags abf)
20202027
{
20212028
struct object_id oid;
20222029
struct commit *ours, *theirs;
@@ -2044,11 +2051,13 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
20442051
if (!ours)
20452052
return -1;
20462053

2054+
*num_theirs = *num_ours = 0;
2055+
20472056
/* are we the same? */
2048-
if (theirs == ours) {
2049-
*num_theirs = *num_ours = 0;
2057+
if (theirs == ours)
20502058
return 0;
2051-
}
2059+
if (abf == AHEAD_BEHIND_QUICK)
2060+
return 1;
20522061

20532062
/* Run "rev-list --left-right ours...theirs" internally... */
20542063
argv_array_push(&argv, ""); /* ignored */
@@ -2064,8 +2073,6 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
20642073
die("revision walk setup failed");
20652074

20662075
/* ... and count the commits on each side. */
2067-
*num_ours = 0;
2068-
*num_theirs = 0;
20692076
while (1) {
20702077
struct commit *c = get_revision(&revs);
20712078
if (!c)
@@ -2081,7 +2088,7 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
20812088
clear_commit_marks(theirs, ALL_REV_FLAGS);
20822089

20832090
argv_array_clear(&argv);
2084-
return 0;
2091+
return 1;
20852092
}
20862093

20872094
/*
@@ -2094,7 +2101,8 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb)
20942101
char *base;
20952102
int upstream_is_gone = 0;
20962103

2097-
if (stat_tracking_info(branch, &ours, &theirs, &full_base) < 0) {
2104+
if (stat_tracking_info(branch, &ours, &theirs, &full_base,
2105+
AHEAD_BEHIND_FULL) < 0) {
20982106
if (!full_base)
20992107
return 0;
21002108
upstream_is_gone = 1;

remote.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,15 @@ enum match_refs_flags {
257257
MATCH_REFS_FOLLOW_TAGS = (1 << 3)
258258
};
259259

260+
/* Flags for --ahead-behind option. */
261+
enum ahead_behind_flags {
262+
AHEAD_BEHIND_QUICK = 0, /* just eq/neq reporting */
263+
AHEAD_BEHIND_FULL = 1, /* traditional a/b reporting */
264+
};
265+
260266
/* Reporting of tracking info */
261267
int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
262-
const char **upstream_name);
268+
const char **upstream_name, enum ahead_behind_flags abf);
263269
int format_tracking_info(struct branch *branch, struct strbuf *sb);
264270

265271
struct ref *get_local_heads(void);

wt-status.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,7 +1796,8 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
17961796

17971797
color_fprintf(s->fp, branch_color_local, "%s", branch_name);
17981798

1799-
if (stat_tracking_info(branch, &num_ours, &num_theirs, &base) < 0) {
1799+
if (stat_tracking_info(branch, &num_ours, &num_theirs, &base,
1800+
AHEAD_BEHIND_FULL) < 0) {
18001801
if (!base)
18011802
goto conclude;
18021803

@@ -1933,7 +1934,8 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
19331934
/* Lookup stats on the upstream tracking branch, if set. */
19341935
branch = branch_get(branch_name);
19351936
base = NULL;
1936-
ab_info = (stat_tracking_info(branch, &nr_ahead, &nr_behind, &base) == 0);
1937+
ab_info = (stat_tracking_info(branch, &nr_ahead, &nr_behind,
1938+
&base, AHEAD_BEHIND_FULL) >= 0);
19371939
if (base) {
19381940
base = shorten_unambiguous_ref(base, 0);
19391941
fprintf(s->fp, "# branch.upstream %s%c", base, eol);

0 commit comments

Comments
 (0)