From 81b50f3ce40bfdd66e5d967bf82be001039a9a98 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 22 Feb 2010 08:42:18 -0800 Subject: Move 'builtin-*' into a 'builtin/' subdirectory This shrinks the top-level directory a bit, and makes it much more pleasant to use auto-completion on the thing. Instead of [torvalds@nehalem git]$ em buil Display all 180 possibilities? (y or n) [torvalds@nehalem git]$ em builtin-sh builtin-shortlog.c builtin-show-branch.c builtin-show-ref.c builtin-shortlog.o builtin-show-branch.o builtin-show-ref.o [torvalds@nehalem git]$ em builtin-shor builtin-shortlog.c builtin-shortlog.o [torvalds@nehalem git]$ em builtin-shortlog.c you get [torvalds@nehalem git]$ em buil [type] builtin/ builtin.h [torvalds@nehalem git]$ em builtin [auto-completes to] [torvalds@nehalem git]$ em builtin/sh [type] shortlog.c shortlog.o show-branch.c show-branch.o show-ref.c show-ref.o [torvalds@nehalem git]$ em builtin/sho [auto-completes to] [torvalds@nehalem git]$ em builtin/shor [type] shortlog.c shortlog.o [torvalds@nehalem git]$ em builtin/shortlog.c which doesn't seem all that different, but not having that annoying break in "Display all 180 possibilities?" is quite a relief. NOTE! If you do this in a clean tree (no object files etc), or using an editor that has auto-completion rules that ignores '*.o' files, you won't see that annoying 'Display all 180 possibilities?' message - it will just show the choices instead. I think bash has some cut-off around 100 choices or something. So the reason I see this is that I'm using an odd editory, and thus don't have the rules to cut down on auto-completion. But you can simulate that by using 'ls' instead, or something similar. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- builtin/branch.c | 696 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 696 insertions(+) create mode 100644 builtin/branch.c (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c new file mode 100644 index 0000000000..a28a13986d --- /dev/null +++ b/builtin/branch.c @@ -0,0 +1,696 @@ +/* + * Builtin "git branch" + * + * Copyright (c) 2006 Kristian Høgsberg + * Based on git-branch.sh by Junio C Hamano. + */ + +#include "cache.h" +#include "color.h" +#include "refs.h" +#include "commit.h" +#include "builtin.h" +#include "remote.h" +#include "parse-options.h" +#include "branch.h" +#include "diff.h" +#include "revision.h" + +static const char * const builtin_branch_usage[] = { + "git branch [options] [-r | -a] [--merged | --no-merged]", + "git branch [options] [-l] [-f] []", + "git branch [options] [-r] (-d | -D) ", + "git branch [options] (-m | -M) [] ", + NULL +}; + +#define REF_LOCAL_BRANCH 0x01 +#define REF_REMOTE_BRANCH 0x02 + +static const char *head; +static unsigned char head_sha1[20]; + +static int branch_use_color = -1; +static char branch_colors[][COLOR_MAXLEN] = { + GIT_COLOR_RESET, + GIT_COLOR_NORMAL, /* PLAIN */ + GIT_COLOR_RED, /* REMOTE */ + GIT_COLOR_NORMAL, /* LOCAL */ + GIT_COLOR_GREEN, /* CURRENT */ +}; +enum color_branch { + BRANCH_COLOR_RESET = 0, + BRANCH_COLOR_PLAIN = 1, + BRANCH_COLOR_REMOTE = 2, + BRANCH_COLOR_LOCAL = 3, + BRANCH_COLOR_CURRENT = 4, +}; + +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) +{ + if (!strcasecmp(var+ofs, "plain")) + return BRANCH_COLOR_PLAIN; + if (!strcasecmp(var+ofs, "reset")) + return BRANCH_COLOR_RESET; + if (!strcasecmp(var+ofs, "remote")) + return BRANCH_COLOR_REMOTE; + if (!strcasecmp(var+ofs, "local")) + return BRANCH_COLOR_LOCAL; + if (!strcasecmp(var+ofs, "current")) + return BRANCH_COLOR_CURRENT; + return -1; +} + +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); + return 0; + } + if (!prefixcmp(var, "color.branch.")) { + int slot = parse_branch_color_slot(var, 13); + if (slot < 0) + return 0; + if (!value) + return config_error_nonbool(var); + color_parse(value, var, branch_colors[slot]); + return 0; + } + return git_color_default_config(var, value, cb); +} + +static const char *branch_get_color(enum color_branch ix) +{ + if (branch_use_color > 0) + return branch_colors[ix]; + return ""; +} + +static int branch_merged(int kind, const char *name, + struct commit *rev, struct commit *head_rev) +{ + /* + * This checks whether the merge bases of branch and HEAD (or + * the other branch this branch builds upon) contains the + * branch, which means that the branch has already been merged + * safely to HEAD (or the other branch). + */ + struct commit *reference_rev = NULL; + const char *reference_name = NULL; + int merged; + + if (kind == REF_LOCAL_BRANCH) { + struct branch *branch = branch_get(name); + unsigned char sha1[20]; + + if (branch && + branch->merge && + branch->merge[0] && + branch->merge[0]->dst && + (reference_name = + resolve_ref(branch->merge[0]->dst, sha1, 1, NULL)) != NULL) + reference_rev = lookup_commit_reference(sha1); + } + if (!reference_rev) + reference_rev = head_rev; + + merged = in_merge_bases(rev, &reference_rev, 1); + + /* + * After the safety valve is fully redefined to "check with + * upstream, if any, otherwise with HEAD", we should just + * return the result of the in_merge_bases() above without + * any of the following code, but during the transition period, + * a gentle reminder is in order. + */ + if ((head_rev != reference_rev) && + in_merge_bases(rev, &head_rev, 1) != merged) { + if (merged) + warning("deleting branch '%s' that has been merged to\n" + " '%s', but it is not yet merged to HEAD.", + name, reference_name); + else + warning("not deleting branch '%s' that is not yet merged to\n" + " '%s', even though it is merged to HEAD.", + name, reference_name); + } + return merged; +} + +static int delete_branches(int argc, const char **argv, int force, int kinds) +{ + struct commit *rev, *head_rev = NULL; + unsigned char sha1[20]; + char *name = NULL; + const char *fmt, *remote; + int i; + int ret = 0; + struct strbuf bname = STRBUF_INIT; + + switch (kinds) { + case REF_REMOTE_BRANCH: + fmt = "refs/remotes/%s"; + remote = "remote "; + force = 1; + break; + case REF_LOCAL_BRANCH: + fmt = "refs/heads/%s"; + remote = ""; + break; + default: + die("cannot use -a with -d"); + } + + if (!force) { + head_rev = lookup_commit_reference(head_sha1); + if (!head_rev) + die("Couldn't look up commit object for HEAD"); + } + for (i = 0; i < argc; i++, strbuf_release(&bname)) { + strbuf_branchname(&bname, argv[i]); + if (kinds == REF_LOCAL_BRANCH && !strcmp(head, bname.buf)) { + error("Cannot delete the branch '%s' " + "which you are currently on.", bname.buf); + ret = 1; + continue; + } + + free(name); + + name = xstrdup(mkpath(fmt, bname.buf)); + if (!resolve_ref(name, sha1, 1, NULL)) { + error("%sbranch '%s' not found.", + remote, bname.buf); + ret = 1; + continue; + } + + rev = lookup_commit_reference(sha1); + if (!rev) { + error("Couldn't look up commit object for '%s'", name); + ret = 1; + continue; + } + + if (!force && !branch_merged(kinds, bname.buf, rev, head_rev)) { + error("The branch '%s' is not fully merged.\n" + "If you are sure you want to delete it, " + "run 'git branch -D %s'.", bname.buf, bname.buf); + ret = 1; + continue; + } + + if (delete_ref(name, sha1, 0)) { + error("Error deleting %sbranch '%s'", remote, + bname.buf); + ret = 1; + } else { + struct strbuf buf = STRBUF_INIT; + printf("Deleted %sbranch %s (was %s).\n", remote, + bname.buf, + find_unique_abbrev(sha1, DEFAULT_ABBREV)); + strbuf_addf(&buf, "branch.%s", bname.buf); + if (git_config_rename_section(buf.buf, NULL) < 0) + warning("Update of config-file failed"); + strbuf_release(&buf); + } + } + + free(name); + + return(ret); +} + +struct ref_item { + char *name; + char *dest; + unsigned int kind, len; + struct commit *commit; +}; + +struct ref_list { + struct rev_info revs; + int index, alloc, maxwidth, verbose, abbrev; + struct ref_item *list; + struct commit_list *with_commit; + int kinds; +}; + +static char *resolve_symref(const char *src, const char *prefix) +{ + unsigned char sha1[20]; + int flag; + const char *dst, *cp; + + dst = resolve_ref(src, sha1, 0, &flag); + if (!(dst && (flag & REF_ISSYMREF))) + return NULL; + if (prefix && (cp = skip_prefix(dst, prefix))) + dst = cp; + return xstrdup(dst); +} + +static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data) +{ + struct ref_list *ref_list = (struct ref_list*)(cb_data); + struct ref_item *newitem; + struct commit *commit; + int kind, i; + const char *prefix, *orig_refname = refname; + + static struct { + int kind; + const char *prefix; + int pfxlen; + } ref_kind[] = { + { REF_LOCAL_BRANCH, "refs/heads/", 11 }, + { REF_REMOTE_BRANCH, "refs/remotes/", 13 }, + }; + + /* Detect kind */ + for (i = 0; i < ARRAY_SIZE(ref_kind); i++) { + prefix = ref_kind[i].prefix; + if (strncmp(refname, prefix, ref_kind[i].pfxlen)) + continue; + kind = ref_kind[i].kind; + refname += ref_kind[i].pfxlen; + break; + } + if (ARRAY_SIZE(ref_kind) <= i) + return 0; + + /* Don't add types the caller doesn't want */ + if ((kind & ref_list->kinds) == 0) + return 0; + + commit = NULL; + if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) { + commit = lookup_commit_reference_gently(sha1, 1); + if (!commit) + return error("branch '%s' does not point at a commit", refname); + + /* Filter with with_commit if specified */ + if (!is_descendant_of(commit, ref_list->with_commit)) + return 0; + + if (merge_filter != NO_FILTER) + add_pending_object(&ref_list->revs, + (struct object *)commit, refname); + } + + /* Resize buffer */ + if (ref_list->index >= ref_list->alloc) { + ref_list->alloc = alloc_nr(ref_list->alloc); + ref_list->list = xrealloc(ref_list->list, + ref_list->alloc * sizeof(struct ref_item)); + } + + /* Record the new item */ + newitem = &(ref_list->list[ref_list->index++]); + newitem->name = xstrdup(refname); + newitem->kind = kind; + newitem->commit = commit; + newitem->len = strlen(refname); + newitem->dest = resolve_symref(orig_refname, prefix); + /* adjust for "remotes/" */ + if (newitem->kind == REF_REMOTE_BRANCH && + ref_list->kinds != REF_REMOTE_BRANCH) + newitem->len += 8; + if (newitem->len > ref_list->maxwidth) + ref_list->maxwidth = newitem->len; + + return 0; +} + +static void free_ref_list(struct ref_list *ref_list) +{ + int i; + + for (i = 0; i < ref_list->index; i++) { + free(ref_list->list[i].name); + free(ref_list->list[i].dest); + } + free(ref_list->list); +} + +static int ref_cmp(const void *r1, const void *r2) +{ + struct ref_item *c1 = (struct ref_item *)(r1); + struct ref_item *c2 = (struct ref_item *)(r2); + + if (c1->kind != c2->kind) + return c1->kind - c2->kind; + return strcmp(c1->name, c2->name); +} + +static void fill_tracking_info(struct strbuf *stat, const char *branch_name, + int show_upstream_ref) +{ + int ours, theirs; + struct branch *branch = branch_get(branch_name); + + if (!stat_tracking_info(branch, &ours, &theirs)) { + if (branch && branch->merge && branch->merge[0]->dst && + show_upstream_ref) + strbuf_addf(stat, "[%s] ", + shorten_unambiguous_ref(branch->merge[0]->dst, 0)); + return; + } + + strbuf_addch(stat, '['); + if (show_upstream_ref) + strbuf_addf(stat, "%s: ", + shorten_unambiguous_ref(branch->merge[0]->dst, 0)); + if (!ours) + strbuf_addf(stat, "behind %d] ", theirs); + else if (!theirs) + strbuf_addf(stat, "ahead %d] ", ours); + else + strbuf_addf(stat, "ahead %d, behind %d] ", ours, theirs); +} + +static int matches_merge_filter(struct commit *commit) +{ + int is_merged; + + if (merge_filter == NO_FILTER) + return 1; + + is_merged = !!(commit->object.flags & UNINTERESTING); + return (is_merged == (merge_filter == SHOW_MERGED)); +} + +static void print_ref_item(struct ref_item *item, int maxwidth, int verbose, + int abbrev, int current, char *prefix) +{ + char c; + int color; + struct commit *commit = item->commit; + struct strbuf out = STRBUF_INIT, name = STRBUF_INIT; + + if (!matches_merge_filter(commit)) + return; + + switch (item->kind) { + case REF_LOCAL_BRANCH: + color = BRANCH_COLOR_LOCAL; + break; + case REF_REMOTE_BRANCH: + color = BRANCH_COLOR_REMOTE; + break; + default: + color = BRANCH_COLOR_PLAIN; + break; + } + + c = ' '; + if (current) { + c = '*'; + color = BRANCH_COLOR_CURRENT; + } + + strbuf_addf(&name, "%s%s", prefix, item->name); + if (verbose) + strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(color), + maxwidth, name.buf, + branch_get_color(BRANCH_COLOR_RESET)); + else + strbuf_addf(&out, "%c %s%s%s", c, branch_get_color(color), + name.buf, branch_get_color(BRANCH_COLOR_RESET)); + + if (item->dest) + strbuf_addf(&out, " -> %s", item->dest); + else if (verbose) { + struct strbuf subject = STRBUF_INIT, stat = STRBUF_INIT; + const char *sub = " **** invalid ref ****"; + + commit = item->commit; + if (commit && !parse_commit(commit)) { + struct pretty_print_context ctx = {0}; + pretty_print_commit(CMIT_FMT_ONELINE, commit, + &subject, &ctx); + sub = subject.buf; + } + + if (item->kind == REF_LOCAL_BRANCH) + fill_tracking_info(&stat, item->name, verbose > 1); + + strbuf_addf(&out, " %s %s%s", + find_unique_abbrev(item->commit->object.sha1, abbrev), + stat.buf, sub); + strbuf_release(&stat); + strbuf_release(&subject); + } + printf("%s\n", out.buf); + strbuf_release(&name); + strbuf_release(&out); +} + +static int calc_maxwidth(struct ref_list *refs) +{ + int i, w = 0; + for (i = 0; i < refs->index; i++) { + if (!matches_merge_filter(refs->list[i].commit)) + continue; + if (refs->list[i].len > w) + w = refs->list[i].len; + } + return w; +} + + +static void show_detached(struct ref_list *ref_list) +{ + struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1); + + if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) { + struct ref_item item; + item.name = xstrdup("(no branch)"); + item.len = strlen(item.name); + item.kind = REF_LOCAL_BRANCH; + item.dest = NULL; + item.commit = head_commit; + if (item.len > ref_list->maxwidth) + ref_list->maxwidth = item.len; + print_ref_item(&item, ref_list->maxwidth, ref_list->verbose, ref_list->abbrev, 1, ""); + free(item.name); + } +} + +static void print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit) +{ + int i; + struct ref_list ref_list; + + memset(&ref_list, 0, sizeof(ref_list)); + ref_list.kinds = kinds; + ref_list.verbose = verbose; + ref_list.abbrev = abbrev; + ref_list.with_commit = with_commit; + if (merge_filter != NO_FILTER) + init_revisions(&ref_list.revs, NULL); + for_each_rawref(append_ref, &ref_list); + if (merge_filter != NO_FILTER) { + struct commit *filter; + filter = lookup_commit_reference_gently(merge_filter_ref, 0); + filter->object.flags |= UNINTERESTING; + add_pending_object(&ref_list.revs, + (struct object *) filter, ""); + ref_list.revs.limited = 1; + prepare_revision_walk(&ref_list.revs); + if (verbose) + ref_list.maxwidth = calc_maxwidth(&ref_list); + } + + qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp); + + detached = (detached && (kinds & REF_LOCAL_BRANCH)); + if (detached) + show_detached(&ref_list); + + for (i = 0; i < ref_list.index; i++) { + int current = !detached && + (ref_list.list[i].kind == REF_LOCAL_BRANCH) && + !strcmp(ref_list.list[i].name, head); + char *prefix = (kinds != REF_REMOTE_BRANCH && + ref_list.list[i].kind == REF_REMOTE_BRANCH) + ? "remotes/" : ""; + print_ref_item(&ref_list.list[i], ref_list.maxwidth, verbose, + abbrev, current, prefix); + } + + free_ref_list(&ref_list); +} + +static void rename_branch(const char *oldname, const char *newname, int force) +{ + struct strbuf oldref = STRBUF_INIT, newref = STRBUF_INIT, logmsg = STRBUF_INIT; + unsigned char sha1[20]; + struct strbuf oldsection = STRBUF_INIT, newsection = STRBUF_INIT; + int recovery = 0; + + if (!oldname) + die("cannot rename the current branch while not on any."); + + if (strbuf_check_branch_ref(&oldref, oldname)) { + /* + * Bad name --- this could be an attempt to rename a + * ref that we used to allow to be created by accident. + */ + if (resolve_ref(oldref.buf, sha1, 1, NULL)) + recovery = 1; + else + die("Invalid branch name: '%s'", oldname); + } + + if (strbuf_check_branch_ref(&newref, newname)) + die("Invalid branch name: '%s'", newname); + + if (resolve_ref(newref.buf, sha1, 1, NULL) && !force) + die("A branch named '%s' already exists.", newref.buf + 11); + + strbuf_addf(&logmsg, "Branch: renamed %s to %s", + oldref.buf, newref.buf); + + if (rename_ref(oldref.buf, newref.buf, logmsg.buf)) + die("Branch rename failed"); + strbuf_release(&logmsg); + + if (recovery) + warning("Renamed a misnamed branch '%s' away", oldref.buf + 11); + + /* no need to pass logmsg here as HEAD didn't really move */ + if (!strcmp(oldname, head) && create_symref("HEAD", newref.buf, NULL)) + die("Branch renamed to %s, but HEAD is not updated!", newname); + + strbuf_addf(&oldsection, "branch.%s", oldref.buf + 11); + strbuf_release(&oldref); + strbuf_addf(&newsection, "branch.%s", newref.buf + 11); + strbuf_release(&newref); + if (git_config_rename_section(oldsection.buf, newsection.buf) < 0) + die("Branch is renamed, but update of config-file failed"); + strbuf_release(&oldsection); + strbuf_release(&newsection); +} + +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; + int verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0; + int reflog = 0; + enum branch_track track; + int kinds = REF_LOCAL_BRANCH; + struct commit_list *with_commit = NULL; + + struct option options[] = { + OPT_GROUP("Generic options"), + OPT__VERBOSE(&verbose), + OPT_SET_INT('t', "track", &track, "set up tracking mode (see git-pull(1))", + BRANCH_TRACK_EXPLICIT), + OPT_SET_INT( 0, "set-upstream", &track, "change upstream info", + BRANCH_TRACK_OVERRIDE), + OPT_BOOLEAN( 0 , "color", &branch_use_color, "use colored output"), + OPT_SET_INT('r', NULL, &kinds, "act on remote-tracking branches", + REF_REMOTE_BRANCH), + { + OPTION_CALLBACK, 0, "contains", &with_commit, "commit", + "print only branches that contain the commit", + PARSE_OPT_LASTARG_DEFAULT, + parse_opt_with_commit, (intptr_t)"HEAD", + }, + { + OPTION_CALLBACK, 0, "with", &with_commit, "commit", + "print only branches that contain the commit", + PARSE_OPT_HIDDEN | PARSE_OPT_LASTARG_DEFAULT, + parse_opt_with_commit, (intptr_t) "HEAD", + }, + OPT__ABBREV(&abbrev), + + OPT_GROUP("Specific git-branch actions:"), + OPT_SET_INT('a', NULL, &kinds, "list both remote-tracking and local branches", + REF_REMOTE_BRANCH | REF_LOCAL_BRANCH), + OPT_BIT('d', NULL, &delete, "delete fully merged branch", 1), + OPT_BIT('D', NULL, &delete, "delete branch (even if not merged)", 2), + OPT_BIT('m', NULL, &rename, "move/rename a branch and its reflog", 1), + 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', "force", &force_create, "force creation (when already exists)"), + { + 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(), + }; + + git_config(git_branch_config, NULL); + + if (branch_use_color == -1) + branch_use_color = git_use_color_default; + + track = git_branch_track; + + head = resolve_ref("HEAD", head_sha1, 0, NULL); + if (!head) + die("Failed to resolve HEAD as a valid ref."); + head = xstrdup(head); + if (!strcmp(head, "HEAD")) { + detached = 1; + } else { + if (prefixcmp(head, "refs/heads/")) + die("HEAD not found below refs/heads!"); + head += 11; + } + hashcpy(merge_filter_ref, head_sha1); + + argc = parse_options(argc, argv, prefix, 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); + else if (argc == 0) + print_ref_list(kinds, detached, verbose, abbrev, with_commit); + else if (rename && (argc == 1)) + rename_branch(head, argv[0], rename > 1); + else if (rename && (argc == 2)) + rename_branch(argv[0], argv[1], rename > 1); + else if (argc <= 2) { + if (kinds != REF_LOCAL_BRANCH) + die("-a and -r options to 'git branch' do not make sense with a branch name"); + create_branch(head, argv[0], (argc == 2) ? argv[1] : head, + force_create, reflog, track); + } else + usage_with_options(builtin_branch_usage, options); + + return 0; +} -- cgit v1.2.3 From 4b05548fc0523744b7a1276cfa0f4aae19d6d9c9 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Fri, 14 May 2010 09:31:35 +0000 Subject: enums: omit trailing comma for portability Without this patch at least IBM VisualAge C 5.0 (I have 5.0.2) on AIX 5.1 fails to compile git. enum style is inconsistent already, with some enums declared on one line, some over 3 lines with the enum values all on the middle line, sometimes with 1 enum value per line... and independently of that the trailing comma is sometimes present and other times absent, often mixing with/without trailing comma styles in a single file, and sometimes in consecutive enum declarations. Clearly, omitting the comma is the more portable style, and this patch changes all enum declarations to use the portable omitted dangling comma style consistently. Signed-off-by: Gary V. Vaughan Signed-off-by: Junio C Hamano --- builtin/branch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 6cf7e721e6..f594af0b3b 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -43,13 +43,13 @@ enum color_branch { BRANCH_COLOR_PLAIN = 1, BRANCH_COLOR_REMOTE = 2, BRANCH_COLOR_LOCAL = 3, - BRANCH_COLOR_CURRENT = 4, + BRANCH_COLOR_CURRENT = 4 }; static enum merge_filter { NO_FILTER = 0, SHOW_NOT_MERGED, - SHOW_MERGED, + SHOW_MERGED } merge_filter; static unsigned char merge_filter_ref[20]; -- cgit v1.2.3 From 1603ade81352a526ccb206f41ff81ecbc855df2d Mon Sep 17 00:00:00 2001 From: Simo Melenius Date: Fri, 4 Jun 2010 12:50:10 +0300 Subject: branch: exit status now reflects if branch listing finds an error If some refs could not be read when listing branches, this can now be observed in the exit status of the "git branch" command. Signed-off-by: Simo Melenius Reviewed-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- builtin/branch.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 6cf7e721e6..5f0873ab68 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -257,9 +257,15 @@ static char *resolve_symref(const char *src, const char *prefix) return xstrdup(dst); } +struct append_ref_cb { + struct ref_list *ref_list; + int ret; +}; + static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data) { - struct ref_list *ref_list = (struct ref_list*)(cb_data); + struct append_ref_cb *cb = (struct append_ref_cb *)(cb_data); + struct ref_list *ref_list = cb->ref_list; struct ref_item *newitem; struct commit *commit; int kind, i; @@ -293,8 +299,10 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags, commit = NULL; if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) { commit = lookup_commit_reference_gently(sha1, 1); - if (!commit) - return error("branch '%s' does not point at a commit", refname); + if (!commit) { + cb->ret = error("branch '%s' does not point at a commit", refname); + return cb->ret; + } /* Filter with with_commit if specified */ if (!is_descendant_of(commit, ref_list->with_commit)) @@ -484,9 +492,10 @@ static void show_detached(struct ref_list *ref_list) } } -static void print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit) +static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit) { int i; + struct append_ref_cb cb; struct ref_list ref_list; memset(&ref_list, 0, sizeof(ref_list)); @@ -496,7 +505,9 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str ref_list.with_commit = with_commit; if (merge_filter != NO_FILTER) init_revisions(&ref_list.revs, NULL); - for_each_rawref(append_ref, &ref_list); + cb.ref_list = &ref_list; + cb.ret = 0; + for_each_rawref(append_ref, &cb); if (merge_filter != NO_FILTER) { struct commit *filter; filter = lookup_commit_reference_gently(merge_filter_ref, 0); @@ -527,6 +538,8 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str } free_ref_list(&ref_list); + + return cb.ret; } static void rename_branch(const char *oldname, const char *newname, int force) @@ -679,7 +692,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) if (delete) return delete_branches(argc, argv, delete > 1, kinds); else if (argc == 0) - print_ref_list(kinds, detached, verbose, abbrev, with_commit); + return print_ref_list(kinds, detached, verbose, abbrev, with_commit); else if (rename && (argc == 1)) rename_branch(head, argv[0], rename > 1); else if (rename && (argc == 2)) -- cgit v1.2.3 From 0e9716e65e40883759082b35e90113d0d0c8f7a6 Mon Sep 17 00:00:00 2001 From: Simo Melenius Date: Fri, 4 Jun 2010 12:50:11 +0300 Subject: branch: don't fail listing branches if one of the commits wasn't found When listing branches with ref lookups, if one of the known raw refs doesn't point to a commit then "git branch" would return error(), terminating the whole for_each_rawref() iteration and possibly hiding any remaining refs. Signed-off-by: Simo Melenius Reviewed-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- builtin/branch.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 5f0873ab68..a92de9a066 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -301,7 +301,7 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags, commit = lookup_commit_reference_gently(sha1, 1); if (!commit) { cb->ret = error("branch '%s' does not point at a commit", refname); - return cb->ret; + return 0; } /* Filter with with_commit if specified */ @@ -539,6 +539,9 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru free_ref_list(&ref_list); + if (cb.ret) + error("some refs could not be read"); + return cb.ret; } -- cgit v1.2.3 From 1dacfbcf13693dad508095735a95bc4b12382c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Fri, 22 Oct 2010 01:42:58 -0500 Subject: branch -h: show usage even in an invalid repository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no need for "git branch -h" to try to access a repository. In the spirit of v1.6.6-rc0~34^2~3 (Let 'git -h' show usage without a git dir, 2009-11-09). This brings git one step closer to passing the following (automatically verifiable) test: Before any repository access (aside from git_config()), a function from the setup_git_directory_* family has been run and thus one step closer to being able to use an automatic repository access checker. [jn: simplified; new commit message, test] Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- builtin/branch.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 87976f0921..0e50556a15 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -667,6 +667,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix) OPT_END(), }; + if (argc == 2 && !strcmp(argv[1], "-h")) + usage_with_options(builtin_branch_usage, options); + git_config(git_branch_config, NULL); if (branch_use_color == -1) -- cgit v1.2.3 From fd03881a48fc31197ab3343ac2f02ed0cdbbbaaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Mon, 8 Nov 2010 18:56:39 +0100 Subject: add description parameter to OPT__VERBOSE Allows better help text to be defined than "be verbose". Also make use of the macro in places that already had a different description. No object code changes intended. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin/branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 87976f0921..10788fc1dd 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -621,7 +621,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) struct option options[] = { OPT_GROUP("Generic options"), - OPT__VERBOSE(&verbose), + OPT__VERBOSE(&verbose, "be verbose"), OPT_SET_INT('t', "track", &track, "set up tracking mode (see git-pull(1))", BRANCH_TRACK_EXPLICIT), OPT_SET_INT( 0, "set-upstream", &track, "change upstream info", -- cgit v1.2.3 From 76946b76fe3d26507d61cae97aa0676fad24ed92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Mon, 8 Nov 2010 19:01:54 +0100 Subject: add OPT__FORCE Add OPT__FORCE as a helper macro in the same spirit as OPT__VERBOSE et.al. to simplify defining -f/--force options. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin/branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 10788fc1dd..e388edc413 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -651,7 +651,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) OPT_BIT('m', NULL, &rename, "move/rename a branch and its reflog", 1), 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', "force", &force_create, "force creation (when already exists)"), + OPT__FORCE(&force_create, "force creation (when already exists)"), { OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref, "commit", "print only not merged branches", -- cgit v1.2.3 From 3927142561e4f5f045aa024f11782446abd1ba6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Mon, 8 Nov 2010 19:03:58 +0100 Subject: branch: improve --verbose description Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin/branch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index e388edc413..807355a198 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -621,7 +621,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix) struct option options[] = { OPT_GROUP("Generic options"), - OPT__VERBOSE(&verbose, "be verbose"), + OPT__VERBOSE(&verbose, + "show hash and subject, give twice for upstream branch"), OPT_SET_INT('t', "track", &track, "set up tracking mode (see git-pull(1))", BRANCH_TRACK_EXPLICIT), OPT_SET_INT( 0, "set-upstream", &track, "change upstream info", -- cgit v1.2.3 From fcbc0d8e8216d7b6235eccf9f3b556455ad3be3d Mon Sep 17 00:00:00 2001 From: Thiago Farina Date: Mon, 13 Dec 2010 23:59:55 -0200 Subject: builtin/branch.c: Use ALLOC_GROW instead of alloc_nr and xrealloc. Signed-off-by: Thiago Farina Signed-off-by: Junio C Hamano --- builtin/branch.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 0cad20bb5a..9e546e4a83 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -313,12 +313,7 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags, (struct object *)commit, refname); } - /* Resize buffer */ - if (ref_list->index >= ref_list->alloc) { - ref_list->alloc = alloc_nr(ref_list->alloc); - ref_list->list = xrealloc(ref_list->list, - ref_list->alloc * sizeof(struct ref_item)); - } + ALLOC_GROW(ref_list->list, ref_list->index + 1, ref_list->alloc); /* Record the new item */ newitem = &(ref_list->list[ref_list->index++]); -- cgit v1.2.3 From 62270f6b0a4e67e5044fb0d70d0e82ac6e553eb2 Mon Sep 17 00:00:00 2001 From: Eric Hanchrow Date: Fri, 25 Feb 2011 19:29:42 -0800 Subject: branch_merged: fix grammar in warning Signed-off-by: Eric Hanchrow Helped-by: Jay Soffian Signed-off-by: Junio C Hamano --- builtin/branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 9e546e4a83..fe8f2fcd52 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -134,7 +134,7 @@ static int branch_merged(int kind, const char *name, in_merge_bases(rev, &head_rev, 1) != merged) { if (merged) warning("deleting branch '%s' that has been merged to\n" - " '%s', but it is not yet merged to HEAD.", + " '%s', but not yet been merged to HEAD.", name, reference_name); else warning("not deleting branch '%s' that is not yet merged to\n" -- cgit v1.2.3 From 49df4b0298ea87ec737221c35ac74f8e6ee108c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Tue, 22 Feb 2011 23:41:34 +0000 Subject: i18n: git-branch basic messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- builtin/branch.c | 56 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 9e546e4a83..6695db4ade 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -133,12 +133,12 @@ static int branch_merged(int kind, const char *name, if ((head_rev != reference_rev) && in_merge_bases(rev, &head_rev, 1) != merged) { if (merged) - warning("deleting branch '%s' that has been merged to\n" - " '%s', but it is not yet merged to HEAD.", + warning(_("deleting branch '%s' that has been merged to\n" + " '%s', but it is not yet merged to HEAD."), name, reference_name); else - warning("not deleting branch '%s' that is not yet merged to\n" - " '%s', even though it is merged to HEAD.", + warning(_("not deleting branch '%s' that is not yet merged to\n" + " '%s', even though it is merged to HEAD."), name, reference_name); } return merged; @@ -165,19 +165,19 @@ static int delete_branches(int argc, const char **argv, int force, int kinds) remote = ""; break; default: - die("cannot use -a with -d"); + die(_("cannot use -a with -d")); } if (!force) { head_rev = lookup_commit_reference(head_sha1); if (!head_rev) - die("Couldn't look up commit object for HEAD"); + die(_("Couldn't look up commit object for HEAD")); } for (i = 0; i < argc; i++, strbuf_release(&bname)) { strbuf_branchname(&bname, argv[i]); if (kinds == REF_LOCAL_BRANCH && !strcmp(head, bname.buf)) { - error("Cannot delete the branch '%s' " - "which you are currently on.", bname.buf); + error(_("Cannot delete the branch '%s' " + "which you are currently on."), bname.buf); ret = 1; continue; } @@ -186,7 +186,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds) name = xstrdup(mkpath(fmt, bname.buf)); if (!resolve_ref(name, sha1, 1, NULL)) { - error("%sbranch '%s' not found.", + error(_("%sbranch '%s' not found."), remote, bname.buf); ret = 1; continue; @@ -194,21 +194,21 @@ static int delete_branches(int argc, const char **argv, int force, int kinds) rev = lookup_commit_reference(sha1); if (!rev) { - error("Couldn't look up commit object for '%s'", name); + error(_("Couldn't look up commit object for '%s'"), name); ret = 1; continue; } if (!force && !branch_merged(kinds, bname.buf, rev, head_rev)) { - error("The branch '%s' is not fully merged.\n" + error(_("The branch '%s' is not fully merged.\n" "If you are sure you want to delete it, " - "run 'git branch -D %s'.", bname.buf, bname.buf); + "run 'git branch -D %s'."), bname.buf, bname.buf); ret = 1; continue; } if (delete_ref(name, sha1, 0)) { - error("Error deleting %sbranch '%s'", remote, + error(_("Error deleting %sbranch '%s'"), remote, bname.buf); ret = 1; } else { @@ -218,7 +218,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds) find_unique_abbrev(sha1, DEFAULT_ABBREV)); strbuf_addf(&buf, "branch.%s", bname.buf); if (git_config_rename_section(buf.buf, NULL) < 0) - warning("Update of config-file failed"); + warning(_("Update of config-file failed")); strbuf_release(&buf); } } @@ -300,7 +300,7 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags, if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) { commit = lookup_commit_reference_gently(sha1, 1); if (!commit) { - cb->ret = error("branch '%s' does not point at a commit", refname); + cb->ret = error(_("branch '%s' does not point at a commit"), refname); return 0; } @@ -535,7 +535,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru free_ref_list(&ref_list); if (cb.ret) - error("some refs could not be read"); + error(_("some refs could not be read")); return cb.ret; } @@ -548,7 +548,7 @@ static void rename_branch(const char *oldname, const char *newname, int force) int recovery = 0; if (!oldname) - die("cannot rename the current branch while not on any."); + die(_("cannot rename the current branch while not on any.")); if (strbuf_check_branch_ref(&oldref, oldname)) { /* @@ -558,35 +558,35 @@ static void rename_branch(const char *oldname, const char *newname, int force) if (resolve_ref(oldref.buf, sha1, 1, NULL)) recovery = 1; else - die("Invalid branch name: '%s'", oldname); + die(_("Invalid branch name: '%s'"), oldname); } if (strbuf_check_branch_ref(&newref, newname)) - die("Invalid branch name: '%s'", newname); + die(_("Invalid branch name: '%s'"), newname); if (resolve_ref(newref.buf, sha1, 1, NULL) && !force) - die("A branch named '%s' already exists.", newref.buf + 11); + die(_("A branch named '%s' already exists."), newref.buf + 11); strbuf_addf(&logmsg, "Branch: renamed %s to %s", oldref.buf, newref.buf); if (rename_ref(oldref.buf, newref.buf, logmsg.buf)) - die("Branch rename failed"); + die(_("Branch rename failed")); strbuf_release(&logmsg); if (recovery) - warning("Renamed a misnamed branch '%s' away", oldref.buf + 11); + warning(_("Renamed a misnamed branch '%s' away"), oldref.buf + 11); /* no need to pass logmsg here as HEAD didn't really move */ if (!strcmp(oldname, head) && create_symref("HEAD", newref.buf, NULL)) - die("Branch renamed to %s, but HEAD is not updated!", newname); + die(_("Branch renamed to %s, but HEAD is not updated!"), newname); strbuf_addf(&oldsection, "branch.%s", oldref.buf + 11); strbuf_release(&oldref); strbuf_addf(&newsection, "branch.%s", newref.buf + 11); strbuf_release(&newref); if (git_config_rename_section(oldsection.buf, newsection.buf) < 0) - die("Branch is renamed, but update of config-file failed"); + die(_("Branch is renamed, but update of config-file failed")); strbuf_release(&oldsection); strbuf_release(&newsection); } @@ -601,7 +601,7 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int if (!arg) arg = "HEAD"; if (get_sha1(arg, merge_filter_ref)) - die("malformed object name %s", arg); + die(_("malformed object name %s"), arg); return 0; } @@ -675,13 +675,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix) head = resolve_ref("HEAD", head_sha1, 0, NULL); if (!head) - die("Failed to resolve HEAD as a valid ref."); + die(_("Failed to resolve HEAD as a valid ref.")); head = xstrdup(head); if (!strcmp(head, "HEAD")) { detached = 1; } else { if (prefixcmp(head, "refs/heads/")) - die("HEAD not found below refs/heads!"); + die(_("HEAD not found below refs/heads!")); head += 11; } hashcpy(merge_filter_ref, head_sha1); @@ -701,7 +701,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) rename_branch(argv[0], argv[1], rename > 1); else if (argc <= 2) { if (kinds != REF_LOCAL_BRANCH) - die("-a and -r options to 'git branch' do not make sense with a branch name"); + die(_("-a and -r options to 'git branch' do not make sense with a branch name")); create_branch(head, argv[0], (argc == 2) ? argv[1] : head, force_create, reflog, track); } else -- cgit v1.2.3 From 2852e1dd5d21a9b43f27801181d9d875efa02598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Tue, 22 Feb 2011 23:41:35 +0000 Subject: i18n: git-branch "remote branch '%s' not found" message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This could be done better by splitting it up, but it would change too much code, which I'm trying to avoid at this point. Instead add a TRANSLATORS comment to explain what "remote " does. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- builtin/branch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 6695db4ade..e9d8a5a31d 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -157,7 +157,8 @@ static int delete_branches(int argc, const char **argv, int force, int kinds) switch (kinds) { case REF_REMOTE_BRANCH: fmt = "refs/remotes/%s"; - remote = "remote "; + /* TRANSLATORS: This is "remote " in "remote branch '%s' not found" */ + remote = _("remote "); force = 1; break; case REF_LOCAL_BRANCH: -- cgit v1.2.3 From 8af42b0f7773bff2529f6c8990bb3d872b8270d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Tue, 22 Feb 2011 23:41:36 +0000 Subject: i18n: git-branch "Deleted branch [...]" message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gettextize the "Deleted %sbranch %s (was %s).\n" messages. test in t3200-branch.sh explicitly checked for this message. Change it to skip under GETTEXT_POISON=YesPlease. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- builtin/branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index e9d8a5a31d..d276681c46 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -214,7 +214,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds) ret = 1; } else { struct strbuf buf = STRBUF_INIT; - printf("Deleted %sbranch %s (was %s).\n", remote, + printf(_("Deleted %sbranch %s (was %s).\n"), remote, bname.buf, find_unique_abbrev(sha1, DEFAULT_ABBREV)); strbuf_addf(&buf, "branch.%s", bname.buf); -- cgit v1.2.3 From a5760906e78adeab2ae8f404528c4ce10d046f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Tue, 22 Feb 2011 23:41:37 +0000 Subject: i18n: git-branch "git branch -v" messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the "git branch -v" messages translatable, e.g.: 5054b57 [ahead 8] branch error fixup This is possibly a plumbing message. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- builtin/branch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index d276681c46..4c1a256247 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -373,11 +373,11 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name, strbuf_addf(stat, "%s: ", shorten_unambiguous_ref(branch->merge[0]->dst, 0)); if (!ours) - strbuf_addf(stat, "behind %d] ", theirs); + strbuf_addf(stat, _("behind %d] "), theirs); else if (!theirs) - strbuf_addf(stat, "ahead %d] ", ours); + strbuf_addf(stat, _("ahead %d] "), ours); else - strbuf_addf(stat, "ahead %d, behind %d] ", ours, theirs); + strbuf_addf(stat, _("ahead %d, behind %d] "), ours, theirs); } static int matches_merge_filter(struct commit *commit) -- cgit v1.2.3 From 409fa556ce5c7e680d773d4bb01ca2c3162a9e9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Tue, 22 Feb 2011 23:41:38 +0000 Subject: i18n: git-branch "(no branch)" message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gettextize the "(no branch)" message that's shown by "git branch" when you're in a detached HEAD. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- builtin/branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 4c1a256247..244589e736 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -476,7 +476,7 @@ static void show_detached(struct ref_list *ref_list) if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) { struct ref_item item; - item.name = xstrdup("(no branch)"); + item.name = xstrdup(_("(no branch)")); item.len = strlen(item.name); item.kind = REF_LOCAL_BRANCH; item.dest = NULL; -- cgit v1.2.3 From 6e0332ec3ea74e635258a30d360bd2e00a51730e Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Wed, 16 Mar 2011 02:10:14 -0500 Subject: branch: split off function that writes tracking info and commit subject Introduce a add_verbose_info function that takes care of adding - an abbreviated object name; - a summary of the form [ahead x, behind y] of the relationship to the corresponding upstream branch; - a one line commit subject for the tip commit of a branch, for use in "git branch -v" output. No functional change intended. This just unindents the code a little and makes it easier to skip on first reading. Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- builtin/branch.c | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index fe8f2fcd52..b9ba011f7b 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -390,6 +390,30 @@ static int matches_merge_filter(struct commit *commit) return (is_merged == (merge_filter == SHOW_MERGED)); } +static void add_verbose_info(struct strbuf *out, struct ref_item *item, + int verbose, int abbrev) +{ + struct strbuf subject = STRBUF_INIT, stat = STRBUF_INIT; + const char *sub = " **** invalid ref ****"; + struct commit *commit = item->commit; + + if (commit && !parse_commit(commit)) { + struct pretty_print_context ctx = {0}; + pretty_print_commit(CMIT_FMT_ONELINE, commit, + &subject, &ctx); + sub = subject.buf; + } + + if (item->kind == REF_LOCAL_BRANCH) + fill_tracking_info(&stat, item->name, verbose > 1); + + strbuf_addf(out, " %s %s%s", + find_unique_abbrev(item->commit->object.sha1, abbrev), + stat.buf, sub); + strbuf_release(&stat); + strbuf_release(&subject); +} + static void print_ref_item(struct ref_item *item, int maxwidth, int verbose, int abbrev, int current, char *prefix) { @@ -430,27 +454,9 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose, if (item->dest) strbuf_addf(&out, " -> %s", item->dest); - else if (verbose) { - struct strbuf subject = STRBUF_INIT, stat = STRBUF_INIT; - const char *sub = " **** invalid ref ****"; - - commit = item->commit; - if (commit && !parse_commit(commit)) { - struct pretty_print_context ctx = {0}; - pretty_print_commit(CMIT_FMT_ONELINE, commit, - &subject, &ctx); - sub = subject.buf; - } - - if (item->kind == REF_LOCAL_BRANCH) - fill_tracking_info(&stat, item->name, verbose > 1); - - strbuf_addf(&out, " %s %s%s", - find_unique_abbrev(item->commit->object.sha1, abbrev), - stat.buf, sub); - strbuf_release(&stat); - strbuf_release(&subject); - } + else if (verbose) + /* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */ + add_verbose_info(&out, item, verbose, abbrev); printf("%s\n", out.buf); strbuf_release(&name); strbuf_release(&out); -- cgit v1.2.3 From 8b8a53744f60274ef07e3a2a51995129c8d42f38 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 26 May 2011 18:27:24 -0400 Subject: pretty: add pp_commit_easy function for simple callers Many callers don't actually care about the pretty print context at all; let's just give them a simple way of pretty-printing a commit without having to create a context struct. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/branch.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 9e546e4a83..d8f15221ed 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -436,9 +436,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose, commit = item->commit; if (commit && !parse_commit(commit)) { - struct pretty_print_context ctx = {0}; - pretty_print_commit(CMIT_FMT_ONELINE, commit, - &subject, &ctx); + pp_commit_easy(CMIT_FMT_ONELINE, commit, &subject); sub = subject.buf; } -- cgit v1.2.3 From 534cea3fce7d32fc924fd477520fa2e631288ca6 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 27 Jun 2011 15:04:32 -0700 Subject: "branch -d" can remove more than one branches Since 03feddd (git-check-ref-format: reject funny ref names, 2005-10-13), "git branch -d" can take more than one branch names to remove. The documentation was correct, but the usage string was not. Signed-off-by: Junio C Hamano --- builtin/branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 9cca1b9afc..63f4e69925 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -19,7 +19,7 @@ static const char * const builtin_branch_usage[] = { "git branch [options] [-r | -a] [--merged | --no-merged]", "git branch [options] [-l] [-f] []", - "git branch [options] [-r] (-d | -D) ", + "git branch [options] [-r] (-d | -D) ...", "git branch [options] (-m | -M) [] ", NULL }; -- cgit v1.2.3 From b792c067872a6b4ec6545dc4375a7084626cb0fa Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 1 Jul 2011 15:06:08 +0900 Subject: branch -v: honor core.abbrev Use the value from 'core.abbrev' configuration variable unless user specifies the length on command line when showing commit object name in "branch -v" output. Signed-off-by: Namhyung Kim Signed-off-by: Junio C Hamano --- builtin/branch.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 3142daa57a..953bc1ca9b 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -613,7 +613,7 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int int cmd_branch(int argc, const char **argv, const char *prefix) { int delete = 0, rename = 0, force_create = 0; - int verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0; + int verbose = 0, abbrev = -1, detached = 0; int reflog = 0; enum branch_track track; int kinds = REF_LOCAL_BRANCH; @@ -696,6 +696,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix) if (!!delete + !!rename + !!force_create > 1) usage_with_options(builtin_branch_usage, options); + if (abbrev == -1) + abbrev = DEFAULT_ABBREV; + if (delete) return delete_branches(argc, argv, delete > 1, kinds); else if (argc == 0) -- cgit v1.2.3 From e269eb7946d0a4ba6a4e175133b5479446ac04a5 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 17 Aug 2011 22:03:48 -0700 Subject: git_config_colorbool: refactor stdout_is_tty handling Usually this function figures out for itself whether stdout is a tty. However, it has an extra parameter just to allow git-config to override the auto-detection for its --get-colorbool option. Instead of an extra parameter, let's just use a global variable. This makes calling easier in the common case, and will make refactoring the colorbool code much simpler. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 3142daa57a..b15fee5e31 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -71,7 +71,7 @@ static int parse_branch_color_slot(const char *var, int ofs) 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); + branch_use_color = git_config_colorbool(var, value); return 0; } if (!prefixcmp(var, "color.branch.")) { -- cgit v1.2.3 From daa0c3d9717624a62ce669252be832db12658ec0 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 17 Aug 2011 22:04:23 -0700 Subject: color: delay auto-color decision until point of use When we read a color value either from a config file or from the command line, we use git_config_colorbool to convert it from the tristate always/never/auto into a single yes/no boolean value. This has some timing implications with respect to starting a pager. If we start (or decide not to start) the pager before checking the colorbool, everything is fine. Either isatty(1) will give us the right information, or we will properly check for pager_in_use(). However, if we decide to start a pager after we have checked the colorbool, things are not so simple. If stdout is a tty, then we will have already decided to use color. However, the user may also have configured color.pager not to use color with the pager. In this case, we need to actually turn off color. Unfortunately, the pager code has no idea which color variables were turned on (and there are many of them throughout the code, and they may even have been manipulated after the colorbool selection by something like "--color" on the command line). This bug can be seen any time a pager is started after config and command line options are checked. This has affected "git diff" since 89d07f7 (diff: don't run pager if user asked for a diff style exit code, 2007-08-12). It has also affect the log family since 1fda91b (Fix 'git log' early pager startup error case, 2010-08-24). This patch splits the notion of parsing a colorbool and actually checking the configuration. The "use_color" variables now have an additional possible value, GIT_COLOR_AUTO. Users of the variable should use the new "want_color()" wrapper, which will lazily determine and cache the auto-color decision. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index b15fee5e31..d6d3c7d85b 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -88,7 +88,7 @@ static int git_branch_config(const char *var, const char *value, void *cb) static const char *branch_get_color(enum color_branch ix) { - if (branch_use_color > 0) + if (want_color(branch_use_color)) return branch_colors[ix]; return ""; } -- cgit v1.2.3 From c9bfb953489e559d513c1627150aa16f8d42d6c5 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 17 Aug 2011 22:05:35 -0700 Subject: want_color: automatically fallback to color.ui All of the "do we want color" flags default to -1 to indicate that we don't have any color configured. This value is handled in one of two ways: 1. In porcelain, we check early on whether the value is still -1 after reading the config, and set it to the value of color.ui (which defaults to 0). 2. In plumbing, it stays untouched as -1, and want_color defaults it to off. This works fine, but means that every porcelain has to check and reassign its color flag. Now that want_color gives us a place to put this check in a single spot, we can do that, simplifying the calling code. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/branch.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index d6d3c7d85b..73d41700d1 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -673,9 +673,6 @@ int cmd_branch(int argc, const char **argv, const char *prefix) git_config(git_branch_config, NULL); - if (branch_use_color == -1) - branch_use_color = git_use_color_default; - track = git_branch_track; head = resolve_ref("HEAD", head_sha1, 0, NULL); -- cgit v1.2.3 From 55c4a673070f40f2ef12d0be269e95f1df6825a9 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Sat, 20 Aug 2011 14:49:48 -0700 Subject: Prevent force-updating of the current branch "git branch -M " allows updating the current branch which HEAD points, without the necessary house-keeping that git reset normally does to make this operation sensible. It also leaves the reflog in a confusing state (you would be warned when trying to read it). "git checkout -B " is also partly vulnerable to this bug; due to inconsistent pre-flight checks it would perform half of its task and then abort just before rewriting the branch. Again this manifested itself as the index file getting out-of-sync with HEAD. "git branch -f" already guarded against this problem, and aborts with a fatal error. Update "git branch -M", "git checkout -B" and "git branch -f" to share the same check before allowing a branch to be created. These prevent you from updating the current branch. We considered suggesting the use of "git reset" in the failure message but concluded that it was not possible to discern what the user was actually trying to do. Signed-off-by: Conrad Irwin Signed-off-by: Junio C Hamano --- builtin/branch.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 3142daa57a..40f885c9fe 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -566,11 +566,7 @@ static void rename_branch(const char *oldname, const char *newname, int force) die(_("Invalid branch name: '%s'"), oldname); } - if (strbuf_check_branch_ref(&newref, newname)) - die(_("Invalid branch name: '%s'"), newname); - - if (resolve_ref(newref.buf, sha1, 1, NULL) && !force) - die(_("A branch named '%s' already exists."), newref.buf + 11); + validate_new_branchname(newname, &newref, force); strbuf_addf(&logmsg, "Branch: renamed %s to %s", oldref.buf, newref.buf); -- cgit v1.2.3 From fa79937675600ad5dda5031c532097a0461d843e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 16 Sep 2011 16:28:38 -0700 Subject: branch --set-upstream: regression fix The "git branch" command, while not in listing mode, calls create_branch() even when the target branch already exists, and it does so even when it is not interested in updating the value of the branch (i.e. the name of the commit object that sits at the tip of the existing branch). This happens when the command is run with "--set-upstream" option. The earlier safety-measure to prevent "git branch -f $branch $commit" from updating the currently checked out branch did not take it into account, and we no longer can update the tracking information of the current branch. Minimally fix this regression by telling the validation code if it is called to really update the value of a potentially existing branch, or if the caller merely is interested in updating auxiliary aspects of a branch. Reported-and-Tested-by: Jay Soffian Signed-off-by: Junio C Hamano --- builtin/branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin/branch.c') diff --git a/builtin/branch.c b/builtin/branch.c index 40f885c9fe..5fb3d85ad3 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -566,7 +566,7 @@ static void rename_branch(const char *oldname, const char *newname, int force) die(_("Invalid branch name: '%s'"), oldname); } - validate_new_branchname(newname, &newref, force); + validate_new_branchname(newname, &newref, force, 0); strbuf_addf(&logmsg, "Branch: renamed %s to %s", oldref.buf, newref.buf); -- cgit v1.2.3