Merge branch 'jl/commit-v-strip-marker'
authorJunio C Hamano <gitster@pobox.com>
Tue, 17 Dec 2013 19:47:18 +0000 (11:47 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 17 Dec 2013 19:47:18 +0000 (11:47 -0800)
"git commit -v" appends the patch to the log message before
editing, and then removes the patch when the editor returned
control. However, the patch was not stripped correctly when the
first modified path was a submodule.

* jl/commit-v-strip-marker:
commit -v: strip diffs and submodule shortlogs from the commit message

1  2 
builtin/commit.c
wt-status.c
diff --combined builtin/commit.c
index e89c519192121d5386ba42b88a0157b31d57c690,fedb45af8c65d28c3b43b3b74362e589d81a95ee..f4ff75d6842f86bfd86d9448ee0a6c941410c574
@@@ -1338,7 -1338,7 +1338,7 @@@ static void print_summary(const char *p
        commit = lookup_commit(sha1);
        if (!commit)
                die(_("couldn't look up newly created commit"));
 -      if (!commit || parse_commit(commit))
 +      if (parse_commit(commit))
                die(_("could not parse newly created commit"));
  
        strbuf_addstr(&format, "format:%h] %s");
@@@ -1505,7 -1505,7 +1505,7 @@@ int cmd_commit(int argc, const char **a
        struct strbuf sb = STRBUF_INIT;
        struct strbuf author_ident = STRBUF_INIT;
        const char *index_file, *reflog_msg;
-       char *nl, *p;
+       char *nl;
        unsigned char sha1[20];
        struct ref_lock *ref_lock;
        struct commit_list *parents = NULL, **pptr = &parents;
                current_head = NULL;
        else {
                current_head = lookup_commit_or_die(sha1, "HEAD");
 -              if (!current_head || parse_commit(current_head))
 +              if (parse_commit(current_head))
                        die(_("could not parse HEAD commit"));
        }
        argc = parse_and_validate_options(argc, argv, builtin_commit_options,
        }
  
        /* Truncate the message just before the diff, if any. */
-       if (verbose) {
-               p = strstr(sb.buf, "\ndiff --git ");
-               if (p != NULL)
-                       strbuf_setlen(&sb, p - sb.buf + 1);
-       }
+       if (verbose)
+               wt_status_truncate_message_at_cut_line(&sb);
  
        if (cleanup_mode != CLEANUP_NONE)
                stripspace(&sb, cleanup_mode == CLEANUP_ALL);
diff --combined wt-status.c
index 4625cdb900f179e94314348340719b677fed1ca1,85390b813f12e2392b73dd6dffe8d1b41e838614..cd7d706a6344fd28b264db4b5c1ea02a2677512e
  #include "submodule.h"
  #include "column.h"
  #include "strbuf.h"
 +#include "utf8.h"
  
+ static char cut_line[] =
+ "------------------------ >8 ------------------------\n";
  static char default_wt_status_colors[][COLOR_MAXLEN] = {
        GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */
        GIT_COLOR_GREEN,  /* WT_STATUS_UPDATED */
@@@ -265,30 -267,6 +268,30 @@@ static void wt_status_print_unmerged_da
        strbuf_release(&onebuf);
  }
  
 +static const char *wt_status_diff_status_string(int status)
 +{
 +      switch (status) {
 +      case DIFF_STATUS_ADDED:
 +              return _("new file");
 +      case DIFF_STATUS_COPIED:
 +              return _("copied");
 +      case DIFF_STATUS_DELETED:
 +              return _("deleted");
 +      case DIFF_STATUS_MODIFIED:
 +              return _("modified");
 +      case DIFF_STATUS_RENAMED:
 +              return _("renamed");
 +      case DIFF_STATUS_TYPE_CHANGED:
 +              return _("typechange");
 +      case DIFF_STATUS_UNKNOWN:
 +              return _("unknown");
 +      case DIFF_STATUS_UNMERGED:
 +              return _("unmerged");
 +      default:
 +              return NULL;
 +      }
 +}
 +
  static void wt_status_print_change_data(struct wt_status *s,
                                        int change_type,
                                        struct string_list_item *it)
        const char *one, *two;
        struct strbuf onebuf = STRBUF_INIT, twobuf = STRBUF_INIT;
        struct strbuf extra = STRBUF_INIT;
 +      static char *padding;
 +      const char *what;
 +      int len;
 +
 +      if (!padding) {
 +              int width = 0;
 +              /* If DIFF_STATUS_* uses outside this range, we're in trouble */
 +              for (status = 'A'; status <= 'Z'; status++) {
 +                      what = wt_status_diff_status_string(status);
 +                      len = what ? strlen(what) : 0;
 +                      if (len > width)
 +                              width = len;
 +              }
 +              width += 2;     /* colon and a space */
 +              padding = xmallocz(width);
 +              memset(padding, ' ', width);
 +      }
  
        one_name = two_name = it->string;
        switch (change_type) {
        two = quote_path(two_name, s->prefix, &twobuf);
  
        status_printf(s, color(WT_STATUS_HEADER, s), "\t");
 -      switch (status) {
 -      case DIFF_STATUS_ADDED:
 -              status_printf_more(s, c, _("new file:   %s"), one);
 -              break;
 -      case DIFF_STATUS_COPIED:
 -              status_printf_more(s, c, _("copied:     %s -> %s"), one, two);
 -              break;
 -      case DIFF_STATUS_DELETED:
 -              status_printf_more(s, c, _("deleted:    %s"), one);
 -              break;
 -      case DIFF_STATUS_MODIFIED:
 -              status_printf_more(s, c, _("modified:   %s"), one);
 -              break;
 -      case DIFF_STATUS_RENAMED:
 -              status_printf_more(s, c, _("renamed:    %s -> %s"), one, two);
 -              break;
 -      case DIFF_STATUS_TYPE_CHANGED:
 -              status_printf_more(s, c, _("typechange: %s"), one);
 -              break;
 -      case DIFF_STATUS_UNKNOWN:
 -              status_printf_more(s, c, _("unknown:    %s"), one);
 -              break;
 -      case DIFF_STATUS_UNMERGED:
 -              status_printf_more(s, c, _("unmerged:   %s"), one);
 -              break;
 -      default:
 +      what = wt_status_diff_status_string(status);
 +      if (!what)
                die(_("bug: unhandled diff status %c"), status);
 -      }
 +      /* 1 for colon, which is not part of "what" */
 +      len = strlen(padding) - (utf8_strwidth(what) + 1);
 +      assert(len >= 0);
 +      if (status == DIFF_STATUS_COPIED || status == DIFF_STATUS_RENAMED)
 +              status_printf_more(s, c, "%s:%.*s%s -> %s",
 +                                 what, len, padding, one, two);
 +      else
 +              status_printf_more(s, c, "%s:%.*s%s",
 +                                 what, len, padding, one);
        if (extra.len) {
                status_printf_more(s, color(WT_STATUS_HEADER, s), "%s", extra.buf);
                strbuf_release(&extra);
@@@ -793,6 -770,18 +796,18 @@@ conclude
        status_printf_ln(s, GIT_COLOR_NORMAL, "");
  }
  
+ void wt_status_truncate_message_at_cut_line(struct strbuf *buf)
+ {
+       const char *p;
+       struct strbuf pattern = STRBUF_INIT;
+       strbuf_addf(&pattern, "%c %s", comment_line_char, cut_line);
+       p = strstr(buf->buf, pattern.buf);
+       if (p && (p == buf->buf || p[-1] == '\n'))
+               strbuf_setlen(buf, p - buf->buf);
+       strbuf_release(&pattern);
+ }
  static void wt_status_print_verbose(struct wt_status *s)
  {
        struct rev_info rev;
         * If we're not going to stdout, then we definitely don't
         * want color, since we are going to the commit message
         * file (and even the "auto" setting won't work, since it
-        * will have checked isatty on stdout).
+        * will have checked isatty on stdout). But we then do want
+        * to insert the scissor line here to reliably remove the
+        * diff before committing.
         */
-       if (s->fp != stdout)
+       if (s->fp != stdout) {
+               const char *explanation = _("Do not touch the line above.\nEverything below will be removed.");
+               struct strbuf buf = STRBUF_INIT;
                rev.diffopt.use_color = 0;
+               fprintf(s->fp, "%c %s", comment_line_char, cut_line);
+               strbuf_add_commented_lines(&buf, explanation, strlen(explanation));
+               fputs(buf.buf, s->fp);
+               strbuf_release(&buf);
+       }
        run_diff_index(&rev, 1);
  }