Merge branch 'pw/sequence-rerere-autoupdate' into next
authorJunio C Hamano <gitster@pobox.com>
Mon, 14 Aug 2017 22:22:52 +0000 (15:22 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 14 Aug 2017 22:22:52 +0000 (15:22 -0700)
Commands like "git rebase" accepted the --rerere-autoupdate option
from the command line, but did not always use it. This has been
fixed.

* pw/sequence-rerere-autoupdate:
cherry-pick/revert: reject --rerere-autoupdate when continuing
cherry-pick/revert: remember --rerere-autoupdate
t3504: use test_commit
rebase -i: honor --rerere-autoupdate
rebase: honor --rerere-autoupdate
am: remember --rerere-autoupdate setting

1  2 
builtin/am.c
sequencer.c
diff --combined builtin/am.c
index 40cc6d6fe8e7d440d544e88cba03be15e675c93f,6962d4db5ffceef3022b7f877a43c8833a839b31..ff0869d46f30681c095d5d388fcfea57431013d0
@@@ -431,6 -431,14 +431,14 @@@ static void am_load(struct am_state *st
        read_state_file(&sb, state, "utf8", 1);
        state->utf8 = !strcmp(sb.buf, "t");
  
+       if (file_exists(am_path(state, "rerere-autoupdate"))) {
+               read_state_file(&sb, state, "rerere-autoupdate", 1);
+               state->allow_rerere_autoupdate = strcmp(sb.buf, "t") ?
+                       RERERE_NOAUTOUPDATE : RERERE_AUTOUPDATE;
+       } else {
+               state->allow_rerere_autoupdate = 0;
+       }
        read_state_file(&sb, state, "keep", 1);
        if (!strcmp(sb.buf, "t"))
                state->keep = KEEP_TRUE;
@@@ -1003,6 -1011,10 +1011,10 @@@ static void am_setup(struct am_state *s
        write_state_bool(state, "sign", state->signoff);
        write_state_bool(state, "utf8", state->utf8);
  
+       if (state->allow_rerere_autoupdate)
+               write_state_bool(state, "rerere-autoupdate",
+                        state->allow_rerere_autoupdate == RERERE_AUTOUPDATE);
        switch (state->keep) {
        case KEEP_FALSE:
                str = "f";
@@@ -1131,7 -1143,7 +1143,7 @@@ static int index_has_changes(struct str
        struct object_id head;
        int i;
  
 -      if (!get_sha1_tree("HEAD", head.hash)) {
 +      if (!get_oid_tree("HEAD", &head)) {
                struct diff_options opt;
  
                diff_setup(&opt);
@@@ -1432,7 -1444,7 +1444,7 @@@ static void write_index_patch(const str
        struct rev_info rev_info;
        FILE *fp;
  
 -      if (!get_sha1_tree("HEAD", head.hash))
 +      if (!get_oid_tree("HEAD", &head))
                tree = lookup_tree(&head);
        else
                tree = lookup_tree(&empty_tree_oid);
@@@ -1661,7 -1673,7 +1673,7 @@@ static void do_commit(const struct am_s
        if (write_cache_as_tree(tree.hash, 0, NULL))
                die(_("git write-tree failed to write a tree"));
  
 -      if (!get_sha1_commit("HEAD", parent.hash)) {
 +      if (!get_oid_commit("HEAD", &parent)) {
                old_oid = &parent;
                commit_list_insert(lookup_commit(&parent), &parents);
        } else {
diff --combined sequencer.c
index f5e85a398dd06ef466a073c463e41a0b9278360c,e0e66b987b27072da4aea6304a565ab708be91e4..fcceabb80f4261006cdd65bc0ec95ac54ea42e7c
@@@ -127,6 -127,7 +127,7 @@@ static GIT_PATH_FUNC(rebase_path_onto, 
  static GIT_PATH_FUNC(rebase_path_autostash, "rebase-merge/autostash")
  static GIT_PATH_FUNC(rebase_path_strategy, "rebase-merge/strategy")
  static GIT_PATH_FUNC(rebase_path_strategy_opts, "rebase-merge/strategy_opts")
+ static GIT_PATH_FUNC(rebase_path_allow_rerere_autoupdate, "rebase-merge/allow_rerere_autoupdate")
  
  static inline int is_rebase_i(const struct replay_opts *opts)
  {
@@@ -691,7 -692,7 +692,7 @@@ static int run_git_commit(const char *d
  
  static int is_original_commit_empty(struct commit *commit)
  {
 -      const unsigned char *ptree_sha1;
 +      const struct object_id *ptree_oid;
  
        if (parse_commit(commit))
                return error(_("could not parse commit %s\n"),
                if (parse_commit(parent))
                        return error(_("could not parse parent commit %s\n"),
                                oid_to_hex(&parent->object.oid));
 -              ptree_sha1 = parent->tree->object.oid.hash;
 +              ptree_oid = &parent->tree->object.oid;
        } else {
 -              ptree_sha1 = EMPTY_TREE_SHA1_BIN; /* commit is root */
 +              ptree_oid = &empty_tree_oid; /* commit is root */
        }
  
 -      return !hashcmp(ptree_sha1, commit->tree->object.oid.hash);
 +      return !oidcmp(ptree_oid, &commit->tree->object.oid);
  }
  
  /*
@@@ -896,18 -897,18 +897,18 @@@ static int update_squash_messages(enum 
  
  static void flush_rewritten_pending(void) {
        struct strbuf buf = STRBUF_INIT;
 -      unsigned char newsha1[20];
 +      struct object_id newoid;
        FILE *out;
  
 -      if (strbuf_read_file(&buf, rebase_path_rewritten_pending(), 82) > 0 &&
 -          !get_sha1("HEAD", newsha1) &&
 +      if (strbuf_read_file(&buf, rebase_path_rewritten_pending(), (GIT_MAX_HEXSZ + 1) * 2) > 0 &&
 +          !get_oid("HEAD", &newoid) &&
            (out = fopen_or_warn(rebase_path_rewritten_list(), "a"))) {
                char *bol = buf.buf, *eol;
  
                while (*bol) {
                        eol = strchrnul(bol, '\n');
                        fprintf(out, "%.*s %s\n", (int)(eol - bol),
 -                                      bol, sha1_to_hex(newsha1));
 +                                      bol, oid_to_hex(&newoid));
                        if (!*eol)
                                break;
                        bol = eol + 1;
@@@ -1438,7 -1439,11 +1439,11 @@@ static int populate_opts_cb(const char 
        else if (!strcmp(key, "options.strategy-option")) {
                ALLOC_GROW(opts->xopts, opts->xopts_nr + 1, opts->xopts_alloc);
                opts->xopts[opts->xopts_nr++] = xstrdup(value);
-       } else
+       } else if (!strcmp(key, "options.allow-rerere-auto"))
+               opts->allow_rerere_auto =
+                       git_config_bool_or_int(key, value, &error_flag) ?
+                               RERERE_AUTOUPDATE : RERERE_NOAUTOUPDATE;
+       else
                return error(_("invalid key: %s"), key);
  
        if (!error_flag)
@@@ -1479,6 -1484,15 +1484,15 @@@ static int read_populate_opts(struct re
                                free(opts->gpg_sign);
                                opts->gpg_sign = xstrdup(buf.buf + 2);
                        }
+                       strbuf_reset(&buf);
+               }
+               if (read_oneliner(&buf, rebase_path_allow_rerere_autoupdate(), 1)) {
+                       if (!strcmp(buf.buf, "--rerere-autoupdate"))
+                               opts->allow_rerere_auto = RERERE_AUTOUPDATE;
+                       else if (!strcmp(buf.buf, "--no-rerere-autoupdate"))
+                               opts->allow_rerere_auto = RERERE_NOAUTOUPDATE;
+                       strbuf_reset(&buf);
                }
  
                if (file_exists(rebase_path_verbose()))
@@@ -1594,37 -1608,36 +1608,37 @@@ static int rollback_is_safe(void
        return !oidcmp(&actual_head, &expected_head);
  }
  
 -static int reset_for_rollback(const unsigned char *sha1)
 +static int reset_for_rollback(const struct object_id *oid)
  {
        const char *argv[4];    /* reset --merge <arg> + NULL */
  
        argv[0] = "reset";
        argv[1] = "--merge";
 -      argv[2] = sha1_to_hex(sha1);
 +      argv[2] = oid_to_hex(oid);
        argv[3] = NULL;
        return run_command_v_opt(argv, RUN_GIT_CMD);
  }
  
  static int rollback_single_pick(void)
  {
 -      unsigned char head_sha1[20];
 +      struct object_id head_oid;
  
        if (!file_exists(git_path_cherry_pick_head()) &&
            !file_exists(git_path_revert_head()))
                return error(_("no cherry-pick or revert in progress"));
 -      if (read_ref_full("HEAD", 0, head_sha1, NULL))
 +      if (read_ref_full("HEAD", 0, head_oid.hash, NULL))
                return error(_("cannot resolve HEAD"));
 -      if (is_null_sha1(head_sha1))
 +      if (is_null_oid(&head_oid))
                return error(_("cannot abort from a branch yet to be born"));
 -      return reset_for_rollback(head_sha1);
 +      return reset_for_rollback(&head_oid);
  }
  
  int sequencer_rollback(struct replay_opts *opts)
  {
        FILE *f;
 -      unsigned char sha1[20];
 +      struct object_id oid;
        struct strbuf buf = STRBUF_INIT;
 +      const char *p;
  
        f = fopen(git_path_head_file(), "r");
        if (!f && errno == ENOENT) {
                goto fail;
        }
        fclose(f);
 -      if (get_sha1_hex(buf.buf, sha1) || buf.buf[40] != '\0') {
 +      if (parse_oid_hex(buf.buf, &oid, &p) || *p != '\0') {
                error(_("stored pre-cherry-pick HEAD file '%s' is corrupt"),
                        git_path_head_file());
                goto fail;
        }
 -      if (is_null_sha1(sha1)) {
 +      if (is_null_oid(&oid)) {
                error(_("cannot abort from a branch yet to be born"));
                goto fail;
        }
                warning(_("You seem to have moved HEAD. "
                          "Not rewinding, check your HEAD!"));
        } else
 -      if (reset_for_rollback(sha1))
 +      if (reset_for_rollback(&oid))
                goto fail;
        strbuf_release(&buf);
        return sequencer_remove_state(opts);
@@@ -1743,6 -1756,10 +1757,10 @@@ static int save_opts(struct replay_opt
                                                        "options.strategy-option",
                                                        opts->xopts[i], "^$", 0);
        }
+       if (opts->allow_rerere_auto)
+               res |= git_config_set_in_file_gently(opts_file, "options.allow-rerere-auto",
+                                                    opts->allow_rerere_auto == RERERE_AUTOUPDATE ?
+                                                    "true" : "false");
        return res;
  }
  
@@@ -1789,13 -1806,13 +1807,13 @@@ static int make_patch(struct commit *co
  
  static int intend_to_amend(void)
  {
 -      unsigned char head[20];
 +      struct object_id head;
        char *p;
  
 -      if (get_sha1("HEAD", head))
 +      if (get_oid("HEAD", &head))
                return error(_("cannot read HEAD"));
  
 -      p = sha1_to_hex(head);
 +      p = oid_to_hex(&head);
        return write_message(p, strlen(p), rebase_path_amend(), 1);
  }
  
@@@ -2080,10 -2097,10 +2098,10 @@@ static int pick_commits(struct todo_lis
                if (read_oneliner(&head_ref, rebase_path_head_name(), 0) &&
                                starts_with(head_ref.buf, "refs/")) {
                        const char *msg;
 -                      unsigned char head[20], orig[20];
 +                      struct object_id head, orig;
                        int res;
  
 -                      if (get_sha1("HEAD", head)) {
 +                      if (get_oid("HEAD", &head)) {
                                res = error(_("cannot read HEAD"));
  cleanup_head_ref:
                                strbuf_release(&head_ref);
                                return res;
                        }
                        if (!read_oneliner(&buf, rebase_path_orig_head(), 0) ||
 -                                      get_sha1_hex(buf.buf, orig)) {
 +                                      get_oid_hex(buf.buf, &orig)) {
                                res = error(_("could not read orig-head"));
                                goto cleanup_head_ref;
                        }
                        }
                        msg = reflog_message(opts, "finish", "%s onto %s",
                                head_ref.buf, buf.buf);
 -                      if (update_ref(msg, head_ref.buf, head, orig,
 +                      if (update_ref(msg, head_ref.buf, head.hash, orig.hash,
                                        REF_NODEREF, UPDATE_REFS_MSG_ON_ERR)) {
                                res = error(_("could not update %s"),
                                        head_ref.buf);
                        log_tree_opt.disable_stdin = 1;
  
                        if (read_oneliner(&buf, rebase_path_orig_head(), 0) &&
 -                          !get_sha1(buf.buf, orig.hash) &&
 -                          !get_sha1("HEAD", head.hash)) {
 +                          !get_oid(buf.buf, &orig) &&
 +                          !get_oid("HEAD", &head)) {
                                diff_tree_oid(&orig, &head, "",
                                              &log_tree_opt.diffopt);
                                log_tree_diff_flush(&log_tree_opt);
@@@ -2206,16 -2223,16 +2224,16 @@@ static int commit_staged_changes(struc
  
        if (file_exists(rebase_path_amend())) {
                struct strbuf rev = STRBUF_INIT;
 -              unsigned char head[20], to_amend[20];
 +              struct object_id head, to_amend;
  
 -              if (get_sha1("HEAD", head))
 +              if (get_oid("HEAD", &head))
                        return error(_("cannot amend non-existing commit"));
                if (!read_oneliner(&rev, rebase_path_amend(), 0))
                        return error(_("invalid file: '%s'"), rebase_path_amend());
 -              if (get_sha1_hex(rev.buf, to_amend))
 +              if (get_oid_hex(rev.buf, &to_amend))
                        return error(_("invalid contents: '%s'"),
                                rebase_path_amend());
 -              if (hashcmp(head, to_amend))
 +              if (oidcmp(&head, &to_amend))
                        return error(_("\nYou have uncommitted changes in your "
                                       "working tree. Please, commit them\n"
                                       "first and then run 'git rebase "
@@@ -2267,7 -2284,7 +2285,7 @@@ int sequencer_continue(struct replay_op
                struct object_id oid;
  
                if (read_oneliner(&buf, rebase_path_stopped_sha(), 1) &&
 -                  !get_sha1_committish(buf.buf, oid.hash))
 +                  !get_oid_committish(buf.buf, &oid))
                        record_in_rewritten(&oid, peek_command(&todo_list, 0));
                strbuf_release(&buf);
        }