#include "branch.h"
static const char * const builtin_branch_usage[] = {
- "git-branch [options] [-r | -a]",
+ "git-branch [options] [-r | -a] [--merged | --no-merged]",
"git-branch [options] [-l] [-f] <branchname> [<start-point>]",
"git-branch [options] [-r] (-d | -D) <branchname>",
"git-branch [options] (-m | -M) [<oldbranch>] <newbranch>",
COLOR_BRANCH_CURRENT = 4,
};
+static int mergefilter = -1;
+
static int parse_branch_color_slot(const char *var, int ofs)
{
if (!strcasecmp(var+ofs, "plain"))
die("bad config variable '%s'", var);
}
-static int git_branch_config(const char *var, const char *value)
+static int git_branch_config(const char *var, const char *value, void *cb)
{
if (!strcmp(var, "color.branch")) {
branch_use_color = git_config_colorbool(var, value, -1);
color_parse(value, var, branch_colors[slot]);
return 0;
}
- return git_color_default_config(var, value);
+ return git_color_default_config(var, value, cb);
}
static const char *branch_get_color(enum color_branch ix)
struct ref_item *newitem;
int kind = REF_UNKNOWN_TYPE;
int len;
+ static struct commit_list branch;
/* Detect kind */
if (!prefixcmp(refname, "refs/heads/")) {
if ((kind & ref_list->kinds) == 0)
return 0;
+ if (mergefilter > -1) {
+ 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))
+ return 0;
+ if (mergefilter == 1 && !has_commit(head_sha1, &branch))
+ return 0;
+ }
+
/* Resize buffer */
if (ref_list->index >= ref_list->alloc) {
ref_list->alloc = alloc_nr(ref_list->alloc);
return strcmp(c1->name, c2->name);
}
+static void fill_tracking_info(char *stat, const char *branch_name)
+{
+ int ours, theirs;
+ struct branch *branch = branch_get(branch_name);
+
+ if (!stat_tracking_info(branch, &ours, &theirs) || (!ours && !theirs))
+ return;
+ if (!ours)
+ sprintf(stat, "[behind %d] ", theirs);
+ else if (!theirs)
+ sprintf(stat, "[ahead %d] ", ours);
+ else
+ sprintf(stat, "[ahead %d, behind %d] ", ours, theirs);
+}
+
static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
int abbrev, int current)
{
if (verbose) {
struct strbuf subject;
const char *sub = " **** invalid ref ****";
+ char stat[128];
strbuf_init(&subject, 0);
+ stat[0] = '\0';
commit = lookup_commit(item->sha1);
if (commit && !parse_commit(commit)) {
&subject, 0, NULL, NULL, 0, 0);
sub = subject.buf;
}
- printf("%c %s%-*s%s %s %s\n", c, branch_get_color(color),
+
+ if (item->kind == REF_LOCAL_BRANCH)
+ fill_tracking_info(stat, item->name);
+
+ printf("%c %s%-*s%s %s %s%s\n", c, branch_get_color(color),
maxwidth, item->name,
branch_get_color(COLOR_BRANCH_RESET),
- find_unique_abbrev(item->sha1, abbrev), sub);
+ find_unique_abbrev(item->sha1, abbrev),
+ stat, sub);
strbuf_release(&subject);
} else {
printf("%c %s%s%s\n", c, branch_get_color(color), item->name,
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),
OPT_END(),
};
- git_config(git_branch_config);
+ git_config(git_branch_config, NULL);
if (branch_use_color == -1)
branch_use_color = git_use_color_default;