From: Christian Couder <christian.couder@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
"Christian Couder" <chriscool@tuxfamily.org>,
"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"Taylor Blau" <me@ttaylorr.com>,
"Johannes Schindelin" <Johannes.Schindelin@gmx.de>,
"Elijah Newren" <newren@gmail.com>
Subject: [RFC PATCH 1/2] merge-ort: add new merge-tree-ort command
Date: Wed, 5 Jan 2022 17:33:23 +0100 [thread overview]
Message-ID: <20220105163324.73369-2-chriscool@tuxfamily.org> (raw)
In-Reply-To: <20220105163324.73369-1-chriscool@tuxfamily.org>
This new command is similar as merge-tree, but uses
merge-ort code and features, especially
merge_incore_nonrecursive(), instead of those from
resursive merge, to perform the merge.
The output from this new command is very different from
merge-tree's custom output, as we are only using code and
features from diff.{h,c}, especially diff_tree_oid(). This
should make it easy to customize and standardize the output
using regular diff options in the future.
This command will be extended to support new features
with the long-term goal of enabling merges and rebases
without a worktree.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
.gitignore | 1 +
Makefile | 1 +
builtin.h | 1 +
builtin/merge-tree-ort.c | 93 ++++++++++++++++++++++++++++++++++++++++
git.c | 1 +
5 files changed, 97 insertions(+)
create mode 100644 builtin/merge-tree-ort.c
diff --git a/.gitignore b/.gitignore
index 054249b20a..2dfcb1a589 100644
--- a/.gitignore
+++ b/.gitignore
@@ -98,6 +98,7 @@
/git-merge-index
/git-merge-file
/git-merge-tree
+/git-merge-tree-ort
/git-merge-octopus
/git-merge-one-file
/git-merge-ours
diff --git a/Makefile b/Makefile
index 75ed168adb..915e500b06 100644
--- a/Makefile
+++ b/Makefile
@@ -1124,6 +1124,7 @@ BUILTIN_OBJS += builtin/merge-index.o
BUILTIN_OBJS += builtin/merge-ours.o
BUILTIN_OBJS += builtin/merge-recursive.o
BUILTIN_OBJS += builtin/merge-tree.o
+BUILTIN_OBJS += builtin/merge-tree-ort.o
BUILTIN_OBJS += builtin/merge.o
BUILTIN_OBJS += builtin/mktag.o
BUILTIN_OBJS += builtin/mktree.o
diff --git a/builtin.h b/builtin.h
index 8a58743ed6..c68f46b118 100644
--- a/builtin.h
+++ b/builtin.h
@@ -182,6 +182,7 @@ int cmd_merge_ours(int argc, const char **argv, const char *prefix);
int cmd_merge_file(int argc, const char **argv, const char *prefix);
int cmd_merge_recursive(int argc, const char **argv, const char *prefix);
int cmd_merge_tree(int argc, const char **argv, const char *prefix);
+int cmd_merge_tree_ort(int argc, const char **argv, const char *prefix);
int cmd_mktag(int argc, const char **argv, const char *prefix);
int cmd_mktree(int argc, const char **argv, const char *prefix);
int cmd_multi_pack_index(int argc, const char **argv, const char *prefix);
diff --git a/builtin/merge-tree-ort.c b/builtin/merge-tree-ort.c
new file mode 100644
index 0000000000..1c8ecd16ec
--- /dev/null
+++ b/builtin/merge-tree-ort.c
@@ -0,0 +1,93 @@
+#include "builtin.h"
+#include "merge-ort.h"
+#include "diff.h"
+
+static const char merge_tree_ort_usage[] = "git merge-tree-ort <base-tree> <branch1> <branch2>";
+
+static void show_result(struct tree *base_tree,
+ struct tree *head_tree,
+ struct tree *merge_tree,
+ struct merge_result *result)
+{
+ const struct object_id *base_oid = &(base_tree->object.oid);
+ const struct object_id *head_oid = &(head_tree->object.oid);
+ const struct object_id *merge_oid = &(merge_tree->object.oid);
+ const struct object_id *result_oid = &(result->tree->object.oid);
+ struct diff_options opts;
+
+ repo_diff_setup(the_repository, &opts);
+ opts.stat_width = -1; /* use full terminal width */
+ opts.output_format |= DIFF_FORMAT_RAW | DIFF_FORMAT_PATCH;
+ opts.detect_rename = DIFF_DETECT_RENAME;
+ diff_setup_done(&opts);
+
+ printf("result tree: %s\n", oid_to_hex(result_oid));
+ printf("clean: %d\n", result->clean);
+
+ printf("diff with branch1:\n");
+ diff_tree_oid(head_oid, result_oid, "", &opts);
+ diffcore_std(&opts);
+ diff_flush(&opts);
+
+ printf("diff with branch2:\n");
+ diff_tree_oid(merge_oid, result_oid, "", &opts);
+ diffcore_std(&opts);
+ diff_flush(&opts);
+
+ printf("diff with base:\n");
+ diff_tree_oid(base_oid, result_oid, "", &opts);
+ diffcore_std(&opts);
+ diff_flush(&opts);
+}
+
+static struct commit *get_commit_by_name_or_die(const char *name)
+{
+ struct commit *c = lookup_commit_reference_by_name(name);
+ if (!c)
+ die(_("not a valid commit name '%s'"), name);
+ return c;
+}
+
+static void merge_trees_ort(const char *base_name,
+ const char *branch1,
+ const char *branch2)
+{
+ struct merge_result result;
+ struct merge_options merge_opt;
+
+ struct commit *base = get_commit_by_name_or_die(base_name);
+ struct commit *head = get_commit_by_name_or_die(branch1);
+ struct commit *merge = get_commit_by_name_or_die(branch2);
+
+ struct tree *base_tree = get_commit_tree(base);
+ struct tree *head_tree = get_commit_tree(head);
+ struct tree *merge_tree = get_commit_tree(merge);
+
+ memset(&result, 0, sizeof(result));
+ init_merge_options(&merge_opt, the_repository);
+
+ merge_opt.show_rename_progress = 1;
+ merge_opt.branch1 = branch1;
+ merge_opt.branch2 = branch2;
+ merge_opt.ancestor = base_name;
+
+ result.tree = head_tree;
+
+ merge_incore_nonrecursive(&merge_opt,
+ base_tree,
+ result.tree,
+ merge_tree,
+ &result);
+
+ show_result(base_tree, head_tree, merge_tree, &result);
+}
+
+int cmd_merge_tree_ort(int argc, const char **argv, const char *prefix)
+{
+ if (argc != 4)
+ usage(merge_tree_ort_usage);
+
+ merge_trees_ort(argv[1], argv[2], argv[3]);
+
+ return 0;
+}
diff --git a/git.c b/git.c
index 7edafd8ecf..90b8a4984c 100644
--- a/git.c
+++ b/git.c
@@ -562,6 +562,7 @@ static struct cmd_struct commands[] = {
{ "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
{ "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
{ "merge-tree", cmd_merge_tree, RUN_SETUP | NO_PARSEOPT },
+ { "merge-tree-ort", cmd_merge_tree_ort, RUN_SETUP | NO_PARSEOPT },
{ "mktag", cmd_mktag, RUN_SETUP | NO_PARSEOPT },
{ "mktree", cmd_mktree, RUN_SETUP },
{ "multi-pack-index", cmd_multi_pack_index, RUN_SETUP },
--
2.34.1.433.g7bc349372a.dirty
next prev parent reply other threads:[~2022-01-05 16:34 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-05 16:33 [RFC PATCH 0/2] Introduce new merge-tree-ort command Christian Couder
2022-01-05 16:33 ` Christian Couder [this message]
2022-01-05 17:08 ` [RFC PATCH 1/2] merge-ort: add " Elijah Newren
2022-01-05 16:33 ` [RFC PATCH 2/2] merge-ort: add t/t4310-merge-tree-ort.sh Christian Couder
2022-01-05 17:29 ` Elijah Newren
2022-01-05 16:53 ` [RFC PATCH 0/2] Introduce new merge-tree-ort command Elijah Newren
2022-01-05 17:32 ` Elijah Newren
2022-01-07 17:58 ` Christian Couder
2022-01-07 19:06 ` Elijah Newren
2022-01-10 13:49 ` Johannes Schindelin
2022-01-10 17:56 ` Junio C Hamano
2022-01-11 13:47 ` Johannes Schindelin
2022-01-11 17:00 ` Ævar Arnfjörð Bjarmason
2022-01-11 22:25 ` Elijah Newren
2022-01-12 18:06 ` Junio C Hamano
2022-01-12 20:06 ` Elijah Newren
2022-01-13 6:08 ` Junio C Hamano
2022-01-13 8:01 ` Elijah Newren
2022-01-13 9:26 ` Ævar Arnfjörð Bjarmason
2022-01-12 17:54 ` Junio C Hamano
2022-01-13 9:22 ` Ævar Arnfjörð Bjarmason
2022-01-10 17:59 ` Elijah Newren
2022-01-11 21:15 ` Elijah Newren
2022-02-22 13:08 ` Johannes Schindelin
2022-01-11 22:30 ` Johannes Schindelin
2022-01-12 0:41 ` Elijah Newren
2022-02-22 12:44 ` Johannes Schindelin
2022-01-07 19:54 ` Johannes Schindelin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220105163324.73369-2-chriscool@tuxfamily.org \
--to=christian.couder@gmail.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=avarab@gmail.com \
--cc=chriscool@tuxfamily.org \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=me@ttaylorr.com \
--cc=newren@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).