[PATCHv3 4/5] branch --exclude option
Example,
$ ./git-branch -r --exclude \*HEAD
origin/maint
origin/master
origin/next
origin/pu
origin/todo
Signed-off-by: Tom Grennan <tmgrennan@gmail.com>
---
Documentation/git-branch.txt | 7 ++++++-
builtin/branch.c | 18 +++++++++++++-----
t/t3200-branch.sh | 23 +++++++++++++++++++++++
3 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 0427e80..ef08872 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -10,7 +10,8 @@ SYNOPSIS
[verse]
'git branch' [--color[=<when>] | --no-color] [-r | -a]
[--list] [-v [--abbrev=<length> | --no-abbrev]]
- [(--merged | --no-merged | --contains) [<commit>]] [<pattern>...]
+ [(--merged | --no-merged | --contains) [<commit>]]
+ [--exclude <pattern>] [<pattern>...]
'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
'git branch' (-m | -M) [<oldbranch>] <newbranch>
'git branch' (-d | -D) [-r] <branchname>...
@@ -166,6 +167,10 @@ start-point is either a local or remote-tracking branch.
--contains <commit>::
Only list branches which contain the specified commit.
+--exclude <pattern>::
+ Don't list branches matching the given pattern. This has
+ precedence over other match pattern arguments.
+
--merged [<commit>]::
Only list branches whose tips are reachable from the
specified commit (HEAD if not specified).
diff --git a/builtin/branch.c b/builtin/branch.c
index e46ed58..ec06f66 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -243,6 +243,7 @@ struct ref_list {
int index, alloc, maxwidth, verbose, abbrev;
struct ref_item *list;
struct commit_list *with_commit;
+ struct string_list *exclude;
int kinds;
};
@@ -300,7 +301,7 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
if ((kind & ref_list->kinds) == 0)
return 0;
- if (!match_pattern(refname, cb->pattern, NULL, 0))
+ if (!match_pattern(refname, cb->pattern, ref_list->exclude, 0))
return 0;
commit = NULL;
@@ -498,7 +499,10 @@ static void show_detached(struct ref_list *ref_list)
}
}
-static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern)
+static int print_ref_list(int kinds, int detached, int verbose, int abbrev,
+ struct commit_list *with_commit,
+ struct string_list *exclude,
+ const char **pattern)
{
int i;
struct append_ref_cb cb;
@@ -509,6 +513,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
ref_list.verbose = verbose;
ref_list.abbrev = abbrev;
ref_list.with_commit = with_commit;
+ ref_list.exclude = exclude;
if (merge_filter != NO_FILTER)
init_revisions(&ref_list.revs, NULL);
cb.ref_list = &ref_list;
@@ -530,7 +535,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
detached = (detached && (kinds & REF_LOCAL_BRANCH));
- if (detached && match_pattern("HEAD", pattern, NULL, 0))
+ if (detached && match_pattern("HEAD", pattern, exclude, 0))
show_detached(&ref_list);
for (i = 0; i < ref_list.index; i++) {
@@ -665,7 +670,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
enum branch_track track;
int kinds = REF_LOCAL_BRANCH;
struct commit_list *with_commit = NULL;
-
+ struct string_list exclude = STRING_LIST_INIT_NODUP;
struct option options[] = {
OPT_GROUP("Generic options"),
OPT__VERBOSE(&verbose,
@@ -689,6 +694,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
PARSE_OPT_HIDDEN | PARSE_OPT_LASTARG_DEFAULT,
parse_opt_with_commit, (intptr_t) "HEAD",
},
+ OPT_CALLBACK(0, "exclude", &exclude, "pattern",
+ "ignorepattern matching branches",
+ parse_opt_string_list),
OPT__ABBREV(&abbrev),
OPT_GROUP("Specific git-branch actions:"),
@@ -753,7 +761,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
return delete_branches(argc, argv, delete > 1, kinds);
else if (list)
return print_ref_list(kinds, detached, verbose, abbrev,
- with_commit, argv);
+ with_commit, &exclude, argv);
else if (edit_description) {
const char *branch_name;
struct strbuf branch_ref = STRBUF_INIT;
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index dd1aceb..8144bc8 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -160,6 +160,29 @@ test_expect_success 'git branch --list -d t should fail' '
test_path_is_missing .git/refs/heads/t
'
+>expect
+test_expect_success \
+ 'git branch --list --exclude "t*" "t*" should be empty' '
+ git branch ta &&
+ git branch tb &&
+ git branch --list --exclude "t*" "t*" > actual &&
+ cmp expect actual
+'
+
+cat >expect <<EOF
+ ta
+EOF
+test_expect_success \
+ 'git branch --list --exclude "tb" "t*" should be "ta"' '
+ git branch --list --exclude "tb" "t*" > actual &&
+ cmp expect actual
+'
+
+test_expect_success \
+ 'git branch -d ta tb should succeed' '
+ git branch -d ta tb
+'
+
mv .git/config .git/config-saved
test_expect_success 'git branch -m q q2 without config should succeed' '
--
1.7.8