{"thread":{"id":"22300","subject":"[PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern","startedAt":"2010-01-20T09:48:25Z","lastAt":"2010-01-22T00:51:06Z","messageCount":12,"participants":["Ilari Liusvaara","Junio C Hamano","Johannes Sixt","Michael J Gruber","Thomas Rast"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"132176","messageId":"1263980906-11058-1-git-send-email-ilari.liusvaara@elisanet.fi","threadId":"22300","inReplyTo":null,"subject":"[PATCH 1/2] rev-parse --glob","fromName":"Ilari Liusvaara","fromEmail":"ilari.liusvaara@elisanet.fi","sentAt":"2010-01-20T09:48:25Z","receivedAt":"2010-01-20T09:48:25Z","isPatch":true,"sender":{"key":"ilari.liusvaara@elisanet.fi","avatar":null},"body":"Add --glob=<glob-pattern> option to rev-parse and everything that\naccepts its options. This option matches all refs that match given\nshell glob pattern (complete with some DWIM logic).\n\nExample:\n\n'git log --branches --not --glob=remotes/origin'\n\nTo show what you have that origin doesn't.\n\nSigned-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>\n---\n--glob can do everything --namespace did and more (in fact, what\nwas valid for --namespace is valid for --glob and even means the same\nthing). Built on top of master.\n\n Documentation/git-log.txt          |   11 +++\n Documentation/git-rev-list.txt     |    1 +\n Documentation/git-rev-parse.txt    |    5 ++\n Documentation/rev-list-options.txt |    7 ++\n builtin-rev-parse.c                |    5 ++\n refs.c                             |   46 ++++++++++++\n refs.h                             |    1 +\n revision.c                         |   16 ++++-\n t/t6018-rev-list-glob.sh           |  136 ++++++++++++++++++++++++++++++++++++\n 9 files changed, 226 insertions(+), 2 deletions(-)\n create mode 100755 t/t6018-rev-list-glob.sh\n\ndiff --git a/Documentation/git-log.txt b/Documentation/git-log.txt\nindex 3d79de1..0b874e3 100644\n--- a/Documentation/git-log.txt\n+++ b/Documentation/git-log.txt\n@@ -107,6 +107,17 @@ git log --follow builtin-rev-list.c::\n \tthose commits that occurred before the file was given its\n \tpresent name.\n \n+git log --branches --not --glob=remotes/origin/*::\n+\n+\tShows all commits that are in any of local branches but not in\n+\tany of remote tracking branches for 'origin' (what you have that\n+\torigin doesn't).\n+\n+git log master --not --glob=remotes/*/master::\n+\n+\tShows all commits that are in local master but not in any remote\n+\trepository master branches.\n+\n Discussion\n ----------\n \ndiff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt\nindex 3341d1b..33122a3 100644\n--- a/Documentation/git-rev-list.txt\n+++ b/Documentation/git-rev-list.txt\n@@ -24,6 +24,7 @@ SYNOPSIS\n \t     [ \\--branches ]\n \t     [ \\--tags ]\n \t     [ \\--remotes ]\n+\t     [ \\--glob=glob-pattern ]\n \t     [ \\--stdin ]\n \t     [ \\--quiet ]\n \t     [ \\--topo-order ]\ndiff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt\nindex 82045a2..6eb8c14 100644\n--- a/Documentation/git-rev-parse.txt\n+++ b/Documentation/git-rev-parse.txt\n@@ -112,6 +112,11 @@ OPTIONS\n --remotes::\n \tShow tag refs found in `$GIT_DIR/refs/remotes`.\n \n+--glob=glob-pattern::\n+\tShow refs matching shell glob pattern `glob-pattern`. If pattern\n+\tspecified lacks leading 'refs/', it is automatically prepended.\n+\tIf pattern lacks '?', '*', or '[', '/*' at the end is impiled.\n+\n --show-prefix::\n \tWhen the command is invoked from a subdirectory, show the\n \tpath of the current directory relative to the top-level\ndiff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt\nindex 1f57aed..6d03c17 100644\n--- a/Documentation/rev-list-options.txt\n+++ b/Documentation/rev-list-options.txt\n@@ -243,6 +243,13 @@ endif::git-rev-list[]\n \tPretend as if all the refs in `$GIT_DIR/refs/remotes` are listed\n \ton the command line as '<commit>'.\n \n+--glob=glob-pattern::\n+\tPretend as if all the refs matching shell glob `glob-pattern`\n+\tare listed on the command line as '<commit>'. Leading 'refs/',\n+\tis automatically prepended if missing. If pattern lacks '?', '*',\n+\tor '[', '/*' at the end is impiled.\n+\n+\n ifndef::git-rev-list[]\n --bisect::\n \ndiff --git a/builtin-rev-parse.c b/builtin-rev-parse.c\nindex 37d0233..a635dde 100644\n--- a/builtin-rev-parse.c\n+++ b/builtin-rev-parse.c\n@@ -52,6 +52,7 @@ static int is_rev_argument(const char *arg)\n \t\t\"--parents\",\n \t\t\"--pretty\",\n \t\t\"--remotes\",\n+\t\t\"--glob=\",\n \t\t\"--sparse\",\n \t\t\"--tags\",\n \t\t\"--topo-order\",\n@@ -577,6 +578,10 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\tfor_each_tag_ref(show_reference, NULL);\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!prefixcmp(arg, \"--glob=\")) {\n+\t\t\t\tfor_each_glob_ref(show_reference, arg + 7, NULL);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(arg, \"--remotes\")) {\n \t\t\t\tfor_each_remote_ref(show_reference, NULL);\n \t\t\t\tcontinue;\ndiff --git a/refs.c b/refs.c\nindex 3e73a0a..5adf69c 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -519,6 +519,14 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *\n \treturn ref;\n }\n \n+/* The argument to filter_refs */\n+struct ref_filter\n+{\n+\tconst char *pattern;\n+\teach_ref_fn *fn;\n+\tvoid *cb_data;\n+};\n+\n int read_ref(const char *ref, unsigned char *sha1)\n {\n \tif (resolve_ref(ref, sha1, 1, NULL))\n@@ -545,6 +553,15 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim,\n \treturn fn(entry->name + trim, entry->sha1, entry->flag, cb_data);\n }\n \n+static int filter_refs(const char* ref, const unsigned char *sha, int flags,\n+\tvoid* data)\n+{\n+\tstruct ref_filter *filter = (struct ref_filter*)data;\n+\tif (fnmatch(filter->pattern, ref, 0))\n+\t\treturn 0;\n+\treturn filter->fn(ref, sha, flags, filter->cb_data);\n+}\n+\n int peel_ref(const char *ref, unsigned char *sha1)\n {\n \tint flag;\n@@ -674,6 +691,35 @@ int for_each_replace_ref(each_ref_fn fn, void *cb_data)\n \treturn do_for_each_ref(\"refs/replace/\", fn, 13, 0, cb_data);\n }\n \n+int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)\n+{\n+\tstruct strbuf real_pattern = STRBUF_INIT;\n+\tstruct ref_filter filter;\n+\tconst char *has_glob_specials;\n+\tint ret;\n+\n+\tif (prefixcmp(pattern, \"refs/\"))\n+\t\tstrbuf_addstr(&real_pattern, \"refs/\");\n+\tstrbuf_addstr(&real_pattern, pattern);\n+\n+\thas_glob_specials = strpbrk(pattern, \"?*[\");\n+\tif (!has_glob_specials) {\n+\t\t/* Append impiled '/' '*' if not present. */\n+\t\tif (real_pattern.buf[real_pattern.len - 1] != '/')\n+\t\t\tstrbuf_addch(&real_pattern, '/');\n+\t\t/* No need to check for '*', there is none. */\n+\t\tstrbuf_addch(&real_pattern, '*');\n+\t}\n+\n+\tfilter.pattern = real_pattern.buf;\n+\tfilter.fn = fn;\n+\tfilter.cb_data = cb_data;\n+\tret = for_each_ref(filter_refs, &filter);\n+\n+\tstrbuf_release(&real_pattern);\n+\treturn ret;\n+}\n+\n int for_each_rawref(each_ref_fn fn, void *cb_data)\n {\n \treturn do_for_each_ref(\"refs/\", fn, 0,\ndiff --git a/refs.h b/refs.h\nindex e141991..78ad173 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -25,6 +25,7 @@ extern int for_each_tag_ref(each_ref_fn, void *);\n extern int for_each_branch_ref(each_ref_fn, void *);\n extern int for_each_remote_ref(each_ref_fn, void *);\n extern int for_each_replace_ref(each_ref_fn, void *);\n+extern int for_each_glob_ref(each_ref_fn, const char *pattern, void *);\n \n /* can be used to learn about broken ref and symref */\n extern int for_each_rawref(each_ref_fn, void *);\ndiff --git a/revision.c b/revision.c\nindex 25fa14d..162b182 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -699,12 +699,18 @@ static int handle_one_ref(const char *path, const unsigned char *sha1, int flag,\n \treturn 0;\n }\n \n+static void init_all_refs_cb(struct all_refs_cb *cb, struct rev_info *revs,\n+\tunsigned flags)\n+{\n+\tcb->all_revs = revs;\n+\tcb->all_flags = flags;\n+}\n+\n static void handle_refs(struct rev_info *revs, unsigned flags,\n \t\tint (*for_each)(each_ref_fn, void *))\n {\n \tstruct all_refs_cb cb;\n-\tcb.all_revs = revs;\n-\tcb.all_flags = flags;\n+\tinit_all_refs_cb(&cb, revs, flags);\n \tfor_each(handle_one_ref, &cb);\n }\n \n@@ -1352,6 +1358,12 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n \t\t\t\thandle_refs(revs, flags, for_each_remote_ref);\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!prefixcmp(arg, \"--glob=\")) {\n+\t\t\t\tstruct all_refs_cb cb;\n+\t\t\t\tinit_all_refs_cb(&cb, revs, flags);\n+\t\t\t\tfor_each_glob_ref(handle_one_ref, arg + 7, &cb);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(arg, \"--reflog\")) {\n \t\t\t\thandle_reflog(revs, flags);\n \t\t\t\tcontinue;\ndiff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh\nnew file mode 100755\nindex 0000000..0d7e4bc\n--- /dev/null\n+++ b/t/t6018-rev-list-glob.sh\n@@ -0,0 +1,136 @@\n+#!/bin/sh\n+\n+test_description='rev-list/rev-parse --glob'\n+\n+. ./test-lib.sh\n+\n+\n+commit () {\n+\ttest_tick &&\n+\techo $1 > foo &&\n+\tgit add foo &&\n+\tgit commit -m \"$1\"\n+}\n+\n+compare () {\n+\t# Split arguments on whitespace.\n+\tgit $1 $2 >expected &&\n+\tgit $1 $3 >actual &&\n+\ttest_cmp expected actual\n+}\n+\n+test_expect_success 'setup' '\n+\n+\tcommit master &&\n+\tgit checkout -b subspace/one master &&\n+\tcommit one &&\n+\tgit checkout -b subspace/two master &&\n+\tcommit two &&\n+\tgit checkout -b subspace-x master &&\n+\tcommit subspace-x &&\n+\tgit checkout -b other/three master &&\n+\tcommit three &&\n+\tgit checkout -b someref master &&\n+\tcommit some &&\n+\tgit checkout master &&\n+\tcommit master2\n+'\n+\n+test_expect_success 'rev-parse --glob=refs/heads/subspace/*' '\n+\n+\tcompare rev-parse \"subspace/one subspace/two\" \"--glob=refs/heads/subspace/*\"\n+\n+'\n+\n+test_expect_success 'rev-parse --glob=heads/subspace/*' '\n+\n+\tcompare rev-parse \"subspace/one subspace/two\" \"--glob=heads/subspace/*\"\n+\n+'\n+\n+test_expect_success 'rev-parse --glob=refs/heads/subspace/' '\n+\n+\tcompare rev-parse \"subspace/one subspace/two\" \"--glob=refs/heads/subspace/\"\n+\n+'\n+\n+test_expect_success 'rev-parse --glob=heads/subspace/' '\n+\n+\tcompare rev-parse \"subspace/one subspace/two\" \"--glob=heads/subspace/\"\n+\n+'\n+\n+test_expect_success 'rev-parse --glob=heads/subspace' '\n+\n+\tcompare rev-parse \"subspace/one subspace/two\" \"--glob=heads/subspace\"\n+\n+'\n+\n+test_expect_success 'rev-parse --glob=heads/subspace/* --glob=heads/other/*' '\n+\n+\tcompare rev-parse \"subspace/one subspace/two other/three\" \"--glob=heads/subspace/* --glob=heads/other/*\"\n+\n+'\n+\n+test_expect_success 'rev-parse --glob=heads/someref/* master' '\n+\n+\tcompare rev-parse \"master\" \"--glob=heads/someref/* master\"\n+\n+'\n+\n+test_expect_success 'rev-parse --glob=heads/*' '\n+\n+\tcompare rev-parse \"master other/three someref subspace-x subspace/one subspace/two\" \"--glob=heads/*\"\n+\n+'\n+\n+test_expect_success 'rev-list --glob=refs/heads/subspace/*' '\n+\n+\tcompare rev-list \"subspace/one subspace/two\" \"--glob=refs/heads/subspace/*\"\n+\n+'\n+\n+test_expect_success 'rev-list --glob=heads/subspace/*' '\n+\n+\tcompare rev-list \"subspace/one subspace/two\" \"--glob=heads/subspace/*\"\n+\n+'\n+\n+test_expect_success 'rev-list --glob=refs/heads/subspace/' '\n+\n+\tcompare rev-list \"subspace/one subspace/two\" \"--glob=refs/heads/subspace/\"\n+\n+'\n+\n+test_expect_success 'rev-list --glob=heads/subspace/' '\n+\n+\tcompare rev-list \"subspace/one subspace/two\" \"--glob=heads/subspace/\"\n+\n+'\n+\n+test_expect_success 'rev-list --glob=heads/subspace' '\n+\n+\tcompare rev-list \"subspace/one subspace/two\" \"--glob=heads/subspace\"\n+\n+'\n+\n+test_expect_success 'rev-list --glob=heads/someref/* master' '\n+\n+\tcompare rev-list \"master\" \"--glob=heads/someref/* master\"\n+\n+'\n+\n+test_expect_success 'rev-list --glob=heads/subspace/* --glob=heads/other/*' '\n+\n+\tcompare rev-list \"subspace/one subspace/two other/three\" \"--glob=heads/subspace/* --glob=heads/other/*\"\n+\n+'\n+\n+test_expect_success 'rev-list --glob=heads/*' '\n+\n+\tcompare rev-list \"master other/three someref subspace-x subspace/one subspace/two\" \"--glob=heads/*\"\n+\n+'\n+\n+\n+test_done\n-- \n1.6.6.199.gff4b0\n"},{"id":"132175","messageId":"1263980906-11058-2-git-send-email-ilari.liusvaara@elisanet.fi","threadId":"22300","inReplyTo":"1263980906-11058-1-git-send-email-ilari.liusvaara@elisanet.fi","subject":"[PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern","fromName":"Ilari Liusvaara","fromEmail":"ilari.liusvaara@elisanet.fi","sentAt":"2010-01-20T09:48:26Z","receivedAt":"2010-01-20T09:48:26Z","isPatch":true,"sender":{"key":"ilari.liusvaara@elisanet.fi","avatar":null},"body":"Since local branch, tags and remote tracking branch namespaces are\nmost often used, add shortcut notations for globbing those in\nmanner similar to --glob option.\n\nWith this, one can express the \"what I have but origin doesn't?\"\nas:\n\n'git log --branches --not --remotes=origin'\n\nOriginal-idea-by: Johannes Sixt <j6t@kdbg.org>\nSigned-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>\n---\nBuilds on top of --glob patch.\n\n Documentation/git-log.txt          |    4 +-\n Documentation/git-rev-list.txt     |    6 ++--\n Documentation/git-rev-parse.txt    |   19 +++++++---\n Documentation/rev-list-options.txt |   18 +++++++---\n builtin-rev-parse.c                |   18 ++++++++++\n refs.c                             |   12 ++++++-\n refs.h                             |    1 +\n revision.c                         |   18 ++++++++++\n t/t6018-rev-list-glob.sh           |   62 +++++++++++++++++++++++++++++++++++-\n 9 files changed, 138 insertions(+), 20 deletions(-)\n\ndiff --git a/Documentation/git-log.txt b/Documentation/git-log.txt\nindex 0b874e3..0acd526 100644\n--- a/Documentation/git-log.txt\n+++ b/Documentation/git-log.txt\n@@ -107,13 +107,13 @@ git log --follow builtin-rev-list.c::\n \tthose commits that occurred before the file was given its\n \tpresent name.\n \n-git log --branches --not --glob=remotes/origin/*::\n+git log --branches --not --remotes=origin::\n \n \tShows all commits that are in any of local branches but not in\n \tany of remote tracking branches for 'origin' (what you have that\n \torigin doesn't).\n \n-git log master --not --glob=remotes/*/master::\n+git log master --not --remotes=*/master::\n \n \tShows all commits that are in local master but not in any remote\n \trepository master branches.\ndiff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt\nindex 33122a3..f857116 100644\n--- a/Documentation/git-rev-list.txt\n+++ b/Documentation/git-rev-list.txt\n@@ -21,9 +21,9 @@ SYNOPSIS\n \t     [ \\--full-history ]\n \t     [ \\--not ]\n \t     [ \\--all ]\n-\t     [ \\--branches ]\n-\t     [ \\--tags ]\n-\t     [ \\--remotes ]\n+\t     [ \\--branches[=pattern] ]\n+\t     [ \\--tags=[pattern] ]\n+\t     [ \\--remotes=[pattern] ]\n \t     [ \\--glob=glob-pattern ]\n \t     [ \\--stdin ]\n \t     [ \\--quiet ]\ndiff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt\nindex 6eb8c14..afe8699 100644\n--- a/Documentation/git-rev-parse.txt\n+++ b/Documentation/git-rev-parse.txt\n@@ -103,14 +103,21 @@ OPTIONS\n --all::\n \tShow all refs found in `$GIT_DIR/refs`.\n \n---branches::\n-\tShow branch refs found in `$GIT_DIR/refs/heads`.\n+--branches[=pattern]::\n+\tShow branch refs found in `$GIT_DIR/refs/heads`. If `pattern`\n+\tis given, only branches matching given shell glob are shown.\n+\tIf pattern lacks '?', '*', or '[', '/*' at the end is impiled.\n \n---tags::\n-\tShow tag refs found in `$GIT_DIR/refs/tags`.\n+--tags[=pattern]::\n+\tShow tag refs found in `$GIT_DIR/refs/tags`. If `pattern`\n+\tis given, only tags matching given shell glob are shown.\n+\tIf pattern lacks '?', '*', or '[', '/*' at the end is impiled.\n \n---remotes::\n-\tShow tag refs found in `$GIT_DIR/refs/remotes`.\n+--remotes[=pattern]::\n+\tShow tag refs found in `$GIT_DIR/refs/remotes`. If `pattern`\n+\tis given, only remote tracking branches matching given shell glob\n+\tare shown. If pattern lacks '?', '*', or '[', '/*' at the end is\n+\timpiled.\n \n --glob=glob-pattern::\n \tShow refs matching shell glob pattern `glob-pattern`. If pattern\ndiff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt\nindex 6d03c17..3ef7117 100644\n--- a/Documentation/rev-list-options.txt\n+++ b/Documentation/rev-list-options.txt\n@@ -228,20 +228,26 @@ endif::git-rev-list[]\n \tPretend as if all the refs in `$GIT_DIR/refs/` are listed on the\n \tcommand line as '<commit>'.\n \n---branches::\n+--branches[=pattern]::\n \n \tPretend as if all the refs in `$GIT_DIR/refs/heads` are listed\n-\ton the command line as '<commit>'.\n+\ton the command line as '<commit>'. If `pattern` is given, limit\n+\tbranches to ones matching given shell glob. If pattern lacks '?',\n+\t'*', or '[', '/*' at the end is impiled.\n \n---tags::\n+--tags[=pattern]::\n \n \tPretend as if all the refs in `$GIT_DIR/refs/tags` are listed\n-\ton the command line as '<commit>'.\n+\ton the command line as '<commit>'. If `pattern` is given, limit\n+\ttags to ones matching given shell glob. If pattern lacks '?', '*',\n+\tor '[', '/*' at the end is impiled.\n \n---remotes::\n+--remotes[=pattern]::\n \n \tPretend as if all the refs in `$GIT_DIR/refs/remotes` are listed\n-\ton the command line as '<commit>'.\n+\ton the command line as '<commit>'. If `pattern`is given, limit\n+\tremote tracking branches to ones matching given shell glob.\n+\tIf pattern lacks '?', '*', or '[', '/*' at the end is impiled.\n \n --glob=glob-pattern::\n \tPretend as if all the refs matching shell glob `glob-pattern`\ndiff --git a/builtin-rev-parse.c b/builtin-rev-parse.c\nindex a635dde..d14fe20 100644\n--- a/builtin-rev-parse.c\n+++ b/builtin-rev-parse.c\n@@ -41,6 +41,7 @@ static int is_rev_argument(const char *arg)\n \t\t\"--all\",\n \t\t\"--bisect\",\n \t\t\"--dense\",\n+\t\t\"--branches=\",\n \t\t\"--branches\",\n \t\t\"--header\",\n \t\t\"--max-age=\",\n@@ -51,9 +52,11 @@ static int is_rev_argument(const char *arg)\n \t\t\"--objects-edge\",\n \t\t\"--parents\",\n \t\t\"--pretty\",\n+\t\t\"--remotes=\",\n \t\t\"--remotes\",\n \t\t\"--glob=\",\n \t\t\"--sparse\",\n+\t\t\"--tags=\",\n \t\t\"--tags\",\n \t\t\"--topo-order\",\n \t\t\"--date-order\",\n@@ -570,10 +573,20 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\tfor_each_ref_in(\"refs/bisect/good\", anti_reference, NULL);\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!prefixcmp(arg, \"--branches=\")) {\n+\t\t\t\tfor_each_glob_ref_in(show_reference, arg + 11,\n+\t\t\t\t\t\"refs/heads/\", NULL);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(arg, \"--branches\")) {\n \t\t\t\tfor_each_branch_ref(show_reference, NULL);\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!prefixcmp(arg, \"--tags=\")) {\n+\t\t\t\tfor_each_glob_ref_in(show_reference, arg + 7,\n+\t\t\t\t\t\"refs/tags/\", NULL);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(arg, \"--tags\")) {\n \t\t\t\tfor_each_tag_ref(show_reference, NULL);\n \t\t\t\tcontinue;\n@@ -582,6 +595,11 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\tfor_each_glob_ref(show_reference, arg + 7, NULL);\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!prefixcmp(arg, \"--remotes=\")) {\n+\t\t\t\tfor_each_glob_ref_in(show_reference, arg + 10,\n+\t\t\t\t\t\"refs/remotes/\", NULL);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(arg, \"--remotes\")) {\n \t\t\t\tfor_each_remote_ref(show_reference, NULL);\n \t\t\t\tcontinue;\ndiff --git a/refs.c b/refs.c\nindex 5adf69c..af78c31 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -691,15 +691,18 @@ int for_each_replace_ref(each_ref_fn fn, void *cb_data)\n \treturn do_for_each_ref(\"refs/replace/\", fn, 13, 0, cb_data);\n }\n \n-int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)\n+int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,\n+\tconst char *prefix, void *cb_data)\n {\n \tstruct strbuf real_pattern = STRBUF_INIT;\n \tstruct ref_filter filter;\n \tconst char *has_glob_specials;\n \tint ret;\n \n-\tif (prefixcmp(pattern, \"refs/\"))\n+\tif (!prefix && prefixcmp(pattern, \"refs/\"))\n \t\tstrbuf_addstr(&real_pattern, \"refs/\");\n+\telse if (prefix)\n+\t\tstrbuf_addstr(&real_pattern, prefix);\n \tstrbuf_addstr(&real_pattern, pattern);\n \n \thas_glob_specials = strpbrk(pattern, \"?*[\");\n@@ -720,6 +723,11 @@ int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)\n \treturn ret;\n }\n \n+int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)\n+{\n+\treturn for_each_glob_ref_in(fn, pattern, NULL, cb_data);\n+}\n+\n int for_each_rawref(each_ref_fn fn, void *cb_data)\n {\n \treturn do_for_each_ref(\"refs/\", fn, 0,\ndiff --git a/refs.h b/refs.h\nindex 78ad173..f7648b9 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -26,6 +26,7 @@ extern int for_each_branch_ref(each_ref_fn, void *);\n extern int for_each_remote_ref(each_ref_fn, void *);\n extern int for_each_replace_ref(each_ref_fn, void *);\n extern int for_each_glob_ref(each_ref_fn, const char *pattern, void *);\n+extern int for_each_glob_ref_in(each_ref_fn, const char *pattern, const char* prefix, void *);\n \n /* can be used to learn about broken ref and symref */\n extern int for_each_rawref(each_ref_fn, void *);\ndiff --git a/revision.c b/revision.c\nindex 162b182..1e9277d 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1364,6 +1364,24 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n \t\t\t\tfor_each_glob_ref(handle_one_ref, arg + 7, &cb);\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!prefixcmp(arg, \"--branches=\")) {\n+\t\t\t\tstruct all_refs_cb cb;\n+\t\t\t\tinit_all_refs_cb(&cb, revs, flags);\n+\t\t\t\tfor_each_glob_ref_in(handle_one_ref, arg + 11, \"refs/heads/\", &cb);\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tif (!prefixcmp(arg, \"--tags=\")) {\n+\t\t\t\tstruct all_refs_cb cb;\n+\t\t\t\tinit_all_refs_cb(&cb, revs, flags);\n+\t\t\t\tfor_each_glob_ref_in(handle_one_ref, arg + 7, \"refs/tags/\", &cb);\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tif (!prefixcmp(arg, \"--remotes=\")) {\n+\t\t\t\tstruct all_refs_cb cb;\n+\t\t\t\tinit_all_refs_cb(&cb, revs, flags);\n+\t\t\t\tfor_each_glob_ref_in(handle_one_ref, arg + 10, \"refs/remotes/\", &cb);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(arg, \"--reflog\")) {\n \t\t\t\thandle_reflog(revs, flags);\n \t\t\t\tcontinue;\ndiff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh\nindex 0d7e4bc..bf85e0c 100755\n--- a/t/t6018-rev-list-glob.sh\n+++ b/t/t6018-rev-list-glob.sh\n@@ -33,7 +33,9 @@ test_expect_success 'setup' '\n \tgit checkout -b someref master &&\n \tcommit some &&\n \tgit checkout master &&\n-\tcommit master2\n+\tcommit master2 &&\n+\tgit tag foo/bar master &&\n+\tgit update-ref refs/remotes/foo/baz master\n '\n \n test_expect_success 'rev-parse --glob=refs/heads/subspace/*' '\n@@ -66,6 +68,24 @@ test_expect_success 'rev-parse --glob=heads/subspace' '\n \n '\n \n+test_expect_success 'rev-parse --branches=subspace/*' '\n+\n+\tcompare rev-parse \"subspace/one subspace/two\" \"--branches=subspace/*\"\n+\n+'\n+\n+test_expect_success 'rev-parse --branches=subspace/' '\n+\n+\tcompare rev-parse \"subspace/one subspace/two\" \"--branches=subspace/\"\n+\n+'\n+\n+test_expect_success 'rev-parse --branches=subspace' '\n+\n+\tcompare rev-parse \"subspace/one subspace/two\" \"--branches=subspace\"\n+\n+'\n+\n test_expect_success 'rev-parse --glob=heads/subspace/* --glob=heads/other/*' '\n \n \tcompare rev-parse \"subspace/one subspace/two other/three\" \"--glob=heads/subspace/* --glob=heads/other/*\"\n@@ -84,6 +104,18 @@ test_expect_success 'rev-parse --glob=heads/*' '\n \n '\n \n+test_expect_success 'rev-parse --tags=foo' '\n+\n+\tcompare rev-parse \"foo/bar\" \"--tags=foo\"\n+\n+'\n+\n+test_expect_success 'rev-parse --remotes=foo' '\n+\n+\tcompare rev-parse \"foo/baz\" \"--remotes=foo\"\n+\n+'\n+\n test_expect_success 'rev-list --glob=refs/heads/subspace/*' '\n \n \tcompare rev-list \"subspace/one subspace/two\" \"--glob=refs/heads/subspace/*\"\n@@ -114,6 +146,23 @@ test_expect_success 'rev-list --glob=heads/subspace' '\n \n '\n \n+test_expect_success 'rev-list --branches=subspace/*' '\n+\n+\tcompare rev-list \"subspace/one subspace/two\" \"--branches=subspace/*\"\n+\n+'\n+\n+test_expect_success 'rev-list --branches=subspace/' '\n+\n+\tcompare rev-list \"subspace/one subspace/two\" \"--branches=subspace/\"\n+\n+'\n+\n+test_expect_success 'rev-list --branches=subspace' '\n+\n+\tcompare rev-list \"subspace/one subspace/two\" \"--branches=subspace\"\n+\n+'\n test_expect_success 'rev-list --glob=heads/someref/* master' '\n \n \tcompare rev-list \"master\" \"--glob=heads/someref/* master\"\n@@ -132,5 +181,16 @@ test_expect_success 'rev-list --glob=heads/*' '\n \n '\n \n+test_expect_success 'rev-list --tags=foo' '\n+\n+\tcompare rev-list \"foo/bar\" \"--tags=foo\"\n+\n+'\n+\n+test_expect_success 'rev-list --remotes=foo' '\n+\n+\tcompare rev-list \"foo/baz\" \"--remotes=foo\"\n+\n+'\n \n test_done\n-- \n1.6.6.199.gff4b0\n"},{"id":"132180","messageId":"7vska13wt0.fsf@alter.siamese.dyndns.org","threadId":"22300","inReplyTo":"1263980906-11058-1-git-send-email-ilari.liusvaara@elisanet.fi","subject":"Re: [PATCH 1/2] rev-parse --glob","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-20T10:17:15Z","receivedAt":"2010-01-20T10:17:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ilari Liusvaara <ilari.liusvaara@elisanet.fi> writes:\n\n> Add --glob=<glob-pattern> option to rev-parse and everything that\n> accepts its options. This option matches all refs that match given\n> shell glob pattern (complete with some DWIM logic).\n>\n> Example:\n>\n> 'git log --branches --not --glob=remotes/origin'\n>\n> To show what you have that origin doesn't.\n>\n> Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>\n> ---\n\nLooks fairly competently done.  Does this mean you've abandoned the --namespace\nseries?  I don't mind reverting them from 'next'.\n\n> +static int filter_refs(const char* ref, const unsigned char *sha, int flags,\n> +\tvoid* data)\n> +{\n> +\tstruct ref_filter *filter = (struct ref_filter*)data;\n> +\tif (fnmatch(filter->pattern, ref, 0))\n> +\t\treturn 0;\n\nIn many places (not just refs) we use \"If leading path component matches,\nor fnmatch() says Ok\" (e.g. builtin-for-each-ref.c, builtin_grep.c), and\nin some other places we only use fnmatch().  I think it is better to pick\none convention, and adjust the other one to match, and my gut feeling is\nthat \"leading path or fnmatch()\", while theologically might be messier,\nwould be more useful in practice.  And that was why I did my \"like this\"\npatch http://article.gmane.org/gmane.comp.version-control.git/137492 that way.\n\nMy longer term desire is to consolidate these fnmatch() users to call a\nsingle helper function, and then perhaps replace fnmatch() in that helper\nfunction with something more powerful.  Although I do not personally care\ntoo much, people often wanted to have \"path/**/leaf-that-is-deep\" matcher.\n\nI don't want you to go there just yet with this series, but at least\nfollowing the same style everywhere would pave the way to consolidating\nthem.\n\n> @@ -674,6 +691,35 @@ int for_each_replace_ref(each_ref_fn fn, void *cb_data)\n>  \treturn do_for_each_ref(\"refs/replace/\", fn, 13, 0, cb_data);\n>  }\n>  \n> +int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)\n> +{\n> +\tstruct strbuf real_pattern = STRBUF_INIT;\n> +\tstruct ref_filter filter;\n> +\tconst char *has_glob_specials;\n> +\tint ret;\n> +\n> +\tif (prefixcmp(pattern, \"refs/\"))\n> +\t\tstrbuf_addstr(&real_pattern, \"refs/\");\n> +\tstrbuf_addstr(&real_pattern, pattern);\n> +\n> +\thas_glob_specials = strpbrk(pattern, \"?*[\");\n\nWould the need for this code hopefully disappear if we take the \"leading\npath or fnmatch()\" check?  If we still need this, we probably would want\nto add a has_glob_special() helper function not as a hardcoded srpbrk(),\nbut in terms of is_glob_special() in git-compat-util.h.\n\nThanks.\n"},{"id":"132181","messageId":"7vockp3wqc.fsf@alter.siamese.dyndns.org","threadId":"22300","inReplyTo":"1263980906-11058-2-git-send-email-ilari.liusvaara@elisanet.fi","subject":"Re: [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-20T10:18:51Z","receivedAt":"2010-01-20T10:18:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ilari Liusvaara <ilari.liusvaara@elisanet.fi> writes:\n\n> Since local branch, tags and remote tracking branch namespaces are\n> most often used, add shortcut notations for globbing those in\n> manner similar to --glob option.\n>\n> With this, one can express the \"what I have but origin doesn't?\"\n> as:\n>\n> 'git log --branches --not --remotes=origin'\n>\n> Original-idea-by: Johannes Sixt <j6t@kdbg.org>\n> Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>\n> ---\n\nNice.\n"},{"id":"132188","messageId":"20100120110843.GA11343@Knoppix","threadId":"22300","inReplyTo":"7vska13wt0.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/2] rev-parse --glob","fromName":"Ilari Liusvaara","fromEmail":"ilari.liusvaara@elisanet.fi","sentAt":"2010-01-20T11:08:44Z","receivedAt":"2010-01-20T11:08:44Z","isPatch":true,"sender":{"key":"ilari.liusvaara@elisanet.fi","avatar":null},"body":"On Wed, Jan 20, 2010 at 02:17:15AM -0800, Junio C Hamano wrote:\n> Ilari Liusvaara <ilari.liusvaara@elisanet.fi> writes:\n> \n> Looks fairly competently done.  Does this mean you've abandoned the --namespace\n> series?  I don't mind reverting them from 'next'.\n\nPretty much.\n \n> > +static int filter_refs(const char* ref, const unsigned char *sha, int flags,\n> > +\tvoid* data)\n> > +{\n> > +\tstruct ref_filter *filter = (struct ref_filter*)data;\n> > +\tif (fnmatch(filter->pattern, ref, 0))\n> > +\t\treturn 0;\n> \n> In many places (not just refs) we use \"If leading path component matches,\n> or fnmatch() says Ok\" (e.g. builtin-for-each-ref.c, builtin_grep.c), and\n> in some other places we only use fnmatch().  I think it is better to pick\n> one convention, and adjust the other one to match, and my gut feeling is\n> that \"leading path or fnmatch()\", while theologically might be messier,\n> would be more useful in practice.  And that was why I did my \"like this\"\n> patch http://article.gmane.org/gmane.comp.version-control.git/137492 that way.\n\nThat pattern of course has been edited before (and the namespace behavoiour\nis implemented that way).\n\n> My longer term desire is to consolidate these fnmatch() users to call a\n> single helper function, and then perhaps replace fnmatch() in that helper\n> function with something more powerful.  Although I do not personally care\n> too much, people often wanted to have \"path/**/leaf-that-is-deep\" matcher.\n\nExtended globs? Except that:\n\n'git check-ref-format refs/heads/X+\\(a\\|b\\) ; echo $?' => 0\n\nAnd '+(a|b)' is wildcard in extended glob (not expressible with standard\nglob operators). \n\nExtended globbing in gitignore would be useful as some have asked if there\nis way to use regular expressions there (nope). At least extended globs\nare equivalent to regular expressions in power.\n\n \n> > @@ -674,6 +691,35 @@ int for_each_replace_ref(each_ref_fn fn, void *cb_data)\n> >  \treturn do_for_each_ref(\"refs/replace/\", fn, 13, 0, cb_data);\n> >  }\n> >  \n> > +int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)\n> > +{\n> > +\tstruct strbuf real_pattern = STRBUF_INIT;\n> > +\tstruct ref_filter filter;\n> > +\tconst char *has_glob_specials;\n> > +\tint ret;\n> > +\n> > +\tif (prefixcmp(pattern, \"refs/\"))\n> > +\t\tstrbuf_addstr(&real_pattern, \"refs/\");\n> > +\tstrbuf_addstr(&real_pattern, pattern);\n> > +\n> > +\thas_glob_specials = strpbrk(pattern, \"?*[\");\n> \n> Would the need for this code hopefully disappear if we take the \"leading\n> path or fnmatch()\" check?  If we still need this, we probably would want\n> to add a has_glob_special() helper function not as a hardcoded srpbrk(),\n> but in terms of is_glob_special() in git-compat-util.h.\n\n'--glob=remotes/origin' and '--glob=remotes/origin*' are not the same. The\nfirst gets DWIMed to '--glob=refs/remotes/origin/*'. The usual case for\nglobbing is globbing entiere namespace (name of one remote can be prefix\nof another).\n\n-Ilari\n"},{"id":"132295","messageId":"4B584DDD.7060701@viscovery.net","threadId":"22300","inReplyTo":"1263980906-11058-2-git-send-email-ilari.liusvaara@elisanet.fi","subject":"Re: [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2010-01-21T12:51:41Z","receivedAt":"2010-01-21T12:51:41Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Works for me, thank you very much!\n\nJunio, kindly squash in these speeling fixes in both patches:\n\nsed -i 's/impiled/implied/g' `git diff HEAD^ --name-only Documentation/`\n\n-- Hannes\n"},{"id":"132297","messageId":"4B585BED.700@drmicha.warpmail.net","threadId":"22300","inReplyTo":"4B584DDD.7060701@viscovery.net","subject":"Re: [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2010-01-21T13:51:41Z","receivedAt":"2010-01-21T13:51:41Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Johannes Sixt venit, vidit, dixit 21.01.2010 13:51:\n> Works for me, thank you very much!\n> \n> Junio, kindly squash in these speeling fixes in both patches:\n> \n> sed -i 's/impiled/implied/g' `git diff HEAD^ --name-only Documentation/`\n> \n\nAlso, the option descriptions are kind of staccato English right now,\nlacking a few \"the\" here and there. Should we fix this or simply leave\nit at that?\n\nMichael\n"},{"id":"132316","messageId":"201001211827.05847.trast@student.ethz.ch","threadId":"22300","inReplyTo":"4B585BED.700@drmicha.warpmail.net","subject":"Re: [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-01-21T17:27:05Z","receivedAt":"2010-01-21T17:27:05Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Thanks Ilari for implementing my wishes :-)\n\nOn Thursday 21 January 2010 14:51:41 Michael J Gruber wrote:\n> Johannes Sixt venit, vidit, dixit 21.01.2010 13:51:\n> > Works for me, thank you very much!\n> > \n> > Junio, kindly squash in these speeling fixes in both patches:\n> > \n> > sed -i 's/impiled/implied/g' `git diff HEAD^ --name-only Documentation/`\n> > \n> \n> Also, the option descriptions are kind of staccato English right now,\n> lacking a few \"the\" here and there. Should we fix this or simply leave\n> it at that?\n\nMaybe the --branches, --tags and --remotes could be consolidated a\nbit, as in the draft patch below.  If --all took a pattern, it could\nbe included there too, but that would probably look too weird.\n\ndiff --git i/Documentation/git-rev-parse.txt w/Documentation/git-rev-parse.txt\nindex 2bbb566..6fce919 100644\n--- i/Documentation/git-rev-parse.txt\n+++ w/Documentation/git-rev-parse.txt\n@@ -104,29 +104,26 @@ OPTIONS\n \tShow all refs found in `$GIT_DIR/refs`.\n \n --branches[=pattern]::\n-\tShow branch refs found in `$GIT_DIR/refs/heads`. If `pattern`\n-\tis given, only branches matching given shell glob are shown.\n-\tIf pattern lacks '?', '*', or '[', '/*' at the end is impiled.\n-\n --tags[=pattern]::\n-\tShow tag refs found in `$GIT_DIR/refs/tags`. If `pattern`\n-\tis given, only tags matching given shell glob are shown.\n-\tIf pattern lacks '?', '*', or '[', '/*' at the end is impiled.\n-\n --remotes[=pattern]::\n-\tShow tag refs found in `$GIT_DIR/refs/remotes`. If `pattern`\n-\tis given, only remote tracking branches matching given shell glob\n-\tare shown. If pattern lacks '?', '*', or '[', '/*' at the end is\n-\timpiled.\n+\tShow all branches, tags, or remote-tracking branches,\n+\trespectively (i.e., refs found in `$GIT_DIR/refs/heads`,\n+\t`$GIT_DIR/refs/tags`, or `$GIT_DIR/refs/remotes`,\n+\trespectively).\n++\n+If a `pattern` is given, only refs matching the given shell glob are\n+shown.  If the pattern does not contain a globbing character (`?`,\n+`\\*`, or `[`), it is anchored by appending `/\\*`.\n+\n+--glob=pattern::\n+\tShow all refs matching the shell glob pattern `pattern`. If\n+\tthe pattern does not start with `refs/`, this is automatically\n+\tprepended.  If the pattern does not contain a globbing\n+\tcharacter (`?`, `\\*`, or `[`), it is anchored by appending `/\\*`.\n \n --show-toplevel::\n \tShow the absolute path of the top-level directory.\n \n---glob=glob-pattern::\n-\tShow refs matching shell glob pattern `glob-pattern`. If pattern\n-\tspecified lacks leading 'refs/', it is automatically prepended.\n-\tIf pattern lacks '?', '*', or '[', '/*' at the end is impiled.\n-\n --show-prefix::\n \tWhen the command is invoked from a subdirectory, show the\n \tpath of the current directory relative to the top-level\n\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"132321","messageId":"7vmy07s5km.fsf@alter.siamese.dyndns.org","threadId":"22300","inReplyTo":"4B584DDD.7060701@viscovery.net","subject":"Re: [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-21T17:58:33Z","receivedAt":"2010-01-21T17:58:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j.sixt@viscovery.net> writes:\n\n> Works for me, thank you very much!\n>\n> Junio, kindly squash in these speeling fixes in both patches:\n>\n> sed -i 's/impiled/implied/g' `git diff HEAD^ --name-only Documentation/`\n\nThanks; I've already pushed out what I was preparing before going to bed,\nso these fixes need to happen in-tree as incremental changes.\n"},{"id":"132331","messageId":"7vbpgnp6d5.fsf@alter.siamese.dyndns.org","threadId":"22300","inReplyTo":"201001211827.05847.trast@student.ethz.ch","subject":"Re: [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-21T20:09:42Z","receivedAt":"2010-01-21T20:09:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@student.ethz.ch> writes:\n\n> Maybe the --branches, --tags and --remotes could be consolidated a\n> bit, as in the draft patch below.\n\nLooks sensible.\n\n> diff --git i/Documentation/git-rev-parse.txt w/Documentation/git-rev-parse.txt\n> index 2bbb566..6fce919 100644\n> --- i/Documentation/git-rev-parse.txt\n> +++ w/Documentation/git-rev-parse.txt\n> @@ -104,29 +104,26 @@ OPTIONS\n>  \tShow all refs found in `$GIT_DIR/refs`.\n>  \n>  --branches[=pattern]::\n> -\tShow branch refs found in `$GIT_DIR/refs/heads`. If `pattern`\n> -\tis given, only branches matching given shell glob are shown.\n> -\tIf pattern lacks '?', '*', or '[', '/*' at the end is impiled.\n> -\n>  --tags[=pattern]::\n> -\tShow tag refs found in `$GIT_DIR/refs/tags`. If `pattern`\n> -\tis given, only tags matching given shell glob are shown.\n> -\tIf pattern lacks '?', '*', or '[', '/*' at the end is impiled.\n> -\n>  --remotes[=pattern]::\n> -\tShow tag refs found in `$GIT_DIR/refs/remotes`. If `pattern`\n> -\tis given, only remote tracking branches matching given shell glob\n> -\tare shown. If pattern lacks '?', '*', or '[', '/*' at the end is\n> -\timpiled.\n> +\tShow all branches, tags, or remote-tracking branches,\n> +\trespectively (i.e., refs found in `$GIT_DIR/refs/heads`,\n> +\t`$GIT_DIR/refs/tags`, or `$GIT_DIR/refs/remotes`,\n> +\trespectively).\n> ++\n> +If a `pattern` is given, only refs matching the given shell glob are\n> +shown.  If the pattern does not contain a globbing character (`?`,\n> +`\\*`, or `[`), it is anchored by appending `/\\*`.\n> +\n> +--glob=pattern::\n> +\tShow all refs matching the shell glob pattern `pattern`. If\n> +\tthe pattern does not start with `refs/`, this is automatically\n> +\tprepended.  If the pattern does not contain a globbing\n> +\tcharacter (`?`, `\\*`, or `[`), it is anchored by appending `/\\*`.\n>  \n>  --show-toplevel::\n>  \tShow the absolute path of the top-level directory.\n>  \n> ---glob=glob-pattern::\n> -\tShow refs matching shell glob pattern `glob-pattern`. If pattern\n> -\tspecified lacks leading 'refs/', it is automatically prepended.\n> -\tIf pattern lacks '?', '*', or '[', '/*' at the end is impiled.\n> -\n>  --show-prefix::\n>  \tWhen the command is invoked from a subdirectory, show the\n>  \tpath of the current directory relative to the top-level\n>\n>\n> -- \n> Thomas Rast\n> trast@{inf,student}.ethz.ch\n"},{"id":"132344","messageId":"e2e992cfb93335b400fd9ec67c6d38cb0157b006.1264119524.git.trast@student.ethz.ch","threadId":"22300","inReplyTo":"7vbpgnp6d5.fsf@alter.siamese.dyndns.org","subject":"[PATCH] Documentation: improve description of --glob=pattern and friends","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-01-22T00:21:38Z","receivedAt":"2010-01-22T00:21:38Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Consolidate the descriptions of --branches, --tags and --remotes a\nbit, to make it less repetitive.  Improve the grammar a bit, and spell\nout the meaning of the 'append /*' rule.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n\nCompared to the earlier draft, I changed \"it is anchored\" (by\nappending '/*') to \"it is turned into a prefix match\", since this is\nnot anchoring in the ^regex$ sense.  (I guess 'leading-component\nmatch' would be even more accurate, but that makes the sentence\nunwieldy in my ears.)\n\n\n Documentation/git-rev-parse.txt |   32 +++++++++++++++-----------------\n 1 files changed, 15 insertions(+), 17 deletions(-)\n\ndiff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt\nindex e2cb913..e7845d4 100644\n--- a/Documentation/git-rev-parse.txt\n+++ b/Documentation/git-rev-parse.txt\n@@ -104,25 +104,23 @@ OPTIONS\n \tShow all refs found in `$GIT_DIR/refs`.\n \n --branches[=pattern]::\n-\tShow branch refs found in `$GIT_DIR/refs/heads`. If `pattern`\n-\tis given, only branches matching given shell glob are shown.\n-\tIf pattern lacks '?', '*', or '[', '/*' at the end is impiled.\n-\n --tags[=pattern]::\n-\tShow tag refs found in `$GIT_DIR/refs/tags`. If `pattern`\n-\tis given, only tags matching given shell glob are shown.\n-\tIf pattern lacks '?', '*', or '[', '/*' at the end is impiled.\n-\n --remotes[=pattern]::\n-\tShow tag refs found in `$GIT_DIR/refs/remotes`. If `pattern`\n-\tis given, only remote tracking branches matching given shell glob\n-\tare shown. If pattern lacks '?', '*', or '[', '/*' at the end is\n-\timpiled.\n-\n---glob=glob-pattern::\n-\tShow refs matching shell glob pattern `glob-pattern`. If pattern\n-\tspecified lacks leading 'refs/', it is automatically prepended.\n-\tIf pattern lacks '?', '*', or '[', '/*' at the end is impiled.\n+\tShow all branches, tags, or remote-tracking branches,\n+\trespectively (i.e., refs found in `$GIT_DIR/refs/heads`,\n+\t`$GIT_DIR/refs/tags`, or `$GIT_DIR/refs/remotes`,\n+\trespectively).\n++\n+If a `pattern` is given, only refs matching the given shell glob are\n+shown.  If the pattern does not contain a globbing character (`?`,\n+`\\*`, or `[`), it is turned into a prefix match by appending `/\\*`.\n+\n+--glob=pattern::\n+\tShow all refs matching the shell glob pattern `pattern`. If\n+\tthe pattern does not start with `refs/`, this is automatically\n+\tprepended.  If the pattern does not contain a globbing\n+\tcharacter (`?`, `\\*`, or `[`), it is turned into a prefix\n+\tmatch by appending `/\\*`.\n \n --show-toplevel::\n \tShow the absolute path of the top-level directory.\n-- \n1.6.6.1.534.gf034a\n"},{"id":"132350","messageId":"7v1vhjj72d.fsf@alter.siamese.dyndns.org","threadId":"22300","inReplyTo":"e2e992cfb93335b400fd9ec67c6d38cb0157b006.1264119524.git.trast@student.ethz.ch","subject":"Re: [PATCH] Documentation: improve description of --glob=pattern and friends","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-22T00:51:06Z","receivedAt":"2010-01-22T00:51:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@student.ethz.ch> writes:\n\n> Consolidate the descriptions of --branches, --tags and --remotes a\n> bit, to make it less repetitive.  Improve the grammar a bit, and spell\n> out the meaning of the 'append /*' rule.\n>\n> Signed-off-by: Thomas Rast <trast@student.ethz.ch>\n> ---\n>\n> Compared to the earlier draft, I changed \"it is anchored\" (by\n> appending '/*') to \"it is turned into a prefix match\", since this is\n> not anchoring in the ^regex$ sense.  (I guess 'leading-component\n> match' would be even more accurate, but that makes the sentence\n> unwieldy in my ears.)\n\nBy the way, we may someday want to change that to do FNM_PATHNAME instead\nof just a flat glob.\n\nIncidentally, that is why I prefer the earlier suggestion to do \"check\nwith memcmp() if it is a path-prefix, and if it fails, then give\nfnmatch(FNM_PATHNAME) a chance\".  That way, we don't have to say \"by\nappending '/*'\" (which is an implementation detail we can change).\n\nIt seems that the suggestion was ignored, though.\n"}]}