git@vger.kernel.org list mirror (unofficial, one of many)
 help / color / mirror / code / Atom feed
From: Alban Gruin <alban.gruin@gmail.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org, phillip.wood@dunelm.org.uk
Subject: Re: [PATCH v2 02/11] merge-one-file: rewrite in C
Date: Wed, 2 Sep 2020 16:50:57 +0200	[thread overview]
Message-ID: <bb2cc3e0-b84e-7814-9898-c6f697f2a72b@gmail.com> (raw)
In-Reply-To: <xmqqk0xdcim6.fsf@gitster.c.googlers.com>

Hi Junio,

Le 01/09/2020 à 23:06, Junio C Hamano a écrit :
> Alban Gruin <alban.gruin@gmail.com> writes:
> 
>> diff --git a/builtin/merge-one-file.c b/builtin/merge-one-file.c
>> new file mode 100644
>> index 0000000000..306a86c2f0
>> --- /dev/null
>> +++ b/builtin/merge-one-file.c
>> @@ -0,0 +1,85 @@
>> +/*
>> + * Builtin "git merge-one-file"
>> + *
>> + * Copyright (c) 2020 Alban Gruin
>> + *
>> + * Based on git-merge-one-file.sh, written by Linus Torvalds.
>> + *
>> + * This is the git per-file merge utility, called with
>> + *
>> + *   argv[1] - original file SHA1 (or empty)
>> + *   argv[2] - file in branch1 SHA1 (or empty)
>> + *   argv[3] - file in branch2 SHA1 (or empty)
>> + *   argv[4] - pathname in repository
>> + *   argv[5] - original file mode (or empty)
>> + *   argv[6] - file in branch1 mode (or empty)
>> + *   argv[7] - file in branch2 mode (or empty)
>> + *
>> + * Handle some trivial cases. The _really_ trivial cases have been
>> + * handled already by git read-tree, but that one doesn't do any merges
>> + * that might change the tree layout.
>> + */
>> +
>> +#include "cache.h"
>> +#include "builtin.h"
>> +#include "lockfile.h"
>> +#include "merge-strategies.h"
>> +
>> +static const char builtin_merge_one_file_usage[] =
>> +	"git merge-one-file <orig blob> <our blob> <their blob> <path> "
>> +	"<orig mode> <our mode> <their mode>\n\n"
>> +	"Blob ids and modes should be empty for missing files.";
>> +
>> +int cmd_merge_one_file(int argc, const char **argv, const char *prefix)
>> +{
>> +	struct object_id orig_blob, our_blob, their_blob,
>> +		*p_orig_blob = NULL, *p_our_blob = NULL, *p_their_blob = NULL;
>> +	unsigned int orig_mode = 0, our_mode = 0, their_mode = 0, ret = 0;
>> +	struct lock_file lock = LOCK_INIT;
>> +
>> +	if (argc != 8)
>> +		usage(builtin_merge_one_file_usage);
>> +
>> +	if (repo_read_index(the_repository) < 0)
>> +		die("invalid index");
>> +
>> +	repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR);
> 
> I do understand why we would want merge_strategies_one_file() helper
> introduced by this step so that the helper can work in an arbitrary
> repository (hence taking a pointer to repository structure as one of
> its parameters).
> 
> But the "merge-one-file" command will always work in the_repository.
> I do not see a point in using helpers that can work in an arbitrary
> repository, like repo_read_index() or repo_hold_locked_index(), in
> the above.  I only see downsides --- it is longer to read, makes
> readers wonder if there is something tricky involving another
> repository going on, etc.
> 

I was under the impression that using the_index is just deprecated, and
that we ought to avoid using it, even in builtins.

Will update that.

>> +	if (!get_oid(argv[1], &orig_blob)) {
>> +		p_orig_blob = &orig_blob;
>> +		orig_mode = strtol(argv[5], NULL, 8);
> 
> Write a wrapper around strtol(...,...,8) to reduce repetition, and
> make sure you do not pass NULL as the second parameter to strtol()
> to always check you parsed the string to the end.
> 
>> +	ret = merge_strategies_one_file(the_repository,
>> +					p_orig_blob, p_our_blob, p_their_blob, argv[4],
>> +					orig_mode, our_mode, their_mode);
> 
> Here, as I said above, it is perfectly fine to pass
> the_repository().
> 
>> +	if (ret) {
>> +		rollback_lock_file(&lock);
>> +		return ret;
>> +	}
>> +
>> +	return write_locked_index(the_repository->index, &lock, COMMIT_LOCK);
> 
> Likewise, I do not see much point in saying the_repository->index; the_index
> is a perfectly fine short-hand.
> 
> -%<-
>> +static int do_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)
>> +{
>> +	int ret, i, dest;
>> +	mmbuffer_t result = {NULL, 0};
>> +	mmfile_t mmfs[3];
>> +	struct ll_merge_options merge_opts = {0};
>> +	struct cache_entry *ce;
>> +
>> +	if (our_mode == S_IFLNK || their_mode == S_IFLNK)
>> +		return error(_("%s: Not merging symbolic link changes."), path);
>> +	else if (our_mode == S_IFGITLINK || their_mode == S_IFGITLINK)
>> +		return error(_("%s: Not merging conflicting submodule changes."), path);
>> +
>> +	read_mmblob(mmfs + 1, our_blob);
>> +	read_mmblob(mmfs + 2, their_blob);
>> +
>> +	if (orig_blob) {
>> +		printf(_("Auto-merging %s\n"), path);
>> +		read_mmblob(mmfs + 0, orig_blob);
>> +	} else {
>> +		printf(_("Added %s in both, but differently.\n"), path);
>> +		read_mmblob(mmfs + 0, &null_oid);
>> +	}
>> +
>> +	merge_opts.xdl_opts = XDL_MERGE_ZEALOUS_ALNUM;
>> +	ret = ll_merge(&result, path,
>> +		       mmfs + 0, "orig",
>> +		       mmfs + 1, "our",
>> +		       mmfs + 2, "their",
>> +		       istate, &merge_opts);
>> +
>> +	for (i = 0; i < 3; i++)
>> +		free(mmfs[i].ptr);
>> +
>> +	if (ret > 127 || !orig_blob)
>> +		ret = error(_("content conflict in %s"), path);
> 
> The original only checked if ret is zero or non-zero; here we
> require ret to be large.  Intended?  
> 
> ll_merge() that called ll_xdl_merge() (i.e. the most common case)
> would return the value returned from xdl_merge(), which can be -1
> when we got an error before calling xdl_do_merge().  xdl_do_merge()
> in turn can return -1.  The most common case returns the value
> returned from xdl_cleanup_merge(), which is 0 for clean merge, and
> any positive integer (not clipped to 127 or 128) for conflicted one.
> 

Huh, not sure why I did this, and I'm puzzled that it did not broke
anything.

>> +	/* Create the working tree file, using "our tree" version from
>> +	   the index, and then store the result of the merge. */
> 
> Style. (cf. Documentation/CodingGuidelines).
> 
>> +	ce = index_file_exists(istate, path, strlen(path), 0);
>> +	if (!ce)
>> +		BUG("file is not present in the cache?");
>> +
>> +	unlink(path);
>> +	dest = open(path, O_WRONLY | O_CREAT, ce->ce_mode);
>> +	write_in_full(dest, result.ptr, result.size);
> 
> If open() fails, we write to a bogus file descriptor here.
> 
>> +	close(dest);
>> +
>> +	free(result.ptr);
>> +
>> +	if (ret && our_mode != their_mode)
>> +		return error(_("permission conflict: %o->%o,%o in %s"),
>> +			     orig_mode, our_mode, their_mode, path);
>> +	if (ret)
>> +		return 1;
> 
> What is the error returning convention around here?  Our usual
> convention is that 0 signals a success, and negative reports an
> error.  Returning the value returned from add_file_to_index() below,
> and error() above, are consistent with the convention, but this one
> returns 1 that is not.  When deviating from convention, it needs to
> be documented for the callers in a comment before the function
> definition.
> 

I stayed to close to the shell script on this one…

Note that this is not the case for "resolve" and "octopus", they use the
convention for merge backends, documented in builtin/merge.c:

> 		/*
> 		 * The backend exits with 1 when conflicts are
> 		 * left to be resolved, with 2 when it does not
> 		 * handle the given merge at all.
> 		 */

(In practice, it looks like any non-zero value lower than 2 indicates a
merge conflict, any value greater or equal to 2 is a general failure.)

>> +
>> +	return add_file_to_index(istate, path, 0);
>> +}
> 
> 
> 
>> +int merge_strategies_one_file(struct repository *r,
>> +			      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)
>> +{
>> +	if (orig_blob &&
>> +	    ((!their_blob && our_blob && oideq(orig_blob, our_blob)) ||
>> +	     (!our_blob && their_blob && oideq(orig_blob, their_blob))))
>> +		/* Deleted in both or deleted in one and unchanged in
>> +		   the other */
>> +		return merge_one_file_deleted(r->index,
>> +					      orig_blob, our_blob, their_blob, path,
>> +					      orig_mode, our_mode, their_mode);
>> +	else if (!orig_blob && our_blob && !their_blob) {
>> +		/* Added in one.  The other side did not add and we
>> +		   added so there is nothing to be done, except making
>> +		   the path merged. */
>> +		return add_to_index_cacheinfo(r->index, our_mode, our_blob, path);
>> +	} else if (!orig_blob && !our_blob && their_blob) {
>> +		printf(_("Adding %s\n"), path);
>> +
>> +		if (file_exists(path))
>> +			return error(_("untracked %s is overwritten by the merge."), path);
>> +
>> +		if (add_to_index_cacheinfo(r->index, their_mode, their_blob, path))
>> +			return 1;
>> +		return checkout_from_index(r->index, path);
>> +	} else if (!orig_blob && our_blob && their_blob &&
>> +		   oideq(our_blob, their_blob)) {
>> +		/* Added in both, identically (check for same
>> +		   permissions). */
>> +		if (our_mode != their_mode)
>> +			return error(_("File %s added identically in both branches, "
>> +				       "but permissions conflict %o->%o."),
>> +				     path, our_mode, their_mode);
>> +
>> +		printf(_("Adding %s\n"), path);
>> +
>> +		if (add_to_index_cacheinfo(r->index, our_mode, our_blob, path))
>> +			return 1;
>> +		return checkout_from_index(r->index, path);
>> +	} else if (our_blob && their_blob)
>> +		/* Modified in both, but differently. */
>> +		return do_merge_one_file(r->index,
>> +					 orig_blob, our_blob, their_blob, path,
>> +					 orig_mode, our_mode, their_mode);
>> +	else {
>> +		char *orig_hex = "", *our_hex = "", *their_hex = "";
>> +
>> +		if (orig_blob)
>> +			orig_hex = oid_to_hex(orig_blob);
>> +		if (our_blob)
>> +			our_hex = oid_to_hex(our_blob);
>> +		if (their_blob)
>> +			their_hex = oid_to_hex(their_blob);
> 
> Prepare three char [] buffers and use oid_to_hex_r() instead,
> instead of relying that we'd have sufficient number of entries in
> the rotating buffer.
> 
>> +		return error(_("%s: Not handling case %s -> %s -> %s"),
>> +			     path, orig_hex, our_hex, their_hex);
>> +	}
>> +
>> +	return 0;
>> +}
>> diff --git a/merge-strategies.h b/merge-strategies.h
>> new file mode 100644
>> index 0000000000..b527d145c7
>> --- /dev/null
>> +++ b/merge-strategies.h
>> @@ -0,0 +1,13 @@
>> +#ifndef MERGE_STRATEGIES_H
>> +#define MERGE_STRATEGIES_H
>> +
>> +#include "object.h"
>> +
>> +int merge_strategies_one_file(struct repository *r,
>> +			      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);
>> +
>> +#endif /* MERGE_STRATEGIES_H */
>> diff --git a/t/t6415-merge-dir-to-symlink.sh b/t/t6415-merge-dir-to-symlink.sh
>> index 2eddcc7664..5fb74e39a0 100755
>> --- a/t/t6415-merge-dir-to-symlink.sh
>> +++ b/t/t6415-merge-dir-to-symlink.sh
>> @@ -94,7 +94,7 @@ test_expect_success SYMLINKS 'a/b was resolved as symlink' '
>>  	test -h a/b
>>  '
>>  
>> -test_expect_failure 'do not lose untracked in merge (resolve)' '
>> +test_expect_success 'do not lose untracked in merge (resolve)' '
>>  	git reset --hard &&
>>  	git checkout baseline^0 &&
>>  	>a/b/c/e &&


  reply	other threads:[~2020-09-02 14:51 UTC|newest]

Thread overview: 156+ 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 [this message]
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

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=bb2cc3e0-b84e-7814-9898-c6f697f2a72b@gmail.com \
    --to=alban.gruin@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=phillip.wood@dunelm.org.uk \
    --subject='Re: [PATCH v2 02/11] merge-one-file: rewrite in C' \
    /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

Code repositories for project(s) associated with this 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).