Git Mailing List Archive mirror
 help / color / mirror / Atom feed
From: Christian Couder <christian.couder@gmail.com>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
	Patrick Steinhardt <ps@pks.im>,
	Johannes Schindelin <Johannes.Schindelin@gmx.de>,
	Elijah Newren <newren@gmail.com>, John Cai <johncai86@gmail.com>,
	Christian Couder <chriscool@tuxfamily.org>
Subject: [PATCH 13/14] replay: add different modes
Date: Fri,  7 Apr 2023 09:24:14 +0200	[thread overview]
Message-ID: <20230407072415.1360068-14-christian.couder@gmail.com> (raw)
In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com>

From: Elijah Newren <newren@gmail.com>

There is already a 'rebase' mode with `--onto`. Let's add an 'advance' or
'cherry-pick' mode with `--advance`. This new mode will make the target
branch advance as we replay commits onto it.

While at it, let's also add a `--contained` that can be used along with
`--onto` to rebase all the branches contained in the <revision-range>
argument.

Co-authored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 Documentation/git-replay.txt |  58 +++++++++--
 builtin/replay.c             | 185 +++++++++++++++++++++++++++++------
 t/t3650-replay-basics.sh     |  45 +++++++++
 3 files changed, 247 insertions(+), 41 deletions(-)

diff --git a/Documentation/git-replay.txt b/Documentation/git-replay.txt
index ce2cafc42e..d714c72188 100644
--- a/Documentation/git-replay.txt
+++ b/Documentation/git-replay.txt
@@ -9,7 +9,7 @@ git-replay - Replay commits on a different base, without touching working tree
 SYNOPSIS
 --------
 [verse]
-'git replay' [--onto <newbase>] <revision-range>...
+'git replay' [--contained] [--onto <newbase> | --advance <branch>] <revision-range>...
 
 DESCRIPTION
 -----------
@@ -20,11 +20,12 @@ references.  However, the output of this command is meant to be used
 as input to `git update-ref --stdin`, which would update the relevant
 branches.
 
-When the `--onto <newbase>` option is not passed, the commits will be
-replayed onto a base guessed from the `<revision-range>`.  For example
-if the `<revision-range>` is `origin/main..mybranch` then `mybranch`
-was probably based on an old version of `origin/main`, so we will
-replay it on the newest version of that branch.
+When neither the `--onto <newbase>` option nor the
+`--advance <branch>` option are passed, the commits will be replayed
+onto a base guessed from the `<revision-range>`.  For example if the
+`<revision-range>` is `origin/main..mybranch` then `mybranch` was
+probably based on an old version of `origin/main`, so we will replay
+it on the newest version of that branch.
 
 OPTIONS
 -------
@@ -33,9 +34,17 @@ OPTIONS
 	Starting point at which to create the new commits.  May be any
 	valid commit, and not just an existing branch name.
 +
-The update-ref commands in the output will update the branch(es)
-in the revision range to point at the new commits (in other
-words, this mimics a rebase operation).
+When `--onto` is specified, the update-ref command(s) in the output will
+update the branch(es) in the revision range to point at the new
+commits (in other words, this mimics a rebase operation).
+
+--advance <branch>::
+	Starting point at which to create the new commits; must be a
+	branch name.
++
+When `--advance` is specified, the update-ref command(s) in the output
+will update the branch passed as an argument to `--advance` to point at
+the new commits (in other words, this mimics a cherry-pick operation).
 
 <revision-range>::
 	Range of commits to replay; see "Specifying Ranges" in
@@ -51,7 +60,10 @@ input to `git update-ref --stdin`.  It is basically of the form:
 	update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH}
 	update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH}
 
-where the number of refs updated depend on the arguments passed.
+where the number of refs updated depend on the arguments passed.  When
+using `--advance`, the number of refs updated is always one, but for
+`--onto`, it can be one or more (rebasing multiple branches
+simultaneously is supported).
 
 EXIT STATUS
 -----------
@@ -71,6 +83,32 @@ $ git replay --onto target origin/main..mybranch
 update refs/heads/mybranch ${NEW_mybranch_HASH} ${OLD_mybranch_HASH}
 ------------
 
+To cherry-pick the commits from mybranch onto target:
+
+------------
+$ git replay --advance target origin/main..mybranch
+update refs/heads/target ${NEW_target_HASH} ${OLD_target_HASH}
+------------
+
+Note that the first two examples replay the exact same commits and on
+top of the exact same new base, they only differ in that the first
+provides instructions to make mybranch point at the new commits and
+the second provides instructions to make target point at them.
+
+What if you have a stack of branches, one depending upon another, and
+you'd really like to rebase the whole set?
+
+------------
+$ git replay --contained --onto origin/main origin/main..tipbranch
+update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH}
+update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH}
+update refs/heads/tipbranch ${NEW_tipbranch_HASH} ${OLD_tipbranch_HASH}
+------------
+
+In contrast, trying to do this with rebase would require 3 separate
+rebases, eacho of which involves a different <ONTO> and <UPSTREAM> and
+forces you to first check out each branch in turn.
+
 When calling `git replay`, one does not need to specify a range of
 commits to replay using the syntax `A..B`; any range expression will
 do:
diff --git a/builtin/replay.c b/builtin/replay.c
index af948af73c..63b3ad518e 100644
--- a/builtin/replay.c
+++ b/builtin/replay.c
@@ -12,6 +12,7 @@
 #include "parse-options.h"
 #include "refs.h"
 #include "revision.h"
+#include "strmap.h"
 
 static const char *short_commit_name(struct commit *commit)
 {
@@ -75,10 +76,24 @@ static struct commit *create_commit(struct tree *tree,
 	return (struct commit *)obj;
 }
 
-static struct commit *guess_new_base(struct rev_cmdline_info *info)
+struct ref_info {
+	struct commit *onto;
+	struct strset positive_refs;
+	struct strset negative_refs;
+	int positive_refexprs;
+	int negative_refexprs;
+};
+
+static void get_ref_information(struct rev_cmdline_info *cmd_info,
+				struct ref_info *ref_info)
 {
-	struct commit *new_base = NULL;
-	int i, bottom_commits = 0;
+	int i;
+
+	ref_info->onto = NULL;
+	strset_init(&ref_info->positive_refs);
+	strset_init(&ref_info->negative_refs);
+	ref_info->positive_refexprs = 0;
+	ref_info->negative_refexprs = 0;
 
 	/*
 	 * When the user specifies e.g.
@@ -95,32 +110,110 @@ static struct commit *guess_new_base(struct rev_cmdline_info *info)
 	 * the second because they'd likely just be replaying commits on top
 	 * of the same commit and not making any difference.
 	 */
-	for (i = 0; i < info->nr; i++) {
-		struct rev_cmdline_entry *e = info->rev + i;
+	for (i = 0; i < cmd_info->nr; i++) {
+		struct rev_cmdline_entry *e = cmd_info->rev + i;
 		struct object_id oid;
+		const char *refexpr = e->name;
 		char *fullname = NULL;
+		int can_uniquely_dwim = 1;
+
+		if (*refexpr == '^')
+			refexpr++;
+		if (dwim_ref(refexpr, strlen(refexpr), &oid, &fullname, 0) != 1)
+			can_uniquely_dwim = 0;
+
+		if (e->flags & BOTTOM) {
+			if (can_uniquely_dwim)
+				strset_add(&ref_info->negative_refs, fullname);
+			if (!ref_info->negative_refexprs)
+				ref_info->onto = lookup_commit_reference_gently(the_repository,
+										&e->item->oid, 1);
+			ref_info->negative_refexprs++;
+		} else {
+			if (can_uniquely_dwim)
+				strset_add(&ref_info->positive_refs, fullname);
+			ref_info->positive_refexprs++;
+		}
 
-		if (!(e->flags & BOTTOM))
-			continue;
+		free(fullname);
+	}
+}
 
+static void determine_replay_mode(struct rev_cmdline_info *cmd_info,
+				  const char *onto_name,
+				  const char **advance_name,
+				  struct commit **onto,
+				  struct strset **update_refs)
+{
+	struct ref_info rinfo;
+
+	get_ref_information(cmd_info, &rinfo);
+	if (!rinfo.positive_refexprs)
+		die(_("need some commits to replay"));
+	if (onto_name && *advance_name)
+		die(_("--onto and --advance are incompatible"));
+	else if (onto_name) {
+		*onto = peel_committish(onto_name);
+		if (rinfo.positive_refexprs <
+		    strset_get_size(&rinfo.positive_refs))
+			die(_("all positive revisions given must be references"));
+	} else if (*advance_name) {
+		struct object_id oid;
+		char *fullname = NULL;
+
+		*onto = peel_committish(*advance_name);
+		if (dwim_ref(*advance_name, strlen(*advance_name),
+			     &oid, &fullname, 0) == 1) {
+			*advance_name = fullname;
+		} else {
+			die(_("argument to --advance must be a reference"));
+		}
+		if (rinfo.positive_refexprs > 1)
+			die(_("cannot advance target with multiple source branches because ordering would be ill-defined"));
+	} else {
+		int positive_refs_complete = (
+			rinfo.positive_refexprs ==
+			strset_get_size(&rinfo.positive_refs));
+		int negative_refs_complete = (
+			rinfo.negative_refexprs ==
+			strset_get_size(&rinfo.negative_refs));
 		/*
-		 * We need a unique base commit to know where to replay; error
-		 * out if not unique.
-		 *
-		 * Also, we usually don't want to replay commits on the same
-		 * base they started on, so only accept this as the base if
-		 * it uniquely names some ref.
+		 * We need either positive_refs_complete or
+		 * negative_refs_complete, but not both.
 		 */
-		if (bottom_commits++ ||
-		    dwim_ref(e->name, strlen(e->name), &oid, &fullname, 0) != 1)
-			die(_("cannot determine where to replay commits; please specify --onto"));
-
-		free(fullname);
-		new_base = lookup_commit_reference_gently(the_repository,
-							  &e->item->oid, 1);
+		if (rinfo.negative_refexprs > 0 &&
+		    positive_refs_complete == negative_refs_complete)
+			die(_("cannot implicitly determine whether this is an --advance or --onto operation"));
+		if (negative_refs_complete) {
+			struct hashmap_iter iter;
+			struct strmap_entry *entry;
+
+			if (rinfo.negative_refexprs == 0)
+				die(_("all positive revisions given must be references"));
+			else if (rinfo.negative_refexprs > 1)
+				die(_("cannot implicitly determine whether this is an --advance or --onto operation"));
+			else if (rinfo.positive_refexprs > 1)
+				die(_("cannot advance target with multiple source branches because ordering would be ill-defined"));
+
+			/* Only one entry, but we have to loop to get it */
+			strset_for_each_entry(&rinfo.negative_refs,
+					      &iter, entry) {
+				*advance_name = entry->key;
+			}
+		} else { /* positive_refs_complete */
+			if (rinfo.negative_refexprs > 1)
+				die(_("cannot implicitly determine correct base for --onto"));
+			if (rinfo.negative_refexprs == 1)
+				*onto = rinfo.onto;
+		}
 	}
-
-	return new_base;
+	if (!*advance_name) {
+		*update_refs = xcalloc(1, sizeof(**update_refs));
+		**update_refs = rinfo.positive_refs;
+		memset(&rinfo.positive_refs, 0, sizeof(**update_refs));
+	}
+	strset_clear(&rinfo.negative_refs);
+	strset_clear(&rinfo.positive_refs);
 }
 
 static struct commit *pick_regular_commit(struct commit *pickme,
@@ -155,29 +248,41 @@ static struct commit *pick_regular_commit(struct commit *pickme,
 
 int cmd_replay(int argc, const char **argv, const char *prefix)
 {
-	struct commit *onto;
+	const char *advance_name = NULL;
+	struct commit *onto = NULL;
 	const char *onto_name = NULL;
-	struct commit *last_commit = NULL;
+	int contained = 0;
+
 	struct rev_info revs;
+	struct commit *last_commit = NULL;
 	struct commit *commit;
 	struct merge_options merge_opt;
 	struct merge_result result;
+	struct strset *update_refs = NULL;
 	int ret = 0;
 
 	const char * const replay_usage[] = {
-		N_("git replay [--onto <newbase>] <revision-range>..."),
+		N_("git replay [--contained] [--onto <newbase> | --advance <branch>] <revision-range>..."),
 		NULL
 	};
 	struct option replay_options[] = {
+		OPT_STRING(0, "advance", &advance_name,
+			   N_("branch"),
+			   N_("make replay advance given branch")),
 		OPT_STRING(0, "onto", &onto_name,
 			   N_("revision"),
 			   N_("replay onto given commit")),
+		OPT_BOOL(0, "contained", &contained,
+			 N_("advance all branches contained in revision-range")),
 		OPT_END()
 	};
 
 	argc = parse_options(argc, argv, prefix, replay_options, replay_usage,
 			     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT);
 
+	if (advance_name && contained)
+		die(_("options '%s' and '%s' cannot be used together"),
+		    "--advance", "--contained");
 
 	repo_init_revisions(the_repository, &revs, prefix);
 
@@ -193,10 +298,11 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
 	revs.topo_order = 1;
 	revs.simplify_history = 0;
 
-	if (onto_name)
-		onto = peel_committish(onto_name);
-	else
-		onto = guess_new_base(&revs.cmdline);
+	determine_replay_mode(&revs.cmdline, onto_name, &advance_name,
+			      &onto, &update_refs);
+
+	if (!onto) /* FIXME: Should handle replaying down to root commit */
+		die("Replaying down to root commit is not supported yet!");
 
 	if (prepare_revision_walk(&revs) < 0) {
 		ret = error(_("error preparing revisions"));
@@ -206,6 +312,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
 	init_merge_options(&merge_opt, the_repository);
 	memset(&result, 0, sizeof(result));
 	merge_opt.show_rename_progress = 0;
+
 	result.tree = get_commit_tree(onto);
 	last_commit = onto;
 	while ((commit = get_revision(&revs))) {
@@ -243,12 +350,16 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
 			    oid_to_hex(&commit->object.oid));
 		}
 
+		/* Update any necessary branches */
+		if (advance_name)
+			continue;
 		decoration = get_name_decoration(&commit->object);
 		if (!decoration)
 			continue;
-
 		while (decoration) {
-			if (decoration->type == DECORATION_REF_LOCAL) {
+			if (decoration->type == DECORATION_REF_LOCAL &&
+			    (contained || strset_contains(update_refs,
+							  decoration->name))) {
 				printf("update %s %s %s\n",
 				       decoration->name,
 				       oid_to_hex(&last_commit->object.oid),
@@ -258,11 +369,23 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
 		}
 	}
 
+	/* In --advance mode, advance the target ref */
+	if (result.clean == 1 && advance_name) {
+		printf("update %s %s %s\n",
+		       advance_name,
+		       oid_to_hex(&last_commit->object.oid),
+		       oid_to_hex(&onto->object.oid));
+	}
+
 	/* Cleanup */
 	merge_finalize(&merge_opt, &result);
 	ret = result.clean;
 
 cleanup:
+	if (update_refs) {
+		strset_clear(update_refs);
+		free(update_refs);
+	}
 	release_revisions(&revs);
 
 	/* Return */
diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh
index f55b71763a..976032ad18 100755
--- a/t/t3650-replay-basics.sh
+++ b/t/t3650-replay-basics.sh
@@ -60,4 +60,49 @@ test_expect_success 'using replay to rebase two branches, one on top of other' '
 	test_cmp expect result
 '
 
+test_expect_success 'using replay to perform basic cherry-pick' '
+	# The differences between this test and the last one are:
+	#   --advance vs --onto
+	# 2nd field of result is refs/heads/main vs. refs/heads/topic2
+	# 4th field of result is hash for main instead of hash for topic2
+
+	git replay --advance main topic1..topic2 >result &&
+
+	test_line_count = 1 result &&
+
+	git log --format=%s $(cut -f 3 -d " " result) >actual &&
+	test_write_lines E D M L B A >expect &&
+	test_cmp expect actual &&
+
+	printf "update refs/heads/main " >expect &&
+	printf "%s " $(cut -f 3 -d " " result) >>expect &&
+	git rev-parse main >>expect &&
+
+	test_cmp expect result
+'
+
+test_expect_success 'using replay to also rebase a contained branch' '
+	git replay --contained --onto main main..topic3 >result &&
+
+	test_line_count = 2 result &&
+	cut -f 3 -d " " result >new-branch-tips &&
+
+	git log --format=%s $(head -n 1 new-branch-tips) >actual &&
+	test_write_lines F C M L B A >expect &&
+	test_cmp expect actual &&
+
+	git log --format=%s $(tail -n 1 new-branch-tips) >actual &&
+	test_write_lines H G F C M L B A >expect &&
+	test_cmp expect actual &&
+
+	printf "update refs/heads/topic1 " >expect &&
+	printf "%s " $(head -n 1 new-branch-tips) >>expect &&
+	git rev-parse topic1 >>expect &&
+	printf "update refs/heads/topic3 " >>expect &&
+	printf "%s " $(tail -n 1 new-branch-tips) >>expect &&
+	git rev-parse topic3 >>expect &&
+
+	test_cmp expect result
+'
+
 test_done
-- 
2.40.0.228.gb2eb5bb98e


  parent reply	other threads:[~2023-04-07  7:25 UTC|newest]

Thread overview: 208+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-07  7:24 [PATCH 00/14] Introduce new `git replay` command Christian Couder
2023-04-07  7:24 ` [PATCH 01/14] replay: introduce new builtin Christian Couder
2023-04-07  7:24 ` [PATCH 02/14] replay: start using parse_options API Christian Couder
2023-04-07  7:24 ` [PATCH 03/14] replay: die() instead of failing assert() Christian Couder
2023-04-07  7:24 ` [PATCH 04/14] replay: introduce pick_regular_commit() Christian Couder
2023-04-07  7:24 ` [PATCH 05/14] replay: don't simplify history Christian Couder
2023-04-07  7:24 ` [PATCH 06/14] replay: add an important FIXME comment about gpg signing Christian Couder
2023-04-07  7:24 ` [PATCH 07/14] replay: remove progress and info output Christian Couder
2023-04-07  7:24 ` [PATCH 08/14] replay: remove HEAD related sanity check Christian Couder
2023-04-07  7:24 ` [PATCH 09/14] replay: very coarse worktree updating Christian Couder
2023-04-07  7:24 ` [PATCH 10/14] replay: make it a minimal server side command Christian Couder
2023-04-07  7:24 ` [PATCH 11/14] replay: use standard revision ranges Christian Couder
2023-04-14 14:09   ` Derrick Stolee
2023-04-14 14:23     ` Derrick Stolee
2023-04-15 19:07       ` Elijah Newren
2023-04-16  5:28         ` Elijah Newren
2023-04-17 14:05         ` Derrick Stolee
2023-04-18  5:54           ` Elijah Newren
2023-04-18 13:10             ` Derrick Stolee
2023-04-20  4:53               ` Elijah Newren
2023-04-20 13:44                 ` Derrick Stolee
2023-04-23  1:18                   ` Elijah Newren
2023-04-24 15:23                     ` Derrick Stolee
2023-04-30  6:45                       ` Elijah Newren
2023-09-03 15:47                         ` Johannes Schindelin
2023-09-07  8:39                           ` Christian Couder
2023-09-07 10:22                             ` Johannes Schindelin
2023-04-17 15:45         ` Junio C Hamano
2023-04-18  5:58           ` Elijah Newren
2023-04-18  4:58       ` Elijah Newren
2023-04-15 18:30     ` Elijah Newren
2023-04-07  7:24 ` [PATCH 12/14] replay: introduce guess_new_base() Christian Couder
2023-04-07  7:24 ` Christian Couder [this message]
2023-04-07  7:24 ` [PATCH 14/14] replay: stop assuming replayed branches do not diverge Christian Couder
2023-04-14 10:12 ` [PATCH 00/14] Introduce new `git replay` command Phillip Wood
2023-04-15 17:18   ` Elijah Newren
2023-04-14 17:39 ` Felipe Contreras
2023-04-15  6:44 ` Elijah Newren
2023-05-09 17:53 ` [PATCH v2 00/15] " Christian Couder
2023-05-09 17:53   ` [PATCH v2 01/15] t6429: remove switching aspects of fast-rebase Christian Couder
2023-05-09 17:53   ` [PATCH v2 02/15] replay: introduce new builtin Christian Couder
2023-05-09 17:53   ` [PATCH v2 03/15] replay: start using parse_options API Christian Couder
2023-05-09 17:53   ` [PATCH v2 04/15] replay: die() instead of failing assert() Christian Couder
2023-05-09 17:53   ` [PATCH v2 05/15] replay: introduce pick_regular_commit() Christian Couder
2023-05-09 17:53   ` [PATCH v2 06/15] replay: don't simplify history Christian Couder
2023-05-09 17:53   ` [PATCH v2 07/15] replay: add an important FIXME comment about gpg signing Christian Couder
2023-05-09 17:53   ` [PATCH v2 08/15] replay: remove progress and info output Christian Couder
2023-05-09 17:53   ` [PATCH v2 09/15] replay: remove HEAD related sanity check Christian Couder
2023-05-09 17:53   ` [PATCH v2 10/15] replay: make it a minimal server side command Christian Couder
2023-05-09 17:53   ` [PATCH v2 11/15] replay: use standard revision ranges Christian Couder
2023-05-09 17:53   ` [PATCH v2 12/15] replay: disallow revision specific options and pathspecs Christian Couder
2023-05-16  4:25     ` Elijah Newren
2023-05-09 17:53   ` [PATCH v2 13/15] replay: add --advance or 'cherry-pick' mode Christian Couder
2023-05-09 17:53   ` [PATCH v2 14/15] replay: add --contained to rebase contained branches Christian Couder
2023-05-16  4:26     ` Elijah Newren
2023-05-09 17:53   ` [PATCH v2 15/15] replay: stop assuming replayed branches do not diverge Christian Couder
2023-05-16  4:26     ` Elijah Newren
2023-05-09 22:28   ` [PATCH v2 00/15] Introduce new `git replay` command Junio C Hamano
2023-05-10  7:33     ` Christian Couder
2023-05-16  4:42   ` Elijah Newren
2023-06-02 10:25   ` [PATCH v3 " Christian Couder
2023-06-02 10:25     ` [PATCH v3 01/15] t6429: remove switching aspects of fast-rebase Christian Couder
2023-06-02 10:25     ` [PATCH v3 02/15] replay: introduce new builtin Christian Couder
2023-06-02 10:25     ` [PATCH v3 03/15] replay: start using parse_options API Christian Couder
2023-06-02 10:25     ` [PATCH v3 04/15] replay: die() instead of failing assert() Christian Couder
2023-06-02 10:25     ` [PATCH v3 05/15] replay: introduce pick_regular_commit() Christian Couder
2023-06-02 10:25     ` [PATCH v3 06/15] replay: don't simplify history Christian Couder
2023-06-02 10:25     ` [PATCH v3 07/15] replay: add an important FIXME comment about gpg signing Christian Couder
2023-06-02 10:25     ` [PATCH v3 08/15] replay: remove progress and info output Christian Couder
2023-06-02 10:25     ` [PATCH v3 09/15] replay: remove HEAD related sanity check Christian Couder
2023-06-02 10:25     ` [PATCH v3 10/15] replay: make it a minimal server side command Christian Couder
2023-06-22 10:01       ` Toon Claes
2023-09-07  8:32         ` Christian Couder
2023-06-02 10:25     ` [PATCH v3 11/15] replay: use standard revision ranges Christian Couder
2023-06-22 10:03       ` Toon Claes
2023-09-07  8:32         ` Christian Couder
2023-09-07 21:02           ` Dragan Simic
2023-10-10 12:44             ` Christian Couder
2023-10-10 14:02               ` Dragan Simic
2023-06-02 10:25     ` [PATCH v3 12/15] replay: disallow revision specific options and pathspecs Christian Couder
2023-07-25 21:16       ` Junio C Hamano
2023-09-07  8:33         ` Christian Couder
2023-06-02 10:25     ` [PATCH v3 13/15] replay: add --advance or 'cherry-pick' mode Christian Couder
2023-06-22 10:05       ` Toon Claes
2023-09-07  8:35         ` Christian Couder
2023-07-25 21:41       ` Junio C Hamano
2023-09-07  8:35         ` Christian Couder
2023-06-02 10:25     ` [PATCH v3 14/15] replay: add --contained to rebase contained branches Christian Couder
2023-06-22 10:10       ` Toon Claes
2023-09-07  8:37         ` Christian Couder
2023-06-02 10:25     ` [PATCH v3 15/15] replay: stop assuming replayed branches do not diverge Christian Couder
2023-06-03  1:42     ` [PATCH v3 00/15] Introduce new `git replay` command Junio C Hamano
2023-06-05  7:11       ` Christian Couder
2023-09-07  9:25     ` [PATCH v4 " Christian Couder
2023-09-07  9:25       ` [PATCH v4 01/15] t6429: remove switching aspects of fast-rebase Christian Couder
2023-09-07  9:25       ` [PATCH v4 02/15] replay: introduce new builtin Christian Couder
2023-09-07 10:23         ` Johannes Schindelin
2023-10-10 12:42           ` Christian Couder
2023-09-07  9:25       ` [PATCH v4 03/15] replay: start using parse_options API Christian Couder
2023-09-07  9:25       ` [PATCH v4 04/15] replay: die() instead of failing assert() Christian Couder
2023-09-07  9:25       ` [PATCH v4 05/15] replay: introduce pick_regular_commit() Christian Couder
2023-09-07  9:25       ` [PATCH v4 06/15] replay: don't simplify history Christian Couder
2023-09-07 10:23         ` Johannes Schindelin
2023-10-10 12:43           ` Christian Couder
2023-09-07  9:25       ` [PATCH v4 07/15] replay: add an important FIXME comment about gpg signing Christian Couder
2023-09-07  9:25       ` [PATCH v4 08/15] replay: remove progress and info output Christian Couder
2023-09-07  9:25       ` [PATCH v4 09/15] replay: remove HEAD related sanity check Christian Couder
2023-09-07  9:25       ` [PATCH v4 10/15] replay: make it a minimal server side command Christian Couder
2023-09-07  9:25       ` [PATCH v4 11/15] replay: use standard revision ranges Christian Couder
2023-09-07 10:24         ` Johannes Schindelin
2023-10-10 12:49           ` Christian Couder
2023-09-08 22:55         ` Linus Arver
2023-09-10  3:20           ` Linus Arver
2023-10-10 12:48             ` Christian Couder
2023-10-10 12:48           ` Christian Couder
2023-10-19 19:26             ` Linus Arver
2023-09-07  9:25       ` [PATCH v4 12/15] replay: disallow revision specific options and pathspecs Christian Couder
2023-09-07 10:24         ` Johannes Schindelin
2023-10-10 12:49           ` Christian Couder
2023-09-07  9:25       ` [PATCH v4 13/15] replay: add --advance or 'cherry-pick' mode Christian Couder
2023-09-07  9:25       ` [PATCH v4 14/15] replay: add --contained to rebase contained branches Christian Couder
2023-09-07  9:25       ` [PATCH v4 15/15] replay: stop assuming replayed branches do not diverge Christian Couder
2023-09-07 10:25       ` [PATCH v4 00/15] Introduce new `git replay` command Johannes Schindelin
2023-10-10 12:50         ` Christian Couder
2023-10-10 12:38       ` [PATCH v5 00/14] " Christian Couder
2023-10-10 12:38         ` [PATCH v5 01/14] t6429: remove switching aspects of fast-rebase Christian Couder
2023-10-10 12:38         ` [PATCH v5 02/14] replay: introduce new builtin Christian Couder
2023-10-10 12:38         ` [PATCH v5 03/14] replay: start using parse_options API Christian Couder
2023-10-10 12:38         ` [PATCH v5 04/14] replay: die() instead of failing assert() Christian Couder
2023-10-10 12:38         ` [PATCH v5 05/14] replay: introduce pick_regular_commit() Christian Couder
2023-10-10 12:38         ` [PATCH v5 06/14] replay: change rev walking options Christian Couder
2023-10-10 12:38         ` [PATCH v5 07/14] replay: add an important FIXME comment about gpg signing Christian Couder
2023-10-10 12:38         ` [PATCH v5 08/14] replay: remove progress and info output Christian Couder
2023-10-10 12:38         ` [PATCH v5 09/14] replay: remove HEAD related sanity check Christian Couder
2023-10-10 12:38         ` [PATCH v5 10/14] replay: make it a minimal server side command Christian Couder
2023-10-10 12:38         ` [PATCH v5 11/14] replay: use standard revision ranges Christian Couder
2023-10-19 19:49           ` Linus Arver
2023-10-10 12:38         ` [PATCH v5 12/14] replay: add --advance or 'cherry-pick' mode Christian Couder
2023-10-10 12:38         ` [PATCH v5 13/14] replay: add --contained to rebase contained branches Christian Couder
2023-10-10 12:38         ` [PATCH v5 14/14] replay: stop assuming replayed branches do not diverge Christian Couder
2023-10-26 13:44         ` [PATCH v5 00/14] Introduce new `git replay` command Johannes Schindelin
2023-10-29  6:01           ` Elijah Newren
2023-11-02 14:59             ` Christian Couder
2023-11-08 12:25               ` Johannes Schindelin
2023-11-02 15:06           ` Christian Couder
2023-11-08 12:25             ` Johannes Schindelin
2023-10-29  6:00         ` Elijah Newren
2023-10-29 14:14           ` Johannes Schindelin
2023-10-30 17:18             ` Elijah Newren
2023-11-02 14:44               ` Christian Couder
2023-11-02 14:48           ` Christian Couder
2023-11-02 13:51         ` [PATCH v6 " Christian Couder
2023-11-02 13:51           ` [PATCH v6 01/14] t6429: remove switching aspects of fast-rebase Christian Couder
2023-11-02 13:51           ` [PATCH v6 02/14] replay: introduce new builtin Christian Couder
2023-11-02 13:51           ` [PATCH v6 03/14] replay: start using parse_options API Christian Couder
2023-11-02 13:51           ` [PATCH v6 04/14] replay: die() instead of failing assert() Christian Couder
2023-11-02 13:51           ` [PATCH v6 05/14] replay: introduce pick_regular_commit() Christian Couder
2023-11-02 13:51           ` [PATCH v6 06/14] replay: change rev walking options Christian Couder
2023-11-02 13:51           ` [PATCH v6 07/14] replay: add an important FIXME comment about gpg signing Christian Couder
2023-11-02 13:51           ` [PATCH v6 08/14] replay: remove progress and info output Christian Couder
2023-11-02 13:51           ` [PATCH v6 09/14] replay: remove HEAD related sanity check Christian Couder
2023-11-02 13:51           ` [PATCH v6 10/14] replay: make it a minimal server side command Christian Couder
2023-11-02 13:51           ` [PATCH v6 11/14] replay: use standard revision ranges Christian Couder
2023-11-02 13:51           ` [PATCH v6 12/14] replay: add --advance or 'cherry-pick' mode Christian Couder
2023-11-02 13:51           ` [PATCH v6 13/14] replay: add --contained to rebase contained branches Christian Couder
2023-11-02 13:51           ` [PATCH v6 14/14] replay: stop assuming replayed branches do not diverge Christian Couder
2023-11-07  2:43           ` [PATCH v6 00/14] Introduce new `git replay` command Elijah Newren
2023-11-07  9:43             ` Christian Couder
2023-11-15 14:51               ` Christian Couder
2023-11-08 12:19             ` Johannes Schindelin
2023-11-08 12:47           ` Johannes Schindelin
2023-11-15 14:46             ` Christian Couder
2023-11-16  8:45               ` Johannes Schindelin
2023-11-16  8:52                 ` Christian Couder
2023-11-15 14:33           ` [PATCH v7 " Christian Couder
2023-11-15 14:33             ` [PATCH v7 01/14] t6429: remove switching aspects of fast-rebase Christian Couder
2023-11-15 14:33             ` [PATCH v7 02/14] replay: introduce new builtin Christian Couder
2023-11-15 14:33             ` [PATCH v7 03/14] replay: start using parse_options API Christian Couder
2023-11-15 14:33             ` [PATCH v7 04/14] replay: die() instead of failing assert() Christian Couder
2023-11-15 14:33             ` [PATCH v7 05/14] replay: introduce pick_regular_commit() Christian Couder
2023-11-15 14:33             ` [PATCH v7 06/14] replay: change rev walking options Christian Couder
2023-11-15 14:33             ` [PATCH v7 07/14] replay: add an important FIXME comment about gpg signing Christian Couder
2023-11-15 14:33             ` [PATCH v7 08/14] replay: remove progress and info output Christian Couder
2023-11-15 14:33             ` [PATCH v7 09/14] replay: remove HEAD related sanity check Christian Couder
2023-11-15 14:33             ` [PATCH v7 10/14] replay: make it a minimal server side command Christian Couder
2023-11-15 14:33             ` [PATCH v7 11/14] replay: use standard revision ranges Christian Couder
2023-11-15 14:33             ` [PATCH v7 12/14] replay: add --advance or 'cherry-pick' mode Christian Couder
2023-11-15 14:33             ` [PATCH v7 13/14] replay: add --contained to rebase contained branches Christian Couder
2023-11-15 14:33             ` [PATCH v7 14/14] replay: stop assuming replayed branches do not diverge Christian Couder
2023-11-16  8:53             ` [PATCH v7 00/14] Introduce new `git replay` command Johannes Schindelin
2023-11-23 19:32               ` Elijah Newren
2023-11-24  0:28                 ` Junio C Hamano
2023-11-24 11:10             ` [PATCH v8 " Christian Couder
2023-11-24 11:10               ` [PATCH v8 01/14] t6429: remove switching aspects of fast-rebase Christian Couder
2023-11-24 11:10               ` [PATCH v8 02/14] replay: introduce new builtin Christian Couder
2023-11-24 11:10               ` [PATCH v8 03/14] replay: start using parse_options API Christian Couder
2023-11-24 11:10               ` [PATCH v8 04/14] replay: die() instead of failing assert() Christian Couder
2023-11-24 11:10               ` [PATCH v8 05/14] replay: introduce pick_regular_commit() Christian Couder
2023-11-24 11:10               ` [PATCH v8 06/14] replay: change rev walking options Christian Couder
2023-11-24 11:10               ` [PATCH v8 07/14] replay: add an important FIXME comment about gpg signing Christian Couder
2023-11-24 11:10               ` [PATCH v8 08/14] replay: remove progress and info output Christian Couder
2023-11-24 11:10               ` [PATCH v8 09/14] replay: remove HEAD related sanity check Christian Couder
2023-11-24 11:10               ` [PATCH v8 10/14] replay: make it a minimal server side command Christian Couder
2023-11-24 11:10               ` [PATCH v8 11/14] replay: use standard revision ranges Christian Couder
2023-11-24 11:10               ` [PATCH v8 12/14] replay: add --advance or 'cherry-pick' mode Christian Couder
2023-11-24 11:10               ` [PATCH v8 13/14] replay: add --contained to rebase contained branches Christian Couder
2023-11-24 11:10               ` [PATCH v8 14/14] replay: stop assuming replayed branches do not diverge Christian Couder
2023-11-25  0:02               ` [PATCH v8 00/14] Introduce new `git replay` command 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

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230407072415.1360068-14-christian.couder@gmail.com \
    --to=christian.couder@gmail.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=chriscool@tuxfamily.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=johncai86@gmail.com \
    --cc=newren@gmail.com \
    --cc=ps@pks.im \
    /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.
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).