Merge branch 'jc/custom-comment-char'
authorJunio C Hamano <gitster@pobox.com>
Mon, 4 Feb 2013 18:23:49 +0000 (10:23 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 4 Feb 2013 18:23:49 +0000 (10:23 -0800)
Allow a configuration variable core.commentchar to customize the
character used to comment out the hint lines in the edited text from
the default '#'.

* jc/custom-comment-char:
Allow custom "comment char"

1  2 
Documentation/config.txt
builtin/branch.c
builtin/commit.c
builtin/fmt-merge-msg.c
builtin/merge.c
cache.h
config.c
environment.c
t/t7502-commit.sh
wt-status.c
diff --combined Documentation/config.txt
index d7ec507003312f731c869958ce3ed4644697806e,e99b9f234e1d9546308466c4abc2e97039f58422..10225cfaf745524ddd01dd7957135bca1c435d91
@@@ -235,12 -235,6 +235,12 @@@ core.trustctime:
        crawlers and some backup systems).
        See linkgit:git-update-index[1]. True by default.
  
 +core.checkstat::
 +      Determines which stat fields to match between the index
 +      and work tree. The user can set this to 'default' or
 +      'minimal'. Default (or explicitly 'default'), is to check
 +      all fields, including the sub-second part of mtime and ctime.
 +
  core.quotepath::
        The commands that output paths (e.g. 'ls-files',
        'diff'), when not given the `-z` option, will quote
@@@ -534,6 -528,12 +534,12 @@@ core.editor:
        variable when it is set, and the environment variable
        `GIT_EDITOR` is not set.  See linkgit:git-var[1].
  
+ core.commentchar::
+       Commands such as `commit` and `tag` that lets you edit
+       messages consider a line that begins with this character
+       commented, and removes them after the editor returns
+       (default '#').
  sequence.editor::
        Text editor used by `git rebase -i` for editing the rebase insn file.
        The value is meant to be interpreted by the shell when it is used.
@@@ -929,15 -929,6 +935,15 @@@ column.tag:
        Specify whether to output tag listing in `git tag` in columns.
        See `column.ui` for details.
  
 +commit.cleanup::
 +      This setting overrides the default of the `--cleanup` option in
 +      `git commit`. See linkgit:git-commit[1] for details. Changing the
 +      default can be useful when you always want to keep lines that begin
 +      with comment character `#` in your log message, in which case you
 +      would do `git config commit.cleanup whitespace` (note that you will
 +      have to remove the help lines that begin with `#` in the commit log
 +      template yourself, if you do this).
 +
  commit.status::
        A boolean to enable/disable inclusion of status information in the
        commit message template when using an editor to prepare the commit
@@@ -1376,12 -1367,6 +1382,12 @@@ help.autocorrect:
        value is 0 - the command will be just shown but not executed.
        This is the default.
  
 +help.htmlpath::
 +      Specify the path where the HTML documentation resides. File system paths
 +      and URLs are supported. HTML pages will be prefixed with this path when
 +      help is displayed in the 'web' format. This defaults to the documentation
 +      path of your Git installation.
 +
  http.proxy::
        Override the HTTP proxy, normally configured using the 'http_proxy',
        'https_proxy', and 'all_proxy' environment variables (see
@@@ -1540,10 -1525,6 +1546,10 @@@ log.showroot:
        Tools like linkgit:git-log[1] or linkgit:git-whatchanged[1], which
        normally hide the root commit will now show it. True by default.
  
 +log.mailmap::
 +      If true, makes linkgit:git-log[1], linkgit:git-show[1], and
 +      linkgit:git-whatchanged[1] assume `--use-mailmap`.
 +
  mailmap.file::
        The location of an augmenting mailmap file. The default
        mailmap, located in the root of the repository, is loaded
diff --combined builtin/branch.c
index ea6498b08a3b290126f64d498ed388f4ce067e9e,3548271c4797ee4464f919a76b510e3e120a833d..77b435825c178ead3ff59d7783137c55057a6649
@@@ -706,11 -706,11 +706,11 @@@ static int edit_branch_description(cons
        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);
+       strbuf_commented_addf(&buf,
+                   "Please edit the description for the branch\n"
+                   "  %s\n"
+                   "Lines starting with '%c' will be stripped.\n",
+                   branch_name, comment_line_char);
        fp = fopen(git_path(edit_description), "w");
        if ((fwrite(buf.buf, 1, buf.len, fp) < buf.len) || fclose(fp)) {
                strbuf_release(&buf);
@@@ -850,11 -850,11 +850,11 @@@ int cmd_branch(int argc, const char **a
                const char *branch_name;
                struct strbuf branch_ref = STRBUF_INIT;
  
 -              if (detached)
 -                      die("Cannot give description to detached HEAD");
 -              if (!argc)
 +              if (!argc) {
 +                      if (detached)
 +                              die("Cannot give description to detached HEAD");
                        branch_name = head;
 -              else if (argc == 1)
 +              else if (argc == 1)
                        branch_name = argv[0];
                else
                        usage_with_options(builtin_branch_usage, options);
diff --combined builtin/commit.c
index 38b9a9cc0d0e1beba3258f907e95ae1ad76f85f5,f95f64abff1228c21e8eab05b902702756840112..6c95fa76d8e4f5a4bb7aaa69721c00034eba8632
@@@ -103,7 -103,7 +103,7 @@@ static enum 
        CLEANUP_NONE,
        CLEANUP_ALL
  } cleanup_mode;
 -static char *cleanup_arg;
 +static const char *cleanup_arg;
  
  static enum commit_whence whence;
  static int use_editor = 1, include_status = 1;
@@@ -733,15 -733,15 +733,15 @@@ static int prepare_to_commit(const cha
                if (cleanup_mode == CLEANUP_ALL)
                        status_printf(s, GIT_COLOR_NORMAL,
                                _("Please enter the commit message for your changes."
-                               " Lines starting\nwith '#' will be ignored, and an empty"
-                               " message aborts the commit.\n"));
+                                 " Lines starting\nwith '%c' will be ignored, and an empty"
+                                 " message aborts the commit.\n"), comment_line_char);
                else /* CLEANUP_SPACE, that is. */
                        status_printf(s, GIT_COLOR_NORMAL,
                                _("Please enter the commit message for your changes."
-                               " Lines starting\n"
-                               "with '#' will be kept; you may remove them"
-                               " yourself if you want to.\n"
-                               "An empty message aborts the commit.\n"));
+                                 " Lines starting\n"
+                                 "with '%c' will be kept; you may remove them"
+                                 " yourself if you want to.\n"
+                                 "An empty message aborts the commit.\n"), comment_line_char);
                if (only_include_assumed)
                        status_printf_ln(s, GIT_COLOR_NORMAL,
                                        "%s", only_include_assumed);
@@@ -1320,8 -1320,6 +1320,8 @@@ static int git_commit_config(const cha
                include_status = git_config_bool(k, v);
                return 0;
        }
 +      if (!strcmp(k, "commit.cleanup"))
 +              return git_config_string(&cleanup_arg, k, v);
  
        status = git_gpg_config(k, v, NULL);
        if (status)
        return git_status_config(k, v, s);
  }
  
 -static const char post_rewrite_hook[] = "hooks/post-rewrite";
 -
  static int run_rewrite_hook(const unsigned char *oldsha1,
                            const unsigned char *newsha1)
  {
        int code;
        size_t n;
  
 -      if (access(git_path(post_rewrite_hook), X_OK) < 0)
 +      argv[0] = find_hook("post-rewrite");
 +      if (!argv[0])
                return 0;
  
 -      argv[0] = git_path(post_rewrite_hook);
        argv[1] = "amend";
        argv[2] = NULL;
  
diff --combined builtin/fmt-merge-msg.c
index d9af43c257150c957bf3bc3c3b7a7e43e370174c,d6d2e1b6c07f5d78f76ac6df30276d426e938f1e..b49612f0ce02e0c8503bee77477800297e84065d
@@@ -232,9 -232,8 +232,9 @@@ static void record_person(int which, st
  {
        char *name_buf, *name, *name_end;
        struct string_list_item *elem;
 -      const char *field = (which == 'a') ? "\nauthor " : "\ncommitter ";
 +      const char *field;
  
 +      field = (which == 'a') ? "\nauthor " : "\ncommitter ";
        name = strstr(commit->buffer, field);
        if (!name)
                return;
@@@ -324,8 -323,7 +324,8 @@@ static void add_people_info(struct strb
  static void shortlog(const char *name,
                     struct origin_data *origin_data,
                     struct commit *head,
 -                   struct rev_info *rev, int limit,
 +                   struct rev_info *rev,
 +                   struct fmt_merge_msg_opts *opts,
                     struct strbuf *out)
  {
        int i, count = 0;
        int flags = UNINTERESTING | TREESAME | SEEN | SHOWN | ADDED;
        struct strbuf sb = STRBUF_INIT;
        const unsigned char *sha1 = origin_data->sha1;
 +      int limit = opts->shortlog_len;
  
        branch = deref_tag(parse_object(sha1), sha1_to_hex(sha1), 40);
        if (!branch || branch->type != OBJ_COMMIT)
  
                if (commit->parents && commit->parents->next) {
                        /* do not list a merge but count committer */
 -                      record_person('c', &committers, commit);
 +                      if (opts->credit_people)
 +                              record_person('c', &committers, commit);
                        continue;
                }
 -              if (!count)
 +              if (!count && opts->credit_people)
                        /* the 'tip' committer */
                        record_person('c', &committers, commit);
 -              record_person('a', &authors, commit);
 +              if (opts->credit_people)
 +                      record_person('a', &authors, commit);
                count++;
                if (subjects.nr > limit)
                        continue;
                        string_list_append(&subjects, strbuf_detach(&sb, NULL));
        }
  
 -      add_people_info(out, &authors, &committers);
 +      if (opts->credit_people)
 +              add_people_info(out, &authors, &committers);
        if (count > limit)
                strbuf_addf(out, "\n* %s: (%d commits)\n", name, count);
        else
@@@ -470,7 -464,7 +470,7 @@@ static void fmt_tag_signature(struct st
        strbuf_complete_line(tagbuf);
        if (sig->len) {
                strbuf_addch(tagbuf, '\n');
-               strbuf_add_lines(tagbuf, "# ", sig->buf, sig->len);
+               strbuf_add_commented_lines(tagbuf, sig->buf, sig->len);
        }
  }
  
@@@ -641,7 -635,7 +641,7 @@@ int fmt_merge_msg(struct strbuf *in, st
                for (i = 0; i < origins.nr; i++)
                        shortlog(origins.items[i].string,
                                 origins.items[i].util,
 -                               head, &rev, opts->shortlog_len, out);
 +                               head, &rev, opts, out);
        }
  
        strbuf_complete_line(out);
@@@ -696,7 -690,6 +696,7 @@@ int cmd_fmt_merge_msg(int argc, const c
  
        memset(&opts, 0, sizeof(opts));
        opts.add_title = !message;
 +      opts.credit_people = 1;
        opts.shortlog_len = shortlog_len;
  
        ret = fmt_merge_msg(&input, &output, &opts);
diff --combined builtin/merge.c
index 9307e9c726587461d002530938dbf2c0d74d55a1,d7baa2683cdef94bd1e2411503b75e29e120f543..7c8922c8b0b44307a0dbb43329301ad7d1654a46
@@@ -788,17 -788,16 +788,16 @@@ static const char merge_editor_comment[
  N_("Please enter a commit message to explain why this merge is necessary,\n"
     "especially if it merges an updated upstream into a topic branch.\n"
     "\n"
-    "Lines starting with '#' will be ignored, and an empty message aborts\n"
+    "Lines starting with '%c' will be ignored, and an empty message aborts\n"
     "the commit.\n");
  
  static void prepare_to_commit(struct commit_list *remoteheads)
  {
        struct strbuf msg = STRBUF_INIT;
-       const char *comment = _(merge_editor_comment);
        strbuf_addbuf(&msg, &merge_msg);
        strbuf_addch(&msg, '\n');
        if (0 < option_edit)
-               strbuf_add_lines(&msg, "# ", comment, strlen(comment));
+               strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char);
        write_merge_msg(&msg);
        if (run_hook(get_index_file(), "prepare-commit-msg",
                     git_path("MERGE_MSG"), "merge", NULL, NULL))
@@@ -1222,7 -1221,6 +1221,7 @@@ int cmd_merge(int argc, const char **ar
                        memset(&opts, 0, sizeof(opts));
                        opts.add_title = !have_message;
                        opts.shortlog_len = shortlog_len;
 +                      opts.credit_people = (0 < option_edit);
  
                        fmt_merge_msg(&merge_names, &merge_msg, &opts);
                        if (merge_msg.len)
diff --combined cache.h
index 7339f21849b45a7f53945317893313498aff5a41,0b435a413feed6a8957a8a19712a22df6ecc95c3..94ffcda8f6cbb603b79eda1ae441a21450a16cb5
+++ b/cache.h
@@@ -536,7 -536,6 +536,7 @@@ extern int delete_ref(const char *, con
  /* Environment bits from configuration mechanism */
  extern int trust_executable_bit;
  extern int trust_ctime;
 +extern int check_stat;
  extern int quote_path_fully;
  extern int has_symlinks;
  extern int minimum_abbrev, default_abbrev;
@@@ -563,6 -562,12 +563,12 @@@ extern int core_preload_index
  extern int core_apply_sparse_checkout;
  extern int precomposed_unicode;
  
+ /*
+  * The character that begins a commented line in user-editable file
+  * that is subject to stripspace.
+  */
+ extern char comment_line_char;
  enum branch_track {
        BRANCH_TRACK_UNSPECIFIED = -1,
        BRANCH_TRACK_NEVER = 0,
@@@ -1012,6 -1017,7 +1018,6 @@@ struct ref 
                requires_force:1,
                merge:1,
                nonfastforward:1,
 -              not_forwardable:1,
                update:1,
                deletion:1;
        enum {
@@@ -1148,7 -1154,7 +1154,7 @@@ extern int check_repository_format_vers
  extern int git_env_bool(const char *, int);
  extern int git_config_system(void);
  extern int config_error_nonbool(const char *);
 -#ifdef __GNUC__
 +#if defined(__GNUC__) && ! defined(__clang__)
  #define config_error_nonbool(s) (config_error_nonbool(s), -1)
  #endif
  extern const char *get_log_output_encoding(void);
diff --combined config.c
index 3f638e3c00c9ee5000a0f3d3518fd1e7bc1457b6,d873c595741335b4101b1215ddd4be39868a22ee..5a20de3fa62b46d73cc0b13bf5d50aefac78fac6
+++ b/config.c
@@@ -565,12 -565,6 +565,12 @@@ static int git_default_core_config(cons
        if (!strcmp(var, "core.trustctime")) {
                trust_ctime = git_config_bool(var, value);
                return 0;
 +      }
 +      if (!strcmp(var, "core.statinfo")) {
 +              if (!strcasecmp(value, "default"))
 +                      check_stat = 1;
 +              else if (!strcasecmp(value, "minimal"))
 +                      check_stat = 0;
        }
  
        if (!strcmp(var, "core.quotepath")) {
        if (!strcmp(var, "core.editor"))
                return git_config_string(&editor_program, var, value);
  
+       if (!strcmp(var, "core.commentchar")) {
+               const char *comment;
+               int ret = git_config_string(&comment, var, value);
+               if (!ret)
+                       comment_line_char = comment[0];
+               return ret;
+       }
        if (!strcmp(var, "core.askpass"))
                return git_config_string(&askpass_program, var, value);
  
diff --combined environment.c
index e828b371f58d5e4cd0a24b3b3b24b35b785edeba,a40c38be0649054058e20f703bee71e0f7dab34e..89d6c70c15a95aff82f0063e3c0dd6bdab026213
@@@ -13,7 -13,6 +13,7 @@@
  
  int trust_executable_bit = 1;
  int trust_ctime = 1;
 +int check_stat = 1;
  int has_symlinks = 1;
  int minimum_abbrev = 4, default_abbrev = 7;
  int ignore_case;
@@@ -63,6 -62,12 +63,12 @@@ int precomposed_unicode = -1; /* see pr
  struct startup_info *startup_info;
  unsigned long pack_size_limit_cfg;
  
+ /*
+  * The character that begins a commented line in user-editable file
+  * that is subject to stripspace.
+  */
+ char comment_line_char = '#';
  /* Parallel index stat data preload? */
  int core_preload_index = 0;
  
diff --combined t/t7502-commit.sh
index b1c76483866f55b4429fc76e7035e65984e7b4c2,6a2c67cd1adc833f3914469db2461c273a5506c8..cbd7a45927eb2d4b04649f21f82192091782ce90
@@@ -4,15 -4,6 +4,15 @@@ test_description='git commit porcelain-
  
  . ./test-lib.sh
  
 +commit_msg_is () {
 +      expect=commit_msg_is.expect
 +      actual=commit_msg_is.actual
 +
 +      printf "%s" "$(git log --pretty=format:%s%b -1)" >$actual &&
 +      printf "%s" "$1" >$expect &&
 +      test_i18ncmp $expect $actual
 +}
 +
  # Arguments: [<prefix] [<commit message>] [<commit options>]
  check_summary_oneline() {
        test_tick &&
@@@ -177,7 -168,7 +177,7 @@@ test_expect_success 'verbose respects d
        git config --unset color.diff
  '
  
 -test_expect_success 'cleanup commit messages (verbatim,-t)' '
 +test_expect_success 'cleanup commit messages (verbatim option,-t)' '
  
        echo >>negative &&
        { echo;echo "# text";echo; } >expect &&
  
  '
  
 -test_expect_success 'cleanup commit messages (verbatim,-F)' '
 +test_expect_success 'cleanup commit messages (verbatim option,-F)' '
  
        echo >>negative &&
        git commit --cleanup=verbatim -F expect -a &&
  
  '
  
 -test_expect_success 'cleanup commit messages (verbatim,-m)' '
 +test_expect_success 'cleanup commit messages (verbatim option,-m)' '
  
        echo >>negative &&
        git commit --cleanup=verbatim -m "$(cat expect)" -a &&
  
  '
  
 -test_expect_success 'cleanup commit messages (whitespace,-F)' '
 +test_expect_success 'cleanup commit messages (whitespace option,-F)' '
  
        echo >>negative &&
        { echo;echo "# text";echo; } >text &&
  
  '
  
 -test_expect_success 'cleanup commit messages (strip,-F)' '
 +test_expect_success 'cleanup commit messages (strip option,-F)' '
  
        echo >>negative &&
        { echo;echo "# text";echo sample;echo; } >text &&
  
  '
  
 -test_expect_success 'cleanup commit messages (strip,-F,-e)' '
 +test_expect_success 'cleanup commit messages (strip option,-F,-e)' '
  
        echo >>negative &&
        { echo;echo sample;echo; } >text &&
@@@ -240,71 -231,10 +240,71 @@@ echo "sampl
  # Please enter the commit message for your changes. Lines starting
  # with '#' will be ignored, and an empty message aborts the commit." >expect
  
 -test_expect_success 'cleanup commit messages (strip,-F,-e): output' '
 +test_expect_success 'cleanup commit messages (strip option,-F,-e): output' '
        test_i18ncmp expect actual
  '
  
 +test_expect_success 'cleanup commit message (fail on invalid cleanup mode option)' '
 +      test_must_fail git commit --cleanup=non-existent
 +'
 +
 +test_expect_success 'cleanup commit message (fail on invalid cleanup mode configuration)' '
 +      test_must_fail git -c commit.cleanup=non-existent commit
 +'
 +
 +test_expect_success 'cleanup commit message (no config and no option uses default)' '
 +      echo content >>file &&
 +      git add file &&
 +      test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
 +      git commit --no-status &&
 +      commit_msg_is "commit message"
 +'
 +
 +test_expect_success 'cleanup commit message (option overrides default)' '
 +      echo content >>file &&
 +      git add file &&
 +      test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
 +      git commit --cleanup=whitespace --no-status &&
 +      commit_msg_is "commit message # comment"
 +'
 +
 +test_expect_success 'cleanup commit message (config overrides default)' '
 +      echo content >>file &&
 +      git add file &&
 +      test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
 +      git -c commit.cleanup=whitespace commit --no-status &&
 +      commit_msg_is "commit message # comment"
 +'
 +
 +test_expect_success 'cleanup commit message (option overrides config)' '
 +      echo content >>file &&
 +      git add file &&
 +      test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
 +      git -c commit.cleanup=whitespace commit --cleanup=default &&
 +      commit_msg_is "commit message"
 +'
 +
 +test_expect_success 'cleanup commit message (default, -m)' '
 +      echo content >>file &&
 +      git add file &&
 +      git commit -m "message #comment " &&
 +      commit_msg_is "message #comment"
 +'
 +
 +test_expect_success 'cleanup commit message (whitespace option, -m)' '
 +      echo content >>file &&
 +      git add file &&
 +      git commit --cleanup=whitespace --no-status -m "message #comment " &&
 +      commit_msg_is "message #comment"
 +'
 +
 +test_expect_success 'cleanup commit message (whitespace config, -m)' '
 +      echo content >>file &&
 +      git add file &&
 +      git -c commit.cleanup=whitespace commit --no-status -m "message #comment " &&
 +      commit_msg_is "message #comment"
 +'
 +
  test_expect_success 'message shows author when it is not equal to committer' '
        echo >>negative &&
        git commit -e -m "sample" -a &&
@@@ -517,4 -447,11 +517,11 @@@ use_template="-t template
  
  try_commit_status_combo
  
+ test_expect_success 'commit --status with custom comment character' '
+       test_when_finished "git config --unset core.commentchar" &&
+       git config core.commentchar ";" &&
+       try_commit --status &&
+       test_i18ngrep "^; Changes to be committed:" .git/COMMIT_EDITMSG
+ '
  test_done
diff --combined wt-status.c
index d7cfe8f31cd3d2b4b8bdc18c5da2449255b0531b,f6f197e985111da9b822b413fa4d711cb12a22d1..aa2734fcbea68850a23468d36cc0d33f1caec2a7
@@@ -45,7 -45,7 +45,7 @@@ static void status_vprintf(struct wt_st
  
        strbuf_vaddf(&sb, fmt, ap);
        if (!sb.len) {
-               strbuf_addch(&sb, '#');
+               strbuf_addch(&sb, comment_line_char);
                if (!trail)
                        strbuf_addch(&sb, ' ');
                color_print_strbuf(s->fp, color, &sb);
@@@ -59,7 -59,7 +59,7 @@@
  
                strbuf_reset(&linebuf);
                if (at_bol) {
-                       strbuf_addch(&linebuf, '#');
+                       strbuf_addch(&linebuf, comment_line_char);
                        if (*line != '\n' && *line != '\t')
                                strbuf_addch(&linebuf, ' ');
                }
@@@ -516,9 -516,7 +516,9 @@@ static void wt_status_collect_untracked
  
        if (s->show_ignored_files) {
                dir.nr = 0;
 -              dir.flags = DIR_SHOW_IGNORED | DIR_SHOW_OTHER_DIRECTORIES;
 +              dir.flags = DIR_SHOW_IGNORED;
 +              if (s->show_untracked_files != SHOW_ALL_UNTRACKED_FILES)
 +                      dir.flags |= DIR_SHOW_OTHER_DIRECTORIES;
                fill_directory(&dir, s->pathspec);
                for (i = 0; i < dir.nr; i++) {
                        struct dir_entry *ent = dir.entries[i];
@@@ -762,8 -760,10 +762,10 @@@ static void wt_status_print_tracking(st
  
        for (cp = sb.buf; (ep = strchr(cp, '\n')) != NULL; cp = ep + 1)
                color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s),
-                                "# %.*s", (int)(ep - cp), cp);
-       color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), "#");
+                                "%c %.*s", comment_line_char,
+                                (int)(ep - cp), cp);
+       color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), "%c",
+                        comment_line_char);
  }
  
  static int has_unmerged(struct wt_status *s)