git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Elijah Newren via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Alex Henrie <alexhenrie24@gmail.com>,
	Phillip Wood <phillip.wood123@gmail.com>,
	Son Luong Ngoc <sluongng@gmail.com>,
	Elijah Newren <newren@gmail.com>,
	Elijah Newren <newren@gmail.com>
Subject: [PATCH 3/5] pull: handle conflicting rebase/merge options via last option wins
Date: Thu, 15 Jul 2021 02:40:47 +0000	[thread overview]
Message-ID: <3c07ce978caa832b08c6bef1c48c061e41a6fd0b.1626316849.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1047.git.git.1626316849.gitgitgadget@gmail.com>

From: Elijah Newren <newren@gmail.com>

The --rebase[=...] flags and the various ff flags are incompatible,
except that --no-rebase (or --rebase=false) work with any of the ff
flags, and --ff works with any of the rebase flags.

Both sets of these flags could also be passed via configuration
options, namely pull.rebase and pull.ff.

As with elsewhere in git:
  * Make the last flag specified win
  * Treat command line flags as coming after any configuration options
  * Do not imply an order between different configuration options; if
    they conflict, just report an error.

Signed-off-by: Elijah Newren <newren@gmail.com>
---
 Documentation/config/pull.txt |  3 +-
 Documentation/git-pull.txt    |  3 ++
 builtin/pull.c                | 12 +++++++
 t/t7601-merge-pull-config.sh  | 67 +++++++++++++++++++++++++++++++++++
 4 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/Documentation/config/pull.txt b/Documentation/config/pull.txt
index 54048306095..e70ed99e408 100644
--- a/Documentation/config/pull.txt
+++ b/Documentation/config/pull.txt
@@ -7,12 +7,13 @@ pull.ff::
 	line). When set to `only`, only such fast-forward merges are
 	allowed (equivalent to giving the `--ff-only` option from the
 	command line). This setting overrides `merge.ff` when pulling.
+	Incompatible with pull.rebase.
 
 pull.rebase::
 	When true, rebase branches on top of the fetched branch, instead
 	of merging the default branch from the default remote when "git
 	pull" is run. See "branch.<name>.rebase" for setting this on a
-	per-branch basis.
+	per-branch basis.  Incompatible with pull.ff.
 +
 When `merges` (or just 'm'), pass the `--rebase-merges` option to 'git rebase'
 so that the local merge commits are included in the rebase (see
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index 5c3fb67c014..03e8694e146 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -121,6 +121,9 @@ When false, merge the current branch into the upstream branch.
 +
 When `interactive`, enable the interactive mode of rebase.
 +
+Note that these flags are incompatible with --no-ff and --ff-only; if
+such incompatible flags are given, the last one will take precedence.
++
 See `pull.rebase`, `branch.<name>.rebase` and `branch.autoSetupRebase` in
 linkgit:git-config[1] if you want to make `git pull` always use
 `--rebase` instead of merging.
diff --git a/builtin/pull.c b/builtin/pull.c
index d99719403d0..b355fd38794 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -109,6 +109,11 @@ static int parse_opt_rebase(const struct option *opt, const char *arg, int unset
 		*value = parse_config_rebase("--rebase", arg, 0);
 	else
 		*value = unset ? REBASE_FALSE : REBASE_TRUE;
+
+	/* --rebase overrides earlier --ff-only and --no-ff */
+	if (*value != REBASE_FALSE)
+		opt_ff = "--ff";
+
 	return *value == REBASE_INVALID ? -1 : 0;
 }
 
@@ -119,6 +124,10 @@ static int parse_opt_ff(const struct option *opt, const char *arg, int unset)
 	else
 		opt_ff = xstrfmt("--%s", opt->long_name);
 
+	/* --ff-only and --no-ff override earlier --rebase */
+	if (strcmp(opt_ff, "--ff"))
+		opt_rebase = REBASE_FALSE;
+
 	return 0;
 }
 
@@ -984,6 +993,9 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 	if (opt_rebase < 0)
 		opt_rebase = config_get_rebase(&rebase_unspecified);
 
+	if (opt_rebase != REBASE_FALSE && opt_ff && strcmp(opt_ff, "--ff"))
+		die(_("pull.rebase and pull.ff are incompatible; please unset one"));
+
 	if (read_cache_unmerged())
 		die_resolve_conflict("pull");
 
diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
index 52e8ccc933a..73a0dbdf25a 100755
--- a/t/t7601-merge-pull-config.sh
+++ b/t/t7601-merge-pull-config.sh
@@ -143,6 +143,73 @@ test_expect_success 'pull.rebase not set and --ff-only given (not-fast-forward)'
 	test_i18ngrep ! "Pulling without specifying how to reconcile" err
 '
 
+test_does_rebase() {
+	git reset --hard c2 &&
+	git "$@" . c1 &&
+	# Check that we actually did a rebase
+	git rev-list --count HEAD >actual &&
+	git rev-list --merges --count HEAD >>actual &&
+	test_write_lines 3 0 >expect &&
+	test_cmp expect actual &&
+	rm actual expect
+}
+
+test_does_merge() {
+	git reset --hard c2 &&
+	git "$@" . c1 &&
+	# Check that we actually did a merge
+	git rev-list --count HEAD >actual &&
+	git rev-list --merges --count HEAD >>actual &&
+	test_write_lines 4 1 >expect &&
+	test_cmp expect actual &&
+	rm actual expect
+}
+
+test_attempts_fast_forward() {
+	git reset --hard c2 &&
+	test_must_fail git "$@" . c1 2>err &&
+	test_i18ngrep "Not possible to fast-forward, aborting" err
+}
+
+test_expect_success 'conflicting options: --ff-only --rebase' '
+	test_does_rebase pull --ff-only --rebase
+'
+
+test_expect_success 'conflicting options: --no-ff --rebase' '
+	test_does_rebase pull --no-ff --rebase
+'
+
+test_expect_success 'conflicting options: -c pull.ff=false --rebase' '
+	test_does_rebase -c pull.ff=false pull --rebase
+'
+
+test_expect_success 'conflicting options: -c pull.ff=only --rebase' '
+	test_does_rebase -c pull.ff=only pull --rebase
+'
+
+test_expect_success 'conflicting options: --rebase --ff-only' '
+	test_attempts_fast_forward pull --rebase --ff-only
+'
+
+test_expect_success 'conflicting options: --rebase --no-ff' '
+	test_does_merge pull --rebase --no-ff
+'
+
+test_expect_success 'conflicting options: -c pull.rebase=true --no-ff' '
+	test_does_merge -c pull.rebase=true pull --no-ff
+'
+
+test_expect_success 'conflicting options: -c pull.rebase=true --ff-only' '
+	test_attempts_fast_forward -c pull.rebase=true pull --ff-only
+'
+
+test_expect_success 'report conflicting configuration' '
+	git reset --hard c2 &&
+	test_must_fail git -c pull.ff=false -c pull.rebase=true pull . c1 2>err &&
+	test_i18ngrep "pull.rebase and pull.ff are incompatible; please unset one" err
+
+'
+
 test_expect_success 'merge c1 with c2' '
 	git reset --hard c1 &&
 	test -f c0.c &&
-- 
gitgitgadget


  parent reply	other threads:[~2021-07-15  2:41 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-15  2:40 [PATCH 0/5] Handle conflicting pull options Elijah Newren via GitGitGadget
2021-07-15  2:40 ` [PATCH 1/5] pull: move definitions of parse_config_rebase and parse_opt_rebase Elijah Newren via GitGitGadget
2021-07-15  2:40 ` [PATCH 2/5] pull: convert OPT_PASSTHRU for fast-forward options to OPT_CALLBACK Elijah Newren via GitGitGadget
2021-07-15  2:40 ` Elijah Newren via GitGitGadget [this message]
2021-07-15  4:59   ` [PATCH 3/5] pull: handle conflicting rebase/merge options via last option wins Eric Sunshine
2021-07-15 17:13     ` Elijah Newren
2021-07-15  9:44   ` Felipe Contreras
2021-07-15 17:33   ` Junio C Hamano
2021-07-15 17:46     ` Felipe Contreras
2021-07-15 19:04     ` Elijah Newren
2021-07-15 19:58       ` Junio C Hamano
2021-07-15 20:40         ` Elijah Newren
2021-07-15 21:12           ` Junio C Hamano
2021-07-16 18:39             ` Elijah Newren
2021-07-16 21:18               ` Junio C Hamano
2021-07-16 21:56                 ` Felipe Contreras
2021-07-15 20:17       ` Junio C Hamano
2021-07-15 20:38         ` Elijah Newren
2021-07-15  2:40 ` [PATCH 4/5] pull: abort if --ff-only is given and fast-forwarding is impossible Alex Henrie via GitGitGadget
2021-07-15  2:40 ` [PATCH 5/5] pull: abort by default when fast-forwarding is not possible Elijah Newren via GitGitGadget
2021-07-15  5:18   ` Eric Sunshine
2021-07-15 16:56     ` Elijah Newren
2021-07-15  9:48   ` Felipe Contreras
2021-07-16  9:32   ` Ævar Arnfjörð Bjarmason
2021-07-16 18:13     ` Felipe Contreras
2021-07-15  9:37 ` [PATCH 0/5] Handle conflicting pull options Felipe Contreras

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=3c07ce978caa832b08c6bef1c48c061e41a6fd0b.1626316849.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=alexhenrie24@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=newren@gmail.com \
    --cc=phillip.wood123@gmail.com \
    --cc=sluongng@gmail.com \
    /path/to/YOUR_REPLY

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

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