Skip to content

Commit 6d68b2a

Browse files
max630gitster
authored andcommitted
describe: teach --match to handle branches and remotes
When `git describe` uses `--match`, it matches only tags, basically ignoring the `--all` argument even when it is specified. Fix it by also matching branch name and $remote_name/$remote_branch_name, for remote-tracking references, with the specified patterns. Update documentation accordingly and add tests. Signed-off-by: Max Kirillov <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3445c3d commit 6d68b2a

File tree

3 files changed

+58
-22
lines changed

3 files changed

+58
-22
lines changed

Documentation/git-describe.txt

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,23 @@ OPTIONS
8787

8888
--match <pattern>::
8989
Only consider tags matching the given `glob(7)` pattern,
90-
excluding the "refs/tags/" prefix. This can be used to avoid
91-
leaking private tags from the repository. If given multiple times, a
92-
list of patterns will be accumulated, and tags matching any of the
93-
patterns will be considered. Use `--no-match` to clear and reset the
94-
list of patterns.
90+
excluding the "refs/tags/" prefix. If used with `--all`, it also
91+
considers local branches and remote-tracking references matching the
92+
pattern, excluding respectively "refs/heads/" and "refs/remotes/"
93+
prefix; references of other types are never considered. If given
94+
multiple times, a list of patterns will be accumulated, and tags
95+
matching any of the patterns will be considered. Use `--no-match` to
96+
clear and reset the list of patterns.
9597

9698
--exclude <pattern>::
9799
Do not consider tags matching the given `glob(7)` pattern, excluding
98-
the "refs/tags/" prefix. This can be used to narrow the tag space and
99-
find only tags matching some meaningful criteria. If given multiple
100-
times, a list of patterns will be accumulated and tags matching any
101-
of the patterns will be excluded. When combined with --match a tag will
102-
be considered when it matches at least one --match pattern and does not
100+
the "refs/tags/" prefix. If used with `--all`, it also does not consider
101+
local branches and remote-tracking references matching the pattern,
102+
excluding respectively "refs/heads/" and "refs/remotes/" prefix;
103+
references of other types are never considered. If given multiple times,
104+
a list of patterns will be accumulated and tags matching any of the
105+
patterns will be excluded. When combined with --match a tag will be
106+
considered when it matches at least one --match pattern and does not
103107
match any of the --exclude patterns. Use `--no-exclude` to clear and
104108
reset the list of patterns.
105109

builtin/describe.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,24 @@ static void add_to_known_names(const char *path,
129129

130130
static int get_name(const char *path, const struct object_id *oid, int flag, void *cb_data)
131131
{
132-
int is_tag = starts_with(path, "refs/tags/");
132+
int is_tag = 0;
133133
struct object_id peeled;
134134
int is_annotated, prio;
135-
136-
/* Reject anything outside refs/tags/ unless --all */
137-
if (!all && !is_tag)
135+
const char *path_to_match = NULL;
136+
137+
if (skip_prefix(path, "refs/tags/", &path_to_match)) {
138+
is_tag = 1;
139+
} else if (all) {
140+
if ((exclude_patterns.nr || patterns.nr) &&
141+
!skip_prefix(path, "refs/heads/", &path_to_match) &&
142+
!skip_prefix(path, "refs/remotes/", &path_to_match)) {
143+
/* Only accept reference of known type if there are match/exclude patterns */
144+
return 0;
145+
}
146+
} else {
147+
/* Reject anything outside refs/tags/ unless --all */
138148
return 0;
149+
}
139150

140151
/*
141152
* If we're given exclude patterns, first exclude any tag which match
@@ -144,11 +155,8 @@ static int get_name(const char *path, const struct object_id *oid, int flag, voi
144155
if (exclude_patterns.nr) {
145156
struct string_list_item *item;
146157

147-
if (!is_tag)
148-
return 0;
149-
150158
for_each_string_list_item(item, &exclude_patterns) {
151-
if (!wildmatch(item->string, path + 10, 0))
159+
if (!wildmatch(item->string, path_to_match, 0))
152160
return 0;
153161
}
154162
}
@@ -161,11 +169,8 @@ static int get_name(const char *path, const struct object_id *oid, int flag, voi
161169
int found = 0;
162170
struct string_list_item *item;
163171

164-
if (!is_tag)
165-
return 0;
166-
167172
for_each_string_list_item(item, &patterns) {
168-
if (!wildmatch(item->string, path + 10, 0)) {
173+
if (!wildmatch(item->string, path_to_match, 0)) {
169174
found = 1;
170175
break;
171176
}

t/t6120-describe.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,33 @@ check_describe "test1-lightweight-*" --long --tags --match="test1-*" --match="te
190190

191191
check_describe "test1-lightweight-*" --long --tags --match="test3-*" --match="test1-*" HEAD
192192

193+
test_expect_success 'set-up branches' '
194+
git branch branch_A A &&
195+
git branch branch_C c &&
196+
git update-ref refs/remotes/origin/remote_branch_A "A^{commit}" &&
197+
git update-ref refs/remotes/origin/remote_branch_C "c^{commit}" &&
198+
git update-ref refs/original/original_branch_A test-annotated~2
199+
'
200+
201+
check_describe "heads/branch_A*" --all --match="branch_*" --exclude="branch_C" HEAD
202+
203+
check_describe "remotes/origin/remote_branch_A*" --all --match="origin/remote_branch_*" --exclude="origin/remote_branch_C" HEAD
204+
205+
check_describe "original/original_branch_A*" --all test-annotated~1
206+
207+
test_expect_success '--match does not work for other types' '
208+
test_must_fail git describe --all --match="*original_branch_*" test-annotated~1
209+
'
210+
211+
test_expect_success '--exclude does not work for other types' '
212+
R=$(git describe --all --exclude="any_pattern_even_not_matching" test-annotated~1) &&
213+
case "$R" in
214+
*original_branch_A*) echo "fail: Found unknown reference $R with --exclude"
215+
false;;
216+
*) echo ok: Found some known type;;
217+
esac
218+
'
219+
193220
test_expect_success 'name-rev with exact tags' '
194221
echo A >expect &&
195222
tag_object=$(git rev-parse refs/tags/A) &&

0 commit comments

Comments
 (0)