* [PATCH 1/2] rev-parse --glob @ 2010-01-20 9:48 Ilari Liusvaara 2010-01-20 9:48 ` [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern Ilari Liusvaara 2010-01-20 10:17 ` [PATCH 1/2] rev-parse --glob Junio C Hamano 0 siblings, 2 replies; 12+ messages in thread From: Ilari Liusvaara @ 2010-01-20 9:48 UTC (permalink / raw) To: git Add --glob=<glob-pattern> option to rev-parse and everything that accepts its options. This option matches all refs that match given shell glob pattern (complete with some DWIM logic). Example: 'git log --branches --not --glob=remotes/origin' To show what you have that origin doesn't. Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi> --- --glob can do everything --namespace did and more (in fact, what was valid for --namespace is valid for --glob and even means the same thing). Built on top of master. Documentation/git-log.txt | 11 +++ Documentation/git-rev-list.txt | 1 + Documentation/git-rev-parse.txt | 5 ++ Documentation/rev-list-options.txt | 7 ++ builtin-rev-parse.c | 5 ++ refs.c | 46 ++++++++++++ refs.h | 1 + revision.c | 16 ++++- t/t6018-rev-list-glob.sh | 136 ++++++++++++++++++++++++++++++++++++ 9 files changed, 226 insertions(+), 2 deletions(-) create mode 100755 t/t6018-rev-list-glob.sh diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index 3d79de1..0b874e3 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -107,6 +107,17 @@ git log --follow builtin-rev-list.c:: those commits that occurred before the file was given its present name. +git log --branches --not --glob=remotes/origin/*:: + + Shows all commits that are in any of local branches but not in + any of remote tracking branches for 'origin' (what you have that + origin doesn't). + +git log master --not --glob=remotes/*/master:: + + Shows all commits that are in local master but not in any remote + repository master branches. + Discussion ---------- diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt index 3341d1b..33122a3 100644 --- a/Documentation/git-rev-list.txt +++ b/Documentation/git-rev-list.txt @@ -24,6 +24,7 @@ SYNOPSIS [ \--branches ] [ \--tags ] [ \--remotes ] + [ \--glob=glob-pattern ] [ \--stdin ] [ \--quiet ] [ \--topo-order ] diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index 82045a2..6eb8c14 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@ -112,6 +112,11 @@ OPTIONS --remotes:: Show tag refs found in `$GIT_DIR/refs/remotes`. +--glob=glob-pattern:: + Show refs matching shell glob pattern `glob-pattern`. If pattern + specified lacks leading 'refs/', it is automatically prepended. + If pattern lacks '?', '*', or '[', '/*' at the end is impiled. + --show-prefix:: When the command is invoked from a subdirectory, show the path of the current directory relative to the top-level diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 1f57aed..6d03c17 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -243,6 +243,13 @@ endif::git-rev-list[] Pretend as if all the refs in `$GIT_DIR/refs/remotes` are listed on the command line as '<commit>'. +--glob=glob-pattern:: + Pretend as if all the refs matching shell glob `glob-pattern` + are listed on the command line as '<commit>'. Leading 'refs/', + is automatically prepended if missing. If pattern lacks '?', '*', + or '[', '/*' at the end is impiled. + + ifndef::git-rev-list[] --bisect:: diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c index 37d0233..a635dde 100644 --- a/builtin-rev-parse.c +++ b/builtin-rev-parse.c @@ -52,6 +52,7 @@ static int is_rev_argument(const char *arg) "--parents", "--pretty", "--remotes", + "--glob=", "--sparse", "--tags", "--topo-order", @@ -577,6 +578,10 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) for_each_tag_ref(show_reference, NULL); continue; } + if (!prefixcmp(arg, "--glob=")) { + for_each_glob_ref(show_reference, arg + 7, NULL); + continue; + } if (!strcmp(arg, "--remotes")) { for_each_remote_ref(show_reference, NULL); continue; diff --git a/refs.c b/refs.c index 3e73a0a..5adf69c 100644 --- a/refs.c +++ b/refs.c @@ -519,6 +519,14 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int * return ref; } +/* The argument to filter_refs */ +struct ref_filter +{ + const char *pattern; + each_ref_fn *fn; + void *cb_data; +}; + int read_ref(const char *ref, unsigned char *sha1) { if (resolve_ref(ref, sha1, 1, NULL)) @@ -545,6 +553,15 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim, return fn(entry->name + trim, entry->sha1, entry->flag, cb_data); } +static int filter_refs(const char* ref, const unsigned char *sha, int flags, + void* data) +{ + struct ref_filter *filter = (struct ref_filter*)data; + if (fnmatch(filter->pattern, ref, 0)) + return 0; + return filter->fn(ref, sha, flags, filter->cb_data); +} + int peel_ref(const char *ref, unsigned char *sha1) { int flag; @@ -674,6 +691,35 @@ int for_each_replace_ref(each_ref_fn fn, void *cb_data) return do_for_each_ref("refs/replace/", fn, 13, 0, cb_data); } +int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data) +{ + struct strbuf real_pattern = STRBUF_INIT; + struct ref_filter filter; + const char *has_glob_specials; + int ret; + + if (prefixcmp(pattern, "refs/")) + strbuf_addstr(&real_pattern, "refs/"); + strbuf_addstr(&real_pattern, pattern); + + has_glob_specials = strpbrk(pattern, "?*["); + if (!has_glob_specials) { + /* Append impiled '/' '*' if not present. */ + if (real_pattern.buf[real_pattern.len - 1] != '/') + strbuf_addch(&real_pattern, '/'); + /* No need to check for '*', there is none. */ + strbuf_addch(&real_pattern, '*'); + } + + filter.pattern = real_pattern.buf; + filter.fn = fn; + filter.cb_data = cb_data; + ret = for_each_ref(filter_refs, &filter); + + strbuf_release(&real_pattern); + return ret; +} + int for_each_rawref(each_ref_fn fn, void *cb_data) { return do_for_each_ref("refs/", fn, 0, diff --git a/refs.h b/refs.h index e141991..78ad173 100644 --- a/refs.h +++ b/refs.h @@ -25,6 +25,7 @@ extern int for_each_tag_ref(each_ref_fn, void *); extern int for_each_branch_ref(each_ref_fn, void *); extern int for_each_remote_ref(each_ref_fn, void *); extern int for_each_replace_ref(each_ref_fn, void *); +extern int for_each_glob_ref(each_ref_fn, const char *pattern, void *); /* can be used to learn about broken ref and symref */ extern int for_each_rawref(each_ref_fn, void *); diff --git a/revision.c b/revision.c index 25fa14d..162b182 100644 --- a/revision.c +++ b/revision.c @@ -699,12 +699,18 @@ static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, return 0; } +static void init_all_refs_cb(struct all_refs_cb *cb, struct rev_info *revs, + unsigned flags) +{ + cb->all_revs = revs; + cb->all_flags = flags; +} + static void handle_refs(struct rev_info *revs, unsigned flags, int (*for_each)(each_ref_fn, void *)) { struct all_refs_cb cb; - cb.all_revs = revs; - cb.all_flags = flags; + init_all_refs_cb(&cb, revs, flags); for_each(handle_one_ref, &cb); } @@ -1352,6 +1358,12 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch handle_refs(revs, flags, for_each_remote_ref); continue; } + if (!prefixcmp(arg, "--glob=")) { + struct all_refs_cb cb; + init_all_refs_cb(&cb, revs, flags); + for_each_glob_ref(handle_one_ref, arg + 7, &cb); + continue; + } if (!strcmp(arg, "--reflog")) { handle_reflog(revs, flags); continue; diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh new file mode 100755 index 0000000..0d7e4bc --- /dev/null +++ b/t/t6018-rev-list-glob.sh @@ -0,0 +1,136 @@ +#!/bin/sh + +test_description='rev-list/rev-parse --glob' + +. ./test-lib.sh + + +commit () { + test_tick && + echo $1 > foo && + git add foo && + git commit -m "$1" +} + +compare () { + # Split arguments on whitespace. + git $1 $2 >expected && + git $1 $3 >actual && + test_cmp expected actual +} + +test_expect_success 'setup' ' + + commit master && + git checkout -b subspace/one master && + commit one && + git checkout -b subspace/two master && + commit two && + git checkout -b subspace-x master && + commit subspace-x && + git checkout -b other/three master && + commit three && + git checkout -b someref master && + commit some && + git checkout master && + commit master2 +' + +test_expect_success 'rev-parse --glob=refs/heads/subspace/*' ' + + compare rev-parse "subspace/one subspace/two" "--glob=refs/heads/subspace/*" + +' + +test_expect_success 'rev-parse --glob=heads/subspace/*' ' + + compare rev-parse "subspace/one subspace/two" "--glob=heads/subspace/*" + +' + +test_expect_success 'rev-parse --glob=refs/heads/subspace/' ' + + compare rev-parse "subspace/one subspace/two" "--glob=refs/heads/subspace/" + +' + +test_expect_success 'rev-parse --glob=heads/subspace/' ' + + compare rev-parse "subspace/one subspace/two" "--glob=heads/subspace/" + +' + +test_expect_success 'rev-parse --glob=heads/subspace' ' + + compare rev-parse "subspace/one subspace/two" "--glob=heads/subspace" + +' + +test_expect_success 'rev-parse --glob=heads/subspace/* --glob=heads/other/*' ' + + compare rev-parse "subspace/one subspace/two other/three" "--glob=heads/subspace/* --glob=heads/other/*" + +' + +test_expect_success 'rev-parse --glob=heads/someref/* master' ' + + compare rev-parse "master" "--glob=heads/someref/* master" + +' + +test_expect_success 'rev-parse --glob=heads/*' ' + + compare rev-parse "master other/three someref subspace-x subspace/one subspace/two" "--glob=heads/*" + +' + +test_expect_success 'rev-list --glob=refs/heads/subspace/*' ' + + compare rev-list "subspace/one subspace/two" "--glob=refs/heads/subspace/*" + +' + +test_expect_success 'rev-list --glob=heads/subspace/*' ' + + compare rev-list "subspace/one subspace/two" "--glob=heads/subspace/*" + +' + +test_expect_success 'rev-list --glob=refs/heads/subspace/' ' + + compare rev-list "subspace/one subspace/two" "--glob=refs/heads/subspace/" + +' + +test_expect_success 'rev-list --glob=heads/subspace/' ' + + compare rev-list "subspace/one subspace/two" "--glob=heads/subspace/" + +' + +test_expect_success 'rev-list --glob=heads/subspace' ' + + compare rev-list "subspace/one subspace/two" "--glob=heads/subspace" + +' + +test_expect_success 'rev-list --glob=heads/someref/* master' ' + + compare rev-list "master" "--glob=heads/someref/* master" + +' + +test_expect_success 'rev-list --glob=heads/subspace/* --glob=heads/other/*' ' + + compare rev-list "subspace/one subspace/two other/three" "--glob=heads/subspace/* --glob=heads/other/*" + +' + +test_expect_success 'rev-list --glob=heads/*' ' + + compare rev-list "master other/three someref subspace-x subspace/one subspace/two" "--glob=heads/*" + +' + + +test_done -- 1.6.6.199.gff4b0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern 2010-01-20 9:48 [PATCH 1/2] rev-parse --glob Ilari Liusvaara @ 2010-01-20 9:48 ` Ilari Liusvaara 2010-01-20 10:18 ` Junio C Hamano 2010-01-21 12:51 ` Johannes Sixt 2010-01-20 10:17 ` [PATCH 1/2] rev-parse --glob Junio C Hamano 1 sibling, 2 replies; 12+ messages in thread From: Ilari Liusvaara @ 2010-01-20 9:48 UTC (permalink / raw) To: git Since local branch, tags and remote tracking branch namespaces are most often used, add shortcut notations for globbing those in manner similar to --glob option. With this, one can express the "what I have but origin doesn't?" as: 'git log --branches --not --remotes=origin' Original-idea-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi> --- Builds on top of --glob patch. Documentation/git-log.txt | 4 +- Documentation/git-rev-list.txt | 6 ++-- Documentation/git-rev-parse.txt | 19 +++++++--- Documentation/rev-list-options.txt | 18 +++++++--- builtin-rev-parse.c | 18 ++++++++++ refs.c | 12 ++++++- refs.h | 1 + revision.c | 18 ++++++++++ t/t6018-rev-list-glob.sh | 62 +++++++++++++++++++++++++++++++++++- 9 files changed, 138 insertions(+), 20 deletions(-) diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index 0b874e3..0acd526 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -107,13 +107,13 @@ git log --follow builtin-rev-list.c:: those commits that occurred before the file was given its present name. -git log --branches --not --glob=remotes/origin/*:: +git log --branches --not --remotes=origin:: Shows all commits that are in any of local branches but not in any of remote tracking branches for 'origin' (what you have that origin doesn't). -git log master --not --glob=remotes/*/master:: +git log master --not --remotes=*/master:: Shows all commits that are in local master but not in any remote repository master branches. diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt index 33122a3..f857116 100644 --- a/Documentation/git-rev-list.txt +++ b/Documentation/git-rev-list.txt @@ -21,9 +21,9 @@ SYNOPSIS [ \--full-history ] [ \--not ] [ \--all ] - [ \--branches ] - [ \--tags ] - [ \--remotes ] + [ \--branches[=pattern] ] + [ \--tags=[pattern] ] + [ \--remotes=[pattern] ] [ \--glob=glob-pattern ] [ \--stdin ] [ \--quiet ] diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index 6eb8c14..afe8699 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@ -103,14 +103,21 @@ OPTIONS --all:: Show all refs found in `$GIT_DIR/refs`. ---branches:: - Show branch refs found in `$GIT_DIR/refs/heads`. +--branches[=pattern]:: + Show branch refs found in `$GIT_DIR/refs/heads`. If `pattern` + is given, only branches matching given shell glob are shown. + If pattern lacks '?', '*', or '[', '/*' at the end is impiled. ---tags:: - Show tag refs found in `$GIT_DIR/refs/tags`. +--tags[=pattern]:: + Show tag refs found in `$GIT_DIR/refs/tags`. If `pattern` + is given, only tags matching given shell glob are shown. + If pattern lacks '?', '*', or '[', '/*' at the end is impiled. ---remotes:: - Show tag refs found in `$GIT_DIR/refs/remotes`. +--remotes[=pattern]:: + Show tag refs found in `$GIT_DIR/refs/remotes`. If `pattern` + is given, only remote tracking branches matching given shell glob + are shown. If pattern lacks '?', '*', or '[', '/*' at the end is + impiled. --glob=glob-pattern:: Show refs matching shell glob pattern `glob-pattern`. If pattern diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 6d03c17..3ef7117 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -228,20 +228,26 @@ endif::git-rev-list[] Pretend as if all the refs in `$GIT_DIR/refs/` are listed on the command line as '<commit>'. ---branches:: +--branches[=pattern]:: Pretend as if all the refs in `$GIT_DIR/refs/heads` are listed - on the command line as '<commit>'. + on the command line as '<commit>'. If `pattern` is given, limit + branches to ones matching given shell glob. If pattern lacks '?', + '*', or '[', '/*' at the end is impiled. ---tags:: +--tags[=pattern]:: Pretend as if all the refs in `$GIT_DIR/refs/tags` are listed - on the command line as '<commit>'. + on the command line as '<commit>'. If `pattern` is given, limit + tags to ones matching given shell glob. If pattern lacks '?', '*', + or '[', '/*' at the end is impiled. ---remotes:: +--remotes[=pattern]:: Pretend as if all the refs in `$GIT_DIR/refs/remotes` are listed - on the command line as '<commit>'. + on the command line as '<commit>'. If `pattern`is given, limit + remote tracking branches to ones matching given shell glob. + If pattern lacks '?', '*', or '[', '/*' at the end is impiled. --glob=glob-pattern:: Pretend as if all the refs matching shell glob `glob-pattern` diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c index a635dde..d14fe20 100644 --- a/builtin-rev-parse.c +++ b/builtin-rev-parse.c @@ -41,6 +41,7 @@ static int is_rev_argument(const char *arg) "--all", "--bisect", "--dense", + "--branches=", "--branches", "--header", "--max-age=", @@ -51,9 +52,11 @@ static int is_rev_argument(const char *arg) "--objects-edge", "--parents", "--pretty", + "--remotes=", "--remotes", "--glob=", "--sparse", + "--tags=", "--tags", "--topo-order", "--date-order", @@ -570,10 +573,20 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) for_each_ref_in("refs/bisect/good", anti_reference, NULL); continue; } + if (!prefixcmp(arg, "--branches=")) { + for_each_glob_ref_in(show_reference, arg + 11, + "refs/heads/", NULL); + continue; + } if (!strcmp(arg, "--branches")) { for_each_branch_ref(show_reference, NULL); continue; } + if (!prefixcmp(arg, "--tags=")) { + for_each_glob_ref_in(show_reference, arg + 7, + "refs/tags/", NULL); + continue; + } if (!strcmp(arg, "--tags")) { for_each_tag_ref(show_reference, NULL); continue; @@ -582,6 +595,11 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) for_each_glob_ref(show_reference, arg + 7, NULL); continue; } + if (!prefixcmp(arg, "--remotes=")) { + for_each_glob_ref_in(show_reference, arg + 10, + "refs/remotes/", NULL); + continue; + } if (!strcmp(arg, "--remotes")) { for_each_remote_ref(show_reference, NULL); continue; diff --git a/refs.c b/refs.c index 5adf69c..af78c31 100644 --- a/refs.c +++ b/refs.c @@ -691,15 +691,18 @@ int for_each_replace_ref(each_ref_fn fn, void *cb_data) return do_for_each_ref("refs/replace/", fn, 13, 0, cb_data); } -int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data) +int for_each_glob_ref_in(each_ref_fn fn, const char *pattern, + const char *prefix, void *cb_data) { struct strbuf real_pattern = STRBUF_INIT; struct ref_filter filter; const char *has_glob_specials; int ret; - if (prefixcmp(pattern, "refs/")) + if (!prefix && prefixcmp(pattern, "refs/")) strbuf_addstr(&real_pattern, "refs/"); + else if (prefix) + strbuf_addstr(&real_pattern, prefix); strbuf_addstr(&real_pattern, pattern); has_glob_specials = strpbrk(pattern, "?*["); @@ -720,6 +723,11 @@ int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data) return ret; } +int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data) +{ + return for_each_glob_ref_in(fn, pattern, NULL, cb_data); +} + int for_each_rawref(each_ref_fn fn, void *cb_data) { return do_for_each_ref("refs/", fn, 0, diff --git a/refs.h b/refs.h index 78ad173..f7648b9 100644 --- a/refs.h +++ b/refs.h @@ -26,6 +26,7 @@ extern int for_each_branch_ref(each_ref_fn, void *); extern int for_each_remote_ref(each_ref_fn, void *); extern int for_each_replace_ref(each_ref_fn, void *); extern int for_each_glob_ref(each_ref_fn, const char *pattern, void *); +extern int for_each_glob_ref_in(each_ref_fn, const char *pattern, const char* prefix, void *); /* can be used to learn about broken ref and symref */ extern int for_each_rawref(each_ref_fn, void *); diff --git a/revision.c b/revision.c index 162b182..1e9277d 100644 --- a/revision.c +++ b/revision.c @@ -1364,6 +1364,24 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch for_each_glob_ref(handle_one_ref, arg + 7, &cb); continue; } + if (!prefixcmp(arg, "--branches=")) { + struct all_refs_cb cb; + init_all_refs_cb(&cb, revs, flags); + for_each_glob_ref_in(handle_one_ref, arg + 11, "refs/heads/", &cb); + continue; + } + if (!prefixcmp(arg, "--tags=")) { + struct all_refs_cb cb; + init_all_refs_cb(&cb, revs, flags); + for_each_glob_ref_in(handle_one_ref, arg + 7, "refs/tags/", &cb); + continue; + } + if (!prefixcmp(arg, "--remotes=")) { + struct all_refs_cb cb; + init_all_refs_cb(&cb, revs, flags); + for_each_glob_ref_in(handle_one_ref, arg + 10, "refs/remotes/", &cb); + continue; + } if (!strcmp(arg, "--reflog")) { handle_reflog(revs, flags); continue; diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh index 0d7e4bc..bf85e0c 100755 --- a/t/t6018-rev-list-glob.sh +++ b/t/t6018-rev-list-glob.sh @@ -33,7 +33,9 @@ test_expect_success 'setup' ' git checkout -b someref master && commit some && git checkout master && - commit master2 + commit master2 && + git tag foo/bar master && + git update-ref refs/remotes/foo/baz master ' test_expect_success 'rev-parse --glob=refs/heads/subspace/*' ' @@ -66,6 +68,24 @@ test_expect_success 'rev-parse --glob=heads/subspace' ' ' +test_expect_success 'rev-parse --branches=subspace/*' ' + + compare rev-parse "subspace/one subspace/two" "--branches=subspace/*" + +' + +test_expect_success 'rev-parse --branches=subspace/' ' + + compare rev-parse "subspace/one subspace/two" "--branches=subspace/" + +' + +test_expect_success 'rev-parse --branches=subspace' ' + + compare rev-parse "subspace/one subspace/two" "--branches=subspace" + +' + test_expect_success 'rev-parse --glob=heads/subspace/* --glob=heads/other/*' ' compare rev-parse "subspace/one subspace/two other/three" "--glob=heads/subspace/* --glob=heads/other/*" @@ -84,6 +104,18 @@ test_expect_success 'rev-parse --glob=heads/*' ' ' +test_expect_success 'rev-parse --tags=foo' ' + + compare rev-parse "foo/bar" "--tags=foo" + +' + +test_expect_success 'rev-parse --remotes=foo' ' + + compare rev-parse "foo/baz" "--remotes=foo" + +' + test_expect_success 'rev-list --glob=refs/heads/subspace/*' ' compare rev-list "subspace/one subspace/two" "--glob=refs/heads/subspace/*" @@ -114,6 +146,23 @@ test_expect_success 'rev-list --glob=heads/subspace' ' ' +test_expect_success 'rev-list --branches=subspace/*' ' + + compare rev-list "subspace/one subspace/two" "--branches=subspace/*" + +' + +test_expect_success 'rev-list --branches=subspace/' ' + + compare rev-list "subspace/one subspace/two" "--branches=subspace/" + +' + +test_expect_success 'rev-list --branches=subspace' ' + + compare rev-list "subspace/one subspace/two" "--branches=subspace" + +' test_expect_success 'rev-list --glob=heads/someref/* master' ' compare rev-list "master" "--glob=heads/someref/* master" @@ -132,5 +181,16 @@ test_expect_success 'rev-list --glob=heads/*' ' ' +test_expect_success 'rev-list --tags=foo' ' + + compare rev-list "foo/bar" "--tags=foo" + +' + +test_expect_success 'rev-list --remotes=foo' ' + + compare rev-list "foo/baz" "--remotes=foo" + +' test_done -- 1.6.6.199.gff4b0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern 2010-01-20 9:48 ` [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern Ilari Liusvaara @ 2010-01-20 10:18 ` Junio C Hamano 2010-01-21 12:51 ` Johannes Sixt 1 sibling, 0 replies; 12+ messages in thread From: Junio C Hamano @ 2010-01-20 10:18 UTC (permalink / raw) To: Ilari Liusvaara; +Cc: git Ilari Liusvaara <ilari.liusvaara@elisanet.fi> writes: > Since local branch, tags and remote tracking branch namespaces are > most often used, add shortcut notations for globbing those in > manner similar to --glob option. > > With this, one can express the "what I have but origin doesn't?" > as: > > 'git log --branches --not --remotes=origin' > > Original-idea-by: Johannes Sixt <j6t@kdbg.org> > Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi> > --- Nice. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern 2010-01-20 9:48 ` [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern Ilari Liusvaara 2010-01-20 10:18 ` Junio C Hamano @ 2010-01-21 12:51 ` Johannes Sixt 2010-01-21 13:51 ` Michael J Gruber 2010-01-21 17:58 ` [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern Junio C Hamano 1 sibling, 2 replies; 12+ messages in thread From: Johannes Sixt @ 2010-01-21 12:51 UTC (permalink / raw) To: Ilari Liusvaara; +Cc: git, Junio C Hamano Works for me, thank you very much! Junio, kindly squash in these speeling fixes in both patches: sed -i 's/impiled/implied/g' `git diff HEAD^ --name-only Documentation/` -- Hannes ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern 2010-01-21 12:51 ` Johannes Sixt @ 2010-01-21 13:51 ` Michael J Gruber 2010-01-21 17:27 ` Thomas Rast 2010-01-21 17:58 ` [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern Junio C Hamano 1 sibling, 1 reply; 12+ messages in thread From: Michael J Gruber @ 2010-01-21 13:51 UTC (permalink / raw) To: Johannes Sixt; +Cc: Ilari Liusvaara, git, Junio C Hamano Johannes Sixt venit, vidit, dixit 21.01.2010 13:51: > Works for me, thank you very much! > > Junio, kindly squash in these speeling fixes in both patches: > > sed -i 's/impiled/implied/g' `git diff HEAD^ --name-only Documentation/` > Also, the option descriptions are kind of staccato English right now, lacking a few "the" here and there. Should we fix this or simply leave it at that? Michael ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern 2010-01-21 13:51 ` Michael J Gruber @ 2010-01-21 17:27 ` Thomas Rast 2010-01-21 20:09 ` Junio C Hamano 0 siblings, 1 reply; 12+ messages in thread From: Thomas Rast @ 2010-01-21 17:27 UTC (permalink / raw) To: Michael J Gruber, Ilari Liusvaara; +Cc: Johannes Sixt, git, Junio C Hamano Thanks Ilari for implementing my wishes :-) On Thursday 21 January 2010 14:51:41 Michael J Gruber wrote: > Johannes Sixt venit, vidit, dixit 21.01.2010 13:51: > > Works for me, thank you very much! > > > > Junio, kindly squash in these speeling fixes in both patches: > > > > sed -i 's/impiled/implied/g' `git diff HEAD^ --name-only Documentation/` > > > > Also, the option descriptions are kind of staccato English right now, > lacking a few "the" here and there. Should we fix this or simply leave > it at that? Maybe the --branches, --tags and --remotes could be consolidated a bit, as in the draft patch below. If --all took a pattern, it could be included there too, but that would probably look too weird. diff --git i/Documentation/git-rev-parse.txt w/Documentation/git-rev-parse.txt index 2bbb566..6fce919 100644 --- i/Documentation/git-rev-parse.txt +++ w/Documentation/git-rev-parse.txt @@ -104,29 +104,26 @@ OPTIONS Show all refs found in `$GIT_DIR/refs`. --branches[=pattern]:: - Show branch refs found in `$GIT_DIR/refs/heads`. If `pattern` - is given, only branches matching given shell glob are shown. - If pattern lacks '?', '*', or '[', '/*' at the end is impiled. - --tags[=pattern]:: - Show tag refs found in `$GIT_DIR/refs/tags`. If `pattern` - is given, only tags matching given shell glob are shown. - If pattern lacks '?', '*', or '[', '/*' at the end is impiled. - --remotes[=pattern]:: - Show tag refs found in `$GIT_DIR/refs/remotes`. If `pattern` - is given, only remote tracking branches matching given shell glob - are shown. If pattern lacks '?', '*', or '[', '/*' at the end is - impiled. + Show all branches, tags, or remote-tracking branches, + respectively (i.e., refs found in `$GIT_DIR/refs/heads`, + `$GIT_DIR/refs/tags`, or `$GIT_DIR/refs/remotes`, + respectively). ++ +If a `pattern` is given, only refs matching the given shell glob are +shown. If the pattern does not contain a globbing character (`?`, +`\*`, or `[`), it is anchored by appending `/\*`. + +--glob=pattern:: + Show all refs matching the shell glob pattern `pattern`. If + the pattern does not start with `refs/`, this is automatically + prepended. If the pattern does not contain a globbing + character (`?`, `\*`, or `[`), it is anchored by appending `/\*`. --show-toplevel:: Show the absolute path of the top-level directory. ---glob=glob-pattern:: - Show refs matching shell glob pattern `glob-pattern`. If pattern - specified lacks leading 'refs/', it is automatically prepended. - If pattern lacks '?', '*', or '[', '/*' at the end is impiled. - --show-prefix:: When the command is invoked from a subdirectory, show the path of the current directory relative to the top-level -- Thomas Rast trast@{inf,student}.ethz.ch ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern 2010-01-21 17:27 ` Thomas Rast @ 2010-01-21 20:09 ` Junio C Hamano 2010-01-22 0:21 ` [PATCH] Documentation: improve description of --glob=pattern and friends Thomas Rast 0 siblings, 1 reply; 12+ messages in thread From: Junio C Hamano @ 2010-01-21 20:09 UTC (permalink / raw) To: Thomas Rast Cc: Michael J Gruber, Ilari Liusvaara, Johannes Sixt, git, Junio C Hamano Thomas Rast <trast@student.ethz.ch> writes: > Maybe the --branches, --tags and --remotes could be consolidated a > bit, as in the draft patch below. Looks sensible. > diff --git i/Documentation/git-rev-parse.txt w/Documentation/git-rev-parse.txt > index 2bbb566..6fce919 100644 > --- i/Documentation/git-rev-parse.txt > +++ w/Documentation/git-rev-parse.txt > @@ -104,29 +104,26 @@ OPTIONS > Show all refs found in `$GIT_DIR/refs`. > > --branches[=pattern]:: > - Show branch refs found in `$GIT_DIR/refs/heads`. If `pattern` > - is given, only branches matching given shell glob are shown. > - If pattern lacks '?', '*', or '[', '/*' at the end is impiled. > - > --tags[=pattern]:: > - Show tag refs found in `$GIT_DIR/refs/tags`. If `pattern` > - is given, only tags matching given shell glob are shown. > - If pattern lacks '?', '*', or '[', '/*' at the end is impiled. > - > --remotes[=pattern]:: > - Show tag refs found in `$GIT_DIR/refs/remotes`. If `pattern` > - is given, only remote tracking branches matching given shell glob > - are shown. If pattern lacks '?', '*', or '[', '/*' at the end is > - impiled. > + Show all branches, tags, or remote-tracking branches, > + respectively (i.e., refs found in `$GIT_DIR/refs/heads`, > + `$GIT_DIR/refs/tags`, or `$GIT_DIR/refs/remotes`, > + respectively). > ++ > +If a `pattern` is given, only refs matching the given shell glob are > +shown. If the pattern does not contain a globbing character (`?`, > +`\*`, or `[`), it is anchored by appending `/\*`. > + > +--glob=pattern:: > + Show all refs matching the shell glob pattern `pattern`. If > + the pattern does not start with `refs/`, this is automatically > + prepended. If the pattern does not contain a globbing > + character (`?`, `\*`, or `[`), it is anchored by appending `/\*`. > > --show-toplevel:: > Show the absolute path of the top-level directory. > > ---glob=glob-pattern:: > - Show refs matching shell glob pattern `glob-pattern`. If pattern > - specified lacks leading 'refs/', it is automatically prepended. > - If pattern lacks '?', '*', or '[', '/*' at the end is impiled. > - > --show-prefix:: > When the command is invoked from a subdirectory, show the > path of the current directory relative to the top-level > > > -- > Thomas Rast > trast@{inf,student}.ethz.ch ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] Documentation: improve description of --glob=pattern and friends 2010-01-21 20:09 ` Junio C Hamano @ 2010-01-22 0:21 ` Thomas Rast 2010-01-22 0:51 ` Junio C Hamano 0 siblings, 1 reply; 12+ messages in thread From: Thomas Rast @ 2010-01-22 0:21 UTC (permalink / raw) To: git; +Cc: Michael J Gruber, Ilari Liusvaara, Johannes Sixt, Junio C Hamano Consolidate the descriptions of --branches, --tags and --remotes a bit, to make it less repetitive. Improve the grammar a bit, and spell out the meaning of the 'append /*' rule. Signed-off-by: Thomas Rast <trast@student.ethz.ch> --- Compared to the earlier draft, I changed "it is anchored" (by appending '/*') to "it is turned into a prefix match", since this is not anchoring in the ^regex$ sense. (I guess 'leading-component match' would be even more accurate, but that makes the sentence unwieldy in my ears.) Documentation/git-rev-parse.txt | 32 +++++++++++++++----------------- 1 files changed, 15 insertions(+), 17 deletions(-) diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index e2cb913..e7845d4 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@ -104,25 +104,23 @@ OPTIONS Show all refs found in `$GIT_DIR/refs`. --branches[=pattern]:: - Show branch refs found in `$GIT_DIR/refs/heads`. If `pattern` - is given, only branches matching given shell glob are shown. - If pattern lacks '?', '*', or '[', '/*' at the end is impiled. - --tags[=pattern]:: - Show tag refs found in `$GIT_DIR/refs/tags`. If `pattern` - is given, only tags matching given shell glob are shown. - If pattern lacks '?', '*', or '[', '/*' at the end is impiled. - --remotes[=pattern]:: - Show tag refs found in `$GIT_DIR/refs/remotes`. If `pattern` - is given, only remote tracking branches matching given shell glob - are shown. If pattern lacks '?', '*', or '[', '/*' at the end is - impiled. - ---glob=glob-pattern:: - Show refs matching shell glob pattern `glob-pattern`. If pattern - specified lacks leading 'refs/', it is automatically prepended. - If pattern lacks '?', '*', or '[', '/*' at the end is impiled. + Show all branches, tags, or remote-tracking branches, + respectively (i.e., refs found in `$GIT_DIR/refs/heads`, + `$GIT_DIR/refs/tags`, or `$GIT_DIR/refs/remotes`, + respectively). ++ +If a `pattern` is given, only refs matching the given shell glob are +shown. If the pattern does not contain a globbing character (`?`, +`\*`, or `[`), it is turned into a prefix match by appending `/\*`. + +--glob=pattern:: + Show all refs matching the shell glob pattern `pattern`. If + the pattern does not start with `refs/`, this is automatically + prepended. If the pattern does not contain a globbing + character (`?`, `\*`, or `[`), it is turned into a prefix + match by appending `/\*`. --show-toplevel:: Show the absolute path of the top-level directory. -- 1.6.6.1.534.gf034a ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] Documentation: improve description of --glob=pattern and friends 2010-01-22 0:21 ` [PATCH] Documentation: improve description of --glob=pattern and friends Thomas Rast @ 2010-01-22 0:51 ` Junio C Hamano 0 siblings, 0 replies; 12+ messages in thread From: Junio C Hamano @ 2010-01-22 0:51 UTC (permalink / raw) To: Thomas Rast Cc: git, Michael J Gruber, Ilari Liusvaara, Johannes Sixt, Junio C Hamano Thomas Rast <trast@student.ethz.ch> writes: > Consolidate the descriptions of --branches, --tags and --remotes a > bit, to make it less repetitive. Improve the grammar a bit, and spell > out the meaning of the 'append /*' rule. > > Signed-off-by: Thomas Rast <trast@student.ethz.ch> > --- > > Compared to the earlier draft, I changed "it is anchored" (by > appending '/*') to "it is turned into a prefix match", since this is > not anchoring in the ^regex$ sense. (I guess 'leading-component > match' would be even more accurate, but that makes the sentence > unwieldy in my ears.) By the way, we may someday want to change that to do FNM_PATHNAME instead of just a flat glob. Incidentally, that is why I prefer the earlier suggestion to do "check with memcmp() if it is a path-prefix, and if it fails, then give fnmatch(FNM_PATHNAME) a chance". That way, we don't have to say "by appending '/*'" (which is an implementation detail we can change). It seems that the suggestion was ignored, though. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern 2010-01-21 12:51 ` Johannes Sixt 2010-01-21 13:51 ` Michael J Gruber @ 2010-01-21 17:58 ` Junio C Hamano 1 sibling, 0 replies; 12+ messages in thread From: Junio C Hamano @ 2010-01-21 17:58 UTC (permalink / raw) To: Johannes Sixt; +Cc: Ilari Liusvaara, git Johannes Sixt <j.sixt@viscovery.net> writes: > Works for me, thank you very much! > > Junio, kindly squash in these speeling fixes in both patches: > > sed -i 's/impiled/implied/g' `git diff HEAD^ --name-only Documentation/` Thanks; I've already pushed out what I was preparing before going to bed, so these fixes need to happen in-tree as incremental changes. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] rev-parse --glob 2010-01-20 9:48 [PATCH 1/2] rev-parse --glob Ilari Liusvaara 2010-01-20 9:48 ` [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern Ilari Liusvaara @ 2010-01-20 10:17 ` Junio C Hamano 2010-01-20 11:08 ` Ilari Liusvaara 1 sibling, 1 reply; 12+ messages in thread From: Junio C Hamano @ 2010-01-20 10:17 UTC (permalink / raw) To: Ilari Liusvaara; +Cc: git Ilari Liusvaara <ilari.liusvaara@elisanet.fi> writes: > Add --glob=<glob-pattern> option to rev-parse and everything that > accepts its options. This option matches all refs that match given > shell glob pattern (complete with some DWIM logic). > > Example: > > 'git log --branches --not --glob=remotes/origin' > > To show what you have that origin doesn't. > > Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi> > --- Looks fairly competently done. Does this mean you've abandoned the --namespace series? I don't mind reverting them from 'next'. > +static int filter_refs(const char* ref, const unsigned char *sha, int flags, > + void* data) > +{ > + struct ref_filter *filter = (struct ref_filter*)data; > + if (fnmatch(filter->pattern, ref, 0)) > + return 0; In many places (not just refs) we use "If leading path component matches, or fnmatch() says Ok" (e.g. builtin-for-each-ref.c, builtin_grep.c), and in some other places we only use fnmatch(). I think it is better to pick one convention, and adjust the other one to match, and my gut feeling is that "leading path or fnmatch()", while theologically might be messier, would be more useful in practice. And that was why I did my "like this" patch http://article.gmane.org/gmane.comp.version-control.git/137492 that way. My longer term desire is to consolidate these fnmatch() users to call a single helper function, and then perhaps replace fnmatch() in that helper function with something more powerful. Although I do not personally care too much, people often wanted to have "path/**/leaf-that-is-deep" matcher. I don't want you to go there just yet with this series, but at least following the same style everywhere would pave the way to consolidating them. > @@ -674,6 +691,35 @@ int for_each_replace_ref(each_ref_fn fn, void *cb_data) > return do_for_each_ref("refs/replace/", fn, 13, 0, cb_data); > } > > +int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data) > +{ > + struct strbuf real_pattern = STRBUF_INIT; > + struct ref_filter filter; > + const char *has_glob_specials; > + int ret; > + > + if (prefixcmp(pattern, "refs/")) > + strbuf_addstr(&real_pattern, "refs/"); > + strbuf_addstr(&real_pattern, pattern); > + > + has_glob_specials = strpbrk(pattern, "?*["); Would the need for this code hopefully disappear if we take the "leading path or fnmatch()" check? If we still need this, we probably would want to add a has_glob_special() helper function not as a hardcoded srpbrk(), but in terms of is_glob_special() in git-compat-util.h. Thanks. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] rev-parse --glob 2010-01-20 10:17 ` [PATCH 1/2] rev-parse --glob Junio C Hamano @ 2010-01-20 11:08 ` Ilari Liusvaara 0 siblings, 0 replies; 12+ messages in thread From: Ilari Liusvaara @ 2010-01-20 11:08 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On Wed, Jan 20, 2010 at 02:17:15AM -0800, Junio C Hamano wrote: > Ilari Liusvaara <ilari.liusvaara@elisanet.fi> writes: > > Looks fairly competently done. Does this mean you've abandoned the --namespace > series? I don't mind reverting them from 'next'. Pretty much. > > +static int filter_refs(const char* ref, const unsigned char *sha, int flags, > > + void* data) > > +{ > > + struct ref_filter *filter = (struct ref_filter*)data; > > + if (fnmatch(filter->pattern, ref, 0)) > > + return 0; > > In many places (not just refs) we use "If leading path component matches, > or fnmatch() says Ok" (e.g. builtin-for-each-ref.c, builtin_grep.c), and > in some other places we only use fnmatch(). I think it is better to pick > one convention, and adjust the other one to match, and my gut feeling is > that "leading path or fnmatch()", while theologically might be messier, > would be more useful in practice. And that was why I did my "like this" > patch http://article.gmane.org/gmane.comp.version-control.git/137492 that way. That pattern of course has been edited before (and the namespace behavoiour is implemented that way). > My longer term desire is to consolidate these fnmatch() users to call a > single helper function, and then perhaps replace fnmatch() in that helper > function with something more powerful. Although I do not personally care > too much, people often wanted to have "path/**/leaf-that-is-deep" matcher. Extended globs? Except that: 'git check-ref-format refs/heads/X+\(a\|b\) ; echo $?' => 0 And '+(a|b)' is wildcard in extended glob (not expressible with standard glob operators). Extended globbing in gitignore would be useful as some have asked if there is way to use regular expressions there (nope). At least extended globs are equivalent to regular expressions in power. > > @@ -674,6 +691,35 @@ int for_each_replace_ref(each_ref_fn fn, void *cb_data) > > return do_for_each_ref("refs/replace/", fn, 13, 0, cb_data); > > } > > > > +int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data) > > +{ > > + struct strbuf real_pattern = STRBUF_INIT; > > + struct ref_filter filter; > > + const char *has_glob_specials; > > + int ret; > > + > > + if (prefixcmp(pattern, "refs/")) > > + strbuf_addstr(&real_pattern, "refs/"); > > + strbuf_addstr(&real_pattern, pattern); > > + > > + has_glob_specials = strpbrk(pattern, "?*["); > > Would the need for this code hopefully disappear if we take the "leading > path or fnmatch()" check? If we still need this, we probably would want > to add a has_glob_special() helper function not as a hardcoded srpbrk(), > but in terms of is_glob_special() in git-compat-util.h. '--glob=remotes/origin' and '--glob=remotes/origin*' are not the same. The first gets DWIMed to '--glob=refs/remotes/origin/*'. The usual case for globbing is globbing entiere namespace (name of one remote can be prefix of another). -Ilari ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2010-01-22 0:51 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-01-20 9:48 [PATCH 1/2] rev-parse --glob Ilari Liusvaara 2010-01-20 9:48 ` [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern Ilari Liusvaara 2010-01-20 10:18 ` Junio C Hamano 2010-01-21 12:51 ` Johannes Sixt 2010-01-21 13:51 ` Michael J Gruber 2010-01-21 17:27 ` Thomas Rast 2010-01-21 20:09 ` Junio C Hamano 2010-01-22 0:21 ` [PATCH] Documentation: improve description of --glob=pattern and friends Thomas Rast 2010-01-22 0:51 ` Junio C Hamano 2010-01-21 17:58 ` [PATCH 2/2] rev-parse --branches/--tags/--remotes=pattern Junio C Hamano 2010-01-20 10:17 ` [PATCH 1/2] rev-parse --glob Junio C Hamano 2010-01-20 11:08 ` Ilari Liusvaara
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 NNTP newsgroup(s).