Merge branch 'jk/list-tag-2.7-regression'

"git tag" started listing a tag "foo" as "tags/foo" when a branch
named "foo" exists in the same repository; remove this unnecessary
disambiguation, which is a regression introduced in v2.7.0.

* jk/list-tag-2.7-regression:
  tag: do not show ambiguous tag names as "tags/foo"
  t6300: use test_atom for some un-modern tests
This commit is contained in:
Junio C Hamano 2016-02-01 15:14:24 -08:00
commit 8bad3de2c8
7 changed files with 72 additions and 56 deletions

View file

@ -92,7 +92,11 @@ refname::
The name of the ref (the part after $GIT_DIR/).
For a non-ambiguous short name of the ref append `:short`.
The option core.warnAmbiguousRefs is used to select the strict
abbreviation mode.
abbreviation mode. If `strip=<N>` is appended, strips `<N>`
slash-separated path components from the front of the refname
(e.g., `%(refname:strip=2)` turns `refs/tags/foo` into `foo`.
`<N>` must be a positive integer. If a displayed ref has fewer
components than `<N>`, the command aborts with an error.
objecttype::
The type of the object (`blob`, `tree`, `commit`, `tag`).

View file

@ -163,7 +163,7 @@ This option is only applicable when listing tags without annotation lines.
A string that interpolates `%(fieldname)` from the object
pointed at by a ref being shown. The format is the same as
that of linkgit:git-for-each-ref[1]. When unspecified,
defaults to `%(refname:short)`.
defaults to `%(refname:strip=2)`.
--[no-]merged [<commit>]::
Only list tags whose tips are reachable, or not reachable

View file

@ -44,11 +44,11 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, con
if (!format) {
if (filter->lines) {
to_free = xstrfmt("%s %%(contents:lines=%d)",
"%(align:15)%(refname:short)%(end)",
"%(align:15)%(refname:strip=2)%(end)",
filter->lines);
format = to_free;
} else
format = "%(refname:short)";
format = "%(refname:strip=2)";
}
verify_ref_format(format);

View file

@ -763,6 +763,29 @@ static inline char *copy_advance(char *dst, const char *src)
return dst;
}
static const char *strip_ref_components(const char *refname, const char *nr_arg)
{
char *end;
long nr = strtol(nr_arg, &end, 10);
long remaining = nr;
const char *start = refname;
if (nr < 1 || *end != '\0')
die(":strip= requires a positive integer argument");
while (remaining) {
switch (*start++) {
case '\0':
die("ref '%s' does not have %ld components to :strip",
refname, nr);
case '/':
remaining--;
break;
}
}
return start;
}
/*
* Parse the object referred by ref, and grab needed value.
*/
@ -909,11 +932,14 @@ static void populate_value(struct ref_array_item *ref)
formatp = strchr(name, ':');
if (formatp) {
int num_ours, num_theirs;
const char *arg;
formatp++;
if (!strcmp(formatp, "short"))
refname = shorten_unambiguous_ref(refname,
warn_ambiguous_refs);
else if (skip_prefix(formatp, "strip=", &arg))
refname = strip_ref_components(refname, arg);
else if (!strcmp(formatp, "track") &&
(starts_with(name, "upstream") ||
starts_with(name, "push"))) {

View file

@ -176,4 +176,12 @@ test_expect_success 'git branch --points-at option' '
test_cmp expect actual
'
test_expect_success 'ambiguous branch/tag not marked' '
git tag ambiguous &&
git branch ambiguous &&
echo " ambiguous" >expect &&
git branch --list ambiguous >actual &&
test_cmp expect actual
'
test_done

View file

@ -49,11 +49,17 @@ test_atom() {
}
test_atom head refname refs/heads/master
test_atom head refname:short master
test_atom head refname:strip=1 heads/master
test_atom head refname:strip=2 master
test_atom head upstream refs/remotes/origin/master
test_atom head upstream:short origin/master
test_atom head push refs/remotes/myfork/master
test_atom head push:short myfork/master
test_atom head objecttype commit
test_atom head objectsize 171
test_atom head objectname $(git rev-parse refs/heads/master)
test_atom head objectname:short $(git rev-parse --short refs/heads/master)
test_atom head tree $(git rev-parse refs/heads/master^{tree})
test_atom head parent ''
test_atom head numparent 0
@ -86,11 +92,13 @@ test_atom head contents 'Initial
test_atom head HEAD '*'
test_atom tag refname refs/tags/testtag
test_atom tag refname:short testtag
test_atom tag upstream ''
test_atom tag push ''
test_atom tag objecttype tag
test_atom tag objectsize 154
test_atom tag objectname $(git rev-parse refs/tags/testtag)
test_atom tag objectname:short $(git rev-parse --short refs/tags/testtag)
test_atom tag tree ''
test_atom tag parent ''
test_atom tag numparent ''
@ -126,6 +134,16 @@ test_expect_success 'Check invalid atoms names are errors' '
test_must_fail git for-each-ref --format="%(INVALID)" refs/heads
'
test_expect_success 'arguments to :strip must be positive integers' '
test_must_fail git for-each-ref --format="%(refname:strip=0)" &&
test_must_fail git for-each-ref --format="%(refname:strip=-1)" &&
test_must_fail git for-each-ref --format="%(refname:strip=foo)"
'
test_expect_success 'stripping refnames too far gives an error' '
test_must_fail git for-each-ref --format="%(refname:strip=3)"
'
test_expect_success 'Check format specifiers are ignored in naming date atoms' '
git for-each-ref --format="%(authordate)" refs/heads &&
git for-each-ref --format="%(authordate:default) %(authordate)" refs/heads &&
@ -338,47 +356,14 @@ for i in "--perl --shell" "-s --python" "--python --tcl" "--tcl --perl"; do
"
done
cat >expected <<\EOF
master
testtag
EOF
test_expect_success 'Check short refname format' '
(git for-each-ref --format="%(refname:short)" refs/heads &&
git for-each-ref --format="%(refname:short)" refs/tags) >actual &&
test_cmp expected actual
'
cat >expected <<EOF
origin/master
EOF
test_expect_success 'Check short upstream format' '
git for-each-ref --format="%(upstream:short)" refs/heads >actual &&
test_cmp expected actual
'
test_expect_success 'setup for upstream:track[short]' '
test_commit two
'
cat >expected <<EOF
[ahead 1]
EOF
test_expect_success 'Check upstream:track format' '
git for-each-ref --format="%(upstream:track)" refs/heads >actual &&
test_cmp expected actual
'
cat >expected <<EOF
>
EOF
test_expect_success 'Check upstream:trackshort format' '
git for-each-ref --format="%(upstream:trackshort)" refs/heads >actual &&
test_cmp expected actual
'
test_atom head upstream:track '[ahead 1]'
test_atom head upstream:trackshort '>'
test_atom head push:track '[ahead 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 &&
@ -398,21 +383,6 @@ test_expect_success 'Check that :track[short] works when upstream is invalid' '
test_cmp expected actual
'
test_expect_success '%(push) supports tracking specifiers, too' '
echo "[ahead 1]" >expected &&
git for-each-ref --format="%(push:track)" refs/heads >actual &&
test_cmp expected actual
'
cat >expected <<EOF
$(git rev-parse --short HEAD)
EOF
test_expect_success 'Check short objectname format' '
git for-each-ref --format="%(objectname:short)" refs/heads >actual &&
test_cmp expected actual
'
test_expect_success 'Check for invalid refname format' '
test_must_fail git for-each-ref --format="%(refname:INVALID)"
'

View file

@ -1558,4 +1558,12 @@ test_expect_success '--no-merged show unmerged tags' '
test_cmp expect actual
'
test_expect_success 'ambiguous branch/tags not marked' '
git tag ambiguous &&
git branch ambiguous &&
echo ambiguous >expect &&
git tag -l ambiguous >actual &&
test_cmp expect actual
'
test_done