git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 0/1] apply: support --ours, --theirs, and --union for three-way merges

From
Alex Henrie <alexhenrie24@gmail.com>
Date
Sep 9, 2024, 14:10 UTC
Message-ID
<20240909141109.3102-1-alexhenrie24@gmail.com>
In-Reply-To
<20240906044222.4881-1-alexhenrie24@gmail.com>
Changes from v1:
- Use OPT_SET_INT_F instead of OPT_CALLBACK_F
- Remove the special message and instead always say that the patch
  applied cleanly when these options are used
Thanks to Junio for your feedback.
Alex Henrie (1):
  apply: support --ours, --theirs, and --union for three-way merges
 Documentation/git-apply.txt |  9 ++++++++-
 apply.c                     | 20 +++++++++++++++++--
 apply.h                     |  1 +
 t/t4108-apply-threeway.sh   | 40 +++++++++++++++++++++++++++++++++++++
 4 files changed, 67 insertions(+), 3 deletions(-)
Range-diff against v1:
1:  e0e4000d47 ! 1:  9307dc5a1b apply: support --ours, --theirs, and --union for three-way merges
    @@ Documentation/git-apply.txt: OPTIONS
      	for each blob to help identify the original version that
     
      ## apply.c ##
    -@@ apply.c: int init_apply_state(struct apply_state *state,
    - 	state->prefix = prefix;
    - 	state->repo = repo;
    - 	state->apply = 1;
    -+	state->merge_opts.conflict_style = -1;
    - 	state->line_termination = '\n';
    - 	state->p_value = 1;
    - 	state->p_context = UINT_MAX;
     @@ apply.c: static int three_way_merge(struct apply_state *state,
    + 			   const struct object_id *theirs)
    + {
    + 	mmfile_t base_file, our_file, their_file;
    ++	struct ll_merge_options merge_opts = LL_MERGE_OPTIONS_INIT;
    + 	mmbuffer_t result = { NULL };
    + 	enum ll_merge_result status;
    + 
    +@@ apply.c: static int three_way_merge(struct apply_state *state,
    + 	read_mmblob(&base_file, base);
    + 	read_mmblob(&our_file, ours);
    + 	read_mmblob(&their_file, theirs);
    ++	merge_opts.variant = state->merge_variant;
    + 	status = ll_merge(&result, path,
    + 			  &base_file, "base",
      			  &our_file, "ours",
      			  &their_file, "theirs",
      			  state->repo->index,
     -			  NULL);
    -+			  &state->merge_opts);
    ++			  &merge_opts);
      	if (status == LL_MERGE_BINARY_CONFLICT)
      		warning("Cannot merge binary files: %s (%s vs. %s)",
      			path, "ours", "theirs");
    -@@ apply.c: static int try_threeway(struct apply_state *state,
    - 		return status;
    - 	}
    - 
    --	if (status) {
    -+	if (state->merge_opts.variant) {
    -+		/*
    -+		 * XDL_MERGE_FAVOR_(OURS|THEIRS|UNION) automatically resolves
    -+		 * conflicts, but the ll_merge function is not yet smart enough
    -+		 * to report whether or not there were conflicts, so just print
    -+		 * a generic message.
    -+		 */
    -+		fprintf(stderr, _("Applied patch to '%s'.\n"), patch->new_name);
    -+	} else if (status) {
    - 		patch->conflicted_threeway = 1;
    - 		if (patch->is_new)
    - 			oidclr(&patch->threeway_stage[0], the_repository->hash_algo);
    -@@ apply.c: static int apply_option_parse_space_change(const struct option *opt,
    - 	return 0;
    - }
    - 
    -+static int apply_option_parse_favorite(const struct option *opt,
    -+				       const char *arg, int unset)
    -+{
    -+	struct apply_state *state = opt->value;
    -+
    -+	BUG_ON_OPT_ARG(arg);
    -+	BUG_ON_OPT_NEG(unset);
    -+
    -+	if (!strcmp(opt->long_name, "ours"))
    -+		state->merge_opts.variant = XDL_MERGE_FAVOR_OURS;
    -+	else if (!strcmp(opt->long_name, "theirs"))
    -+		state->merge_opts.variant = XDL_MERGE_FAVOR_THEIRS;
    -+	else
    -+		state->merge_opts.variant = XDL_MERGE_FAVOR_UNION;
    -+	return 0;
    -+}
    -+
    - static int apply_option_parse_whitespace(const struct option *opt,
    - 					 const char *arg, int unset)
    - {
     @@ apply.c: int apply_parse_options(int argc, const char **argv,
      			N_("also apply the patch (use with --stat/--summary/--check)")),
      		OPT_BOOL('3', "3way", &state->threeway,
      			 N_( "attempt three-way merge, fall back on normal patch if that fails")),
    -+		OPT_CALLBACK_F(0, "ours", state, NULL,
    ++		OPT_SET_INT_F(0, "ours", &state->merge_variant,
     +			N_("for conflicts, use our version"),
    -+			PARSE_OPT_NOARG | PARSE_OPT_NONEG,
    -+			apply_option_parse_favorite),
    -+		OPT_CALLBACK_F(0, "theirs", state, NULL,
    ++			XDL_MERGE_FAVOR_OURS, PARSE_OPT_NONEG),
    ++		OPT_SET_INT_F(0, "theirs", &state->merge_variant,
     +			N_("for conflicts, use their version"),
    -+			PARSE_OPT_NOARG | PARSE_OPT_NONEG,
    -+			apply_option_parse_favorite),
    -+		OPT_CALLBACK_F(0, "union", state, NULL,
    ++			XDL_MERGE_FAVOR_THEIRS, PARSE_OPT_NONEG),
    ++		OPT_SET_INT_F(0, "union", &state->merge_variant,
     +			N_("for conflicts, use a union version"),
    -+			PARSE_OPT_NOARG | PARSE_OPT_NONEG,
    -+			apply_option_parse_favorite),
    ++			XDL_MERGE_FAVOR_UNION, PARSE_OPT_NONEG),
      		OPT_FILENAME(0, "build-fake-ancestor", &state->fake_ancestor,
      			N_("build a temporary index based on embedded index information")),
      		/* Think twice before adding "--nul" synonym to this */
    @@ apply.c: int apply_parse_options(int argc, const char **argv,
     -	return parse_options(argc, argv, state->prefix, builtin_apply_options, apply_usage, 0);
     +	argc = parse_options(argc, argv, state->prefix, builtin_apply_options, apply_usage, 0);
     +
    -+	if (state->merge_opts.variant && !state->threeway)
    ++	if (state->merge_variant && !state->threeway)
     +		die(_("--ours, --theirs, and --union require --3way"));
     +
     +	return argc;
      }
     
      ## apply.h ##
    -@@
    - 
    - #include "hash.h"
    - #include "lockfile.h"
    -+#include "merge-ll.h"
    - #include "string-list.h"
    - #include "strmap.h"
    - 
     @@ apply.h: struct apply_state {
      	struct repository *repo;
      	const char *index_file;
      	enum apply_verbosity apply_verbosity;
    -+	struct ll_merge_options merge_opts;
    ++	int merge_variant;
      	char *fake_ancestor;
      	const char *patch_input_file;
      	int line_termination;
-- 
2.46.0
Previous: Alex HenrieNext: Alex Henrie
Message 4 of 5 in “apply: support --ours, --theirs, and --union for three-way merges”
  1. apply: support --ours, --theirs, and --union for three-way mergesAlex Henrie, Sep 6, 2024
  2. Junio C HamanoSep 6, 2024
  3. Alex HenrieSep 9, 2024
  4. 0/1 apply: support --ours, --theirs, and --union for three-way mergesAlex Henrie, Sep 9, 2024
  5. 1/1 apply: support --ours, --theirs, and --union for three-way mergesAlex Henrie, Sep 9, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.