All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.