Merge branch 'mg/killed-merge'
authorJunio C Hamano <gitster@pobox.com>
Sun, 27 Aug 2017 05:55:10 +0000 (22:55 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 27 Aug 2017 05:55:10 +0000 (22:55 -0700)
Killing "git merge --edit" before the editor returns control left
the repository in a state with MERGE_MSG but without MERGE_HEAD,
which incorrectly tells the subsequent "git commit" that there was
a squash merge in progress. This has been fixed.

* mg/killed-merge:
merge: save merge state earlier
merge: split write_merge_state in two
merge: clarify call chain
Documentation/git-merge: explain --continue

1  2 
Documentation/git-merge.txt
builtin/merge.c
index 6b308ab6d0b52b8962da63a8bc268cdf3f7ed227,f90faf7aaa250b2fea09d611e4efac31968ce6db..615e6bacde7355e3125268bc969d0fee2a06392e
@@@ -64,14 -64,6 +64,14 @@@ OPTION
  -------
  include::merge-options.txt[]
  
 +--signoff::
 +      Add Signed-off-by line by the committer at the end of the commit
 +      log message.  The meaning of a signoff depends on the project,
 +      but it typically certifies that committer has
 +      the rights to submit this work under the same license and
 +      agrees to a Developer Certificate of Origin
 +      (see http://developercertificate.org/ for more information).
 +
  -S[<keyid>]::
  --gpg-sign[=<keyid>]::
        GPG-sign the resulting merge commit. The `keyid` argument is
@@@ -288,7 -280,10 +288,10 @@@ After seeing a conflict, you can do tw
  
   * Resolve the conflicts.  Git will mark the conflicts in
     the working tree.  Edit the files into shape and
-    'git add' them to the index.  Use 'git commit' to seal the deal.
+    'git add' them to the index.  Use 'git commit' or
+    'git merge --continue' to seal the deal. The latter command
+    checks whether there is a (interrupted) merge in progress
+    before calling 'git commit'.
  
  You can work through the conflict with a number of tools:
  
diff --combined builtin/merge.c
index 7b7320dede66d4392107eba7ff78baa8a47de65e,08a4083b6de51954b545028003c303e4df9e3127..7df3fe3927ef8a1c65f7baad7d957602436315cd
@@@ -32,7 -32,6 +32,7 @@@
  #include "gpg-interface.h"
  #include "sequencer.h"
  #include "string-list.h"
 +#include "packfile.h"
  
  #define DEFAULT_TWOHEAD (1<<0)
  #define DEFAULT_OCTOPUS (1<<1)
@@@ -71,7 -70,6 +71,7 @@@ static int continue_current_merge
  static int allow_unrelated_histories;
  static int show_progress = -1;
  static int default_to_upstream = 1;
 +static int signoff;
  static const char *sign_commit;
  
  static struct strategy all_strategy[] = {
@@@ -235,7 -233,6 +235,7 @@@ static struct option builtin_merge_opti
        { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"),
          N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
        OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")),
 +      OPT_BOOL(0, "signoff", &signoff, N_("add Signed-off-by:")),
        OPT_END()
  };
  
@@@ -540,7 -537,7 +540,7 @@@ static void parse_branch_merge_options(
                die(_("Bad branch.%s.mergeoptions string: %s"), branch,
                    split_cmdline_strerror(argc));
        REALLOC_ARRAY(argv, argc + 2);
 -      memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
 +      MOVE_ARRAY(argv + 1, argv, argc + 1);
        argc++;
        argv[0] = "branch.*.mergeoptions";
        parse_options(argc, argv, NULL, builtin_merge_options,
@@@ -569,7 -566,7 +569,7 @@@ static int git_merge_config(const char 
        else if (!strcmp(k, "merge.renormalize"))
                option_renormalize = git_config_bool(k, v);
        else if (!strcmp(k, "merge.ff")) {
 -              int boolval = git_config_maybe_bool(k, v);
 +              int boolval = git_parse_maybe_bool(v);
                if (0 <= boolval) {
                        fast_forward = boolval ? FF_ALLOW : FF_NO;
                } else if (v && !strcmp(v, "only")) {
@@@ -759,15 -756,17 +759,19 @@@ N_("Please enter a commit message to ex
     "Lines starting with '%c' will be ignored, and an empty message aborts\n"
     "the commit.\n");
  
+ static void write_merge_heads(struct commit_list *);
  static void prepare_to_commit(struct commit_list *remoteheads)
  {
        struct strbuf msg = STRBUF_INIT;
        strbuf_addbuf(&msg, &merge_msg);
        strbuf_addch(&msg, '\n');
+       if (squash)
+               BUG("the control must not reach here under --squash");
        if (0 < option_edit)
                strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char);
 +      if (signoff)
 +              append_signoff(&msg, ignore_non_trailer(msg.buf, msg.len), 0);
+       write_merge_heads(remoteheads);
        write_file_buf(git_path_merge_msg(), msg.buf, msg.len);
        if (run_commit_hook(0 < option_edit, get_index_file(), "prepare-commit-msg",
                            git_path_merge_msg(), "merge", NULL))
@@@ -909,7 -908,7 +913,7 @@@ static int setup_with_upstream(const ch
        return i;
  }
  
- static void write_merge_state(struct commit_list *remoteheads)
+ static void write_merge_heads(struct commit_list *remoteheads)
  {
        struct commit_list *j;
        struct strbuf buf = STRBUF_INIT;
                strbuf_addf(&buf, "%s\n", oid_to_hex(oid));
        }
        write_file_buf(git_path_merge_head(), buf.buf, buf.len);
-       strbuf_addch(&merge_msg, '\n');
-       write_file_buf(git_path_merge_msg(), merge_msg.buf, merge_msg.len);
  
        strbuf_reset(&buf);
        if (fast_forward == FF_NO)
        write_file_buf(git_path_merge_mode(), buf.buf, buf.len);
  }
  
+ static void write_merge_state(struct commit_list *remoteheads)
+ {
+       write_merge_heads(remoteheads);
+       strbuf_addch(&merge_msg, '\n');
+       write_file_buf(git_path_merge_msg(), merge_msg.buf, merge_msg.len);
+ }
  static int default_edit_option(void)
  {
        static const char name[] = "GIT_MERGE_AUTOEDIT";
                return 0;
  
        if (e) {
 -              int v = git_config_maybe_bool(name, e);
 +              int v = git_parse_maybe_bool(e);
                if (v < 0)
                        die(_("Bad value '%s' in environment '%s'"), e, name);
                return v;
@@@ -1122,8 -1126,8 +1131,8 @@@ int cmd_merge(int argc, const char **ar
         * current branch.
         */
        branch = branch_to_free = resolve_refdup("HEAD", 0, head_oid.hash, NULL);
 -      if (branch && starts_with(branch, "refs/heads/"))
 -              branch += 11;
 +      if (branch)
 +              skip_prefix(branch, "refs/heads/", &branch);
        if (!branch || is_null_oid(&head_oid))
                head_commit = NULL;
        else