summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-for-each-ref.txt6
-rw-r--r--Documentation/git-tag.txt2
-rw-r--r--builtin/tag.c4
-rw-r--r--ref-filter.c26
-rwxr-xr-xt/t3203-branch-output.sh8
-rwxr-xr-xt/t6300-for-each-ref.sh74
-rwxr-xr-xt/t7004-tag.sh8
7 files changed, 72 insertions, 56 deletions
diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt
index 06208c4..2e3e96f 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -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`).
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 7220e5e..abab481 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -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
diff --git a/builtin/tag.c b/builtin/tag.c
index 8db8c87..1705c94 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -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);
diff --git a/ref-filter.c b/ref-filter.c
index 7bef7f8..f097176 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -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"))) {
diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh
index d3913f9..4261403 100755
--- a/t/t3203-branch-output.sh
+++ b/t/t3203-branch-output.sh
@@ -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
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 03873b0..19a2823 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -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)"
'
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index 2797f22..cf3469b 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -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