git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: git@vger.kernel.org
Cc: "Taylor Blau" <me@ttaylorr.com>,
	"Junio C Hamano" <gitster@pobox.com>,
	"Alban Gruin" <alban.gruin@gmail.com>,
	"Phillip Wood" <phillip.wood123@gmail.com>,
	"Elijah Newren" <newren@gmail.com>,
	"Johannes Schindelin" <Johannes.Schindelin@gmx.de>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: [PATCH v9 00/12] merge-index: prepare to rewrite merge drivers in C
Date: Fri, 18 Nov 2022 12:18:17 +0100	[thread overview]
Message-ID: <cover-v9-00.12-00000000000-20221118T110058Z-avarab@gmail.com> (raw)
In-Reply-To: <20220809185429.20098-1-alban.gruin@gmail.com>

This is a prep series for a re-roll of Alban Gruin's series to rewrite
various merge drivers from *.sh to *.c, and being able to call those
in-process.

This was last discussed on-list in August[1], and has been ejected
from "seen" due to staleness.

The last time around there were concerns with the later part of this
topic, but the parts that are included here weren't controversial,
those will be part 2 (and I think I've addressed those concerns).

Changes since the v8:

 * Migrate "merge-index" to parse_options(), first in a bug-for-bug
   compatible way, and then later on fix the behavior, and add tests
   along the way.

 * The 5-9/12 here were all split out in one way or another from
   Alban's 3/14[2], in such a way as to make the diff for 10/12 as
   friendly as possible (e.g. catering to rename detection).

 * Alban's converted die()/exit() in the built-in to "error()", but in
   doing so introduced a behavior change: When we'd previously process
   N items we'd exit right away, but in the v8 we'd attempt all N
   items.

   It turns out that almost nothing that came after care about the
   die(), i.e. even if we've lib-ified it it's OK to call die() within
   that library.

 * A new 11/12 hopefully makes the way merge-index parses out OIDs and
   types easier to reason about.

 * Finally, 12/12 makes the semantics of "merge-index" sane vis-a-vis
   parse_options().

Passing CI and branch for this at
https://github.com/avar/git/tree/ag/merge-strategies-in-c-prep

The follow-on from this is then
https://github.com/avar/git/tree/ag/merge-strategies-in-c-2, for those
that want to peek ahead.

1. https://lore.kernel.org/git/20220809185429.20098-9-alban.gruin@gmail.com/
2. https://lore.kernel.org/git/20220809185429.20098-4-alban.gruin@gmail.com/

Alban Gruin (4):
  t6060: modify multiple files to expose a possible issue with
    merge-index
  t6060: add tests for removed files
  merge-index: improve die() error messages
  merge-index: libify merge_one_path() and merge_all()

Ævar Arnfjörð Bjarmason (8):
  merge-index doc & -h: fix padding, labels and "()" use
  merge-index tests: add usage tests
  merge-index: migrate to parse_options() API
  merge-index i18n: mark die() messages for translation
  merge-index: stop calling ensure_full_index() twice
  builtin/merge-index.c: don't USE_THE_INDEX_COMPATIBILITY_MACROS
  merge-index: use "struct strvec" and helper to prepare args
  merge-index: make the argument parsing sensible & simpler

 Documentation/git-merge-index.txt |   2 +-
 Makefile                          |   1 +
 builtin/merge-index.c             | 169 ++++++++++++++----------------
 git.c                             |   2 +-
 merge-strategies.c                |  87 +++++++++++++++
 merge-strategies.h                |  19 ++++
 t/t0450/txt-help-mismatches       |   1 -
 t/t6060-merge-index.sh            |  65 +++++++++++-
 8 files changed, 250 insertions(+), 96 deletions(-)
 create mode 100644 merge-strategies.c
 create mode 100644 merge-strategies.h

Range-diff against v8:
 -:  ----------- >  1:  cafc7db374e merge-index doc & -h: fix padding, labels and "()" use
 1:  0f791f500e6 !  2:  099d4812601 t6060: modify multiple files to expose a possible issue with merge-index
    @@ Commit message
         be trivially mergeable.
     
         Signed-off-by: Alban Gruin <alban.gruin@gmail.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## t/t6060-merge-index.sh ##
    -@@ t/t6060-merge-index.sh: test_description='basic git merge-index / git-merge-one-file tests'
    +@@ t/t6060-merge-index.sh: TEST_PASSES_SANITIZE_LEAK=true
      
      test_expect_success 'setup diverging branches' '
      	test_write_lines 1 2 3 4 5 6 7 8 9 10 >file &&
 2:  ed9e7a45855 !  3:  af3a235a224 t6060: add tests for removed files
    @@ Commit message
         tagged as `base', and deletes it in the commit tagged as `two'.
     
         Signed-off-by: Alban Gruin <alban.gruin@gmail.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## t/t6060-merge-index.sh ##
    -@@ t/t6060-merge-index.sh: test_description='basic git merge-index / git-merge-one-file tests'
    +@@ t/t6060-merge-index.sh: TEST_PASSES_SANITIZE_LEAK=true
      test_expect_success 'setup diverging branches' '
      	test_write_lines 1 2 3 4 5 6 7 8 9 10 >file &&
      	cp file file2 &&
 -:  ----------- >  4:  7d686637fa3 merge-index tests: add usage tests
 -:  ----------- >  5:  845f9b0cc19 merge-index: migrate to parse_options() API
 -:  ----------- >  6:  fc4e64f669e merge-index: improve die() error messages
 -:  ----------- >  7:  04c2bae9e68 merge-index i18n: mark die() messages for translation
 -:  ----------- >  8:  badfc60354a merge-index: stop calling ensure_full_index() twice
 -:  ----------- >  9:  f29343197eb builtin/merge-index.c: don't USE_THE_INDEX_COMPATIBILITY_MACROS
 3:  d1d5740a8e5 ! 10:  c7a131a9a86 merge-index: libify merge_one_path() and merge_all()
    @@ Metadata
      ## Commit message ##
         merge-index: libify merge_one_path() and merge_all()
     
    -    The "resolve" and "octopus" merge strategies do not call directly `git
    -    merge-one-file', they delegate the work to another git command, `git
    -    merge-index', that will loop over files in the index and call the
    -    specified command.  Unfortunately, these functions are not part of
    -    libgit.a, which means that once rewritten, the strategies would still
    -    have to invoke `merge-one-file' by spawning a new process first.
    +    Move the workhorse functions in "builtin/merge-index.c" into a new
    +    "merge-strategies" library, and mostly "libify" the code while doing
    +    so.
     
    -    To avoid this, this moves and renames merge_one_path(), merge_all(), and
    -    their helpers to merge-strategies.c.  They also take a callback to
    -    dictate what they should do for each file.  For now, to preserve the
    -    behaviour of `merge-index', only one callback, launching a new process,
    -    is defined.
    +    Eventually this will allow us to invoke merge strategies such as
    +    "resolve" and "octopus" in-process, once we've followed-up and
    +    replaced "git-merge-{resolve,octopus}.sh" etc.
    +
    +    But for now let's move this code, while trying to optimize for as much
    +    of it as possible being highlighted by the diff rename detection.
    +
    +    We still call die() in this library. An earlier version of this[1]
    +    converted these to "error()", but the problem with that that we'd then
    +    potentially run into the same error N times, e.g. once for every
    +    "<file>" we were asked to operate on, instead of dying on the first
    +    case. So let's leave those to "die()" for now.
    +
    +    1. https://lore.kernel.org/git/20220809185429.20098-4-alban.gruin@gmail.com/
     
         Signed-off-by: Alban Gruin <alban.gruin@gmail.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Makefile ##
     @@ Makefile: LIB_OBJS += merge-blobs.o
    @@ Makefile: LIB_OBJS += merge-blobs.o
     
      ## builtin/merge-index.c ##
     @@
    - #define USE_THE_INDEX_COMPATIBILITY_MACROS
      #include "builtin.h"
    + #include "parse-options.h"
     +#include "merge-strategies.h"
      #include "run-command.h"
      
    - static const char *pgm;
    +-static const char *pgm;
     -static int one_shot, quiet;
     -static int err;
    ++struct mofs_data {
    ++	const char *program;
    ++};
      
    --static int merge_entry(int pos, const char *path)
    -+static int merge_one_file_spawn(struct index_state *istate,
    -+				const struct object_id *orig_blob,
    -+				const struct object_id *our_blob,
    -+				const struct object_id *their_blob, const char *path,
    -+				unsigned int orig_mode, unsigned int our_mode, unsigned int their_mode,
    -+				void *data)
    +-static int merge_entry(struct index_state *istate, int pos, const char *path)
    ++static int merge_one_file(struct index_state *istate,
    ++			  const struct object_id *orig_blob,
    ++			  const struct object_id *our_blob,
    ++			  const struct object_id *their_blob, const char *path,
    ++			  unsigned int orig_mode, unsigned int our_mode,
    ++			  unsigned int their_mode, void *data)
      {
     -	int found;
    --	const char *arguments[] = { pgm, "", "", "", path, "", "", "", NULL };
    --	char hexbuf[4][GIT_MAX_HEXSZ + 1];
    --	char ownbuf[4][60];
    -+	char oids[3][GIT_MAX_HEXSZ + 1] = {{0}};
    -+	char modes[3][10] = {{0}};
    -+	const char *arguments[] = { pgm, oids[0], oids[1], oids[2],
    -+				    path, modes[0], modes[1], modes[2], NULL };
    ++	struct mofs_data *d = data;
    ++	const char *pgm = d->program;
    + 	const char *arguments[] = { pgm, "", "", "", path, "", "", "", NULL };
    + 	char hexbuf[4][GIT_MAX_HEXSZ + 1];
    + 	char ownbuf[4][60];
    ++	int stage = 0;
    + 	struct child_process cmd = CHILD_PROCESS_INIT;
      
    --	if (pos >= active_nr)
    --		die("git merge-index: %s not in the cache", path);
    +-	if (pos >= istate->cache_nr)
    +-		die(_("'%s' is not in the cache"), path);
     -	found = 0;
     -	do {
    --		const struct cache_entry *ce = active_cache[pos];
    +-		const struct cache_entry *ce = istate->cache[pos];
     -		int stage = ce_stage(ce);
     -
     -		if (strcmp(ce->name, path))
    @@ builtin/merge-index.c
     -		xsnprintf(ownbuf[stage], sizeof(ownbuf[stage]), "%o", ce->ce_mode);
     -		arguments[stage] = hexbuf[stage];
     -		arguments[stage + 4] = ownbuf[stage];
    --	} while (++pos < active_nr);
    +-	} while (++pos < istate->cache_nr);
     -	if (!found)
    --		die("git merge-index: %s not in the cache", path);
    +-		die(_("'%s' is not in the cache"), path);
     -
    --	if (run_command_v_opt(arguments, 0)) {
    +-	strvec_pushv(&cmd.args, arguments);
    +-	if (run_command(&cmd)) {
     -		if (one_shot)
     -			err++;
     -		else {
     -			if (!quiet)
    --				die("merge program failed");
    +-				die(_("merge program failed"));
     -			exit(1);
     -		}
    -+	if (orig_blob) {
    -+		oid_to_hex_r(oids[0], orig_blob);
    -+		xsnprintf(modes[0], sizeof(modes[0]), "%06o", orig_mode);
    ++#define ADD_MOF_ARG(oid, mode) \
    ++	if ((oid)) { \
    ++		stage++; \
    ++		oid_to_hex_r(hexbuf[stage], (oid)); \
    ++		xsnprintf(ownbuf[stage], sizeof(ownbuf[stage]), "%06o", (mode)); \
    ++		arguments[stage] = hexbuf[stage]; \
    ++		arguments[stage + 4] = ownbuf[stage]; \
      	}
     -	return found;
     -}
    - 
    --static void merge_one_path(const char *path)
    --{
    --	int pos = cache_name_pos(path, strlen(path));
     -
    +-static void merge_one_path(struct index_state *istate, const char *path)
    +-{
    +-	int pos = index_name_pos(istate, path, strlen(path));
    + 
     -	/*
     -	 * If it already exists in the cache as stage0, it's
     -	 * already merged and there is nothing to do.
     -	 */
     -	if (pos < 0)
    --		merge_entry(-pos-1, path);
    +-		merge_entry(istate, -pos-1, path);
     -}
    -+	if (our_blob) {
    -+		oid_to_hex_r(oids[1], our_blob);
    -+		xsnprintf(modes[1], sizeof(modes[1]), "%06o", our_mode);
    -+	}
    - 
    --static void merge_all(void)
    +-
    +-static void merge_all(struct index_state *istate)
     -{
     -	int i;
    --	/* TODO: audit for interaction with sparse-index. */
    --	ensure_full_index(&the_index);
    --	for (i = 0; i < active_nr; i++) {
    --		const struct cache_entry *ce = active_cache[i];
    ++	ADD_MOF_ARG(orig_blob, orig_mode);
    ++	ADD_MOF_ARG(our_blob, our_mode);
    ++	ADD_MOF_ARG(their_blob, their_mode);
    + 
    +-	for (i = 0; i < istate->cache_nr; i++) {
    +-		const struct cache_entry *ce = istate->cache[i];
     -		if (!ce_stage(ce))
     -			continue;
    --		i += merge_entry(i, ce->name)-1;
    -+	if (their_blob) {
    -+		oid_to_hex_r(oids[2], their_blob);
    -+		xsnprintf(modes[2], sizeof(modes[2]), "%06o", their_mode);
    - 	}
    -+
    -+	return run_command_v_opt(arguments, 0);
    +-		i += merge_entry(istate, i, ce->name)-1;
    +-	}
    ++	strvec_pushv(&cmd.args, arguments);
    ++	return run_command(&cmd);
      }
      
      int cmd_merge_index(int argc, const char **argv, const char *prefix)
      {
    --	int i, force_file = 0;
    -+	int i, force_file = 0, err = 0, one_shot = 0, quiet = 0;
    ++	int err = 0;
    + 	int all = 0;
    ++	int one_shot = 0;
    ++	int quiet = 0;
    + 	const char * const usage[] = {
    + 		N_("git merge-index [-o] [-q] <merge-program> (-a | ([--] <file>...))"),
    + 		NULL
    +@@ builtin/merge-index.c: int cmd_merge_index(int argc, const char **argv, const char *prefix)
    + 		OPT_END(),
    + 	};
    + #undef OPT__MERGE_INDEX_ALL
    ++	struct mofs_data data = { 0 };
      
      	/* Without this we cannot rely on waitpid() to tell
      	 * what happened to our children.
     @@ builtin/merge-index.c: int cmd_merge_index(int argc, const char **argv, const char *prefix)
    - 		quiet = 1;
    - 		i++;
    - 	}
    -+
    - 	pgm = argv[i++];
    -+
    - 	for (; i < argc; i++) {
    - 		const char *arg = argv[i];
    - 		if (!force_file && *arg == '-') {
    + 	/* <merge-program> and its options */
    + 	if (!argc)
    + 		usage_msg_opt(_("need a <merge-program> argument"), usage, options);
    +-	pgm = argv[0];
    ++	data.program = argv[0];
    + 	argc = parse_options(argc, argv, prefix, options_prog, usage, 0);
    + 	if (argc && all)
    + 		usage_msg_opt(_("'-a' and '<file>...' are mutually exclusive"),
     @@ builtin/merge-index.c: int cmd_merge_index(int argc, const char **argv, const char *prefix)
    - 				continue;
    - 			}
    - 			if (!strcmp(arg, "-a")) {
    --				merge_all();
    -+				err |= merge_all_index(&the_index, one_shot, quiet,
    -+						       merge_one_file_spawn, NULL);
    - 				continue;
    - 			}
    - 			die("git merge-index: unknown option %s", arg);
    - 		}
    --		merge_one_path(arg);
    -+		err |= merge_index_path(&the_index, one_shot, quiet, arg,
    -+					merge_one_file_spawn, NULL);
    - 	}
    + 	ensure_full_index(the_repository->index);
    + 
    + 	if (all)
    +-		merge_all(the_repository->index);
    ++		err |= merge_all_index(the_repository->index, one_shot, quiet,
    ++				       merge_one_file, &data);
    + 	else
    + 		for (size_t i = 0; i < argc; i++)
    +-			merge_one_path(the_repository->index, argv[i]);
    ++			err |= merge_index_path(the_repository->index,
    ++						one_shot, quiet, argv[i],
    ++						merge_one_file, &data);
    + 
     -	if (err && !quiet)
    --		die("merge program failed");
    -+
    +-		die(_("merge program failed"));
      	return err;
      }
     
    @@ merge-strategies.c (new)
     +#include "merge-strategies.h"
     +
     +static int merge_entry(struct index_state *istate, unsigned int pos,
    -+		       const char *path, int *err, merge_fn fn, void *data)
    ++		       const char *path, int *err, merge_index_fn fn,
    ++		       void *data)
     +{
     +	int found = 0;
    -+	const struct object_id *oids[3] = {NULL};
    -+	unsigned int modes[3] = {0};
    ++	const struct object_id *oids[3] = { 0 };
    ++	unsigned int modes[3] = { 0 };
     +
    ++	*err = 0;
    ++
    ++	if (pos >= istate->cache_nr)
    ++		die(_("'%s' is not in the cache"), path);
     +	do {
     +		const struct cache_entry *ce = istate->cache[pos];
     +		int stage = ce_stage(ce);
    @@ merge-strategies.c (new)
     +		modes[stage - 1] = ce->ce_mode;
     +	} while (++pos < istate->cache_nr);
     +	if (!found)
    -+		return error(_("%s is not in the cache"), path);
    ++		die(_("'%s' is not in the cache"), path);
     +
    -+	if (fn(istate, oids[0], oids[1], oids[2], path,
    -+	       modes[0], modes[1], modes[2], data))
    ++	if (fn(istate, oids[0], oids[1], oids[2], path, modes[0], modes[1],
    ++	       modes[2], data))
     +		(*err)++;
     +
     +	return found;
     +}
     +
     +int merge_index_path(struct index_state *istate, int oneshot, int quiet,
    -+		     const char *path, merge_fn fn, void *data)
    ++		     const char *path, merge_index_fn fn, void *data)
     +{
    -+	int pos = index_name_pos(istate, path, strlen(path)), ret, err = 0;
    ++	int err, ret;
    ++	int pos = index_name_pos(istate, path, strlen(path));
     +
     +	/*
     +	 * If it already exists in the cache as stage0, it's
     +	 * already merged and there is nothing to do.
     +	 */
    -+	if (pos < 0) {
    -+		ret = merge_entry(istate, -pos - 1, path, &err, fn, data);
    -+		if (ret == -1)
    -+			return -1;
    -+		else if (err) {
    -+			if (!quiet && !oneshot)
    -+				error(_("merge program failed"));
    -+			return 1;
    -+		}
    ++	if (pos >= 0)
    ++		return 0;
    ++
    ++	ret = merge_entry(istate, -pos - 1, path, &err, fn, data);
    ++	if (ret < 0)
    ++		return ret;
    ++	if (err) {
    ++		if (!quiet && !oneshot)
    ++			die(_("merge program failed"));
    ++		return 1;
     +	}
     +	return 0;
     +}
     +
     +int merge_all_index(struct index_state *istate, int oneshot, int quiet,
    -+		    merge_fn fn, void *data)
    ++		    merge_index_fn fn, void *data)
     +{
    -+	int err = 0, ret;
    ++	int err, ret;
     +	unsigned int i;
     +
    -+	/* TODO: audit for interaction with sparse-index. */
    -+	ensure_full_index(istate);
     +	for (i = 0; i < istate->cache_nr; i++) {
     +		const struct cache_entry *ce = istate->cache[i];
     +		if (!ce_stage(ce))
     +			continue;
     +
     +		ret = merge_entry(istate, i, ce->name, &err, fn, data);
    -+		if (ret > 0)
    ++		if (ret < 0)
    ++			return ret;
    ++		else if (ret > 0)
     +			i += ret - 1;
    -+		else if (ret == -1)
    -+			return -1;
     +
     +		if (err && !oneshot) {
     +			if (!quiet)
    -+				error(_("merge program failed"));
    ++				die(_("merge program failed"));
     +			return 1;
     +		}
     +	}
     +
     +	if (err && !quiet)
    -+		error(_("merge program failed"));
    ++		die(_("merge program failed"));
     +	return err;
     +}
     
    @@ merge-strategies.h (new)
     +#ifndef MERGE_STRATEGIES_H
     +#define MERGE_STRATEGIES_H
     +
    -+#include "object.h"
    -+
    -+typedef int (*merge_fn)(struct index_state *istate,
    -+			const struct object_id *orig_blob,
    -+			const struct object_id *our_blob,
    -+			const struct object_id *their_blob, const char *path,
    -+			unsigned int orig_mode, unsigned int our_mode, unsigned int their_mode,
    -+			void *data);
    ++struct object_id;
    ++struct index_state;
    ++typedef int (*merge_index_fn)(struct index_state *istate,
    ++			      const struct object_id *orig_blob,
    ++			      const struct object_id *our_blob,
    ++			      const struct object_id *their_blob,
    ++			      const char *path, unsigned int orig_mode,
    ++			      unsigned int our_mode, unsigned int their_mode,
    ++			      void *data);
     +
     +int merge_index_path(struct index_state *istate, int oneshot, int quiet,
    -+		     const char *path, merge_fn fn, void *data);
    ++		     const char *path, merge_index_fn fn, void *data);
     +int merge_all_index(struct index_state *istate, int oneshot, int quiet,
    -+		    merge_fn fn, void *data);
    ++		    merge_index_fn fn, void *data);
     +
     +#endif /* MERGE_STRATEGIES_H */
    -
    - ## t/t7607-merge-state.sh ##
    -@@ t/t7607-merge-state.sh: test_expect_success 'Ensure we restore original state if no merge strategy handl
    - 	# just hit conflicts, it completely fails and says that it cannot
    - 	# handle this type of merge.
    - 	test_expect_code 2 git merge branch2 branch3 >output 2>&1 &&
    --	grep "fatal: merge program failed" output &&
    -+	grep "error: merge program failed" output &&
    - 	grep "Should not be doing an octopus" output &&
    - 
    - 	# Make sure we did not leave stray changes around when no appropriate
 4:  4b0420836c1 <  -:  ----------- merge-index: drop the index
 5:  19a4fc52c57 <  -:  ----------- merge-index: add a new way to invoke `git-merge-one-file'
 6:  376130c1334 <  -:  ----------- update-index: move add_cacheinfo() to read-cache.c
 7:  e440127edf2 <  -:  ----------- merge-one-file: rewrite in C
 8:  661c358836e <  -:  ----------- merge-resolve: rewrite in C
 9:  388128cd351 <  -:  ----------- merge-recursive: move better_branch_name() to merge.c
10:  1515e154bf5 <  -:  ----------- merge-octopus: rewrite in C
11:  701c47371a7 <  -:  ----------- merge: use the "resolve" strategy without forking
12:  17597d0cc57 <  -:  ----------- merge: use the "octopus" strategy without forking
13:  cecfa666ecb <  -:  ----------- sequencer: use the "resolve" strategy without forking
14:  a23c0491a1f <  -:  ----------- sequencer: use the "octopus" strategy without forking
 -:  ----------- > 11:  adb712ca7a5 merge-index: use "struct strvec" and helper to prepare args
 -:  ----------- > 12:  f0368560140 merge-index: make the argument parsing sensible & simpler
-- 
2.38.0.1511.gcdcff1f1dc2


  parent reply	other threads:[~2022-11-18 11:19 UTC|newest]

Thread overview: 221+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-25 12:19 [RFC PATCH v1 00/17] Rewrite the remaining merge strategies from shell to C Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 01/17] t6027: modernise tests Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 02/17] merge-one-file: rewrite in C Alban Gruin
2020-06-25 14:55   ` Chris Torek
2020-06-25 15:16   ` Phillip Wood
2020-06-25 18:17     ` Phillip Wood
2020-06-26 14:33       ` Phillip Wood
2020-07-12 11:22     ` Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 03/17] merge-one-file: remove calls to external processes Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 04/17] merge-one-file: use error() instead of fprintf(stderr, ...) Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 05/17] merge-one-file: libify merge_one_file() Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 06/17] merge-index: libify merge_one_path() and merge_all() Alban Gruin
2020-06-26 10:13   ` Phillip Wood
2020-06-26 14:32     ` Phillip Wood
2020-07-12 11:36     ` Alban Gruin
2020-07-12 18:02       ` Phillip Wood
2020-07-12 20:10         ` Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 07/17] merge-resolve: rewrite in C Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 08/17] merge-resolve: remove calls to external processes Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 09/17] merge-resolve: libify merge_resolve() Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 10/17] merge-recursive: move better_branch_name() to merge.c Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 11/17] merge-octopus: rewrite in C Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 12/17] merge-octopus: remove calls to external processes Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 13/17] merge-octopus: libify merge_octopus() Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 14/17] merge: use the "resolve" strategy without forking Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 15/17] merge: use the "octopus" " Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 16/17] sequencer: use the "resolve" " Alban Gruin
2020-06-25 16:11   ` Phillip Wood
2020-07-12 11:27     ` Alban Gruin
2020-06-25 12:19 ` [RFC PATCH v1 17/17] sequencer: use the "octopus" merge " Alban Gruin
2020-09-01 10:56 ` [PATCH v2 00/11] Rewrite the remaining merge strategies from shell to C Alban Gruin
2020-09-01 10:56   ` [PATCH v2 01/11] t6027: modernise tests Alban Gruin
2020-09-01 10:56   ` [PATCH v2 02/11] merge-one-file: rewrite in C Alban Gruin
2020-09-01 21:06     ` Junio C Hamano
2020-09-02 14:50       ` Alban Gruin
2020-09-01 10:56   ` [PATCH v2 03/11] merge-index: libify merge_one_path() and merge_all() Alban Gruin
2020-09-01 21:11     ` Junio C Hamano
2020-09-02 15:37       ` Alban Gruin
2020-09-01 10:56   ` [PATCH v2 04/11] merge-index: don't fork if the requested program is `git-merge-one-file' Alban Gruin
2020-09-01 10:56   ` [PATCH v2 05/11] merge-resolve: rewrite in C Alban Gruin
2020-09-01 10:57   ` [PATCH v2 06/11] merge-recursive: move better_branch_name() to merge.c Alban Gruin
2020-09-01 10:57   ` [PATCH v2 07/11] merge-octopus: rewrite in C Alban Gruin
2020-09-01 10:57   ` [PATCH v2 08/11] merge: use the "resolve" strategy without forking Alban Gruin
2020-09-01 10:57   ` [PATCH v2 09/11] merge: use the "octopus" " Alban Gruin
2020-09-01 10:57   ` [PATCH v2 10/11] sequencer: use the "resolve" " Alban Gruin
2020-09-01 10:57   ` [PATCH v2 11/11] sequencer: use the "octopus" merge " Alban Gruin
2020-10-05 12:26   ` [PATCH v3 00/11] Rewrite the remaining merge strategies from shell to C Alban Gruin
2020-10-05 12:26     ` [PATCH v3 01/11] t6027: modernise tests Alban Gruin
2020-10-06 20:50       ` Junio C Hamano
2020-10-05 12:26     ` [PATCH v3 02/11] merge-one-file: rewrite in C Alban Gruin
2020-10-06 22:01       ` Junio C Hamano
2020-10-21 19:47         ` Alban Gruin
2020-10-21 20:28           ` Junio C Hamano
2020-10-21 21:20             ` Junio C Hamano
2020-10-21 20:30           ` Junio C Hamano
2020-10-05 12:26     ` [PATCH v3 03/11] merge-index: libify merge_one_path() and merge_all() Alban Gruin
2020-10-09  4:48       ` Junio C Hamano
2020-11-06 19:53         ` Alban Gruin
2020-10-05 12:26     ` [PATCH v3 04/11] merge-index: don't fork if the requested program is `git-merge-one-file' Alban Gruin
2020-10-16 19:07       ` Junio C Hamano
2020-10-05 12:26     ` [PATCH v3 05/11] merge-resolve: rewrite in C Alban Gruin
2020-10-16 19:19       ` Junio C Hamano
2020-11-06 19:53         ` Alban Gruin
2020-10-05 12:26     ` [PATCH v3 06/11] merge-recursive: move better_branch_name() to merge.c Alban Gruin
2020-10-05 12:26     ` [PATCH v3 07/11] merge-octopus: rewrite in C Alban Gruin
2020-10-05 12:26     ` [PATCH v3 08/11] merge: use the "resolve" strategy without forking Alban Gruin
2020-10-05 12:26     ` [PATCH v3 09/11] merge: use the "octopus" " Alban Gruin
2020-10-05 12:26     ` [PATCH v3 10/11] sequencer: use the "resolve" " Alban Gruin
2020-10-05 12:26     ` [PATCH v3 11/11] sequencer: use the "octopus" merge " Alban Gruin
2020-10-07  6:57     ` [PATCH v3 00/11] Rewrite the remaining merge strategies from shell to C Johannes Schindelin
2020-11-13 11:04     ` [PATCH v4 00/12] " Alban Gruin
2020-11-13 11:04       ` [PATCH v4 01/12] t6027: modernise tests Alban Gruin
2020-11-13 11:04       ` [PATCH v4 02/12] update-index: move add_cacheinfo() to read-cache.c Alban Gruin
2020-11-13 11:04       ` [PATCH v4 03/12] merge-one-file: rewrite in C Alban Gruin
2020-11-13 11:04       ` [PATCH v4 04/12] merge-index: libify merge_one_path() and merge_all() Alban Gruin
2020-11-13 11:04       ` [PATCH v4 05/12] merge-index: don't fork if the requested program is `git-merge-one-file' Alban Gruin
2020-11-13 11:04       ` [PATCH v4 06/12] merge-resolve: rewrite in C Alban Gruin
2020-11-13 11:04       ` [PATCH v4 07/12] merge-recursive: move better_branch_name() to merge.c Alban Gruin
2020-11-13 11:04       ` [PATCH v4 08/12] merge-octopus: rewrite in C Alban Gruin
2020-11-13 11:04       ` [PATCH v4 09/12] merge: use the "resolve" strategy without forking Alban Gruin
2020-11-13 11:04       ` [PATCH v4 10/12] merge: use the "octopus" " Alban Gruin
2020-11-13 11:04       ` [PATCH v4 11/12] sequencer: use the "resolve" " Alban Gruin
2020-11-13 11:04       ` [PATCH v4 12/12] sequencer: use the "octopus" merge " Alban Gruin
2020-11-16 10:21       ` [PATCH v5 00/12] Rewrite the remaining merge strategies from shell to C Alban Gruin
2020-11-16 10:21         ` [PATCH v5 01/12] t6027: modernise tests Alban Gruin
2020-11-16 10:21         ` [PATCH v5 02/12] update-index: move add_cacheinfo() to read-cache.c Alban Gruin
2020-11-16 10:21         ` [PATCH v5 03/12] merge-one-file: rewrite in C Alban Gruin
2020-11-16 10:21         ` [PATCH v5 04/12] merge-index: libify merge_one_path() and merge_all() Alban Gruin
2020-11-16 10:21         ` [PATCH v5 05/12] merge-index: don't fork if the requested program is `git-merge-one-file' Alban Gruin
2020-11-16 10:21         ` [PATCH v5 06/12] merge-resolve: rewrite in C Alban Gruin
2020-11-16 10:21         ` [PATCH v5 07/12] merge-recursive: move better_branch_name() to merge.c Alban Gruin
2020-11-16 10:21         ` [PATCH v5 08/12] merge-octopus: rewrite in C Alban Gruin
2020-11-16 10:21         ` [PATCH v5 09/12] merge: use the "resolve" strategy without forking Alban Gruin
2020-11-16 10:21         ` [PATCH v5 10/12] merge: use the "octopus" " Alban Gruin
2020-11-16 10:21         ` [PATCH v5 11/12] sequencer: use the "resolve" " Alban Gruin
2020-11-16 10:21         ` [PATCH v5 12/12] sequencer: use the "octopus" merge " Alban Gruin
2020-11-24 11:53         ` [PATCH v6 00/13] Rewrite the remaining merge strategies from shell to C Alban Gruin
2020-11-24 11:53           ` [PATCH v6 01/13] t6407: modernise tests Alban Gruin
2020-11-24 11:53           ` [PATCH v6 02/13] t6060: modify multiple files to expose a possible issue with merge-index Alban Gruin
2020-11-24 11:53           ` [PATCH v6 03/13] update-index: move add_cacheinfo() to read-cache.c Alban Gruin
2020-12-22 20:54             ` Junio C Hamano
2020-11-24 11:53           ` [PATCH v6 04/13] merge-one-file: rewrite in C Alban Gruin
2020-12-22 21:36             ` Junio C Hamano
2021-01-03 22:41               ` Alban Gruin
2021-01-08  6:54                 ` Junio C Hamano
2020-11-24 11:53           ` [PATCH v6 05/13] merge-index: libify merge_one_path() and merge_all() Alban Gruin
2021-01-05 15:59             ` Derrick Stolee
2021-01-05 23:20               ` Alban Gruin
2020-11-24 11:53           ` [PATCH v6 06/13] merge-index: don't fork if the requested program is `git-merge-one-file' Alban Gruin
2021-01-05 16:11             ` Derrick Stolee
2021-01-05 17:35               ` Martin Ågren
2021-01-05 23:20                 ` Alban Gruin
2021-01-05 23:20               ` Alban Gruin
2021-01-06  2:04                 ` Junio C Hamano
2021-01-10 17:15                   ` Alban Gruin
2021-01-10 20:51                     ` Junio C Hamano
2021-03-08 20:32                       ` Alban Gruin
2020-11-24 11:53           ` [PATCH v6 07/13] merge-resolve: rewrite in C Alban Gruin
2020-11-24 11:53           ` [PATCH v6 08/13] merge-recursive: move better_branch_name() to merge.c Alban Gruin
2021-01-05 16:19             ` Derrick Stolee
2020-11-24 11:53           ` [PATCH v6 09/13] merge-octopus: rewrite in C Alban Gruin
2021-01-05 16:40             ` Derrick Stolee
2020-11-24 11:53           ` [PATCH v6 10/13] merge: use the "resolve" strategy without forking Alban Gruin
2021-01-05 16:45             ` Derrick Stolee
2020-11-24 11:53           ` [PATCH v6 11/13] merge: use the "octopus" " Alban Gruin
2020-11-24 11:53           ` [PATCH v6 12/13] sequencer: use the "resolve" " Alban Gruin
2020-11-24 11:53           ` [PATCH v6 13/13] sequencer: use the "octopus" merge " Alban Gruin
2020-11-24 19:34           ` [PATCH v6 00/13] Rewrite the remaining merge strategies from shell to C SZEDER Gábor
2021-01-05 16:50           ` Derrick Stolee
2021-03-17 20:49           ` [PATCH v7 00/15] " Alban Gruin
2021-03-17 20:49             ` [PATCH v7 01/15] t6407: modernise tests Alban Gruin
2021-03-17 20:49             ` [PATCH v7 02/15] t6060: modify multiple files to expose a possible issue with merge-index Alban Gruin
2021-03-17 20:49             ` [PATCH v7 03/15] t6060: add tests for removed files Alban Gruin
2021-03-22 21:36               ` Johannes Schindelin
2021-03-23 20:43                 ` Alban Gruin
2021-03-17 20:49             ` [PATCH v7 04/15] merge-index: libify merge_one_path() and merge_all() Alban Gruin
2021-03-17 20:49             ` [PATCH v7 05/15] merge-index: drop the index Alban Gruin
2021-03-17 20:49             ` [PATCH v7 06/15] merge-index: add a new way to invoke `git-merge-one-file' Alban Gruin
2021-03-17 20:49             ` [PATCH v7 07/15] update-index: move add_cacheinfo() to read-cache.c Alban Gruin
2021-03-22 21:59               ` Johannes Schindelin
2021-03-23 20:45                 ` Alban Gruin
2021-03-17 20:49             ` [PATCH v7 08/15] merge-one-file: rewrite in C Alban Gruin
2021-03-22 22:20               ` Johannes Schindelin
2021-03-23 20:53                 ` Alban Gruin
2021-03-24  9:10                   ` Johannes Schindelin
2021-04-10 14:17                     ` Alban Gruin
2021-03-17 20:49             ` [PATCH v7 09/15] merge-resolve: " Alban Gruin
2021-03-23 22:21               ` Johannes Schindelin
2021-04-10 14:17                 ` Alban Gruin
2021-03-17 20:49             ` [PATCH v7 10/15] merge-recursive: move better_branch_name() to merge.c Alban Gruin
2021-03-17 20:49             ` [PATCH v7 11/15] merge-octopus: rewrite in C Alban Gruin
2021-03-23 23:58               ` Johannes Schindelin
2021-03-17 20:49             ` [PATCH v7 12/15] merge: use the "resolve" strategy without forking Alban Gruin
2021-03-17 20:49             ` [PATCH v7 13/15] merge: use the "octopus" " Alban Gruin
2021-03-17 20:49             ` [PATCH v7 14/15] sequencer: use the "resolve" " Alban Gruin
2021-03-17 20:49             ` [PATCH v7 15/15] sequencer: use the "octopus" merge " Alban Gruin
2022-08-09 18:54             ` [PATCH v8 00/14] Rewrite the remaining merge strategies from shell to C Alban Gruin
2022-08-09 18:54               ` [PATCH v8 01/14] t6060: modify multiple files to expose a possible issue with merge-index Alban Gruin
2022-08-09 18:54               ` [PATCH v8 02/14] t6060: add tests for removed files Alban Gruin
2022-08-09 18:54               ` [PATCH v8 03/14] merge-index: libify merge_one_path() and merge_all() Alban Gruin
2022-08-17  2:10                 ` Ævar Arnfjörð Bjarmason
2022-08-09 18:54               ` [PATCH v8 04/14] merge-index: drop the index Alban Gruin
2022-08-09 18:54               ` [PATCH v8 05/14] merge-index: add a new way to invoke `git-merge-one-file' Alban Gruin
2022-08-09 21:36                 ` Johannes Schindelin
2022-08-10 13:14                   ` Phillip Wood
2022-08-09 18:54               ` [PATCH v8 06/14] update-index: move add_cacheinfo() to read-cache.c Alban Gruin
2022-08-09 18:54               ` [PATCH v8 07/14] merge-one-file: rewrite in C Alban Gruin
2022-08-09 22:01                 ` Johannes Schindelin
2022-08-09 18:54               ` [PATCH v8 08/14] merge-resolve: " Alban Gruin
2022-08-10 15:03                 ` Phillip Wood
2022-08-10 21:20                   ` Junio C Hamano
2022-08-16 12:09                     ` Johannes Schindelin
2022-08-16 19:36                       ` Junio C Hamano
2022-08-17  9:42                         ` Johannes Schindelin
2022-08-17 19:06                           ` Elijah Newren
2022-08-17 19:18                             ` Junio C Hamano
2022-08-18 14:24                               ` Ævar Arnfjörð Bjarmason
2022-08-18 17:32                                 ` Junio C Hamano
2022-08-19  1:43                                 ` Elijah Newren
2022-08-19  2:45                                   ` Ævar Arnfjörð Bjarmason
2022-08-19  4:27                                     ` Elijah Newren
2022-08-17 19:12                           ` Junio C Hamano
2022-08-16 12:17                   ` Johannes Schindelin
2022-08-16 14:02                     ` Phillip Wood
2022-08-17  2:16                 ` Ævar Arnfjörð Bjarmason
2022-08-18 14:43                 ` Ævar Arnfjörð Bjarmason
2022-08-09 18:54               ` [PATCH v8 09/14] merge-recursive: move better_branch_name() to merge.c Alban Gruin
2022-08-09 18:54               ` [PATCH v8 10/14] merge-octopus: rewrite in C Alban Gruin
2022-08-09 18:54               ` [PATCH v8 11/14] merge: use the "resolve" strategy without forking Alban Gruin
2022-08-13 16:18                 ` Junio C Hamano
2022-08-09 18:54               ` [PATCH v8 12/14] merge: use the "octopus" " Alban Gruin
2022-08-09 18:54               ` [PATCH v8 13/14] sequencer: use the "resolve" " Alban Gruin
2022-08-09 18:54               ` [PATCH v8 14/14] sequencer: use the "octopus" " Alban Gruin
2022-11-18 11:18               ` Ævar Arnfjörð Bjarmason [this message]
2022-11-18 11:18                 ` [PATCH v9 01/12] merge-index doc & -h: fix padding, labels and "()" use Ævar Arnfjörð Bjarmason
2022-11-18 11:18                 ` [PATCH v9 02/12] t6060: modify multiple files to expose a possible issue with merge-index Ævar Arnfjörð Bjarmason
2022-11-18 11:18                 ` [PATCH v9 03/12] t6060: add tests for removed files Ævar Arnfjörð Bjarmason
2022-11-18 11:18                 ` [PATCH v9 04/12] merge-index tests: add usage tests Ævar Arnfjörð Bjarmason
2022-11-18 11:18                 ` [PATCH v9 05/12] merge-index: migrate to parse_options() API Ævar Arnfjörð Bjarmason
2022-11-18 11:18                 ` [PATCH v9 06/12] merge-index: improve die() error messages Ævar Arnfjörð Bjarmason
2022-11-18 11:18                 ` [PATCH v9 07/12] merge-index i18n: mark die() messages for translation Ævar Arnfjörð Bjarmason
2022-11-18 11:18                 ` [PATCH v9 08/12] merge-index: stop calling ensure_full_index() twice Ævar Arnfjörð Bjarmason
2022-11-18 11:18                 ` [PATCH v9 09/12] builtin/merge-index.c: don't USE_THE_INDEX_COMPATIBILITY_MACROS Ævar Arnfjörð Bjarmason
2022-11-18 11:18                 ` [PATCH v9 10/12] merge-index: libify merge_one_path() and merge_all() Ævar Arnfjörð Bjarmason
2022-11-18 11:18                 ` [PATCH v9 11/12] merge-index: use "struct strvec" and helper to prepare args Ævar Arnfjörð Bjarmason
2022-11-18 11:18                 ` [PATCH v9 12/12] merge-index: make the argument parsing sensible & simpler Ævar Arnfjörð Bjarmason
2022-11-18 23:30                 ` [PATCH v9 00/12] merge-index: prepare to rewrite merge drivers in C Taylor Blau
2022-11-19 12:46                   ` Ævar Arnfjörð Bjarmason
2022-12-15  8:52                 ` [PATCH v10 " Ævar Arnfjörð Bjarmason
2022-12-15  8:52                   ` [PATCH v10 01/12] merge-index doc & -h: fix padding, labels and "()" use Ævar Arnfjörð Bjarmason
2022-12-15  8:52                   ` [PATCH v10 02/12] t6060: modify multiple files to expose a possible issue with merge-index Ævar Arnfjörð Bjarmason
2022-12-15  8:52                   ` [PATCH v10 03/12] t6060: add tests for removed files Ævar Arnfjörð Bjarmason
2022-12-15  8:52                   ` [PATCH v10 04/12] merge-index tests: add usage tests Ævar Arnfjörð Bjarmason
2022-12-15  8:52                   ` [PATCH v10 05/12] merge-index: migrate to parse_options() API Ævar Arnfjörð Bjarmason
2022-12-15  8:52                   ` [PATCH v10 06/12] merge-index: improve die() error messages Ævar Arnfjörð Bjarmason
2022-12-15  8:52                   ` [PATCH v10 07/12] merge-index i18n: mark die() messages for translation Ævar Arnfjörð Bjarmason
2022-12-15  8:52                   ` [PATCH v10 08/12] merge-index: stop calling ensure_full_index() twice Ævar Arnfjörð Bjarmason
2022-12-15  8:52                   ` [PATCH v10 09/12] builtin/merge-index.c: don't USE_THE_INDEX_VARIABLE Ævar Arnfjörð Bjarmason
2022-12-15  8:52                   ` [PATCH v10 10/12] merge-index: libify merge_one_path() and merge_all() Ævar Arnfjörð Bjarmason
2022-12-15  8:52                   ` [PATCH v10 11/12] merge-index: use "struct strvec" and helper to prepare args Ævar Arnfjörð Bjarmason
2022-12-15  8:52                   ` [PATCH v10 12/12] merge-index: make the argument parsing sensible & simpler Ævar Arnfjörð Bjarmason

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=cover-v9-00.12-00000000000-20221118T110058Z-avarab@gmail.com \
    --to=avarab@gmail.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=alban.gruin@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=me@ttaylorr.com \
    --cc=newren@gmail.com \
    --cc=phillip.wood123@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).