Merge branch 'dr/ref-filter-push-track-fix'

%(push:track) token used in the --format option to "git
for-each-ref" and friends was not showing the right branch, which
has been fixed.

* dr/ref-filter-push-track-fix:
  ref-filter: use correct branch for %(push:track)
This commit is contained in:
Junio C Hamano 2019-05-09 00:37:26 +09:00
commit f560a4d159
5 changed files with 66 additions and 28 deletions

View File

@ -1392,7 +1392,8 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
*s = show_ref(&atom->u.remote_ref.refname, refname);
else if (atom->u.remote_ref.option == RR_TRACK) {
if (stat_tracking_info(branch, &num_ours, &num_theirs,
NULL, AHEAD_BEHIND_FULL) < 0) {
NULL, atom->u.remote_ref.push,
AHEAD_BEHIND_FULL) < 0) {
*s = xstrdup(msgs.gone);
} else if (!num_ours && !num_theirs)
*s = xstrdup("");
@ -1410,7 +1411,8 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
}
} else if (atom->u.remote_ref.option == RR_TRACKSHORT) {
if (stat_tracking_info(branch, &num_ours, &num_theirs,
NULL, AHEAD_BEHIND_FULL) < 0) {
NULL, atom->u.remote_ref.push,
AHEAD_BEHIND_FULL) < 0) {
*s = xstrdup("");
return;
}

View File

@ -1880,37 +1880,27 @@ int resolve_remote_symref(struct ref *ref, struct ref *list)
}
/*
* Lookup the upstream branch for the given branch and if present, optionally
* compute the commit ahead/behind values for the pair.
* Compute the commit ahead/behind values for the pair branch_name, base.
*
* 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
* upstream defined, or ref does not exist). Returns 0 if the commits are
* identical. Returns 1 if commits are different.
* Returns -1 if num_ours and num_theirs could not be filled in (e.g., 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,
const char **upstream_name, enum ahead_behind_flags abf)
static int stat_branch_pair(const char *branch_name, const char *base,
int *num_ours, int *num_theirs,
enum ahead_behind_flags abf)
{
struct object_id oid;
struct commit *ours, *theirs;
struct rev_info revs;
const char *base;
struct argv_array argv = ARGV_ARRAY_INIT;
/* Cannot stat unless we are marked to build on top of somebody else. */
base = branch_get_upstream(branch, NULL);
if (upstream_name)
*upstream_name = base;
if (!base)
return -1;
/* Cannot stat if what we used to build on no longer exists */
if (read_ref(base, &oid))
return -1;
@ -1918,7 +1908,7 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
if (!theirs)
return -1;
if (read_ref(branch->refname, &oid))
if (read_ref(branch_name, &oid))
return -1;
ours = lookup_commit_reference(the_repository, &oid);
if (!ours)
@ -1932,7 +1922,7 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
if (abf == AHEAD_BEHIND_QUICK)
return 1;
if (abf != AHEAD_BEHIND_FULL)
BUG("stat_tracking_info: invalid abf '%d'", abf);
BUG("stat_branch_pair: invalid abf '%d'", abf);
/* Run "rev-list --left-right ours...theirs" internally... */
argv_array_push(&argv, ""); /* ignored */
@ -1966,6 +1956,42 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
return 1;
}
/*
* Lookup the tracking branch for the given branch and if present, optionally
* compute the commit ahead/behind values for the pair.
*
* If for_push is true, the tracking branch refers to the push branch,
* otherwise it refers to the upstream branch.
*
* The name of the tracking branch (or NULL if it is not defined) is
* returned via *tracking_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).
*
* Returns -1 if num_ours and num_theirs could not be filled in (e.g., no
* 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,
const char **tracking_name, int for_push,
enum ahead_behind_flags abf)
{
const char *base;
/* Cannot stat unless we are marked to build on top of somebody else. */
base = for_push ? branch_get_push(branch, NULL) :
branch_get_upstream(branch, NULL);
if (tracking_name)
*tracking_name = base;
if (!base)
return -1;
return stat_branch_pair(branch->refname, base, num_ours, num_theirs, abf);
}
/*
* Return true when there is anything to report, otherwise false.
*/
@ -1977,7 +2003,7 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb,
char *base;
int upstream_is_gone = 0;
sti = stat_tracking_info(branch, &ours, &theirs, &full_base, abf);
sti = stat_tracking_info(branch, &ours, &theirs, &full_base, 0, abf);
if (sti < 0) {
if (!full_base)
return 0;

View File

@ -255,7 +255,8 @@ enum ahead_behind_flags {
/* Reporting of tracking info */
int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
const char **upstream_name, enum ahead_behind_flags abf);
const char **upstream_name, int for_push,
enum ahead_behind_flags abf);
int format_tracking_info(struct branch *branch, struct strbuf *sb,
enum ahead_behind_flags abf);

View File

@ -392,8 +392,15 @@ test_atom head upstream:track '[ahead 1]'
test_atom head upstream:trackshort '>'
test_atom head upstream:track,nobracket 'ahead 1'
test_atom head upstream:nobracket,track 'ahead 1'
test_atom head push:track '[ahead 1]'
test_atom head push:trackshort '>'
test_expect_success 'setup for push:track[short]' '
test_commit third &&
git update-ref refs/remotes/myfork/master master &&
git reset master~1
'
test_atom head push:track '[behind 1]'
test_atom head push:trackshort '<'
test_expect_success 'Check that :track[short] cannot be used with other atoms' '
test_must_fail git for-each-ref --format="%(refname:track)" 2>/dev/null &&
@ -420,8 +427,10 @@ test_expect_success 'Check for invalid refname format' '
test_expect_success 'set up color tests' '
cat >expected.color <<-EOF &&
$(git rev-parse --short refs/heads/master) <GREEN>master<RESET>
$(git rev-parse --short refs/remotes/myfork/master) <GREEN>myfork/master<RESET>
$(git rev-parse --short refs/remotes/origin/master) <GREEN>origin/master<RESET>
$(git rev-parse --short refs/tags/testtag) <GREEN>testtag<RESET>
$(git rev-parse --short refs/tags/third) <GREEN>third<RESET>
$(git rev-parse --short refs/tags/two) <GREEN>two<RESET>
EOF
sed "s/<[^>]*>//g" <expected.color >expected.bare &&

View File

@ -1857,7 +1857,7 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
color_fprintf(s->fp, branch_color_local, "%s", branch_name);
sti = stat_tracking_info(branch, &num_ours, &num_theirs, &base,
s->ahead_behind_flags);
0, s->ahead_behind_flags);
if (sti < 0) {
if (!base)
goto conclude;
@ -1996,7 +1996,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
branch = branch_get(branch_name);
base = NULL;
ab_info = stat_tracking_info(branch, &nr_ahead, &nr_behind,
&base, s->ahead_behind_flags);
&base, 0, s->ahead_behind_flags);
if (base) {
base = shorten_unambiguous_ref(base, 0);
fprintf(s->fp, "# branch.upstream %s%c", base, eol);