diff options
author | Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com> | 2015-01-05 11:58:55 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-01-12 15:10:46 -0800 |
commit | b6160d950c9ef168d0f7d7c9b2812f280e5b88fb (patch) | |
tree | ff477be184149287796005aeb522288174d658ae | |
parent | 9a8c2b67cd5a51666f2c0ce3fbbdb08b97b79b3d (diff) | |
download | git-b6160d950c9ef168d0f7d7c9b2812f280e5b88fb.tar.gz git-b6160d950c9ef168d0f7d7c9b2812f280e5b88fb.tar.xz |
for-each-ref: always check stat_tracking_info()'s return value
The code handling %(upstream:track) and %(upstream:trackshort)
assumed that it always had a valid branch that had been sanitized
earlier in populate_value(), and thus did not check the return value
of the call to stat_tracking_info().
While there is indeed some sanitization code that basically
corresponds to stat_tracking_info() returning 0 (no base branch
set), the function can also return -1 when the base branch did exist
but has since then been deleted.
In this case, num_ours and num_theirs had undefined values and a
call to `git for-each-ref --format="%(upstream:track)"` could print
spurious values such as
[behind -111794512]
[ahead 38881640, behind 5103867]
even for repositories with one single commit.
Verify stat_tracking_info()'s return value and do not print anything
if it returns -1. This behavior also matches the documentation ("has
no effect if the ref does not have tracking information associated
with it").
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | builtin/for-each-ref.c | 11 | ||||
-rwxr-xr-x | t/t6300-for-each-ref.sh | 13 |
2 files changed, 22 insertions, 2 deletions
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 3e1d5c333..edf9c3c74 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -728,7 +728,10 @@ static void populate_value(struct refinfo *ref) starts_with(name, "upstream")) { char buf[40]; - stat_tracking_info(branch, &num_ours, &num_theirs); + if (stat_tracking_info(branch, &num_ours, + &num_theirs) != 1) + continue; + if (!num_ours && !num_theirs) v->s = ""; else if (!num_ours) { @@ -746,7 +749,11 @@ static void populate_value(struct refinfo *ref) } else if (!strcmp(formatp, "trackshort") && starts_with(name, "upstream")) { assert(branch); - stat_tracking_info(branch, &num_ours, &num_theirs); + + if (stat_tracking_info(branch, &num_ours, + &num_theirs) != 1) + continue; + if (!num_ours && !num_theirs) v->s = "="; else if (!num_ours) diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index bda354c1c..c66bf7981 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -334,6 +334,19 @@ test_expect_success 'Check that :track[short] cannot be used with other atoms' ' test_must_fail git for-each-ref --format="%(refname:trackshort)" 2>/dev/null ' +test_expect_success 'Check that :track[short] works when upstream is invalid' ' + cat >expected <<-\EOF && + + + EOF + test_when_finished "git config branch.master.merge refs/heads/master" && + git config branch.master.merge refs/heads/does-not-exist && + git for-each-ref \ + --format="%(upstream:track)$LF%(upstream:trackshort)" \ + refs/heads >actual && + test_cmp expected actual +' + cat >expected <<EOF $(git rev-parse --short HEAD) EOF |