Merge branch 'pw/rebase-i-regression-fix' into maint
authorJunio C Hamano <gitster@pobox.com>
Sun, 4 Jun 2017 01:20:55 +0000 (10:20 +0900)
committerJunio C Hamano <gitster@pobox.com>
Sun, 4 Jun 2017 01:20:55 +0000 (10:20 +0900)
Just the first one of three? new tests that follows up a regression
fix.

* pw/rebase-i-regression-fix:
rebase -i: add missing newline to end of message
rebase -i: silence stash apply
rebase -i: fix reflog message

1  2 
sequencer.c
diff --combined sequencer.c
index 10c3b4ff81547891172319cee0e291c5160050e1,dc7573940ac8c992f01901845112343462728a99..9cb5cc75190ee527045cf47ce23e30592b23839e
@@@ -602,12 -602,6 +602,12 @@@ N_("you have staged changes in your wor
  "\n"
  "  git rebase --continue\n");
  
 +#define ALLOW_EMPTY (1<<0)
 +#define EDIT_MSG    (1<<1)
 +#define AMEND_MSG   (1<<2)
 +#define CLEANUP_MSG (1<<3)
 +#define VERIFY_MSG  (1<<4)
 +
  /*
   * If we are cherry-pick, and if the merge did not result in
   * hand-editing, we will hit this commit and inherit the original
   * author metadata.
   */
  static int run_git_commit(const char *defmsg, struct replay_opts *opts,
 -                        int allow_empty, int edit, int amend,
 -                        int cleanup_commit_message)
 +                        unsigned int flags)
  {
        struct child_process cmd = CHILD_PROCESS_INIT;
        const char *value;
        cmd.git_cmd = 1;
  
        if (is_rebase_i(opts)) {
 -              if (!edit) {
 +              if (!(flags & EDIT_MSG)) {
                        cmd.stdout_to_stderr = 1;
                        cmd.err = -1;
                }
        }
  
        argv_array_push(&cmd.args, "commit");
 -      argv_array_push(&cmd.args, "-n");
  
 -      if (amend)
 +      if (!(flags & VERIFY_MSG))
 +              argv_array_push(&cmd.args, "-n");
 +      if ((flags & AMEND_MSG))
                argv_array_push(&cmd.args, "--amend");
        if (opts->gpg_sign)
                argv_array_pushf(&cmd.args, "-S%s", opts->gpg_sign);
                argv_array_push(&cmd.args, "-s");
        if (defmsg)
                argv_array_pushl(&cmd.args, "-F", defmsg, NULL);
 -      if (cleanup_commit_message)
 +      if ((flags & CLEANUP_MSG))
                argv_array_push(&cmd.args, "--cleanup=strip");
 -      if (edit)
 +      if ((flags & EDIT_MSG))
                argv_array_push(&cmd.args, "-e");
 -      else if (!cleanup_commit_message &&
 +      else if (!(flags & CLEANUP_MSG) &&
                 !opts->signoff && !opts->record_origin &&
                 git_config_get_value("commit.cleanup", &value))
                argv_array_push(&cmd.args, "--cleanup=verbatim");
  
 -      if (allow_empty)
 +      if ((flags & ALLOW_EMPTY))
                argv_array_push(&cmd.args, "--allow-empty");
  
        if (opts->allow_empty_message)
@@@ -932,14 -926,14 +932,14 @@@ static void record_in_rewritten(struct 
  static int do_pick_commit(enum todo_command command, struct commit *commit,
                struct replay_opts *opts, int final_fixup)
  {
 -      int edit = opts->edit, cleanup_commit_message = 0;
 -      const char *msg_file = edit ? NULL : git_path_merge_msg();
 +      unsigned int flags = opts->edit ? EDIT_MSG : 0;
 +      const char *msg_file = opts->edit ? NULL : git_path_merge_msg();
        unsigned char head[20];
        struct commit *base, *next, *parent;
        const char *base_label, *next_label;
        struct commit_message msg = { NULL, NULL, NULL, NULL };
        struct strbuf msgbuf = STRBUF_INIT;
 -      int res, unborn = 0, amend = 0, allow = 0;
 +      int res, unborn = 0, allow;
  
        if (opts->no_commit) {
                /*
                        opts);
                if (res || command != TODO_REWORD)
                        goto leave;
 -              edit = amend = 1;
 +              flags |= EDIT_MSG | AMEND_MSG;
 +              if (command == TODO_REWORD)
 +                      flags |= VERIFY_MSG;
                msg_file = NULL;
                goto fast_forward_edit;
        }
        }
  
        if (command == TODO_REWORD)
 -              edit = 1;
 +              flags |= EDIT_MSG | VERIFY_MSG;
        else if (is_fixup(command)) {
                if (update_squash_messages(command, commit, opts))
                        return -1;
 -              amend = 1;
 +              flags |= AMEND_MSG;
                if (!final_fixup)
                        msg_file = rebase_path_squash_msg();
                else if (file_exists(rebase_path_fixup_msg())) {
 -                      cleanup_commit_message = 1;
 +                      flags |= CLEANUP_MSG;
                        msg_file = rebase_path_fixup_msg();
                } else {
 -                      const char *dest = git_path("SQUASH_MSG");
 +                      const char *dest = git_path_squash_msg();
                        unlink(dest);
                        if (copy_file(dest, rebase_path_squash_msg(), 0666))
                                return error(_("could not rename '%s' to '%s'"),
                                             rebase_path_squash_msg(), dest);
 -                      unlink(git_path("MERGE_MSG"));
 +                      unlink(git_path_merge_msg());
                        msg_file = dest;
 -                      edit = 1;
 +                      flags |= EDIT_MSG;
                }
        }
  
        if (allow < 0) {
                res = allow;
                goto leave;
 -      }
 +      } else if (allow)
 +              flags |= ALLOW_EMPTY;
        if (!opts->no_commit)
  fast_forward_edit:
 -              res = run_git_commit(msg_file, opts, allow, edit, amend,
 -                                   cleanup_commit_message);
 +              res = run_git_commit(msg_file, opts, flags);
  
        if (!res && final_fixup) {
                unlink(rebase_path_fixup_msg());
@@@ -1200,7 -1192,6 +1200,7 @@@ struct todo_list 
        struct todo_item *items;
        int nr, alloc, current;
        int done_nr, total_nr;
 +      struct stat_data stat;
  };
  
  #define TODO_LIST_INIT { STRBUF_INIT }
@@@ -1331,7 -1322,6 +1331,7 @@@ static int count_commands(struct todo_l
  static int read_populate_todo(struct todo_list *todo_list,
                        struct replay_opts *opts)
  {
 +      struct stat st;
        const char *todo_file = get_todo_path(opts);
        int fd, res;
  
        }
        close(fd);
  
 +      res = stat(todo_file, &st);
 +      if (res)
 +              return error(_("could not stat '%s'"), todo_file);
 +      fill_stat_data(&todo_list->stat, &st);
 +
        res = parse_insn_buffer(todo_list->buf.buf, todo_list);
        if (res) {
                if (is_rebase_i(opts))
@@@ -1827,10 -1812,10 +1827,10 @@@ static int error_failed_squash(struct c
                return error(_("could not rename '%s' to '%s'"),
                        rebase_path_squash_msg(), rebase_path_message());
        unlink(rebase_path_fixup_msg());
 -      unlink(git_path("MERGE_MSG"));
 -      if (copy_file(git_path("MERGE_MSG"), rebase_path_message(), 0666))
 +      unlink(git_path_merge_msg());
 +      if (copy_file(git_path_merge_msg(), rebase_path_message(), 0666))
                return error(_("could not copy '%s' to '%s'"),
 -                           rebase_path_message(), git_path("MERGE_MSG"));
 +                           rebase_path_message(), git_path_merge_msg());
        return error_with_patch(commit, subject, subject_len, opts, 1, 0);
  }
  
@@@ -1913,11 -1898,13 +1913,13 @@@ static int apply_autostash(struct repla
        strbuf_trim(&stash_sha1);
  
        child.git_cmd = 1;
+       child.no_stdout = 1;
+       child.no_stderr = 1;
        argv_array_push(&child.args, "stash");
        argv_array_push(&child.args, "apply");
        argv_array_push(&child.args, stash_sha1.buf);
        if (!run_command(&child))
-               printf(_("Applied autostash."));
+               printf(_("Applied autostash.\n"));
        else {
                struct child_process store = CHILD_PROCESS_INIT;
  
@@@ -2035,25 -2022,10 +2037,25 @@@ static int pick_commits(struct todo_lis
                } else if (item->command == TODO_EXEC) {
                        char *end_of_arg = (char *)(item->arg + item->arg_len);
                        int saved = *end_of_arg;
 +                      struct stat st;
  
                        *end_of_arg = '\0';
                        res = do_exec(item->arg);
                        *end_of_arg = saved;
 +
 +                      /* Reread the todo file if it has changed. */
 +                      if (res)
 +                              ; /* fall through */
 +                      else if (stat(get_todo_path(opts), &st))
 +                              res = error_errno(_("could not stat '%s'"),
 +                                                get_todo_path(opts));
 +                      else if (match_stat_data(&todo_list->stat, &st)) {
 +                              todo_list_release(todo_list);
 +                              if (read_populate_todo(todo_list, opts))
 +                                      res = -1; /* message was printed */
 +                              /* `current` will be incremented below */
 +                              todo_list->current = -1;
 +                      }
                } else if (!is_noop(item->command))
                        return error(_("unknown command %d"), item->command);
  
@@@ -2088,6 -2060,7 +2090,7 @@@ cleanup_head_ref
                                res = error(_("could not read orig-head"));
                                goto cleanup_head_ref;
                        }
+                       strbuf_reset(&buf);
                        if (!read_oneliner(&buf, rebase_path_onto(), 0)) {
                                res = error(_("could not read 'onto'"));
                                goto cleanup_head_ref;
@@@ -2184,12 -2157,12 +2187,12 @@@ static int continue_single_pick(void
  
  static int commit_staged_changes(struct replay_opts *opts)
  {
 -      int amend = 0;
 +      unsigned int flags = ALLOW_EMPTY | EDIT_MSG;
  
        if (has_unstaged_changes(1))
                return error(_("cannot rebase: You have unstaged changes."));
        if (!has_uncommitted_changes(0)) {
 -              const char *cherry_pick_head = git_path("CHERRY_PICK_HEAD");
 +              const char *cherry_pick_head = git_path_cherry_pick_head();
  
                if (file_exists(cherry_pick_head) && unlink(cherry_pick_head))
                        return error(_("could not remove CHERRY_PICK_HEAD"));
                                       "--continue' again."));
  
                strbuf_release(&rev);
 -              amend = 1;
 +              flags |= AMEND_MSG;
        }
  
 -      if (run_git_commit(rebase_path_message(), opts, 1, 1, amend, 0))
 +      if (run_git_commit(rebase_path_message(), opts, flags))
                return error(_("could not commit staged changes."));
        unlink(rebase_path_amend());
        return 0;