In this series, I show the new merge API I have developed in merge-ort, and show how it differs from that provided by merge-recursive. I do this in four steps, each corresponding to a patch. Changes since v4: * Fix a bug where 'cherry-pick --continue' would report 'fatal: cherry-pick: --strategy cannot be used with --continue' when pull.twohead was set to ort (found by user of internal deployment at $DAYJOB) Elijah Newren (4): merge-ort: barebones API of new merge strategy with empty implementation merge-ort-wrappers: new convience wrappers to mimic the old merge API fast-rebase: demonstrate merge-ort's API via new test-tool command merge,rebase,revert: select ort or recursive by config or environment Makefile | 3 + builtin/merge.c | 26 ++++- builtin/rebase.c | 13 ++- builtin/revert.c | 7 ++ merge-ort-wrappers.c | 62 +++++++++++ merge-ort-wrappers.h | 25 +++++ merge-ort.c | 52 +++++++++ merge-ort.h | 58 ++++++++++ sequencer.c | 72 ++++++++++-- sequencer.h | 1 + t/helper/test-fast-rebase.c | 211 ++++++++++++++++++++++++++++++++++++ t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + 13 files changed, 517 insertions(+), 15 deletions(-) create mode 100644 merge-ort-wrappers.c create mode 100644 merge-ort-wrappers.h create mode 100644 merge-ort.c create mode 100644 merge-ort.h create mode 100644 t/helper/test-fast-rebase.c base-commit: 69986e19ffcfb9af674ae5180689ab7bbf92ed28 Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-895%2Fnewren%2Fort-api-with-empty-implementation-v5 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-895/newren/ort-api-with-empty-implementation-v5 Pull-Request: https://github.com/git/git/pull/895 Range-diff vs v4: 1: 3357ea415e = 1: 3357ea415e merge-ort: barebones API of new merge strategy with empty implementation 2: d7f6a834ab = 2: d7f6a834ab merge-ort-wrappers: new convience wrappers to mimic the old merge API 3: fce0db8778 = 3: fce0db8778 fast-rebase: demonstrate merge-ort's API via new test-tool command 4: 75d19804bd ! 4: 61217a83bd merge,rebase,revert: select ort or recursive by config or environment @@ builtin/rebase.c: static struct replay_opts get_replay_opts(const struct rebase_ - replay.strategy = opts->strategy; + if (opts->strategy) + replay.strategy = opts->strategy; ++ else if (!replay.strategy && replay.default_strategy) { ++ replay.strategy = replay.default_strategy; ++ replay.default_strategy = NULL; ++ } if (opts->strategy_opts) parse_strategy_opts(&replay, opts->strategy_opts); @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix case REBASE_PRESERVE_MERGES: ## builtin/revert.c ## +@@ builtin/revert.c: static int run_sequencer(int argc, const char **argv, struct replay_opts *opts) + NULL); + } + ++ if (!opts->strategy && opts->default_strategy) { ++ opts->strategy = opts->default_strategy; ++ opts->default_strategy = NULL; ++ } ++ + if (opts->allow_ff) + verify_opt_compatible(me, "--ff", + "--signoff", opts->signoff, @@ builtin/revert.c: static int run_sequencer(int argc, const char **argv, struct replay_opts *opts) /* These option values will be free()d */ opts->gpg_sign = xstrdup_or_null(opts->gpg_sign); @@ sequencer.c: static int git_sequencer_config(const char *k, const char *v, void return 0; } -+ if (!opts->strategy && !strcmp(k, "pull.twohead")) { -+ int ret = git_config_string((const char**)&opts->strategy, k, v); ++ if (!opts->default_strategy && !strcmp(k, "pull.twohead")) { ++ int ret = git_config_string((const char**)&opts->default_strategy, k, v); + if (ret == 0) { + /* + * pull.twohead is allowed to be multi-valued; we only + * care about the first value. + */ -+ char *tmp = strchr(opts->strategy, ' '); ++ char *tmp = strchr(opts->default_strategy, ' '); + if (tmp) + *tmp = '\0'; + } @@ sequencer.c: static int git_sequencer_config(const char *k, const char *v, void status = git_gpg_config(k, v, NULL); if (status) return status; +@@ sequencer.c: int sequencer_remove_state(struct replay_opts *opts) + free(opts->committer_name); + free(opts->committer_email); + free(opts->gpg_sign); ++ free(opts->default_strategy); + free(opts->strategy); + for (i = 0; i < opts->xopts_nr; i++) + free(opts->xopts[i]); @@ sequencer.c: static int do_recursive_merge(struct repository *r, struct replay_opts *opts) { @@ sequencer.c: static int do_merge(struct repository *r, if (ret <= 0) fputs(o.obuf.buf, stdout); strbuf_release(&o.obuf); + + ## sequencer.h ## +@@ sequencer.h: struct replay_opts { + int explicit_cleanup; + + /* Merge strategy */ ++ char *default_strategy; /* from config options */ + char *strategy; + char **xopts; + size_t xopts_nr, xopts_alloc; -- gitgitgadget