All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alex Henrie <alexhenrie24@gmail.com>
To: git@vger.kernel.org, liu.denton@gmail.com,
	sunshine@sunshineco.com, gitster@pobox.com, avarab@gmail.com,
	Johannes.Schindelin@gmx.de
Cc: Alex Henrie <alexhenrie24@gmail.com>
Subject: [PATCH v2] rebase: use correct base for --keep-base when a branch is given
Date: Wed, 20 Apr 2022 22:42:33 -0600	[thread overview]
Message-ID: <20220421044233.894255-1-alexhenrie24@gmail.com> (raw)
In-Reply-To: <20220418012716.2683624-1-alexhenrie24@gmail.com>

--keep-base rebases onto the merge base of the given upstream and the
current HEAD regardless of whether a branch is given. This is contrary
to the documentation and to the option's intended purpose. Instead,
rebase onto the merge base of the given upstream and the given branch.

Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
---
v2: clear previous test cruft more efficiently
---
 Documentation/git-rebase.txt     |  5 +--
 builtin/rebase.c                 | 55 ++++++++++++++++----------------
 t/t3416-rebase-onto-threedots.sh | 29 +++++++++++++++++
 3 files changed, 60 insertions(+), 29 deletions(-)

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 9da4647061..262fb01aec 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -215,9 +215,10 @@ leave out at most one of A and B, in which case it defaults to HEAD.
 
 --keep-base::
 	Set the starting point at which to create the new commits to the
-	merge base of <upstream> <branch>. Running
+	merge base of <upstream> and <branch>. Running
 	'git rebase --keep-base <upstream> <branch>' is equivalent to
-	running 'git rebase --onto <upstream>... <upstream>'.
+	running
+	'git rebase --onto <upstream>...<branch> <upstream> <branch>'.
 +
 This option is useful in the case where one is developing a feature on
 top of an upstream branch. While the feature is being worked on, the
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 27fde7bf28..7f3bffc0a2 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -1583,33 +1583,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 		options.upstream_arg = "--root";
 	}
 
-	/* Make sure the branch to rebase onto is valid. */
-	if (keep_base) {
-		strbuf_reset(&buf);
-		strbuf_addstr(&buf, options.upstream_name);
-		strbuf_addstr(&buf, "...");
-		options.onto_name = xstrdup(buf.buf);
-	} else if (!options.onto_name)
-		options.onto_name = options.upstream_name;
-	if (strstr(options.onto_name, "...")) {
-		if (get_oid_mb(options.onto_name, &merge_base) < 0) {
-			if (keep_base)
-				die(_("'%s': need exactly one merge base with branch"),
-				    options.upstream_name);
-			else
-				die(_("'%s': need exactly one merge base"),
-				    options.onto_name);
-		}
-		options.onto = lookup_commit_or_die(&merge_base,
-						    options.onto_name);
-	} else {
-		options.onto =
-			lookup_commit_reference_by_name(options.onto_name);
-		if (!options.onto)
-			die(_("Does not point to a valid commit '%s'"),
-				options.onto_name);
-	}
-
 	/*
 	 * If the branch to rebase is given, that is the branch we will rebase
 	 * branch_name -- branch/commit being rebased, or
@@ -1659,6 +1632,34 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 	} else
 		BUG("unexpected number of arguments left to parse");
 
+	/* Make sure the branch to rebase onto is valid. */
+	if (keep_base) {
+		strbuf_reset(&buf);
+		strbuf_addstr(&buf, options.upstream_name);
+		strbuf_addstr(&buf, "...");
+		strbuf_addstr(&buf, branch_name);
+		options.onto_name = xstrdup(buf.buf);
+	} else if (!options.onto_name)
+		options.onto_name = options.upstream_name;
+	if (strstr(options.onto_name, "...")) {
+		if (get_oid_mb(options.onto_name, &merge_base) < 0) {
+			if (keep_base)
+				die(_("'%s': need exactly one merge base with branch"),
+				    options.upstream_name);
+			else
+				die(_("'%s': need exactly one merge base"),
+				    options.onto_name);
+		}
+		options.onto = lookup_commit_or_die(&merge_base,
+						    options.onto_name);
+	} else {
+		options.onto =
+			lookup_commit_reference_by_name(options.onto_name);
+		if (!options.onto)
+			die(_("Does not point to a valid commit '%s'"),
+				options.onto_name);
+	}
+
 	if (options.fork_point > 0) {
 		struct commit *head =
 			lookup_commit_reference(the_repository,
diff --git a/t/t3416-rebase-onto-threedots.sh b/t/t3416-rebase-onto-threedots.sh
index 3716a42e81..3e04802cb0 100755
--- a/t/t3416-rebase-onto-threedots.sh
+++ b/t/t3416-rebase-onto-threedots.sh
@@ -129,6 +129,20 @@ test_expect_success 'rebase --keep-base main from topic' '
 	test_cmp expect actual
 '
 
+test_expect_success 'rebase --keep-base main topic from main' '
+	git checkout main &&
+	git branch -f topic G &&
+
+	git rebase --keep-base main topic &&
+	git rev-parse C >base.expect &&
+	git merge-base main HEAD >base.actual &&
+	test_cmp base.expect base.actual &&
+
+	git rev-parse HEAD~2 >actual &&
+	git rev-parse C^0 >expect &&
+	test_cmp expect actual
+'
+
 test_expect_success 'rebase --keep-base main from side' '
 	git reset --hard &&
 	git checkout side &&
@@ -153,6 +167,21 @@ test_expect_success 'rebase -i --keep-base main from topic' '
 	test_cmp expect actual
 '
 
+test_expect_success 'rebase -i --keep-base main topic from main' '
+	git checkout main &&
+	git branch -f topic G &&
+
+	set_fake_editor &&
+	EXPECT_COUNT=2 git rebase -i --keep-base main topic &&
+	git rev-parse C >base.expect &&
+	git merge-base main HEAD >base.actual &&
+	test_cmp base.expect base.actual &&
+
+	git rev-parse HEAD~2 >actual &&
+	git rev-parse C^0 >expect &&
+	test_cmp expect actual
+'
+
 test_expect_success 'rebase -i --keep-base main from side' '
 	git reset --hard &&
 	git checkout side &&
-- 
2.36.0


      parent reply	other threads:[~2022-04-21  4:44 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-18  1:27 [PATCH] rebase: use correct base for --keep-base when a branch is given Alex Henrie
2022-04-20 20:46 ` Junio C Hamano
2022-04-21  4:38   ` Alex Henrie
2022-04-21  4:42 ` Alex Henrie [this message]

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=20220421044233.894255-1-alexhenrie24@gmail.com \
    --to=alexhenrie24@gmail.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=liu.denton@gmail.com \
    --cc=sunshine@sunshineco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.