branch: teach --edit-description option
[gitweb.git] / builtin / branch.c
index 3142daa57a6fa1c8a7d21095946bf5d26443d0e0..fffa319e0e2e0ca86815e14641213a581634caf6 100644 (file)
@@ -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.")) {
@@ -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 "";
 }
@@ -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, 0);
 
        strbuf_addf(&logmsg, "Branch: renamed %s to %s",
                 oldref.buf, newref.buf);
@@ -610,11 +606,49 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int
        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;
-       int verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;
-       int reflog = 0;
+       int verbose = 0, abbrev = -1, detached = 0;
+       int reflog = 0, edit_description = 0;
        enum branch_track track;
        int kinds = REF_LOCAL_BRANCH;
        struct commit_list *with_commit = NULL;
@@ -652,6 +686,8 @@ 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(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,
@@ -673,9 +709,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);
@@ -696,9 +729,24 @@ 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)
+       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 (argc == 0)
                return print_ref_list(kinds, detached, verbose, abbrev, with_commit);
        else if (rename && (argc == 1))
                rename_branch(head, argv[0], rename > 1);