From: Max Kirillov <max@max630.net>
To: Jacob Keller <jacob.keller@gmail.com>,
Junio C Hamano <gitster@pobox.com>
Cc: Max Kirillov <max@max630.net>, git@vger.kernel.org
Subject: [PATCH] describe: teach --match to handle branches and remotes
Date: Sun, 17 Sep 2017 17:24:16 +0300 [thread overview]
Message-ID: <20170917142416.30685-1-max@max630.net> (raw)
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 <max@max630.net>
---
Requires https://public-inbox.org/git/20170916055344.31866-1-max@max630.net/
This extends --match to branches and remote-tracking references. It is in some respect
regression, if anybody have used --all and --match together this would find another
reference, but since that combination did not make sense anyway probably it is not
a big issue.
There are ambiguity with this approach if --match=foo matches tag "foo", or branch "foo".
Probably to resolve it there should appear some --match-full option, so that --match would mean
full reference name, with prefix. It could be a room for further improvement.
From documentation I removed the usage example part, mainly to not expand the size too much, but
probably they do not really belong there.
Documentation/git-describe.txt | 24 ++++++++++++++----------
builtin/describe.c | 26 ++++++++++++++++++++++----
t/t6120-describe.sh | 18 ++++++++++++++++++
3 files changed, 54 insertions(+), 14 deletions(-)
diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt
index 26f19d3b07..c924c945ba 100644
--- a/Documentation/git-describe.txt
+++ b/Documentation/git-describe.txt
@@ -87,19 +87,23 @@ OPTIONS
--match <pattern>::
Only consider tags matching the given `glob(7)` pattern,
- excluding the "refs/tags/" prefix. This can be used to avoid
- leaking private tags from the repository. If given multiple times, a
- list of patterns will be accumulated, and tags matching any of the
- patterns will be considered. Use `--no-match` to clear and reset the
- list of patterns.
+ excluding the "refs/tags/" prefix. If used with `--all`, it also
+ considers local branches and remote-tracking references matching the
+ pattern, excluding respectively "refs/heads/" and "refs/remotes/"
+ prefix; references of other types are never considered. If given
+ multiple times, a list of patterns will be accumulated, and tags
+ matching any of the patterns will be considered. Use `--no-match` to
+ clear and reset the list of patterns.
--exclude <pattern>::
Do not consider tags matching the given `glob(7)` pattern, excluding
- the "refs/tags/" prefix. This can be used to narrow the tag space and
- find only tags matching some meaningful criteria. If given multiple
- times, a list of patterns will be accumulated and tags matching any
- of the patterns will be excluded. When combined with --match a tag will
- be considered when it matches at least one --match pattern and does not
+ the "refs/tags/" prefix. If used with `--all`, it also does not consider
+ local branches and remote-tracking references matching the pattern,
+ excluding respectively "refs/heads/" and "refs/remotes/" prefix;
+ references of other types are never considered. If given multiple times,
+ a list of patterns will be accumulated and tags matching any of the
+ patterns will be excluded. When combined with --match a tag will be
+ considered when it matches at least one --match pattern and does not
match any of the --exclude patterns. Use `--no-exclude` to clear and
reset the list of patterns.
diff --git a/builtin/describe.c b/builtin/describe.c
index 94ff2fba0b..2a2e998063 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -124,6 +124,22 @@ static void add_to_known_names(const char *path,
}
}
+/* Drops prefix. Returns NULL if the path is not expected with current settings. */
+static const char *get_path_to_match(int is_tag, int all, const char *path)
+{
+ if (is_tag)
+ return path + 10;
+ else if (all) {
+ if (starts_with(path, "refs/heads/"))
+ return path + 11; /* "refs/heads/..." */
+ else if (starts_with(path, "refs/remotes/"))
+ return path + 13; /* "refs/remotes/..." */
+ else
+ return 0;
+ } else
+ return NULL;
+}
+
static int get_name(const char *path, const struct object_id *oid, int flag, void *cb_data)
{
int is_tag = starts_with(path, "refs/tags/");
@@ -140,12 +156,13 @@ static int get_name(const char *path, const struct object_id *oid, int flag, voi
*/
if (exclude_patterns.nr) {
struct string_list_item *item;
+ const char *path_to_match = get_path_to_match(is_tag, all, path);
- if (!is_tag)
+ if (!path_to_match)
return 0;
for_each_string_list_item(item, &exclude_patterns) {
- if (!wildmatch(item->string, path + 10, 0))
+ if (!wildmatch(item->string, path_to_match, 0))
return 0;
}
}
@@ -156,13 +173,14 @@ static int get_name(const char *path, const struct object_id *oid, int flag, voi
*/
if (patterns.nr) {
int found = 0;
+ const char *path_to_match = get_path_to_match(is_tag, all, path);
struct string_list_item *item;
- if (!is_tag)
+ if (!path_to_match)
return 0;
for_each_string_list_item(item, &patterns) {
- if (!wildmatch(item->string, path + 10, 0)) {
+ if (!wildmatch(item->string, path_to_match, 0)) {
found = 1;
break;
}
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index 25110ea55d..fac52bd9dc 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -190,6 +190,24 @@ check_describe "test1-lightweight-*" --long --tags --match="test1-*" --match="te
check_describe "test1-lightweight-*" --long --tags --match="test3-*" --match="test1-*" HEAD
+test_expect_success 'set-up branches' '
+ git branch branch_A A &&
+ git branch branch_c c &&
+ git update-ref refs/remotes/origin/remote_branch_A "A^{commit}" &&
+ git update-ref refs/remotes/origin/remote_branch_c "c^{commit}" &&
+ git update-ref refs/original/original_branch_A test-annotated~2
+'
+
+check_describe "heads/branch_A*" --all --match="branch_*" --exclude="branch_c" HEAD
+
+check_describe "remotes/origin/remote_branch_A*" --all --match="origin/remote_branch_*" --exclude="origin/remote_branch_c" HEAD
+
+check_describe "original/original_branch_A*" --all test-annotated~1
+
+test_expect_success '--match does not work for other types' '
+ test_must_fail git describe --all --match="*original_branch_*" test-annotated~1
+'
+
test_expect_success 'name-rev with exact tags' '
echo A >expect &&
tag_object=$(git rev-parse refs/tags/A) &&
--
2.11.0.1122.gc3fec58.dirty
next reply other threads:[~2017-09-17 14:32 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-17 14:24 Max Kirillov [this message]
2017-09-18 23:52 ` [PATCH] describe: teach --match to handle branches and remotes Junio C Hamano
2017-09-19 0:45 ` Jacob Keller
2017-09-20 1:07 ` Max Kirillov
2017-09-20 1:10 ` [PATCH v2] " Max Kirillov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170917142416.30685-1-max@max630.net \
--to=max@max630.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jacob.keller@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).