rev-parse --branches/--tags/--remotes=pattern
authorIlari Liusvaara <ilari.liusvaara@elisanet.fi>
Wed, 20 Jan 2010 09:48:26 +0000 (11:48 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 20 Jan 2010 20:30:25 +0000 (12:30 -0800)
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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-log.txt
Documentation/git-rev-list.txt
Documentation/git-rev-parse.txt
Documentation/rev-list-options.txt
builtin-rev-parse.c
refs.c
refs.h
revision.c
t/t6018-rev-list-glob.sh
index 0b874e3d1ab41f6195dad7559ff4be60b1bcbd2a..0acd526303ec4cce8e8c0d1cbefb31411b52acde 100644 (file)
@@ -107,13 +107,13 @@ git log --follow builtin-rev-list.c::
        those commits that occurred before the file was given its
        present name.
 
        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).
 
 
        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.
 
        Shows all commits that are in local master but not in any remote
        repository master branches.
index 33122a3f335f145a79edb58ad7728c0e2c2a1ad3..f85711676b2320a739014070b6b3486919925c5e 100644 (file)
@@ -21,9 +21,9 @@ SYNOPSIS
             [ \--full-history ]
             [ \--not ]
             [ \--all ]
             [ \--full-history ]
             [ \--not ]
             [ \--all ]
-            [ \--branches ]
-            [ \--tags ]
-            [ \--remotes ]
+            [ \--branches[=pattern] ]
+            [ \--tags=[pattern] ]
+            [ \--remotes=[pattern] ]
             [ \--glob=glob-pattern ]
             [ \--stdin ]
             [ \--quiet ]
             [ \--glob=glob-pattern ]
             [ \--stdin ]
             [ \--quiet ]
index 6eb8c14f62d976e3adb6ff9d7f7a96cfca04b843..afe86999996bdac3af0499126cbec5767873dc79 100644 (file)
@@ -103,14 +103,21 @@ OPTIONS
 --all::
        Show all refs found in `$GIT_DIR/refs`.
 
 --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
 
 --glob=glob-pattern::
        Show refs matching shell glob pattern `glob-pattern`. If pattern
index 6d03c17a684364d5c6576883d5408df833407c61..3ef71179d9b234733e392a36cae8aa37be6235b0 100644 (file)
@@ -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>'.
 
        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
 
        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
 
        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
 
        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`
 
 --glob=glob-pattern::
        Pretend as if all the refs matching shell glob `glob-pattern`
index a635dded65f1d6504bf84c872e0dc4d9efc0126d..d14fe20692aa0903f45da96bf9f31f4564b7816a 100644 (file)
@@ -41,6 +41,7 @@ static int is_rev_argument(const char *arg)
                "--all",
                "--bisect",
                "--dense",
                "--all",
                "--bisect",
                "--dense",
+               "--branches=",
                "--branches",
                "--header",
                "--max-age=",
                "--branches",
                "--header",
                "--max-age=",
@@ -51,9 +52,11 @@ static int is_rev_argument(const char *arg)
                "--objects-edge",
                "--parents",
                "--pretty",
                "--objects-edge",
                "--parents",
                "--pretty",
+               "--remotes=",
                "--remotes",
                "--glob=",
                "--sparse",
                "--remotes",
                "--glob=",
                "--sparse",
+               "--tags=",
                "--tags",
                "--topo-order",
                "--date-order",
                "--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;
                        }
                                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 (!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;
                        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;
                        }
                                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;
                        if (!strcmp(arg, "--remotes")) {
                                for_each_remote_ref(show_reference, NULL);
                                continue;
diff --git a/refs.c b/refs.c
index 34fff75b0d2062b7c7445864fe9f9d70962b1bee..503a8c2bd0fa7e4fb825d543e007995701150948 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -690,15 +690,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);
 }
 
        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;
 
 {
        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/");
                strbuf_addstr(&real_pattern, "refs/");
+       else if (prefix)
+               strbuf_addstr(&real_pattern, prefix);
        strbuf_addstr(&real_pattern, pattern);
 
        has_glob_specials = strpbrk(pattern, "?*[");
        strbuf_addstr(&real_pattern, pattern);
 
        has_glob_specials = strpbrk(pattern, "?*[");
@@ -719,6 +722,11 @@ int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
        return ret;
 }
 
        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,
 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 78ad173f1b6eaf307543ea7fc5922e15cf343efc..f7648b9bd3b719936024678246d0603028e72aa7 100644 (file)
--- 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_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 *);
 
 /* can be used to learn about broken ref and symref */
 extern int for_each_rawref(each_ref_fn, void *);
index 162b18291499886977ae2a348b78e7622bf72e16..1e9277d335aa4a5469f380c16b040c886b34ea5c 100644 (file)
@@ -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;
                        }
                                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;
                        if (!strcmp(arg, "--reflog")) {
                                handle_reflog(revs, flags);
                                continue;
index 1f251e1f4364370ca4abc90bafdfd8c4b87667fa..8d3fa7d014c1e5a856f6c4c35cfb46eb8c44e684 100755 (executable)
@@ -32,7 +32,9 @@ test_expect_success 'setup' '
        git checkout -b someref master &&
        commit some &&
        git checkout master &&
        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/*' '
 '
 
 test_expect_success 'rev-parse --glob=refs/heads/subspace/*' '
@@ -65,6 +67,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/*"
 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/*"
@@ -83,6 +103,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/*"
 test_expect_success 'rev-list --glob=refs/heads/subspace/*' '
 
        compare rev-list "subspace/one subspace/two" "--glob=refs/heads/subspace/*"
@@ -113,6 +145,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"
 test_expect_success 'rev-list --glob=heads/someref/* master' '
 
        compare rev-list "master" "--glob=heads/someref/* master"
@@ -131,4 +180,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
 test_done