summaryrefslogtreecommitdiff
path: root/builtin-branch.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2008-07-09 00:55:47 (GMT)
committerJunio C Hamano <gitster@pobox.com>2008-07-09 09:12:24 (GMT)
commit049716b370f2cebdbdeb278eb2a8c4eff8ed0acd (patch)
treece392fdd134fc4b4b5257c5f6aa2922a0074db0a /builtin-branch.c
parente84fb2ff75f861a708ea5a914883e178a845f4ef (diff)
downloadgit-049716b370f2cebdbdeb278eb2a8c4eff8ed0acd.zip
git-049716b370f2cebdbdeb278eb2a8c4eff8ed0acd.tar.gz
git-049716b370f2cebdbdeb278eb2a8c4eff8ed0acd.tar.bz2
branch --merged/--no-merged: allow specifying arbitrary commit
"git-branch --merged" is a handy way to list all the branches that have already been merged to the current branch, but it did not allow checking against anything but the current branch. Having to switch branches only to list the branches that are merged with another branch made the feature practically useless. This updates the option parser so that "git branch --merged next" is accepted when you are on 'master' branch. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-branch.c')
-rw-r--r--builtin-branch.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/builtin-branch.c b/builtin-branch.c
index 50cbc9c..1926c47 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -46,7 +46,12 @@ enum color_branch {
COLOR_BRANCH_CURRENT = 4,
};
-static int mergefilter = -1;
+static enum merge_filter {
+ NO_FILTER = 0,
+ SHOW_NOT_MERGED,
+ SHOW_MERGED,
+} merge_filter;
+static unsigned char merge_filter_ref[20];
static int parse_branch_color_slot(const char *var, int ofs)
{
@@ -234,13 +239,15 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
if ((kind & ref_list->kinds) == 0)
return 0;
- if (mergefilter > -1) {
+ if (merge_filter != NO_FILTER) {
branch.item = lookup_commit_reference_gently(sha1, 1);
if (!branch.item)
die("Unable to lookup tip of branch %s", refname);
- if (mergefilter == 0 && has_commit(head_sha1, &branch))
+ if (merge_filter == SHOW_NOT_MERGED &&
+ has_commit(merge_filter_ref, &branch))
return 0;
- if (mergefilter == 1 && !has_commit(head_sha1, &branch))
+ if (merge_filter == SHOW_MERGED &&
+ !has_commit(merge_filter_ref, &branch))
return 0;
}
@@ -421,6 +428,20 @@ static int opt_parse_with_commit(const struct option *opt, const char *arg, int
return 0;
}
+static int opt_parse_merge_filter(const struct option *opt, const char *arg, int unset)
+{
+ merge_filter = ((opt->long_name[0] == 'n')
+ ? SHOW_NOT_MERGED
+ : SHOW_MERGED);
+ if (unset)
+ merge_filter = SHOW_NOT_MERGED; /* b/c for --no-merged */
+ if (!arg)
+ arg = "HEAD";
+ if (get_sha1(arg, merge_filter_ref))
+ die("malformed object name %s", arg);
+ return 0;
+}
+
int cmd_branch(int argc, const char **argv, const char *prefix)
{
int delete = 0, rename = 0, force_create = 0;
@@ -461,7 +482,18 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
OPT_BIT('M', NULL, &rename, "move/rename a branch, even if target exists", 2),
OPT_BOOLEAN('l', NULL, &reflog, "create the branch's reflog"),
OPT_BOOLEAN('f', NULL, &force_create, "force creation (when already exists)"),
- OPT_SET_INT(0, "merged", &mergefilter, "list only merged branches", 1),
+ {
+ OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref,
+ "commit", "print only not merged branches",
+ PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG,
+ opt_parse_merge_filter, (intptr_t) "HEAD",
+ },
+ {
+ OPTION_CALLBACK, 0, "merged", &merge_filter_ref,
+ "commit", "print only merged branches",
+ PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG,
+ opt_parse_merge_filter, (intptr_t) "HEAD",
+ },
OPT_END(),
};
@@ -471,9 +503,6 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
branch_use_color = git_use_color_default;
track = git_branch_track;
- argc = parse_options(argc, argv, options, builtin_branch_usage, 0);
- if (!!delete + !!rename + !!force_create > 1)
- usage_with_options(builtin_branch_usage, options);
head = resolve_ref("HEAD", head_sha1, 0, NULL);
if (!head)
@@ -486,6 +515,11 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
die("HEAD not found below refs/heads!");
head += 11;
}
+ hashcpy(merge_filter_ref, head_sha1);
+
+ argc = parse_options(argc, argv, options, builtin_branch_usage, 0);
+ if (!!delete + !!rename + !!force_create > 1)
+ usage_with_options(builtin_branch_usage, options);
if (delete)
return delete_branches(argc, argv, delete > 1, kinds);