From: Junio C Hamano Date: Wed, 14 Dec 2011 06:53:08 +0000 (-0800) Subject: Merge branch 'jn/branch-move-to-self' X-Git-Tag: v1.7.9-rc0~69 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/b2dd02112052aff875e8dc7d12b9915c91feafe2?ds=inline;hp=-c Merge branch 'jn/branch-move-to-self' * jn/branch-move-to-self: Allow checkout -B to update the current branch branch: allow a no-op "branch -M HEAD" --- b2dd02112052aff875e8dc7d12b9915c91feafe2 diff --combined branch.c index d91a099fdd,f85c438284..a715a11749 --- a/branch.c +++ b/branch.c @@@ -136,37 -136,6 +136,37 @@@ static int setup_tracking(const char *n return 0; } +struct branch_desc_cb { + const char *config_name; + const char *value; +}; + +static int read_branch_desc_cb(const char *var, const char *value, void *cb) +{ + struct branch_desc_cb *desc = cb; + if (strcmp(desc->config_name, var)) + return 0; + free((char *)desc->value); + return git_config_string(&desc->value, var, value); +} + +int read_branch_desc(struct strbuf *buf, const char *branch_name) +{ + struct branch_desc_cb cb; + struct strbuf name = STRBUF_INIT; + strbuf_addf(&name, "branch.%s.description", branch_name); + cb.config_name = name.buf; + cb.value = NULL; + if (git_config(read_branch_desc_cb, &cb) < 0) { + strbuf_release(&name); + return -1; + } + if (cb.value) + strbuf_addstr(buf, cb.value); + strbuf_release(&name); + return 0; +} + int validate_new_branchname(const char *name, struct strbuf *ref, int force, int attr_only) { @@@ -191,7 -160,8 +191,8 @@@ void create_branch(const char *head, const char *name, const char *start_name, - int force, int reflog, enum branch_track track) + int force, int reflog, int clobber_head, + enum branch_track track) { struct ref_lock *lock = NULL; struct commit *commit; @@@ -206,7 -176,8 +207,8 @@@ explicit_tracking = 1; if (validate_new_branchname(name, &ref, force, - track == BRANCH_TRACK_OVERRIDE)) { + track == BRANCH_TRACK_OVERRIDE || + clobber_head)) { if (!force) dont_change_ref = 1; else diff --combined branch.h index 1493f73722,e125ff4ca8..b99c5a369e --- a/branch.h +++ b/branch.h @@@ -13,7 -13,8 +13,8 @@@ * branch for (if any). */ void create_branch(const char *head, const char *name, const char *start_name, - int force, int reflog, enum branch_track track); + int force, int reflog, + int clobber_head, enum branch_track track); /* * Validates that the requested branch may be created, returning the @@@ -46,9 -47,4 +47,9 @@@ void remove_branch_state(void) #define BRANCH_CONFIG_VERBOSE 01 extern void install_branch_config(int flag, const char *local, const char *origin, const char *remote); +/* + * Read branch description + */ +extern int read_branch_desc(struct strbuf *, const char *branch_name); + #endif diff --combined builtin/branch.c index e1e486e4c5,823789fc95..465ff6a513 --- a/builtin/branch.c +++ b/builtin/branch.c @@@ -115,10 -115,8 +115,10 @@@ static int branch_merged(int kind, cons branch->merge[0] && branch->merge[0]->dst && (reference_name = - resolve_ref(branch->merge[0]->dst, sha1, 1, NULL)) != NULL) + resolve_ref(branch->merge[0]->dst, sha1, 1, NULL)) != NULL) { + reference_name = xstrdup(reference_name); reference_rev = lookup_commit_reference(sha1); + } } if (!reference_rev) reference_rev = head_rev; @@@ -143,7 -141,6 +143,7 @@@ " '%s', even though it is merged to HEAD."), name, reference_name); } + free((char *)reference_name); return merged; } @@@ -189,7 -186,7 +189,7 @@@ static int delete_branches(int argc, co free(name); name = xstrdup(mkpath(fmt, bname.buf)); - if (!resolve_ref(name, sha1, 1, NULL)) { + if (read_ref(name, sha1)) { error(_("%sbranch '%s' not found."), remote, bname.buf); ret = 1; @@@ -568,8 -565,10 +568,9 @@@ static int print_ref_list(int kinds, in 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; + int clobber_head_ok; if (!oldname) die(_("cannot rename the current branch while not on any.")); @@@ -579,13 -578,19 +580,19 @@@ * 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)) + if (ref_exists(oldref.buf)) recovery = 1; else die(_("Invalid branch name: '%s'"), oldname); } - validate_new_branchname(newname, &newref, force, 0); + /* + * A command like "git branch -M currentbranch currentbranch" cannot + * cause the worktree to become inconsistent with HEAD, so allow it. + */ + clobber_head_ok = !strcmp(oldname, newname); + + validate_new_branchname(newname, &newref, force, clobber_head_ok); strbuf_addf(&logmsg, "Branch: renamed %s to %s", oldref.buf, newref.buf); @@@ -625,49 -630,11 +632,49 @@@ static int opt_parse_merge_filter(cons return 0; } +static const char edit_description[] = "BRANCH_DESCRIPTION"; + +static int edit_branch_description(const char *branch_name) +{ + FILE *fp; + int status; + struct strbuf buf = STRBUF_INIT; + struct strbuf name = STRBUF_INIT; + + read_branch_desc(&buf, branch_name); + if (!buf.len || buf.buf[buf.len-1] != '\n') + strbuf_addch(&buf, '\n'); + strbuf_addf(&buf, + "# Please edit the description for the branch\n" + "# %s\n" + "# Lines starting with '#' will be stripped.\n", + branch_name); + fp = fopen(git_path(edit_description), "w"); + if ((fwrite(buf.buf, 1, buf.len, fp) < buf.len) || fclose(fp)) { + strbuf_release(&buf); + return error(_("could not write branch description template: %s\n"), + strerror(errno)); + } + strbuf_reset(&buf); + if (launch_editor(git_path(edit_description), &buf, NULL)) { + strbuf_release(&buf); + return -1; + } + stripspace(&buf, 1); + + strbuf_addf(&name, "branch.%s.description", branch_name); + status = git_config_set(name.buf, buf.buf); + strbuf_release(&name); + strbuf_release(&buf); + + return status; +} + int cmd_branch(int argc, const char **argv, const char *prefix) { int delete = 0, rename = 0, force_create = 0, list = 0; int verbose = 0, abbrev = -1, detached = 0; - int reflog = 0; + int reflog = 0, edit_description = 0; enum branch_track track; int kinds = REF_LOCAL_BRANCH; struct commit_list *with_commit = NULL; @@@ -706,8 -673,6 +713,8 @@@ OPT_BIT('M', NULL, &rename, "move/rename a branch, even if target exists", 2), OPT_BOOLEAN(0, "list", &list, "list branch names"), OPT_BOOLEAN('l', "create-reflog", &reflog, "create the branch's reflog"), + OPT_BOOLEAN(0, "edit-description", &edit_description, + "edit the description for the branch"), OPT__FORCE(&force_create, "force creation (when already exists)"), { OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref, @@@ -747,7 -712,7 +754,7 @@@ argc = parse_options(argc, argv, prefix, options, builtin_branch_usage, 0); - if (!delete && !rename && !force_create && argc == 0) + if (!delete && !rename && !edit_description && argc == 0) list = 1; if (!!delete + !!rename + !!force_create + !!list > 1) @@@ -761,30 -726,18 +768,30 @@@ else if (list) return print_ref_list(kinds, detached, verbose, abbrev, with_commit, argv); - else if (rename) { + else if (edit_description) { + const char *branch_name; + if (detached) + die("Cannot give description to detached HEAD"); + if (!argc) + branch_name = head; + else if (argc == 1) + branch_name = argv[0]; + else + usage_with_options(builtin_branch_usage, options); + if (edit_branch_description(branch_name)) + return 1; + } else if (rename) { if (argc == 1) rename_branch(head, argv[0], rename > 1); else if (argc == 2) rename_branch(argv[0], argv[1], rename > 1); else usage_with_options(builtin_branch_usage, options); - } else if (argc <= 2) { + } else if (argc > 0 && 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); + force_create, reflog, 0, track); } else usage_with_options(builtin_branch_usage, options); diff --combined builtin/checkout.c index b7c630287d,ca00a8538a..3f5d9b629a --- a/builtin/checkout.c +++ b/builtin/checkout.c @@@ -288,7 -288,7 +288,7 @@@ static int checkout_paths(struct tree * commit_locked_index(lock_file)) die(_("unable to write new index file")); - resolve_ref("HEAD", rev, 0, &flag); + read_ref_full("HEAD", rev, 0, &flag); head = lookup_commit_reference_gently(rev, 1); errs |= post_checkout_hook(head, head, 0); @@@ -411,7 -411,7 +411,7 @@@ static int merge_working_tree(struct ch topts.fn = twoway_merge; topts.dir = xcalloc(1, sizeof(*topts.dir)); topts.dir->flags |= DIR_SHOW_IGNORED; - topts.dir->exclude_per_dir = ".gitignore"; + setup_standard_excludes(topts.dir); tree = parse_tree_indirect(old->commit ? old->commit->object.sha1 : EMPTY_TREE_SHA1_BIN); @@@ -540,7 -540,9 +540,9 @@@ static void update_refs_for_switch(stru else create_branch(old->name, opts->new_branch, new->name, opts->new_branch_force ? 1 : 0, - opts->new_branch_log, opts->track); + opts->new_branch_log, + opts->new_branch_force ? 1 : 0, + opts->track); new->name = opts->new_branch; setup_branch_path(new); } @@@ -565,8 -567,12 +567,12 @@@ create_symref("HEAD", new->path, msg.buf); if (!opts->quiet) { if (old->path && !strcmp(new->path, old->path)) { - fprintf(stderr, _("Already on '%s'\n"), - new->name); + if (opts->new_branch_force) + fprintf(stderr, _("Reset branch '%s'\n"), + new->name); + else + fprintf(stderr, _("Already on '%s'\n"), + new->name); } else if (opts->new_branch) { if (opts->branch_exists) fprintf(stderr, _("Switched to and reset branch '%s'\n"), new->name); @@@ -699,9 -705,7 +705,9 @@@ static int switch_branches(struct check unsigned char rev[20]; int flag; memset(&old, 0, sizeof(old)); - old.path = xstrdup(resolve_ref("HEAD", rev, 0, &flag)); + old.path = resolve_ref("HEAD", rev, 0, &flag); + if (old.path) + old.path = xstrdup(old.path); old.commit = lookup_commit_reference_gently(rev, 1); if (!(flag & REF_ISSYMREF)) { free((char *)old.path); @@@ -868,7 -872,7 +874,7 @@@ static int parse_branchname_arg(int arg setup_branch_path(new); if (!check_refname_format(new->path, 0) && - resolve_ref(new->path, branch_rev, 1, NULL)) + !read_ref(new->path, branch_rev)) hashcpy(rev, branch_rev); else new->path = NULL; /* not an existing branch */ @@@ -1059,7 -1063,8 +1065,8 @@@ int cmd_checkout(int argc, const char * struct strbuf buf = STRBUF_INIT; opts.branch_exists = validate_new_branchname(opts.new_branch, &buf, - !!opts.new_branch_force, 0); + !!opts.new_branch_force, + !!opts.new_branch_force); strbuf_release(&buf); }