branch: teach --edit-description option
authorJunio C Hamano <gitster@pobox.com>
Tue, 20 Sep 2011 22:10:08 +0000 (15:10 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 5 Oct 2011 21:51:26 +0000 (14:51 -0700)
Using branch.$name.description as the configuration key, give users a
place to write about what the purpose of the branch is and things like
that, so that various subsystems, e.g. "push -s", "request-pull", and
"format-patch --cover-letter", can later be taught to use this
information.

The "-m" option similar to "commit/tag" is deliberately omitted, as the
whole point of branch description is about giving descriptive information
(the name of the branch itself is a better place for information that fits
on a single-line).

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-branch.txt
builtin/branch.c

index 507b8d0ab2a2d524a607c5b91e6d17f6d2f36392..8871a4ec2143bc8683004cf32847f2d93fb39040 100644 (file)
@@ -14,6 +14,7 @@ SYNOPSIS
 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
 'git branch' (-m | -M) [<oldbranch>] <newbranch>
 'git branch' (-d | -D) [-r] <branchname>...
+'git branch' --edit-description [<branchname>]
 
 DESCRIPTION
 -----------
@@ -144,6 +145,10 @@ start-point is either a local or remote-tracking branch.
        like '--track' would when creating the branch, except that where
        branch points to is not changed.
 
+--edit-description::
+       Open an editor and edit the text to explain what the branch is
+       for, to be used by various other commands (e.g. `request-pull`).
+
 --contains <commit>::
        Only list branches which contain the specified commit.
 
index f49596f826228e22d354194ddbb73ec100d8728e..fffa319e0e2e0ca86815e14641213a581634caf6 100644 (file)
@@ -606,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 = -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;
@@ -648,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,
@@ -694,7 +734,19 @@ 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)
+       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);