[PATCH v3 0/4] Beginning of new merge strategy: New API, empty implementation
- From
Elijah Newren via GitGitGadget <gitgitgadget@gmail.com>
- Date
- Oct 27, 2020, 02:08 UTC
- Message-ID
- <pull.895.v3.git.git.1603764490.gitgitgadget@gmail.com>
- In-Reply-To
- <pull.895.v2.git.git.1603731448.gitgitgadget@gmail.com>
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 v2:
* Extended comments in struct merge_result and in front of function definitions to make API usage clearer; in particular, noting how this merge backend differs in not using the index (and only updating it as part of merge_switch_to_result()). * Drop the other private field of struct merge_result, for now. * Rename merge_inmemory_* to merge_incore_*
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 temporary/hidden command
merge,rebase,revert: select ort or recursive by config or environmentMakefile | 3 + builtin.h | 1 + builtin/fast-rebase.c | 210 ++++++++++++++++++++++++++++++++++++++++++ builtin/merge.c | 26 +++++- builtin/rebase.c | 9 +- builtin/revert.c | 2 + git.c | 1 + merge-ort-wrappers.c | 62 +++++++++++++ merge-ort-wrappers.h | 25 +++++ merge-ort.c | 52 +++++++++++ merge-ort.h | 58 ++++++++++++ sequencer.c | 71 +++++++++++--- 12 files changed, 505 insertions(+), 15 deletions(-) create mode 100644 builtin/fast-rebase.c 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
base-commit: 69986e19ffcfb9af674ae5180689ab7bbf92ed28 Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-895%2Fnewren%2Fort-api-with-empty-implementation-v3 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-895/newren/ort-api-with-empty-implementation-v3 Pull-Request: https://github.com/git/git/pull/895
Range-diff vs v2:
1: b9e73975ea ! 1: 3357ea415e merge-ort: barebones API of new merge strategy with empty implementation
@@ merge-ort.c (new)
+ die("Not yet implemented");
+}
+
-+void merge_inmemory_nonrecursive(struct merge_options *opt,
-+ struct tree *merge_base,
-+ struct tree *side1,
-+ struct tree *side2,
-+ struct merge_result *result)
++void merge_incore_nonrecursive(struct merge_options *opt,
++ struct tree *merge_base,
++ struct tree *side1,
++ struct tree *side2,
++ struct merge_result *result)
+{
+ die("Not yet implemented");
+}
+
-+void merge_inmemory_recursive(struct merge_options *opt,
-+ struct commit_list *merge_bases,
-+ struct commit *side1,
-+ struct commit *side2,
-+ struct merge_result *result)
++void merge_incore_recursive(struct merge_options *opt,
++ struct commit_list *merge_bases,
++ struct commit *side1,
++ struct commit *side2,
++ struct merge_result *result)
+{
+ die("Not yet implemented");
+}
@@ merge-ort.h (new)
+struct tree;
+
+struct merge_result {
-+ /* whether the merge is clean */
++ /* Whether the merge is clean */
+ int clean;
+
-+ /* Result of merge. If !clean, represents what would go in worktree */
++ /*
++ * Result of merge. If !clean, represents what would go in worktree
++ * (thus possibly including files containing conflict markers).
++ */
+ struct tree *tree;
+
+ /*
+ * Additional metadata used by merge_switch_to_result() or future calls
-+ * to merge_inmemory_*(). Not for external use.
++ * to merge_incore_*(). Includes data needed to update the index (if
++ * !clean) and to print "CONFLICT" messages. Not for external use.
+ */
+ void *priv;
-+ unsigned ate;
+};
+
-+/* rename-detecting three-way merge with recursive ancestor consolidation. */
-+void merge_inmemory_recursive(struct merge_options *opt,
-+ struct commit_list *merge_bases,
-+ struct commit *side1,
-+ struct commit *side2,
-+ struct merge_result *result);
++/*
++ * rename-detecting three-way merge with recursive ancestor consolidation.
++ * working tree and index are untouched.
++ */
++void merge_incore_recursive(struct merge_options *opt,
++ struct commit_list *merge_bases,
++ struct commit *side1,
++ struct commit *side2,
++ struct merge_result *result);
+
-+/* rename-detecting three-way merge, no recursion. */
-+void merge_inmemory_nonrecursive(struct merge_options *opt,
-+ struct tree *merge_base,
-+ struct tree *side1,
-+ struct tree *side2,
-+ struct merge_result *result);
++/*
++ * rename-detecting three-way merge, no recursion.
++ * working tree and index are untouched.
++ */
++void merge_incore_nonrecursive(struct merge_options *opt,
++ struct tree *merge_base,
++ struct tree *side1,
++ struct tree *side2,
++ struct merge_result *result);
+
-+/* Update the working tree and index from head to result after inmemory merge */
++/* Update the working tree and index from head to result after incore merge */
+void merge_switch_to_result(struct merge_options *opt,
+ struct tree *head,
+ struct merge_result *result,
2: a9fff811a2 ! 2: d7f6a834ab merge-ort-wrappers: new convience wrappers to mimic the old merge API
@@ merge-ort-wrappers.c (new)
+ }
+
+ memset(&result, 0, sizeof(result));
-+ merge_inmemory_nonrecursive(opt, merge_base, head, merge, &result);
++ merge_incore_nonrecursive(opt, merge_base, head, merge, &result);
+ merge_switch_to_result(opt, head, &result, 1, 1);
+
+ return result.clean;
@@ merge-ort-wrappers.c (new)
+ return -1;
+
+ memset(&tmp, 0, sizeof(tmp));
-+ merge_inmemory_recursive(opt, merge_bases, side1, side2, &tmp);
++ merge_incore_recursive(opt, merge_bases, side1, side2, &tmp);
+ merge_switch_to_result(opt, head, &tmp, 1, 1);
+ *result = NULL;
+
3: f38d140c15 ! 3: 27ad756600 fast-rebase: demonstrate merge-ort's API via temporary/hidden command
@@ builtin/fast-rebase.c (new)
+ merge_opt.branch2 = short_commit_name(commit);
+ merge_opt.ancestor = xstrfmt("parent of %s", merge_opt.branch2);
+
-+ merge_inmemory_nonrecursive(&merge_opt,
-+ base_tree,
-+ result.tree,
-+ next_tree,
-+ &result);
++ merge_incore_nonrecursive(&merge_opt,
++ base_tree,
++ result.tree,
++ next_tree,
++ &result);
+
+ free((char*)merge_opt.ancestor);
+ merge_opt.ancestor = NULL;
4: 5f6c97b889 ! 4: 0479d59c33 merge,rebase,revert: select ort or recursive by config or environment
@@ sequencer.c: static int do_recursive_merge(struct repository *r,
- strbuf_release(&o.obuf);
+ if (opts->strategy && !strcmp(opts->strategy, "ort")) {
+ memset(&result, 0, sizeof(result));
-+ merge_inmemory_nonrecursive(&o, base_tree, head_tree, next_tree,
++ merge_incore_nonrecursive(&o, base_tree, head_tree, next_tree,
+ &result);
+ show_output = !is_rebase_i(opts) || !result.clean;
+ /*
@@ sequencer.c: static int do_merge(struct repository *r,
- ret = merge_recursive(&o, head_commit, merge_commit, reversed, &i);
+ if (opts->strategy && !strcmp(opts->strategy, "ort")) {
+ /*
-+ * TODO: Should use merge_inmemory_recursive() and
++ * TODO: Should use merge_incore_recursive() and
+ * merge_switch_to_result(), skipping the call to
+ * merge_switch_to_result() when we don't actually need to
+ * update the index and working copy immediately.-- gitgitgadget