All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/14] pull: default warning improvements
@ 2020-12-04  6:16 Felipe Contreras
  2020-12-04  6:16 ` [PATCH v2 01/14] doc: pull: explain what is a fast-forward Felipe Contreras
                   ` (13 more replies)
  0 siblings, 14 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

The old thread "Pull is Mostly Evil" [1] came to haunt us back again.

The main solution--reject non-fast-forward merges by default--seems to have lost traction (again).

There are multiple approaches floating around, but no clear path forward.

This patch series attempts to fix as much as possible of the current situation without committing to
any particular solution.

It does:

1. Improve the current documentation
2. Improve the current default warning
3. Minimize the instances where we display the default warning
4. Add a --merge option
5. Improve the error message with --ff-only
6. Fix the behavior of the warning with --ff

And tentatively (and this should be the only controversial change):

7. Change the semantics of -ff-only

It does not:

* Introduce the suggested pull.mode
* Change the current default (still --ff)

It is not a complete solution, but should improve the current situation.

[1] https://lore.kernel.org/git/5363BB9F.40102@xiplink.com/


Felipe Contreras (14):
  doc: pull: explain what is a fast-forward
  pull: improve default warning
  pull: refactor fast-forward check
  pull: cleanup autostash check
  pull: trivial cleanup
  pull: move default warning
  pull: display default warning only when non-ff
  pull: trivial whitespace style fix
  pull: introduce --merge option
  pull: add proper error with --ff-only
  tentative: pull: change the semantics of --ff-only
  pull: show warning with --ff
  test: merge-pull-config: trivial cleanup
  test: pull-options: revert unnecessary changes

 Documentation/git-pull.txt   | 24 ++++++++-
 builtin/pull.c               | 98 ++++++++++++++++++++++--------------
 t/t5520-pull.sh              | 62 +++++++++++++++++++++++
 t/t5521-pull-options.sh      | 22 ++++----
 t/t7601-merge-pull-config.sh | 35 +++++++------
 5 files changed, 174 insertions(+), 67 deletions(-)

-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 01/14] doc: pull: explain what is a fast-forward
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04 22:55   ` Elijah Newren
  2020-12-05  1:21   ` Jacob Keller
  2020-12-04  6:16 ` [PATCH v2 02/14] pull: improve default warning Felipe Contreras
                   ` (12 subsequent siblings)
  13 siblings, 2 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

We want users to know what is a fast-forward in order to understand the
default warning.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 Documentation/git-pull.txt | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index 5c3fb67c01..dc812139f4 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -38,6 +38,20 @@ as set by linkgit:git-branch[1] `--track`.
 Assume the following history exists and the current branch is
 "`master`":
 
+------------
+	  A---B---C master on origin
+	 /
+    D---E master
+------------
+
+Then `git pull` will merge in a fast-foward way up to the new master.
+
+------------
+    D---E---A---B---C master, origin/master
+------------
+
+However, a non-fast-foward case looks very different.
+
 ------------
 	  A---B---C master on origin
 	 /
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 02/14] pull: improve default warning
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
  2020-12-04  6:16 ` [PATCH v2 01/14] doc: pull: explain what is a fast-forward Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04 22:59   ` Elijah Newren
  2020-12-04  6:16 ` [PATCH v2 03/14] pull: refactor fast-forward check Felipe Contreras
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

We want to:

1. Be clear about what "specifying" means; merge or rebase.
2. Mention a direct shortcut for people that just want to get on with
   their lives: git pull --no-rebase.
3. Have a quick reference for users to understand what this
   "fast-forward" business means.

This patch does all three.

Thanks to the previous patch now "git pull --help" explains what a
fast-forward is, and a further patch changes --no-rebase to --merge so
it's actually user friendly.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/pull.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/builtin/pull.c b/builtin/pull.c
index 1034372f8b..22a9ffcade 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -346,17 +346,18 @@ static enum rebase_type config_get_rebase(void)
 
 	if (opt_verbosity >= 0 && !opt_ff) {
 		advise(_("Pulling without specifying how to reconcile divergent branches is\n"
-			 "discouraged. You can squelch this message by running one of the following\n"
-			 "commands sometime before your next pull:\n"
-			 "\n"
-			 "  git config pull.rebase false  # merge (the default strategy)\n"
-			 "  git config pull.rebase true   # rebase\n"
-			 "  git config pull.ff only       # fast-forward only\n"
-			 "\n"
-			 "You can replace \"git config\" with \"git config --global\" to set a default\n"
-			 "preference for all repositories. You can also pass --rebase, --no-rebase,\n"
-			 "or --ff-only on the command line to override the configured default per\n"
-			 "invocation.\n"));
+			"discouraged; you need to specify if you want a merge, or a rebase.\n"
+			"You can squelch this message by running one of the following commands:\n"
+			"\n"
+			"  git config pull.rebase false  # merge (the default strategy)\n"
+			"  git config pull.rebase true   # rebase\n"
+			"  git config pull.ff only       # fast-forward only\n"
+			"\n"
+			"You can replace \"git config\" with \"git config --global\" to set a default\n"
+			"preference for all repositories.\n"
+			"If unsure, run \"git pull --no-rebase\".\n"
+			"Read \"git pull --help\" for more information."
+			));
 	}
 
 	return REBASE_FALSE;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 03/14] pull: refactor fast-forward check
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
  2020-12-04  6:16 ` [PATCH v2 01/14] doc: pull: explain what is a fast-forward Felipe Contreras
  2020-12-04  6:16 ` [PATCH v2 02/14] pull: improve default warning Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04  6:16 ` [PATCH v2 04/14] pull: cleanup autostash check Felipe Contreras
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

This way we will be able to do the check unconditionally (merge or
rebase).

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/pull.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/builtin/pull.c b/builtin/pull.c
index 22a9ffcade..6279e9ee37 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -907,6 +907,20 @@ static int run_rebase(const struct object_id *curr_head,
 	return ret;
 }
 
+static int get_can_ff(struct object_id *orig_head, struct object_id *orig_merge_head)
+{
+	int ret;
+	struct commit_list *list = NULL;
+	struct commit *merge_head, *head;
+
+	head = lookup_commit_reference(the_repository, orig_head);
+	commit_list_insert(head, &list);
+	merge_head = lookup_commit_reference(the_repository, orig_merge_head);
+	ret = repo_is_descendant_of(the_repository, merge_head, list);
+	free_commit_list(list);
+	return ret;
+}
+
 int cmd_pull(int argc, const char **argv, const char *prefix)
 {
 	const char *repo, **refspecs;
@@ -1017,22 +1031,12 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 		    submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))
 			die(_("cannot rebase with locally recorded submodule modifications"));
 		if (!autostash) {
-			struct commit_list *list = NULL;
-			struct commit *merge_head, *head;
-
-			head = lookup_commit_reference(the_repository,
-						       &orig_head);
-			commit_list_insert(head, &list);
-			merge_head = lookup_commit_reference(the_repository,
-							     &merge_heads.oid[0]);
-			if (repo_is_descendant_of(the_repository,
-						  merge_head, list)) {
+			if (get_can_ff(&orig_head, &merge_heads.oid[0])) {
 				/* we can fast-forward this without invoking rebase */
 				opt_ff = "--ff-only";
 				ran_ff = 1;
 				ret = run_merge();
 			}
-			free_commit_list(list);
 		}
 		if (!ran_ff)
 			ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 04/14] pull: cleanup autostash check
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
                   ` (2 preceding siblings ...)
  2020-12-04  6:16 ` [PATCH v2 03/14] pull: refactor fast-forward check Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04 23:07   ` Elijah Newren
  2020-12-04  6:16 ` [PATCH v2 05/14] pull: trivial cleanup Felipe Contreras
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

This essentially reverts commit f15e7cf5cc.

Once commit d9f15d37f1 introduced the autostash option for the merge
mode, it's not necessary to skip the fast-forward run_merge() when
autostash is set.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/pull.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/builtin/pull.c b/builtin/pull.c
index 6279e9ee37..c38548dab8 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -927,7 +927,6 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 	struct oid_array merge_heads = OID_ARRAY_INIT;
 	struct object_id orig_head, curr_head;
 	struct object_id rebase_fork_point;
-	int autostash;
 
 	if (!getenv("GIT_REFLOG_ACTION"))
 		set_reflog_message(argc, argv);
@@ -960,8 +959,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 	if (get_oid("HEAD", &orig_head))
 		oidclr(&orig_head);
 
-	autostash = config_autostash;
 	if (opt_rebase) {
+		int autostash = config_autostash;
 		if (opt_autostash != -1)
 			autostash = opt_autostash;
 
@@ -1030,13 +1029,11 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 		     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&
 		    submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))
 			die(_("cannot rebase with locally recorded submodule modifications"));
-		if (!autostash) {
-			if (get_can_ff(&orig_head, &merge_heads.oid[0])) {
-				/* we can fast-forward this without invoking rebase */
-				opt_ff = "--ff-only";
-				ran_ff = 1;
-				ret = run_merge();
-			}
+		if (get_can_ff(&orig_head, &merge_heads.oid[0])) {
+			/* we can fast-forward this without invoking rebase */
+			opt_ff = "--ff-only";
+			ran_ff = 1;
+			ret = run_merge();
 		}
 		if (!ran_ff)
 			ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 05/14] pull: trivial cleanup
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
                   ` (3 preceding siblings ...)
  2020-12-04  6:16 ` [PATCH v2 04/14] pull: cleanup autostash check Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04 23:09   ` Elijah Newren
  2020-12-04  6:16 ` [PATCH v2 06/14] pull: move default warning Felipe Contreras
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

There's no need to store ran_ff. Now it's obvious from the conditionals.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/pull.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/builtin/pull.c b/builtin/pull.c
index c38548dab8..8daba7539c 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -1024,19 +1024,18 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 
 	if (opt_rebase) {
 		int ret = 0;
-		int ran_ff = 0;
 		if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
 		     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&
 		    submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))
 			die(_("cannot rebase with locally recorded submodule modifications"));
+
 		if (get_can_ff(&orig_head, &merge_heads.oid[0])) {
 			/* we can fast-forward this without invoking rebase */
 			opt_ff = "--ff-only";
-			ran_ff = 1;
 			ret = run_merge();
-		}
-		if (!ran_ff)
+		} else {
 			ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
+		}
 
 		if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||
 			     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 06/14] pull: move default warning
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
                   ` (4 preceding siblings ...)
  2020-12-04  6:16 ` [PATCH v2 05/14] pull: trivial cleanup Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04 23:18   ` Elijah Newren
  2020-12-04  6:16 ` [PATCH v2 07/14] pull: display default warning only when non-ff Felipe Contreras
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

Up to the point where can check if we can fast-forward or not.

No functional changes.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/pull.c | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/builtin/pull.c b/builtin/pull.c
index 8daba7539c..f82e214fc8 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -27,6 +27,8 @@
 #include "commit-reach.h"
 #include "sequencer.h"
 
+static int default_mode;
+
 /**
  * Parses the value of --rebase. If value is a false value, returns
  * REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is
@@ -344,21 +346,7 @@ static enum rebase_type config_get_rebase(void)
 	if (!git_config_get_value("pull.rebase", &value))
 		return parse_config_rebase("pull.rebase", value, 1);
 
-	if (opt_verbosity >= 0 && !opt_ff) {
-		advise(_("Pulling without specifying how to reconcile divergent branches is\n"
-			"discouraged; you need to specify if you want a merge, or a rebase.\n"
-			"You can squelch this message by running one of the following commands:\n"
-			"\n"
-			"  git config pull.rebase false  # merge (the default strategy)\n"
-			"  git config pull.rebase true   # rebase\n"
-			"  git config pull.ff only       # fast-forward only\n"
-			"\n"
-			"You can replace \"git config\" with \"git config --global\" to set a default\n"
-			"preference for all repositories.\n"
-			"If unsure, run \"git pull --no-rebase\".\n"
-			"Read \"git pull --help\" for more information."
-			));
-	}
+	default_mode = 1;
 
 	return REBASE_FALSE;
 }
@@ -927,6 +915,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 	struct oid_array merge_heads = OID_ARRAY_INIT;
 	struct object_id orig_head, curr_head;
 	struct object_id rebase_fork_point;
+	int can_ff;
 
 	if (!getenv("GIT_REFLOG_ACTION"))
 		set_reflog_message(argc, argv);
@@ -1022,6 +1011,24 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 	if (opt_rebase && merge_heads.nr > 1)
 		die(_("Cannot rebase onto multiple branches."));
 
+	can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);
+
+	if (default_mode && opt_verbosity >= 0 && !opt_ff) {
+		advise(_("Pulling without specifying how to reconcile divergent branches is\n"
+			"discouraged; you need to specify if you want a merge, or a rebase.\n"
+			"You can squelch this message by running one of the following commands:\n"
+			"\n"
+			"  git config pull.rebase false  # merge (the default strategy)\n"
+			"  git config pull.rebase true   # rebase\n"
+			"  git config pull.ff only       # fast-forward only\n"
+			"\n"
+			"You can replace \"git config\" with \"git config --global\" to set a default\n"
+			"preference for all repositories.\n"
+			"If unsure, run \"git pull --no-rebase\".\n"
+			"Read \"git pull --help\" for more information."
+			));
+	}
+
 	if (opt_rebase) {
 		int ret = 0;
 		if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
@@ -1029,7 +1036,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 		    submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))
 			die(_("cannot rebase with locally recorded submodule modifications"));
 
-		if (get_can_ff(&orig_head, &merge_heads.oid[0])) {
+		if (can_ff) {
 			/* we can fast-forward this without invoking rebase */
 			opt_ff = "--ff-only";
 			ret = run_merge();
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 07/14] pull: display default warning only when non-ff
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
                   ` (5 preceding siblings ...)
  2020-12-04  6:16 ` [PATCH v2 06/14] pull: move default warning Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04 23:24   ` Elijah Newren
  2020-12-04  6:16 ` [PATCH v2 08/14] pull: trivial whitespace style fix Felipe Contreras
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

There's no need to display the annoying warning on every pull... only
the ones that are not fast-forward.

This requires the tests to pick another base, so the merge is not
fast-forward.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 Documentation/git-pull.txt   |  3 +++
 builtin/pull.c               |  2 +-
 t/t7601-merge-pull-config.sh | 28 +++++++++++++++++-----------
 3 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index dc812139f4..ad33d2472c 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -60,6 +60,9 @@ However, a non-fast-foward case looks very different.
 	origin/master in your repository
 ------------
 
+By default `git pull` will warn about these situations, however, most likely
+you would want to force a merge, which you can do with `git pull --no-rebase`.
+
 Then "`git pull`" will fetch and replay the changes from the remote
 `master` branch since it diverged from the local `master` (i.e., `E`)
 until its current commit (`C`) on top of `master` and record the
diff --git a/builtin/pull.c b/builtin/pull.c
index f82e214fc8..f0b1c6bfea 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -1013,7 +1013,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 
 	can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);
 
-	if (default_mode && opt_verbosity >= 0 && !opt_ff) {
+	if (default_mode && !can_ff && opt_verbosity >= 0 && !opt_ff) {
 		advise(_("Pulling without specifying how to reconcile divergent branches is\n"
 			"discouraged; you need to specify if you want a merge, or a rebase.\n"
 			"You can squelch this message by running one of the following commands:\n"
diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
index 6774e9d86f..6b4adab8b1 100755
--- a/t/t7601-merge-pull-config.sh
+++ b/t/t7601-merge-pull-config.sh
@@ -28,7 +28,7 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'pull.rebase not set' '
-	git reset --hard c0 &&
+	git reset --hard c2 &&
 	git -c color.advice=always pull . c1 2>err &&
 	test_decode_color <err >decoded &&
 	test_i18ngrep "<YELLOW>hint: " decoded &&
@@ -36,54 +36,60 @@ test_expect_success 'pull.rebase not set' '
 
 '
 
-test_expect_success 'pull.rebase not set and pull.ff=true' '
+test_expect_success 'pull.rebase not set (fast-forward)' '
 	git reset --hard c0 &&
+	git pull . c1 2>err &&
+	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+'
+
+test_expect_success 'pull.rebase not set and pull.ff=true' '
+	git reset --hard c2 &&
 	test_config pull.ff true &&
 	git pull . c1 2>err &&
 	test_i18ngrep ! "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and pull.ff=false' '
-	git reset --hard c0 &&
+	git reset --hard c2 &&
 	test_config pull.ff false &&
 	git pull . c1 2>err &&
 	test_i18ngrep ! "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and pull.ff=only' '
-	git reset --hard c0 &&
+	git reset --hard c2 &&
 	test_config pull.ff only &&
-	git pull . c1 2>err &&
+	test_must_fail git pull . c1 2>err &&
 	test_i18ngrep ! "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --rebase given' '
-	git reset --hard c0 &&
+	git reset --hard c2 &&
 	git pull --rebase . c1 2>err &&
 	test_i18ngrep ! "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --no-rebase given' '
-	git reset --hard c0 &&
+	git reset --hard c2 &&
 	git pull --no-rebase . c1 2>err &&
 	test_i18ngrep ! "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --ff given' '
-	git reset --hard c0 &&
+	git reset --hard c2 &&
 	git pull --ff . c1 2>err &&
 	test_i18ngrep ! "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --no-ff given' '
-	git reset --hard c0 &&
+	git reset --hard c2 &&
 	git pull --no-ff . c1 2>err &&
 	test_i18ngrep ! "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --ff-only given' '
-	git reset --hard c0 &&
-	git pull --ff-only . c1 2>err &&
+	git reset --hard c2 &&
+	test_must_fail git pull --ff-only . c1 2>err &&
 	test_i18ngrep ! "Pulling without specifying how to reconcile" err
 '
 
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 08/14] pull: trivial whitespace style fix
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
                   ` (6 preceding siblings ...)
  2020-12-04  6:16 ` [PATCH v2 07/14] pull: display default warning only when non-ff Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04  6:16 ` [PATCH v2 09/14] pull: introduce --merge option Felipe Contreras
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

Two spaces unaligned to anything is not part of the coding-style. A
single tab is.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/pull.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/builtin/pull.c b/builtin/pull.c
index f0b1c6bfea..b200f7544c 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -128,9 +128,9 @@ static struct option pull_options[] = {
 	/* Options passed to git-merge or git-rebase */
 	OPT_GROUP(N_("Options related to merging")),
 	OPT_CALLBACK_F('r', "rebase", &opt_rebase,
-	  "(false|true|merges|preserve|interactive)",
-	  N_("incorporate changes by rebasing rather than merging"),
-	  PARSE_OPT_OPTARG, parse_opt_rebase),
+		"(false|true|merges|preserve|interactive)",
+		N_("incorporate changes by rebasing rather than merging"),
+		PARSE_OPT_OPTARG, parse_opt_rebase),
 	OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,
 		N_("do not show a diffstat at the end of the merge"),
 		PARSE_OPT_NOARG | PARSE_OPT_NONEG),
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 09/14] pull: introduce --merge option
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
                   ` (7 preceding siblings ...)
  2020-12-04  6:16 ` [PATCH v2 08/14] pull: trivial whitespace style fix Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04 23:27   ` Elijah Newren
  2020-12-04  6:16 ` [PATCH v2 10/14] pull: add proper error with --ff-only Felipe Contreras
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

Previously --no-rebase (which still works for backwards compatbility).

Now we can update the default warning, and the git-pull(1) man page to
use --merge instead of the non-intuitive --no-rebase.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 Documentation/git-pull.txt   | 9 ++++++---
 builtin/pull.c               | 4 +++-
 t/t7601-merge-pull-config.sh | 4 ++--
 3 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index ad33d2472c..c220da143a 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -61,7 +61,7 @@ However, a non-fast-foward case looks very different.
 ------------
 
 By default `git pull` will warn about these situations, however, most likely
-you would want to force a merge, which you can do with `git pull --no-rebase`.
+you would want to force a merge, which you can do with `git pull --merge`.
 
 Then "`git pull`" will fetch and replay the changes from the remote
 `master` branch since it diverged from the local `master` (i.e., `E`)
@@ -148,8 +148,11 @@ It rewrites history, which does not bode well when you
 published that history already.  Do *not* use this option
 unless you have read linkgit:git-rebase[1] carefully.
 
---no-rebase::
-	Override earlier --rebase.
+-m::
+--merge::
+	Force a merge.
++
+Previously this was --no-rebase, but that usage has been deprecated.
 
 Options related to fetching
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/builtin/pull.c b/builtin/pull.c
index b200f7544c..6ea95c9fc9 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -131,6 +131,8 @@ static struct option pull_options[] = {
 		"(false|true|merges|preserve|interactive)",
 		N_("incorporate changes by rebasing rather than merging"),
 		PARSE_OPT_OPTARG, parse_opt_rebase),
+	OPT_SET_INT('m', "merge", &opt_rebase,
+		N_("incorporate changes by merging"), 0),
 	OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,
 		N_("do not show a diffstat at the end of the merge"),
 		PARSE_OPT_NOARG | PARSE_OPT_NONEG),
@@ -1024,7 +1026,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 			"\n"
 			"You can replace \"git config\" with \"git config --global\" to set a default\n"
 			"preference for all repositories.\n"
-			"If unsure, run \"git pull --no-rebase\".\n"
+			"If unsure, run \"git pull --merge\".\n"
 			"Read \"git pull --help\" for more information."
 			));
 	}
diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
index 6b4adab8b1..1de64e6cc5 100755
--- a/t/t7601-merge-pull-config.sh
+++ b/t/t7601-merge-pull-config.sh
@@ -69,9 +69,9 @@ test_expect_success 'pull.rebase not set and --rebase given' '
 	test_i18ngrep ! "Pulling without specifying how to reconcile" err
 '
 
-test_expect_success 'pull.rebase not set and --no-rebase given' '
+test_expect_success 'pull.rebase not set and --merge given' '
 	git reset --hard c2 &&
-	git pull --no-rebase . c1 2>err &&
+	git pull --merge . c1 2>err &&
 	test_i18ngrep ! "Pulling without specifying how to reconcile" err
 '
 
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 10/14] pull: add proper error with --ff-only
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
                   ` (8 preceding siblings ...)
  2020-12-04  6:16 ` [PATCH v2 09/14] pull: introduce --merge option Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04 23:34   ` Elijah Newren
  2020-12-04  6:16 ` [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only Felipe Contreras
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

The current error is not user-friendly:

  fatal: not possible to fast-forward, aborting.

We want something that actually explains what is going on:

  The pull was not fast-forward, please either merge or rebase.
  If unsure, run "git pull --merge".

The user can get rid of the warning by doing either --merge or
--rebase.

Except: doing "git pull --merge" is not actually enough; we would return
to the previous behavior: "fatal: not possible to fast-forward, aborting."

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/pull.c  | 34 ++++++++++++++++-----------
 t/t5520-pull.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+), 14 deletions(-)

diff --git a/builtin/pull.c b/builtin/pull.c
index 6ea95c9fc9..f54ff36b57 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -1015,20 +1015,26 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 
 	can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);
 
-	if (default_mode && !can_ff && opt_verbosity >= 0 && !opt_ff) {
-		advise(_("Pulling without specifying how to reconcile divergent branches is\n"
-			"discouraged; you need to specify if you want a merge, or a rebase.\n"
-			"You can squelch this message by running one of the following commands:\n"
-			"\n"
-			"  git config pull.rebase false  # merge (the default strategy)\n"
-			"  git config pull.rebase true   # rebase\n"
-			"  git config pull.ff only       # fast-forward only\n"
-			"\n"
-			"You can replace \"git config\" with \"git config --global\" to set a default\n"
-			"preference for all repositories.\n"
-			"If unsure, run \"git pull --merge\".\n"
-			"Read \"git pull --help\" for more information."
-			));
+	if (!can_ff && default_mode) {
+		if (opt_ff && !strcmp(opt_ff, "--ff-only")) {
+			die(_("The pull was not fast-forward, please either merge or rebase.\n"
+				"If unsure, run \"git pull --merge\"."));
+		}
+		if (opt_verbosity >= 0 && !opt_ff) {
+			advise(_("Pulling without specifying how to reconcile divergent branches is\n"
+				"discouraged; you need to specify if you want a merge, or a rebase.\n"
+				"You can squelch this message by running one of the following commands:\n"
+				"\n"
+				"  git config pull.rebase false  # merge (the default strategy)\n"
+				"  git config pull.rebase true   # rebase\n"
+				"  git config pull.ff only       # fast-forward only\n"
+				"\n"
+				"You can replace \"git config\" with \"git config --global\" to set a default\n"
+				"preference for all repositories.\n"
+				"If unsure, run \"git pull --merge\".\n"
+				"Read \"git pull --help\" for more information."
+				));
+		}
 	}
 
 	if (opt_rebase) {
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index 9fae07cdfa..fdd1f79b06 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -819,4 +819,66 @@ test_expect_success 'git pull --rebase against local branch' '
 	test_cmp expect file2
 '
 
+test_expect_success 'git pull fast-forward (ff-only)' '
+	test_when_finished "git checkout master && git branch -D other test" &&
+	test_config pull.ff only &&
+	git checkout -b other master &&
+	>new &&
+	git add new &&
+	git commit -m new &&
+	git checkout -b test -t other &&
+	git reset --hard master &&
+	git pull
+'
+
+test_expect_success 'git pull non-fast-forward (ff-only)' '
+	test_when_finished "git checkout master && git branch -D other test" &&
+	test_config pull.ff only &&
+	git checkout -b other master^ &&
+	>new &&
+	git add new &&
+	git commit -m new &&
+	git checkout -b test -t other &&
+	git reset --hard master &&
+	test_must_fail git pull
+'
+
+test_expect_failure 'git pull non-fast-forward with merge (ff-only)' '
+	test_when_finished "git checkout master && git branch -D other test" &&
+	test_config pull.ff only &&
+	git checkout -b other master^ &&
+	>new &&
+	git add new &&
+	git commit -m new &&
+	git checkout -b test -t other &&
+	git reset --hard master &&
+	git pull --no-rebase
+'
+
+test_expect_success 'git pull non-fast-forward with rebase (ff-only)' '
+	test_when_finished "git checkout master && git branch -D other test" &&
+	test_config pull.ff only &&
+	git checkout -b other master^ &&
+	>new &&
+	git add new &&
+	git commit -m new &&
+	git checkout -b test -t other &&
+	git reset --hard master &&
+	git pull --rebase
+'
+
+test_expect_success 'git pull non-fast-forward error message' '
+	test_when_finished "git checkout master && git branch -D other test" &&
+	test_config pull.ff only &&
+	git checkout -b other master^ &&
+	>new &&
+	git add new &&
+	git commit -m new &&
+	git checkout -b test -t other &&
+	git reset --hard master &&
+	test_must_fail git pull 2> error &&
+	cat error &&
+	grep -q "The pull was not fast-forward" error
+'
+
 test_done
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
                   ` (9 preceding siblings ...)
  2020-12-04  6:16 ` [PATCH v2 10/14] pull: add proper error with --ff-only Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04 23:39   ` Elijah Newren
  2020-12-04  6:16 ` [PATCH v2 12/14] pull: show warning with --ff Felipe Contreras
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

We want --ff-only to make sense only when no --merge or --rebase option
is specified.

Currently --rebase already ignores --ff-only (or any other --ff option),
but --merge fails.

Make it so --ff-only is only considered in the default mode.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/pull.c  | 4 ++++
 t/t5520-pull.sh | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/builtin/pull.c b/builtin/pull.c
index f54ff36b57..ebf2ac687b 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -1037,6 +1037,10 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 		}
 	}
 
+	/* Disable --ff-only when --merge is specified */
+	if (!can_ff && !default_mode && !opt_rebase && opt_ff && !strcmp(opt_ff, "--ff-only"))
+		opt_ff = NULL;
+
 	if (opt_rebase) {
 		int ret = 0;
 		if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index fdd1f79b06..eec6224fb0 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -843,7 +843,7 @@ test_expect_success 'git pull non-fast-forward (ff-only)' '
 	test_must_fail git pull
 '
 
-test_expect_failure 'git pull non-fast-forward with merge (ff-only)' '
+test_expect_success 'git pull non-fast-forward with merge (ff-only)' '
 	test_when_finished "git checkout master && git branch -D other test" &&
 	test_config pull.ff only &&
 	git checkout -b other master^ &&
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 12/14] pull: show warning with --ff
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
                   ` (10 preceding siblings ...)
  2020-12-04  6:16 ` [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04 23:41   ` Elijah Newren
  2020-12-04  6:16 ` [PATCH v2 13/14] test: merge-pull-config: trivial cleanup Felipe Contreras
  2020-12-04  6:16 ` [PATCH v2 14/14] test: pull-options: revert unnecessary changes Felipe Contreras
  13 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

It's unclear why --ff should remove the warning, since:

  git pull --ff

Is implicitly the same as:

  git pull

Unless of course pull.ff is specified otherwise.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/pull.c               | 2 +-
 t/t7601-merge-pull-config.sh | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/builtin/pull.c b/builtin/pull.c
index ebf2ac687b..e389ffcdc3 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -1020,7 +1020,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 			die(_("The pull was not fast-forward, please either merge or rebase.\n"
 				"If unsure, run \"git pull --merge\"."));
 		}
-		if (opt_verbosity >= 0 && !opt_ff) {
+		if (opt_verbosity >= 0 && (!opt_ff || !strcmp(opt_ff, "--ff"))) {
 			advise(_("Pulling without specifying how to reconcile divergent branches is\n"
 				"discouraged; you need to specify if you want a merge, or a rebase.\n"
 				"You can squelch this message by running one of the following commands:\n"
diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
index 1de64e6cc5..d709799f8b 100755
--- a/t/t7601-merge-pull-config.sh
+++ b/t/t7601-merge-pull-config.sh
@@ -46,7 +46,7 @@ test_expect_success 'pull.rebase not set and pull.ff=true' '
 	git reset --hard c2 &&
 	test_config pull.ff true &&
 	git pull . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	test_i18ngrep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and pull.ff=false' '
@@ -78,7 +78,7 @@ test_expect_success 'pull.rebase not set and --merge given' '
 test_expect_success 'pull.rebase not set and --ff given' '
 	git reset --hard c2 &&
 	git pull --ff . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	test_i18ngrep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --no-ff given' '
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 13/14] test: merge-pull-config: trivial cleanup
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
                   ` (11 preceding siblings ...)
  2020-12-04  6:16 ` [PATCH v2 12/14] pull: show warning with --ff Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04 23:41   ` Elijah Newren
  2020-12-04  6:16 ` [PATCH v2 14/14] test: pull-options: revert unnecessary changes Felipe Contreras
  13 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

Commit e01ae2a4a7 introduced an extra space.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 t/t7601-merge-pull-config.sh | 1 -
 1 file changed, 1 deletion(-)

diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
index d709799f8b..8a6aae564a 100755
--- a/t/t7601-merge-pull-config.sh
+++ b/t/t7601-merge-pull-config.sh
@@ -33,7 +33,6 @@ test_expect_success 'pull.rebase not set' '
 	test_decode_color <err >decoded &&
 	test_i18ngrep "<YELLOW>hint: " decoded &&
 	test_i18ngrep "Pulling without specifying how to reconcile" decoded
-
 '
 
 test_expect_success 'pull.rebase not set (fast-forward)' '
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 14/14] test: pull-options: revert unnecessary changes
  2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
                   ` (12 preceding siblings ...)
  2020-12-04  6:16 ` [PATCH v2 13/14] test: merge-pull-config: trivial cleanup Felipe Contreras
@ 2020-12-04  6:16 ` Felipe Contreras
  2020-12-04 23:49   ` Elijah Newren
  13 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04  6:16 UTC (permalink / raw)
  To: git
  Cc: Vít Ondruch, Alex Henrie, Junio C Hamano, Jeff King,
	Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	Elijah Newren, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King, Felipe Contreras

Commit d18c950a69 changed these tests, but it's unclear why. Probably
because earlier versions of the patch series died instead of printing a
warning.

Cc: Alex Henrie <alexhenrie24@gmail.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 t/t5521-pull-options.sh | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh
index db1a381cd9..1a4fe2583a 100755
--- a/t/t5521-pull-options.sh
+++ b/t/t5521-pull-options.sh
@@ -11,10 +11,10 @@ test_expect_success 'setup' '
 	 git commit -m one)
 '
 
-test_expect_success 'git pull -q --no-rebase' '
+test_expect_success 'git pull -q' '
 	mkdir clonedq &&
 	(cd clonedq && git init &&
-	git pull -q --no-rebase "../parent" >out 2>err &&
+	git pull -q "../parent" >out 2>err &&
 	test_must_be_empty err &&
 	test_must_be_empty out)
 '
@@ -30,10 +30,10 @@ test_expect_success 'git pull -q --rebase' '
 	test_must_be_empty out)
 '
 
-test_expect_success 'git pull --no-rebase' '
+test_expect_success 'git pull' '
 	mkdir cloned &&
 	(cd cloned && git init &&
-	git pull --no-rebase "../parent" >out 2>err &&
+	git pull "../parent" >out 2>err &&
 	test -s err &&
 	test_must_be_empty out)
 '
@@ -46,10 +46,10 @@ test_expect_success 'git pull --rebase' '
 	test_must_be_empty out)
 '
 
-test_expect_success 'git pull -v --no-rebase' '
+test_expect_success 'git pull -v' '
 	mkdir clonedv &&
 	(cd clonedv && git init &&
-	git pull -v --no-rebase "../parent" >out 2>err &&
+	git pull -v "../parent" >out 2>err &&
 	test -s err &&
 	test_must_be_empty out)
 '
@@ -62,25 +62,25 @@ test_expect_success 'git pull -v --rebase' '
 	test_must_be_empty out)
 '
 
-test_expect_success 'git pull -v -q --no-rebase' '
+test_expect_success 'git pull -v -q' '
 	mkdir clonedvq &&
 	(cd clonedvq && git init &&
-	git pull -v -q --no-rebase "../parent" >out 2>err &&
+	git pull -v -q "../parent" >out 2>err &&
 	test_must_be_empty out &&
 	test_must_be_empty err)
 '
 
-test_expect_success 'git pull -q -v --no-rebase' '
+test_expect_success 'git pull -q -v' '
 	mkdir clonedqv &&
 	(cd clonedqv && git init &&
-	git pull -q -v --no-rebase "../parent" >out 2>err &&
+	git pull -q -v "../parent" >out 2>err &&
 	test_must_be_empty out &&
 	test -s err)
 '
 test_expect_success 'git pull --cleanup errors early on invalid argument' '
 	mkdir clonedcleanup &&
 	(cd clonedcleanup && git init &&
-	test_must_fail git pull --no-rebase --cleanup invalid "../parent" >out 2>err &&
+	test_must_fail git pull --cleanup invalid "../parent" >out 2>err &&
 	test_must_be_empty out &&
 	test -s err)
 '
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 01/14] doc: pull: explain what is a fast-forward
  2020-12-04  6:16 ` [PATCH v2 01/14] doc: pull: explain what is a fast-forward Felipe Contreras
@ 2020-12-04 22:55   ` Elijah Newren
  2020-12-05  1:21   ` Jacob Keller
  1 sibling, 0 replies; 79+ messages in thread
From: Elijah Newren @ 2020-12-04 22:55 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> We want users to know what is a fast-forward in order to understand the
> default warning.
>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  Documentation/git-pull.txt | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
> index 5c3fb67c01..dc812139f4 100644
> --- a/Documentation/git-pull.txt
> +++ b/Documentation/git-pull.txt
> @@ -38,6 +38,20 @@ as set by linkgit:git-branch[1] `--track`.
>  Assume the following history exists and the current branch is
>  "`master`":
>
> +------------
> +         A---B---C master on origin
> +        /
> +    D---E master
> +------------
> +
> +Then `git pull` will merge in a fast-foward way up to the new master.
> +
> +------------
> +    D---E---A---B---C master, origin/master
> +------------
> +
> +However, a non-fast-foward case looks very different.
> +
>  ------------
>           A---B---C master on origin
>          /
> --
> 2.29.2

Makes sense to me.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-04  6:16 ` [PATCH v2 02/14] pull: improve default warning Felipe Contreras
@ 2020-12-04 22:59   ` Elijah Newren
  2020-12-05  0:12     ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Elijah Newren @ 2020-12-04 22:59 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> We want to:
>
> 1. Be clear about what "specifying" means; merge or rebase.
> 2. Mention a direct shortcut for people that just want to get on with
>    their lives: git pull --no-rebase.

This is a shortcut for what?

> 3. Have a quick reference for users to understand what this
>    "fast-forward" business means.
>
> This patch does all three.
>
> Thanks to the previous patch now "git pull --help" explains what a
> fast-forward is, and a further patch changes --no-rebase to --merge so
> it's actually user friendly.
>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  builtin/pull.c | 23 ++++++++++++-----------
>  1 file changed, 12 insertions(+), 11 deletions(-)
>
> diff --git a/builtin/pull.c b/builtin/pull.c
> index 1034372f8b..22a9ffcade 100644
> --- a/builtin/pull.c
> +++ b/builtin/pull.c
> @@ -346,17 +346,18 @@ static enum rebase_type config_get_rebase(void)
>
>         if (opt_verbosity >= 0 && !opt_ff) {
>                 advise(_("Pulling without specifying how to reconcile divergent branches is\n"
> -                        "discouraged. You can squelch this message by running one of the following\n"
> -                        "commands sometime before your next pull:\n"
> -                        "\n"
> -                        "  git config pull.rebase false  # merge (the default strategy)\n"
> -                        "  git config pull.rebase true   # rebase\n"
> -                        "  git config pull.ff only       # fast-forward only\n"
> -                        "\n"
> -                        "You can replace \"git config\" with \"git config --global\" to set a default\n"
> -                        "preference for all repositories. You can also pass --rebase, --no-rebase,\n"
> -                        "or --ff-only on the command line to override the configured default per\n"
> -                        "invocation.\n"));
> +                       "discouraged; you need to specify if you want a merge, or a rebase.\n"

...want a merge, a rebase, or neither.

> +                       "You can squelch this message by running one of the following commands:\n"
> +                       "\n"
> +                       "  git config pull.rebase false  # merge (the default strategy)\n"

Should this be labelled as the default given the desire to make
--ff-only the default?  Perhaps I'm jumping ahead and you plan to
change that later in this series.

> +                       "  git config pull.rebase true   # rebase\n"
> +                       "  git config pull.ff only       # fast-forward only\n"
> +                       "\n"
> +                       "You can replace \"git config\" with \"git config --global\" to set a default\n"
> +                       "preference for all repositories.\n"

Good up to here.

> +                       "If unsure, run \"git pull --no-rebase\".\n"

Why is that safe to suggest?  The original text may not have been the
easiest to parse, but this seems more problematic to me.

> +                       "Read \"git pull --help\" for more information."

Nice addition.


> +                       ));
>         }
>
>         return REBASE_FALSE;
> --
> 2.29.2
>

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 04/14] pull: cleanup autostash check
  2020-12-04  6:16 ` [PATCH v2 04/14] pull: cleanup autostash check Felipe Contreras
@ 2020-12-04 23:07   ` Elijah Newren
  2020-12-05  0:47     ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Elijah Newren @ 2020-12-04 23:07 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> This essentially reverts commit f15e7cf5cc.
>
> Once commit d9f15d37f1 introduced the autostash option for the merge
> mode, it's not necessary to skip the fast-forward run_merge() when
> autostash is set.

It helps reviewers and future code readers if you provide a little
context when referring to commits, making use of git log's
--pretty=reference option to get the output.  So, for example, here
your commit would read:

"""
This essentially reverts commit f15e7cf5cc (pull: ff --rebase
--autostash works in dirty repo, 2017-06-01).

Once commit d9f15d37f1 (pull: pass --autostash to merge, 2020-04-07)
introduced the autostash option for the merge
mode, it's not necessary to skip the fast-forward run_merge() when
autostash is set.
"""

I still found it slightly hard to follow the explanation even with the
added summaries, though.  An extra sentence at the end of the second
paragraph to make it clear what is being changed ("So, change the code
to fast-forward even when autostash is set.") seems to help.



> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  builtin/pull.c | 15 ++++++---------
>  1 file changed, 6 insertions(+), 9 deletions(-)
>
> diff --git a/builtin/pull.c b/builtin/pull.c
> index 6279e9ee37..c38548dab8 100644
> --- a/builtin/pull.c
> +++ b/builtin/pull.c
> @@ -927,7 +927,6 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>         struct oid_array merge_heads = OID_ARRAY_INIT;
>         struct object_id orig_head, curr_head;
>         struct object_id rebase_fork_point;
> -       int autostash;
>
>         if (!getenv("GIT_REFLOG_ACTION"))
>                 set_reflog_message(argc, argv);
> @@ -960,8 +959,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>         if (get_oid("HEAD", &orig_head))
>                 oidclr(&orig_head);
>
> -       autostash = config_autostash;
>         if (opt_rebase) {
> +               int autostash = config_autostash;
>                 if (opt_autostash != -1)
>                         autostash = opt_autostash;
>
> @@ -1030,13 +1029,11 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>                      recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&
>                     submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))
>                         die(_("cannot rebase with locally recorded submodule modifications"));
> -               if (!autostash) {
> -                       if (get_can_ff(&orig_head, &merge_heads.oid[0])) {
> -                               /* we can fast-forward this without invoking rebase */
> -                               opt_ff = "--ff-only";
> -                               ran_ff = 1;
> -                               ret = run_merge();
> -                       }
> +               if (get_can_ff(&orig_head, &merge_heads.oid[0])) {
> +                       /* we can fast-forward this without invoking rebase */
> +                       opt_ff = "--ff-only";
> +                       ran_ff = 1;
> +                       ret = run_merge();
>                 }
>                 if (!ran_ff)
>                         ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
> --
> 2.29.2
>

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 05/14] pull: trivial cleanup
  2020-12-04  6:16 ` [PATCH v2 05/14] pull: trivial cleanup Felipe Contreras
@ 2020-12-04 23:09   ` Elijah Newren
  2020-12-05  0:48     ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Elijah Newren @ 2020-12-04 23:09 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> There's no need to store ran_ff. Now it's obvious from the conditionals.
>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  builtin/pull.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/builtin/pull.c b/builtin/pull.c
> index c38548dab8..8daba7539c 100644
> --- a/builtin/pull.c
> +++ b/builtin/pull.c
> @@ -1024,19 +1024,18 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>
>         if (opt_rebase) {
>                 int ret = 0;
> -               int ran_ff = 0;
>                 if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
>                      recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&
>                     submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))
>                         die(_("cannot rebase with locally recorded submodule modifications"));
> +
spurious change?

(It does make it look nicer, though.)

>                 if (get_can_ff(&orig_head, &merge_heads.oid[0])) {
>                         /* we can fast-forward this without invoking rebase */
>                         opt_ff = "--ff-only";
> -                       ran_ff = 1;
>                         ret = run_merge();
> -               }
> -               if (!ran_ff)
> +               } else {
>                         ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
> +               }
>
>                 if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||
>                              recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))
> --
> 2.29.2

Yeah, reads better to me after this cleanup.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 06/14] pull: move default warning
  2020-12-04  6:16 ` [PATCH v2 06/14] pull: move default warning Felipe Contreras
@ 2020-12-04 23:18   ` Elijah Newren
  2020-12-04 23:36     ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Elijah Newren @ 2020-12-04 23:18 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> Up to the point where can check if we can fast-forward or not.

Seem to be missing some subjects in that sentence.  ;-)  Perhaps:

Move the default warning to the point where we can check if we can
fast-forward or not.

> No functional changes.

You didn't explain the reasoning for the change here, though I suspect
it makes it easier to change the default to ff-only later.  However,
looking over the patch and pulling up the code, I actually find it
pretty odd that this warning was in a function named
config_get_rebase().  The warning is not rebase-specific, and so
clearly does not belong there.  And for such a function name, the only
kinds of warnings I'd expect are ones where the user configured some
option but set it to a value that cannot make sense.  So it all around
seems like the wrong place to me, and I find your patch to be a good
cleanup.  It would benefit from a slightly improved commit message
though.  :-)



>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  builtin/pull.c | 39 +++++++++++++++++++++++----------------
>  1 file changed, 23 insertions(+), 16 deletions(-)
>
> diff --git a/builtin/pull.c b/builtin/pull.c
> index 8daba7539c..f82e214fc8 100644
> --- a/builtin/pull.c
> +++ b/builtin/pull.c
> @@ -27,6 +27,8 @@
>  #include "commit-reach.h"
>  #include "sequencer.h"
>
> +static int default_mode;
> +
>  /**
>   * Parses the value of --rebase. If value is a false value, returns
>   * REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is
> @@ -344,21 +346,7 @@ static enum rebase_type config_get_rebase(void)
>         if (!git_config_get_value("pull.rebase", &value))
>                 return parse_config_rebase("pull.rebase", value, 1);
>
> -       if (opt_verbosity >= 0 && !opt_ff) {
> -               advise(_("Pulling without specifying how to reconcile divergent branches is\n"
> -                       "discouraged; you need to specify if you want a merge, or a rebase.\n"
> -                       "You can squelch this message by running one of the following commands:\n"
> -                       "\n"
> -                       "  git config pull.rebase false  # merge (the default strategy)\n"
> -                       "  git config pull.rebase true   # rebase\n"
> -                       "  git config pull.ff only       # fast-forward only\n"
> -                       "\n"
> -                       "You can replace \"git config\" with \"git config --global\" to set a default\n"
> -                       "preference for all repositories.\n"
> -                       "If unsure, run \"git pull --no-rebase\".\n"
> -                       "Read \"git pull --help\" for more information."
> -                       ));
> -       }
> +       default_mode = 1;
>
>         return REBASE_FALSE;
>  }
> @@ -927,6 +915,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>         struct oid_array merge_heads = OID_ARRAY_INIT;
>         struct object_id orig_head, curr_head;
>         struct object_id rebase_fork_point;
> +       int can_ff;
>
>         if (!getenv("GIT_REFLOG_ACTION"))
>                 set_reflog_message(argc, argv);
> @@ -1022,6 +1011,24 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>         if (opt_rebase && merge_heads.nr > 1)
>                 die(_("Cannot rebase onto multiple branches."));
>
> +       can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);
> +
> +       if (default_mode && opt_verbosity >= 0 && !opt_ff) {
> +               advise(_("Pulling without specifying how to reconcile divergent branches is\n"
> +                       "discouraged; you need to specify if you want a merge, or a rebase.\n"
> +                       "You can squelch this message by running one of the following commands:\n"
> +                       "\n"
> +                       "  git config pull.rebase false  # merge (the default strategy)\n"
> +                       "  git config pull.rebase true   # rebase\n"
> +                       "  git config pull.ff only       # fast-forward only\n"
> +                       "\n"
> +                       "You can replace \"git config\" with \"git config --global\" to set a default\n"
> +                       "preference for all repositories.\n"
> +                       "If unsure, run \"git pull --no-rebase\".\n"
> +                       "Read \"git pull --help\" for more information."
> +                       ));
> +       }
> +
>         if (opt_rebase) {
>                 int ret = 0;
>                 if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
> @@ -1029,7 +1036,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>                     submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))
>                         die(_("cannot rebase with locally recorded submodule modifications"));
>
> -               if (get_can_ff(&orig_head, &merge_heads.oid[0])) {
> +               if (can_ff) {
>                         /* we can fast-forward this without invoking rebase */
>                         opt_ff = "--ff-only";
>                         ret = run_merge();
> --
> 2.29.2
>

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 07/14] pull: display default warning only when non-ff
  2020-12-04  6:16 ` [PATCH v2 07/14] pull: display default warning only when non-ff Felipe Contreras
@ 2020-12-04 23:24   ` Elijah Newren
  2020-12-05  1:03     ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Elijah Newren @ 2020-12-04 23:24 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> There's no need to display the annoying warning on every pull... only
> the ones that are not fast-forward.

I like this.  :-)

> This requires the tests to pick another base, so the merge is not
> fast-forward.
>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  Documentation/git-pull.txt   |  3 +++
>  builtin/pull.c               |  2 +-
>  t/t7601-merge-pull-config.sh | 28 +++++++++++++++++-----------
>  3 files changed, 21 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
> index dc812139f4..ad33d2472c 100644
> --- a/Documentation/git-pull.txt
> +++ b/Documentation/git-pull.txt
> @@ -60,6 +60,9 @@ However, a non-fast-foward case looks very different.
>         origin/master in your repository
>  ------------
>
> +By default `git pull` will warn about these situations, however, most likely
> +you would want to force a merge, which you can do with `git pull --no-rebase`.
> +

Everything in this sentence after the first comma seems dangerous to
me for a number of workflows.

>  Then "`git pull`" will fetch and replay the changes from the remote
>  `master` branch since it diverged from the local `master` (i.e., `E`)
>  until its current commit (`C`) on top of `master` and record the
> diff --git a/builtin/pull.c b/builtin/pull.c
> index f82e214fc8..f0b1c6bfea 100644
> --- a/builtin/pull.c
> +++ b/builtin/pull.c
> @@ -1013,7 +1013,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>
>         can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);
>
> -       if (default_mode && opt_verbosity >= 0 && !opt_ff) {
> +       if (default_mode && !can_ff && opt_verbosity >= 0 && !opt_ff) {
>                 advise(_("Pulling without specifying how to reconcile divergent branches is\n"
>                         "discouraged; you need to specify if you want a merge, or a rebase.\n"
>                         "You can squelch this message by running one of the following commands:\n"
> diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
> index 6774e9d86f..6b4adab8b1 100755
> --- a/t/t7601-merge-pull-config.sh
> +++ b/t/t7601-merge-pull-config.sh
> @@ -28,7 +28,7 @@ test_expect_success 'setup' '
>  '
>
>  test_expect_success 'pull.rebase not set' '
> -       git reset --hard c0 &&
> +       git reset --hard c2 &&
>         git -c color.advice=always pull . c1 2>err &&
>         test_decode_color <err >decoded &&
>         test_i18ngrep "<YELLOW>hint: " decoded &&
> @@ -36,54 +36,60 @@ test_expect_success 'pull.rebase not set' '
>
>  '
>
> -test_expect_success 'pull.rebase not set and pull.ff=true' '
> +test_expect_success 'pull.rebase not set (fast-forward)' '
>         git reset --hard c0 &&
> +       git pull . c1 2>err &&
> +       test_i18ngrep ! "Pulling without specifying how to reconcile" err
> +'
> +
> +test_expect_success 'pull.rebase not set and pull.ff=true' '
> +       git reset --hard c2 &&
>         test_config pull.ff true &&
>         git pull . c1 2>err &&
>         test_i18ngrep ! "Pulling without specifying how to reconcile" err
>  '
>
>  test_expect_success 'pull.rebase not set and pull.ff=false' '
> -       git reset --hard c0 &&
> +       git reset --hard c2 &&
>         test_config pull.ff false &&
>         git pull . c1 2>err &&
>         test_i18ngrep ! "Pulling without specifying how to reconcile" err
>  '
>
>  test_expect_success 'pull.rebase not set and pull.ff=only' '
> -       git reset --hard c0 &&
> +       git reset --hard c2 &&
>         test_config pull.ff only &&
> -       git pull . c1 2>err &&
> +       test_must_fail git pull . c1 2>err &&

It makes sense to me that you'd need test_must_fail here...but why
wasn't it needed before??  How did this test pass without it before
this series?

>         test_i18ngrep ! "Pulling without specifying how to reconcile" err
>  '
>
>  test_expect_success 'pull.rebase not set and --rebase given' '
> -       git reset --hard c0 &&
> +       git reset --hard c2 &&
>         git pull --rebase . c1 2>err &&
>         test_i18ngrep ! "Pulling without specifying how to reconcile" err
>  '
>
>  test_expect_success 'pull.rebase not set and --no-rebase given' '
> -       git reset --hard c0 &&
> +       git reset --hard c2 &&
>         git pull --no-rebase . c1 2>err &&
>         test_i18ngrep ! "Pulling without specifying how to reconcile" err
>  '
>
>  test_expect_success 'pull.rebase not set and --ff given' '
> -       git reset --hard c0 &&
> +       git reset --hard c2 &&
>         git pull --ff . c1 2>err &&
>         test_i18ngrep ! "Pulling without specifying how to reconcile" err
>  '
>
>  test_expect_success 'pull.rebase not set and --no-ff given' '
> -       git reset --hard c0 &&
> +       git reset --hard c2 &&
>         git pull --no-ff . c1 2>err &&
>         test_i18ngrep ! "Pulling without specifying how to reconcile" err
>  '
>
>  test_expect_success 'pull.rebase not set and --ff-only given' '
> -       git reset --hard c0 &&
> -       git pull --ff-only . c1 2>err &&
> +       git reset --hard c2 &&
> +       test_must_fail git pull --ff-only . c1 2>err &&

Same question; how did this test pass before without the test_must_fail??


>         test_i18ngrep ! "Pulling without specifying how to reconcile" err
>  '
>
> --
> 2.29.2

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 09/14] pull: introduce --merge option
  2020-12-04  6:16 ` [PATCH v2 09/14] pull: introduce --merge option Felipe Contreras
@ 2020-12-04 23:27   ` Elijah Newren
  2020-12-05  1:06     ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Elijah Newren @ 2020-12-04 23:27 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> Previously --no-rebase (which still works for backwards compatbility).
>
> Now we can update the default warning, and the git-pull(1) man page to
> use --merge instead of the non-intuitive --no-rebase.
>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  Documentation/git-pull.txt   | 9 ++++++---
>  builtin/pull.c               | 4 +++-
>  t/t7601-merge-pull-config.sh | 4 ++--
>  3 files changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
> index ad33d2472c..c220da143a 100644
> --- a/Documentation/git-pull.txt
> +++ b/Documentation/git-pull.txt
> @@ -61,7 +61,7 @@ However, a non-fast-foward case looks very different.
>  ------------
>
>  By default `git pull` will warn about these situations, however, most likely
> -you would want to force a merge, which you can do with `git pull --no-rebase`.
> +you would want to force a merge, which you can do with `git pull --merge`.

I'm glad you updated all the references, but as noted earlier in the
series I think this suggestion is problematic.

>
>  Then "`git pull`" will fetch and replay the changes from the remote
>  `master` branch since it diverged from the local `master` (i.e., `E`)
> @@ -148,8 +148,11 @@ It rewrites history, which does not bode well when you
>  published that history already.  Do *not* use this option
>  unless you have read linkgit:git-rebase[1] carefully.
>
> ---no-rebase::
> -       Override earlier --rebase.
> +-m::
> +--merge::
> +       Force a merge.
> ++
> +Previously this was --no-rebase, but that usage has been deprecated.
>
>  Options related to fetching
>  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> diff --git a/builtin/pull.c b/builtin/pull.c
> index b200f7544c..6ea95c9fc9 100644
> --- a/builtin/pull.c
> +++ b/builtin/pull.c
> @@ -131,6 +131,8 @@ static struct option pull_options[] = {
>                 "(false|true|merges|preserve|interactive)",
>                 N_("incorporate changes by rebasing rather than merging"),
>                 PARSE_OPT_OPTARG, parse_opt_rebase),
> +       OPT_SET_INT('m', "merge", &opt_rebase,
> +               N_("incorporate changes by merging"), 0),
>         OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,
>                 N_("do not show a diffstat at the end of the merge"),
>                 PARSE_OPT_NOARG | PARSE_OPT_NONEG),
> @@ -1024,7 +1026,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>                         "\n"
>                         "You can replace \"git config\" with \"git config --global\" to set a default\n"
>                         "preference for all repositories.\n"
> -                       "If unsure, run \"git pull --no-rebase\".\n"
> +                       "If unsure, run \"git pull --merge\".\n"

This was the other problematic copy of that suggestion.

>                         "Read \"git pull --help\" for more information."
>                         ));
>         }
> diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
> index 6b4adab8b1..1de64e6cc5 100755
> --- a/t/t7601-merge-pull-config.sh
> +++ b/t/t7601-merge-pull-config.sh
> @@ -69,9 +69,9 @@ test_expect_success 'pull.rebase not set and --rebase given' '
>         test_i18ngrep ! "Pulling without specifying how to reconcile" err
>  '
>
> -test_expect_success 'pull.rebase not set and --no-rebase given' '
> +test_expect_success 'pull.rebase not set and --merge given' '
>         git reset --hard c2 &&
> -       git pull --no-rebase . c1 2>err &&
> +       git pull --merge . c1 2>err &&
>         test_i18ngrep ! "Pulling without specifying how to reconcile" err
>  '
>
> --
> 2.29.2

I very much like the change in this patch, other than the obvious
couple places where you are just tweaking an earlier problematic
suggestion.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 10/14] pull: add proper error with --ff-only
  2020-12-04  6:16 ` [PATCH v2 10/14] pull: add proper error with --ff-only Felipe Contreras
@ 2020-12-04 23:34   ` Elijah Newren
  2020-12-05  1:18     ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Elijah Newren @ 2020-12-04 23:34 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> The current error is not user-friendly:
>
>   fatal: not possible to fast-forward, aborting.
>
> We want something that actually explains what is going on:
>
>   The pull was not fast-forward, please either merge or rebase.
>   If unsure, run "git pull --merge".

Sorry to be a broken record, but I don't like the suggestion in the
second sentence.  I've said it enough times that I'll quit harping on
each instance.

> The user can get rid of the warning by doing either --merge or
> --rebase.
>
> Except: doing "git pull --merge" is not actually enough; we would return
> to the previous behavior: "fatal: not possible to fast-forward, aborting."

Do you mean that the changes in this patch aren't enough and that
future patches will address this shortcoming?  Or do you mean that
prior to this patch such a bug existed?  Or something else?

>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  builtin/pull.c  | 34 ++++++++++++++++-----------
>  t/t5520-pull.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 82 insertions(+), 14 deletions(-)
>
> diff --git a/builtin/pull.c b/builtin/pull.c
> index 6ea95c9fc9..f54ff36b57 100644
> --- a/builtin/pull.c
> +++ b/builtin/pull.c
> @@ -1015,20 +1015,26 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>
>         can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);
>
> -       if (default_mode && !can_ff && opt_verbosity >= 0 && !opt_ff) {
> -               advise(_("Pulling without specifying how to reconcile divergent branches is\n"
> -                       "discouraged; you need to specify if you want a merge, or a rebase.\n"
> -                       "You can squelch this message by running one of the following commands:\n"
> -                       "\n"
> -                       "  git config pull.rebase false  # merge (the default strategy)\n"
> -                       "  git config pull.rebase true   # rebase\n"
> -                       "  git config pull.ff only       # fast-forward only\n"
> -                       "\n"
> -                       "You can replace \"git config\" with \"git config --global\" to set a default\n"
> -                       "preference for all repositories.\n"
> -                       "If unsure, run \"git pull --merge\".\n"
> -                       "Read \"git pull --help\" for more information."
> -                       ));
> +       if (!can_ff && default_mode) {
> +               if (opt_ff && !strcmp(opt_ff, "--ff-only")) {
> +                       die(_("The pull was not fast-forward, please either merge or rebase.\n"
> +                               "If unsure, run \"git pull --merge\"."));

This is a much better message for when the user requests --ff-only.

> +               }
> +               if (opt_verbosity >= 0 && !opt_ff) {
> +                       advise(_("Pulling without specifying how to reconcile divergent branches is\n"
> +                               "discouraged; you need to specify if you want a merge, or a rebase.\n"
> +                               "You can squelch this message by running one of the following commands:\n"
> +                               "\n"
> +                               "  git config pull.rebase false  # merge (the default strategy)\n"
> +                               "  git config pull.rebase true   # rebase\n"
> +                               "  git config pull.ff only       # fast-forward only\n"
> +                               "\n"
> +                               "You can replace \"git config\" with \"git config --global\" to set a default\n"
> +                               "preference for all repositories.\n"
> +                               "If unsure, run \"git pull --merge\".\n"
> +                               "Read \"git pull --help\" for more information."
> +                               ));
> +               }
>         }
>
>         if (opt_rebase) {
> diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
> index 9fae07cdfa..fdd1f79b06 100755
> --- a/t/t5520-pull.sh
> +++ b/t/t5520-pull.sh
> @@ -819,4 +819,66 @@ test_expect_success 'git pull --rebase against local branch' '
>         test_cmp expect file2
>  '
>
> +test_expect_success 'git pull fast-forward (ff-only)' '
> +       test_when_finished "git checkout master && git branch -D other test" &&
> +       test_config pull.ff only &&
> +       git checkout -b other master &&
> +       >new &&
> +       git add new &&
> +       git commit -m new &&
> +       git checkout -b test -t other &&
> +       git reset --hard master &&
> +       git pull
> +'
> +
> +test_expect_success 'git pull non-fast-forward (ff-only)' '
> +       test_when_finished "git checkout master && git branch -D other test" &&
> +       test_config pull.ff only &&
> +       git checkout -b other master^ &&
> +       >new &&
> +       git add new &&
> +       git commit -m new &&
> +       git checkout -b test -t other &&
> +       git reset --hard master &&
> +       test_must_fail git pull
> +'
> +
> +test_expect_failure 'git pull non-fast-forward with merge (ff-only)' '
> +       test_when_finished "git checkout master && git branch -D other test" &&
> +       test_config pull.ff only &&
> +       git checkout -b other master^ &&
> +       >new &&
> +       git add new &&
> +       git commit -m new &&
> +       git checkout -b test -t other &&
> +       git reset --hard master &&
> +       git pull --no-rebase

Do you mean `git pull --merge`?


> +'
> +
> +test_expect_success 'git pull non-fast-forward with rebase (ff-only)' '
> +       test_when_finished "git checkout master && git branch -D other test" &&
> +       test_config pull.ff only &&
> +       git checkout -b other master^ &&
> +       >new &&
> +       git add new &&
> +       git commit -m new &&
> +       git checkout -b test -t other &&
> +       git reset --hard master &&
> +       git pull --rebase
> +'
> +
> +test_expect_success 'git pull non-fast-forward error message' '
> +       test_when_finished "git checkout master && git branch -D other test" &&
> +       test_config pull.ff only &&
> +       git checkout -b other master^ &&
> +       >new &&
> +       git add new &&
> +       git commit -m new &&
> +       git checkout -b test -t other &&
> +       git reset --hard master &&
> +       test_must_fail git pull 2> error &&
> +       cat error &&
> +       grep -q "The pull was not fast-forward" error
> +'
> +
>  test_done
> --
> 2.29.2

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 06/14] pull: move default warning
  2020-12-04 23:18   ` Elijah Newren
@ 2020-12-04 23:36     ` Felipe Contreras
  0 siblings, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-04 23:36 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 5:18 PM Elijah Newren <newren@gmail.com> wrote:
>
> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > Up to the point where can check if we can fast-forward or not.
>
> Seem to be missing some subjects in that sentence.  ;-)  Perhaps:
>
> Move the default warning to the point where we can check if we can
> fast-forward or not.

Yes, I missed a "we".

I usually continue what I said in the subject, but lately while
reviewing my own patches in lore.kernel.org I've found it hard to
understand the first paragraph since it's not easy to find the
subject.

Maybe I should stop doing that.

> > No functional changes.
>
> You didn't explain the reasoning for the change here, though I suspect
> it makes it easier to change the default to ff-only later.

Right, I noticed that after the nth time I reviewed the series.

It's not actually to change the default to ff-only, it's mainly to
display the annoying warning only when a non-fast-forward pull is
being attempted.

I'll add that to the commit message.

> However,
> looking over the patch and pulling up the code, I actually find it
> pretty odd that this warning was in a function named
> config_get_rebase().  The warning is not rebase-specific, and so
> clearly does not belong there.  And for such a function name, the only
> kinds of warnings I'd expect are ones where the user configured some
> option but set it to a value that cannot make sense.  So it all around
> seems like the wrong place to me, and I find your patch to be a good
> cleanup.  It would benefit from a slightly improved commit message
> though.  :-)

Indeed. The only reason it's there is that it's the only place we know
the user has not done either --rebase, or --merge (--no-rebase), or
the config equivalents.

I fixed that by introducing a default_mode flag, but in other patch
series I replace default_mode with a check for REBASE_DEFAULT (which
doesn't exist yet).

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only
  2020-12-04  6:16 ` [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only Felipe Contreras
@ 2020-12-04 23:39   ` Elijah Newren
  2020-12-05  4:01     ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Elijah Newren @ 2020-12-04 23:39 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> We want --ff-only to make sense only when no --merge or --rebase option
> is specified.

A lot of git commands have opposite options, and git allows them both
to be specified with the last one winning.  Thus, much like
  git log --patch --no-patch
mean show logs without patches and
  git log --no-patch --patch
means show logs with patches, I would similarly expect the following
two commands to have opposite behavior:
  git pull --merge --no-ff
  git pull --no-ff --merge


> Currently --rebase already ignores --ff-only (or any other --ff option),
> but --merge fails.
>
> Make it so --ff-only is only considered in the default mode.
>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  builtin/pull.c  | 4 ++++
>  t/t5520-pull.sh | 2 +-
>  2 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/builtin/pull.c b/builtin/pull.c
> index f54ff36b57..ebf2ac687b 100644
> --- a/builtin/pull.c
> +++ b/builtin/pull.c
> @@ -1037,6 +1037,10 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>                 }
>         }
>
> +       /* Disable --ff-only when --merge is specified */
> +       if (!can_ff && !default_mode && !opt_rebase && opt_ff && !strcmp(opt_ff, "--ff-only"))
> +               opt_ff = NULL;
> +
>         if (opt_rebase) {
>                 int ret = 0;
>                 if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
> diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
> index fdd1f79b06..eec6224fb0 100755
> --- a/t/t5520-pull.sh
> +++ b/t/t5520-pull.sh
> @@ -843,7 +843,7 @@ test_expect_success 'git pull non-fast-forward (ff-only)' '
>         test_must_fail git pull
>  '
>
> -test_expect_failure 'git pull non-fast-forward with merge (ff-only)' '
> +test_expect_success 'git pull non-fast-forward with merge (ff-only)' '
>         test_when_finished "git checkout master && git branch -D other test" &&
>         test_config pull.ff only &&
>         git checkout -b other master^ &&
> --
> 2.29.2
>

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 12/14] pull: show warning with --ff
  2020-12-04  6:16 ` [PATCH v2 12/14] pull: show warning with --ff Felipe Contreras
@ 2020-12-04 23:41   ` Elijah Newren
  2020-12-05  1:25     ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Elijah Newren @ 2020-12-04 23:41 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> It's unclear why --ff should remove the warning, since:
>
>   git pull --ff
>
> Is implicitly the same as:
>
>   git pull
>
> Unless of course pull.ff is specified otherwise.
>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  builtin/pull.c               | 2 +-
>  t/t7601-merge-pull-config.sh | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/builtin/pull.c b/builtin/pull.c
> index ebf2ac687b..e389ffcdc3 100644
> --- a/builtin/pull.c
> +++ b/builtin/pull.c
> @@ -1020,7 +1020,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>                         die(_("The pull was not fast-forward, please either merge or rebase.\n"
>                                 "If unsure, run \"git pull --merge\"."));
>                 }
> -               if (opt_verbosity >= 0 && !opt_ff) {
> +               if (opt_verbosity >= 0 && (!opt_ff || !strcmp(opt_ff, "--ff"))) {
>                         advise(_("Pulling without specifying how to reconcile divergent branches is\n"
>                                 "discouraged; you need to specify if you want a merge, or a rebase.\n"
>                                 "You can squelch this message by running one of the following commands:\n"
> diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
> index 1de64e6cc5..d709799f8b 100755
> --- a/t/t7601-merge-pull-config.sh
> +++ b/t/t7601-merge-pull-config.sh
> @@ -46,7 +46,7 @@ test_expect_success 'pull.rebase not set and pull.ff=true' '
>         git reset --hard c2 &&
>         test_config pull.ff true &&
>         git pull . c1 2>err &&
> -       test_i18ngrep ! "Pulling without specifying how to reconcile" err
> +       test_i18ngrep "Pulling without specifying how to reconcile" err
>  '
>
>  test_expect_success 'pull.rebase not set and pull.ff=false' '
> @@ -78,7 +78,7 @@ test_expect_success 'pull.rebase not set and --merge given' '
>  test_expect_success 'pull.rebase not set and --ff given' '
>         git reset --hard c2 &&
>         git pull --ff . c1 2>err &&
> -       test_i18ngrep ! "Pulling without specifying how to reconcile" err
> +       test_i18ngrep "Pulling without specifying how to reconcile" err
>  '
>
>  test_expect_success 'pull.rebase not set and --no-ff given' '
> --
> 2.29.2

Ah, this answers one of my earlier questions.  I'd be tempted to move
this earlier in the series; it seems like an obvious cleanup and helps
explain the "opt_ff" flag that keeps coming up for readers of the
series.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 13/14] test: merge-pull-config: trivial cleanup
  2020-12-04  6:16 ` [PATCH v2 13/14] test: merge-pull-config: trivial cleanup Felipe Contreras
@ 2020-12-04 23:41   ` Elijah Newren
  0 siblings, 0 replies; 79+ messages in thread
From: Elijah Newren @ 2020-12-04 23:41 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> Commit e01ae2a4a7 introduced an extra space.
>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  t/t7601-merge-pull-config.sh | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
> index d709799f8b..8a6aae564a 100755
> --- a/t/t7601-merge-pull-config.sh
> +++ b/t/t7601-merge-pull-config.sh
> @@ -33,7 +33,6 @@ test_expect_success 'pull.rebase not set' '
>         test_decode_color <err >decoded &&
>         test_i18ngrep "<YELLOW>hint: " decoded &&
>         test_i18ngrep "Pulling without specifying how to reconcile" decoded
> -
>  '
>
>  test_expect_success 'pull.rebase not set (fast-forward)' '
> --
> 2.29.2

Indeed, quite obvious and simple.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 14/14] test: pull-options: revert unnecessary changes
  2020-12-04  6:16 ` [PATCH v2 14/14] test: pull-options: revert unnecessary changes Felipe Contreras
@ 2020-12-04 23:49   ` Elijah Newren
  2020-12-05  1:28     ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Elijah Newren @ 2020-12-04 23:49 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> Commit d18c950a69 changed these tests, but it's unclear why. Probably
> because earlier versions of the patch series died instead of printing a
> warning.

Another case where log --pretty=reference notation would be more
helpful in referring to commits.

Looking up that commit, I see that commit made a number of other test
changes which seem to be better motivated by the commit message and
code changes.  I wonder if we could make that clearer in the commit
message somehow.  Perhaps

Commit d18c950a69 ("pull: warn if the user didn't say whether to
rebase or to merge", 2020-03-09) changed a number of tests in t5521
and added some new tests in t7601, but it is not clear why the changes
in t5521 were made...


>
> Cc: Alex Henrie <alexhenrie24@gmail.com>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  t/t5521-pull-options.sh | 22 +++++++++++-----------
>  1 file changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh
> index db1a381cd9..1a4fe2583a 100755
> --- a/t/t5521-pull-options.sh
> +++ b/t/t5521-pull-options.sh
> @@ -11,10 +11,10 @@ test_expect_success 'setup' '
>          git commit -m one)
>  '
>
> -test_expect_success 'git pull -q --no-rebase' '
> +test_expect_success 'git pull -q' '
>         mkdir clonedq &&
>         (cd clonedq && git init &&
> -       git pull -q --no-rebase "../parent" >out 2>err &&
> +       git pull -q "../parent" >out 2>err &&
>         test_must_be_empty err &&
>         test_must_be_empty out)
>  '
> @@ -30,10 +30,10 @@ test_expect_success 'git pull -q --rebase' '
>         test_must_be_empty out)
>  '
>
> -test_expect_success 'git pull --no-rebase' '
> +test_expect_success 'git pull' '
>         mkdir cloned &&
>         (cd cloned && git init &&
> -       git pull --no-rebase "../parent" >out 2>err &&
> +       git pull "../parent" >out 2>err &&
>         test -s err &&
>         test_must_be_empty out)
>  '
> @@ -46,10 +46,10 @@ test_expect_success 'git pull --rebase' '
>         test_must_be_empty out)
>  '
>
> -test_expect_success 'git pull -v --no-rebase' '
> +test_expect_success 'git pull -v' '
>         mkdir clonedv &&
>         (cd clonedv && git init &&
> -       git pull -v --no-rebase "../parent" >out 2>err &&
> +       git pull -v "../parent" >out 2>err &&
>         test -s err &&
>         test_must_be_empty out)
>  '
> @@ -62,25 +62,25 @@ test_expect_success 'git pull -v --rebase' '
>         test_must_be_empty out)
>  '
>
> -test_expect_success 'git pull -v -q --no-rebase' '
> +test_expect_success 'git pull -v -q' '
>         mkdir clonedvq &&
>         (cd clonedvq && git init &&
> -       git pull -v -q --no-rebase "../parent" >out 2>err &&
> +       git pull -v -q "../parent" >out 2>err &&
>         test_must_be_empty out &&
>         test_must_be_empty err)
>  '
>
> -test_expect_success 'git pull -q -v --no-rebase' '
> +test_expect_success 'git pull -q -v' '
>         mkdir clonedqv &&
>         (cd clonedqv && git init &&
> -       git pull -q -v --no-rebase "../parent" >out 2>err &&
> +       git pull -q -v "../parent" >out 2>err &&
>         test_must_be_empty out &&
>         test -s err)
>  '
>  test_expect_success 'git pull --cleanup errors early on invalid argument' '
>         mkdir clonedcleanup &&
>         (cd clonedcleanup && git init &&
> -       test_must_fail git pull --no-rebase --cleanup invalid "../parent" >out 2>err &&
> +       test_must_fail git pull --cleanup invalid "../parent" >out 2>err &&
>         test_must_be_empty out &&
>         test -s err)
>  '
> --
> 2.29.2
>

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-04 22:59   ` Elijah Newren
@ 2020-12-05  0:12     ` Felipe Contreras
  2020-12-05  0:56       ` Elijah Newren
  0 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05  0:12 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 5:00 PM Elijah Newren <newren@gmail.com> wrote:
>
> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > We want to:
> >
> > 1. Be clear about what "specifying" means; merge or rebase.
> > 2. Mention a direct shortcut for people that just want to get on with
> >    their lives: git pull --no-rebase.
>
> This is a shortcut for what?

  git config --global pull.rebase false
  git pull

It's a shorter way of saying: "do a 'git pull' like you've always done
but don't warn me".

> > 3. Have a quick reference for users to understand what this
> >    "fast-forward" business means.
> >
> > This patch does all three.
> >
> > Thanks to the previous patch now "git pull --help" explains what a
> > fast-forward is, and a further patch changes --no-rebase to --merge so
> > it's actually user friendly.
> >
> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> > ---
> >  builtin/pull.c | 23 ++++++++++++-----------
> >  1 file changed, 12 insertions(+), 11 deletions(-)
> >
> > diff --git a/builtin/pull.c b/builtin/pull.c
> > index 1034372f8b..22a9ffcade 100644
> > --- a/builtin/pull.c
> > +++ b/builtin/pull.c
> > @@ -346,17 +346,18 @@ static enum rebase_type config_get_rebase(void)
> >
> >         if (opt_verbosity >= 0 && !opt_ff) {
> >                 advise(_("Pulling without specifying how to reconcile divergent branches is\n"
> > -                        "discouraged. You can squelch this message by running one of the following\n"
> > -                        "commands sometime before your next pull:\n"
> > -                        "\n"
> > -                        "  git config pull.rebase false  # merge (the default strategy)\n"
> > -                        "  git config pull.rebase true   # rebase\n"
> > -                        "  git config pull.ff only       # fast-forward only\n"
> > -                        "\n"
> > -                        "You can replace \"git config\" with \"git config --global\" to set a default\n"
> > -                        "preference for all repositories. You can also pass --rebase, --no-rebase,\n"
> > -                        "or --ff-only on the command line to override the configured default per\n"
> > -                        "invocation.\n"));
> > +                       "discouraged; you need to specify if you want a merge, or a rebase.\n"
>
> ...want a merge, a rebase, or neither.

There is no "git pull --no-merge". Years ago some people argued for a
"pull.mode=none" (essentially making "git pull" the same as "git
fetch"). But right now there's no option to do that.

There's an option to do --ff-only, but that's still a merge.

Perhaps: a merge, a rebase, or a fast-forward?

> > +                       "You can squelch this message by running one of the following commands:\n"
> > +                       "\n"
> > +                       "  git config pull.rebase false  # merge (the default strategy)\n"
>
> Should this be labelled as the default given the desire to make
> --ff-only the default?  Perhaps I'm jumping ahead and you plan to
> change that later in this series.

That's right.

In the previous series which does indeed make "pull.mode=ff-only" the
default [1], I do change the warning to specify the future default
[2], but in that series the warnings is changed to:

  The pull was not fast-forward, in the future you will have to choose
a merge, or a rebase.
  To squelch this message and maintain the current behavior, use:

    git config --global pull.mode merge

  To squelch this message and adopt the new behavior now, use:

    git config --global push.mode ff-only

  Falling back to old style for now (merge).
  Read "git pull --help" for more information.

Since that series didn't get any traction, I decided to only implement
step 1: fix the current situation. And later on another series would
do step 2: introduce "pull.mode=ff-only" and do the preparations to
make it the default.

> > +                       "  git config pull.rebase true   # rebase\n"
> > +                       "  git config pull.ff only       # fast-forward only\n"
> > +                       "\n"
> > +                       "You can replace \"git config\" with \"git config --global\" to set a default\n"
> > +                       "preference for all repositories.\n"
>
> Good up to here.
>
> > +                       "If unsure, run \"git pull --no-rebase\".\n"
>
> Why is that safe to suggest?  The original text may not have been the
> easiest to parse, but this seems more problematic to me.

Because "git pull" has been doing the same as "git pull --no-rebase"
for more than a decade. It's safe for people to continue with this
behavior for a few more months.

Some people need to get things done today, and they are not interested
in future changes, nor changing their default configuration, or what
the warning has to say.

They just want "git pull" to do the same as yesterday, and the year
before, without being bothered with an annoying warning.

Those people can start training their fingers to do "git pull
--merge", and learn the problems with "git pull" later.

We want to respect the user's time, and not force them to read the
warning today.

> > +                       "Read \"git pull --help\" for more information."
>
> Nice addition.

Especially since now it explains what a fast-forward is.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 04/14] pull: cleanup autostash check
  2020-12-04 23:07   ` Elijah Newren
@ 2020-12-05  0:47     ` Felipe Contreras
  2020-12-05  0:57       ` Elijah Newren
  0 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05  0:47 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 5:07 PM Elijah Newren <newren@gmail.com> wrote:
>
> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > This essentially reverts commit f15e7cf5cc.
> >
> > Once commit d9f15d37f1 introduced the autostash option for the merge
> > mode, it's not necessary to skip the fast-forward run_merge() when
> > autostash is set.
>
> It helps reviewers and future code readers if you provide a little
> context when referring to commits, making use of git log's
> --pretty=reference option to get the output.

Yes, I actually have this alias:

  short = show --quiet --format='%C(auto)%h (%s)%C(reset)'

Which shows almost the same thing. I've updated it to
--format=reference. Thanks for the suggestion.

And I usually add those descriptions.

> So, for example, here
> your commit would read:
>
> """
> This essentially reverts commit f15e7cf5cc (pull: ff --rebase
> --autostash works in dirty repo, 2017-06-01).
>
> Once commit d9f15d37f1 (pull: pass --autostash to merge, 2020-04-07)
> introduced the autostash option for the merge
> mode, it's not necessary to skip the fast-forward run_merge() when
> autostash is set.
> """
>
> I still found it slightly hard to follow the explanation even with the
> added summaries, though.

And that's the reason I didn't add them. You need to look at both the
commits to understand why one cancels the other. In my opinion in this
particular case the description only makes the text harder to read.

Probably some better $subjects like f15e7cf5cc (pull: skip ff merge
shortcut on --rebase --autostash) would have helped.

> An extra sentence at the end of the second
> paragraph to make it clear what is being changed ("So, change the code
> to fast-forward even when autostash is set.") seems to help.

OK. That's implied by "it's not necessary to skip the fast-forward"
but it's better to be explicit.

How about this:

Currently "git pull --rebase" takes a shortcut in the case a
fast-forward merge is possible; run_merge() is called with --ff-only.

However, "git merge" didn't have an --autostash option, so, when "git
pull --rebase --autostash" was called *and* the fast-forward merge
shortcut was taken, then the pull failed.

This was fixed in commit f15e7cf5cc (pull: ff --rebase --autostash
works in dirty repo, 2017-06-01) by simply skipping the fast-forward
merge shortcut.

Later on "git merge" learned the --autostash option [a03b55530a
(merge: teach --autostash option, 2020-04-07)], and so did "git pull"
[d9f15d37f1 (pull: pass --autostash to merge, 2020-04-07)].

Therefore it's not necessary to skip the fast-forward merge shortcut
anymore when called with --rebase --autostash.

Let's always take the fast-forward merge shortcut by essentially
reverting f15e7cf5cc.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 05/14] pull: trivial cleanup
  2020-12-04 23:09   ` Elijah Newren
@ 2020-12-05  0:48     ` Felipe Contreras
  0 siblings, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05  0:48 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 5:09 PM Elijah Newren <newren@gmail.com> wrote:
>
> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > There's no need to store ran_ff. Now it's obvious from the conditionals.
> >
> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> > ---
> >  builtin/pull.c | 7 +++----
> >  1 file changed, 3 insertions(+), 4 deletions(-)
> >
> > diff --git a/builtin/pull.c b/builtin/pull.c
> > index c38548dab8..8daba7539c 100644
> > --- a/builtin/pull.c
> > +++ b/builtin/pull.c
> > @@ -1024,19 +1024,18 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
> >
> >         if (opt_rebase) {
> >                 int ret = 0;
> > -               int ran_ff = 0;
> >                 if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
> >                      recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&
> >                     submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))
> >                         die(_("cannot rebase with locally recorded submodule modifications"));
> > +
> spurious change?
>
> (It does make it look nicer, though.)

Nope. Was intentional.

> >                 if (get_can_ff(&orig_head, &merge_heads.oid[0])) {
> >                         /* we can fast-forward this without invoking rebase */
> >                         opt_ff = "--ff-only";
> > -                       ran_ff = 1;
> >                         ret = run_merge();
> > -               }
> > -               if (!ran_ff)
> > +               } else {
> >                         ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
> > +               }
> >
> >                 if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||
> >                              recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))
> > --
> > 2.29.2
>
> Yeah, reads better to me after this cleanup.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-05  0:12     ` Felipe Contreras
@ 2020-12-05  0:56       ` Elijah Newren
  2020-12-05  1:56         ` Felipe Contreras
  2020-12-07  9:23         ` Felipe Contreras
  0 siblings, 2 replies; 79+ messages in thread
From: Elijah Newren @ 2020-12-05  0:56 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

Hi Felipe,

On Fri, Dec 4, 2020 at 4:12 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> On Fri, Dec 4, 2020 at 5:00 PM Elijah Newren <newren@gmail.com> wrote:
> >
> > On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> > <felipe.contreras@gmail.com> wrote:
> > >
> > > We want to:
> > >
> > > 1. Be clear about what "specifying" means; merge or rebase.
> > > 2. Mention a direct shortcut for people that just want to get on with
> > >    their lives: git pull --no-rebase.
> >
> > This is a shortcut for what?
>
>   git config --global pull.rebase false
>   git pull
>
> It's a shorter way of saying: "do a 'git pull' like you've always done
> but don't warn me".
>
> > > 3. Have a quick reference for users to understand what this
> > >    "fast-forward" business means.
> > >
> > > This patch does all three.
> > >
> > > Thanks to the previous patch now "git pull --help" explains what a
> > > fast-forward is, and a further patch changes --no-rebase to --merge so
> > > it's actually user friendly.
> > >
> > > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> > > ---
> > >  builtin/pull.c | 23 ++++++++++++-----------
> > >  1 file changed, 12 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/builtin/pull.c b/builtin/pull.c
> > > index 1034372f8b..22a9ffcade 100644
> > > --- a/builtin/pull.c
> > > +++ b/builtin/pull.c
> > > @@ -346,17 +346,18 @@ static enum rebase_type config_get_rebase(void)
> > >
> > >         if (opt_verbosity >= 0 && !opt_ff) {
> > >                 advise(_("Pulling without specifying how to reconcile divergent branches is\n"
> > > -                        "discouraged. You can squelch this message by running one of the following\n"
> > > -                        "commands sometime before your next pull:\n"
> > > -                        "\n"
> > > -                        "  git config pull.rebase false  # merge (the default strategy)\n"
> > > -                        "  git config pull.rebase true   # rebase\n"
> > > -                        "  git config pull.ff only       # fast-forward only\n"
> > > -                        "\n"
> > > -                        "You can replace \"git config\" with \"git config --global\" to set a default\n"
> > > -                        "preference for all repositories. You can also pass --rebase, --no-rebase,\n"
> > > -                        "or --ff-only on the command line to override the configured default per\n"
> > > -                        "invocation.\n"));
> > > +                       "discouraged; you need to specify if you want a merge, or a rebase.\n"
> >
> > ...want a merge, a rebase, or neither.
>
> There is no "git pull --no-merge". Years ago some people argued for a
> "pull.mode=none" (essentially making "git pull" the same as "git
> fetch"). But right now there's no option to do that.
>
> There's an option to do --ff-only, but that's still a merge.

I disagree.  I'm well aware that checkout_fast_forward() (which is
what is ultimately called to do the fast-forwarding) is in a file
called merge.c, but that doesn't make it a merge.  I don't believe it
was anything more than a convenient place to dump some extra code at
the time.

> Perhaps: a merge, a rebase, or a fast-forward?

Sure, that works; in fact, that's much better than my suggestion.  I like it.

> > > +                       "You can squelch this message by running one of the following commands:\n"
> > > +                       "\n"
> > > +                       "  git config pull.rebase false  # merge (the default strategy)\n"
> >
> > Should this be labelled as the default given the desire to make
> > --ff-only the default?  Perhaps I'm jumping ahead and you plan to
> > change that later in this series.
>
> That's right.
>
> In the previous series which does indeed make "pull.mode=ff-only" the
> default [1], I do change the warning to specify the future default
> [2], but in that series the warnings is changed to:
>
>   The pull was not fast-forward, in the future you will have to choose
> a merge, or a rebase.
>   To squelch this message and maintain the current behavior, use:
>
>     git config --global pull.mode merge
>
>   To squelch this message and adopt the new behavior now, use:
>
>     git config --global push.mode ff-only
>
>   Falling back to old style for now (merge).
>   Read "git pull --help" for more information.
>
> Since that series didn't get any traction, I decided to only implement
> step 1: fix the current situation. And later on another series would
> do step 2: introduce "pull.mode=ff-only" and do the preparations to
> make it the default.

I like this longer plan.  However, on the shorter scale plan...I think
the suggestion to use "git pull --no-rebase" makes the current
situation worse rather than fixing it.

> > > +                       "  git config pull.rebase true   # rebase\n"
> > > +                       "  git config pull.ff only       # fast-forward only\n"
> > > +                       "\n"
> > > +                       "You can replace \"git config\" with \"git config --global\" to set a default\n"
> > > +                       "preference for all repositories.\n"
> >
> > Good up to here.
> >
> > > +                       "If unsure, run \"git pull --no-rebase\".\n"
> >
> > Why is that safe to suggest?  The original text may not have been the
> > easiest to parse, but this seems more problematic to me.
>
> Because "git pull" has been doing the same as "git pull --no-rebase"
> for more than a decade. It's safe for people to continue with this
> behavior for a few more months.
>
> Some people need to get things done today, and they are not interested
> in future changes, nor changing their default configuration, or what
> the warning has to say.
>
> They just want "git pull" to do the same as yesterday, and the year
> before, without being bothered with an annoying warning.
>
> Those people can start training their fingers to do "git pull
> --merge", and learn the problems with "git pull" later.
>
> We want to respect the user's time, and not force them to read the
> warning today.

The warning was added because sending users down paths that break
things badly is a waste of user's time, and often a much bigger waste
of user's time than making them read up on the meaning behind the two
different choices of what kind of changes they can make.  I agree the
warning went too far, but I fully agree with the original folks who
put this warning here that we need to have it for at least some cases
and that there is a decision to be made.  Though I am just one voice,
and perhaps others will agree with you on your point here, I'll
continue to disagree with blindly suggesting "git pull --no-rebase".

> > > +                       "Read \"git pull --help\" for more information."
> >
> > Nice addition.
>
> Especially since now it explains what a fast-forward is.

Indeed.  :-)

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 04/14] pull: cleanup autostash check
  2020-12-05  0:47     ` Felipe Contreras
@ 2020-12-05  0:57       ` Elijah Newren
  0 siblings, 0 replies; 79+ messages in thread
From: Elijah Newren @ 2020-12-05  0:57 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 4:47 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> On Fri, Dec 4, 2020 at 5:07 PM Elijah Newren <newren@gmail.com> wrote:
> >
> > On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> > <felipe.contreras@gmail.com> wrote:
> > >
> > > This essentially reverts commit f15e7cf5cc.
> > >
> > > Once commit d9f15d37f1 introduced the autostash option for the merge
> > > mode, it's not necessary to skip the fast-forward run_merge() when
> > > autostash is set.
> >
> > It helps reviewers and future code readers if you provide a little
> > context when referring to commits, making use of git log's
> > --pretty=reference option to get the output.
>
> Yes, I actually have this alias:
>
>   short = show --quiet --format='%C(auto)%h (%s)%C(reset)'
>
> Which shows almost the same thing. I've updated it to
> --format=reference. Thanks for the suggestion.
>
> And I usually add those descriptions.
>
> > So, for example, here
> > your commit would read:
> >
> > """
> > This essentially reverts commit f15e7cf5cc (pull: ff --rebase
> > --autostash works in dirty repo, 2017-06-01).
> >
> > Once commit d9f15d37f1 (pull: pass --autostash to merge, 2020-04-07)
> > introduced the autostash option for the merge
> > mode, it's not necessary to skip the fast-forward run_merge() when
> > autostash is set.
> > """
> >
> > I still found it slightly hard to follow the explanation even with the
> > added summaries, though.
>
> And that's the reason I didn't add them. You need to look at both the
> commits to understand why one cancels the other. In my opinion in this
> particular case the description only makes the text harder to read.
>
> Probably some better $subjects like f15e7cf5cc (pull: skip ff merge
> shortcut on --rebase --autostash) would have helped.
>
> > An extra sentence at the end of the second
> > paragraph to make it clear what is being changed ("So, change the code
> > to fast-forward even when autostash is set.") seems to help.
>
> OK. That's implied by "it's not necessary to skip the fast-forward"
> but it's better to be explicit.
>
> How about this:
>
> Currently "git pull --rebase" takes a shortcut in the case a
> fast-forward merge is possible; run_merge() is called with --ff-only.
>
> However, "git merge" didn't have an --autostash option, so, when "git
> pull --rebase --autostash" was called *and* the fast-forward merge
> shortcut was taken, then the pull failed.
>
> This was fixed in commit f15e7cf5cc (pull: ff --rebase --autostash
> works in dirty repo, 2017-06-01) by simply skipping the fast-forward
> merge shortcut.
>
> Later on "git merge" learned the --autostash option [a03b55530a
> (merge: teach --autostash option, 2020-04-07)], and so did "git pull"
> [d9f15d37f1 (pull: pass --autostash to merge, 2020-04-07)].
>
> Therefore it's not necessary to skip the fast-forward merge shortcut
> anymore when called with --rebase --autostash.
>
> Let's always take the fast-forward merge shortcut by essentially
> reverting f15e7cf5cc.

Yes, very nice!  Thanks.

Elijah

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 07/14] pull: display default warning only when non-ff
  2020-12-04 23:24   ` Elijah Newren
@ 2020-12-05  1:03     ` Felipe Contreras
  0 siblings, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05  1:03 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 5:24 PM Elijah Newren <newren@gmail.com> wrote:
>
> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > There's no need to display the annoying warning on every pull... only
> > the ones that are not fast-forward.
>
> I like this.  :-)
>
> > This requires the tests to pick another base, so the merge is not
> > fast-forward.
> >
> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> > ---
> >  Documentation/git-pull.txt   |  3 +++
> >  builtin/pull.c               |  2 +-
> >  t/t7601-merge-pull-config.sh | 28 +++++++++++++++++-----------
> >  3 files changed, 21 insertions(+), 12 deletions(-)
> >
> > diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
> > index dc812139f4..ad33d2472c 100644
> > --- a/Documentation/git-pull.txt
> > +++ b/Documentation/git-pull.txt
> > @@ -60,6 +60,9 @@ However, a non-fast-foward case looks very different.
> >         origin/master in your repository
> >  ------------
> >
> > +By default `git pull` will warn about these situations, however, most likely
> > +you would want to force a merge, which you can do with `git pull --no-rebase`.
> > +
>
> Everything in this sentence after the first comma seems dangerous to
> me for a number of workflows.

And this is precisely the reason why the default of "git pull" must be
changed to --ff-only (or similar).

But today "git pull" by default is the equivalent of "git pull
--merge". We need to explain to users why the warning is there, and
that "git pull" is doing an implicit "git pull --merge", and if they
do it explicitly they can get rid of the warning.

Later on when the default is changed to --ff-only this text can be
updated to something less dangerous.

But not explaining what "git pull" is doing today by default will not
make it any less dangerous.

> >  Then "`git pull`" will fetch and replay the changes from the remote
> >  `master` branch since it diverged from the local `master` (i.e., `E`)
> >  until its current commit (`C`) on top of `master` and record the
> > diff --git a/builtin/pull.c b/builtin/pull.c
> > index f82e214fc8..f0b1c6bfea 100644
> > --- a/builtin/pull.c
> > +++ b/builtin/pull.c
> > @@ -1013,7 +1013,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
> >
> >         can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);
> >
> > -       if (default_mode && opt_verbosity >= 0 && !opt_ff) {
> > +       if (default_mode && !can_ff && opt_verbosity >= 0 && !opt_ff) {
> >                 advise(_("Pulling without specifying how to reconcile divergent branches is\n"
> >                         "discouraged; you need to specify if you want a merge, or a rebase.\n"
> >                         "You can squelch this message by running one of the following commands:\n"
> > diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
> > index 6774e9d86f..6b4adab8b1 100755
> > --- a/t/t7601-merge-pull-config.sh
> > +++ b/t/t7601-merge-pull-config.sh
> > @@ -28,7 +28,7 @@ test_expect_success 'setup' '
> >  '
> >
> >  test_expect_success 'pull.rebase not set' '
> > -       git reset --hard c0 &&
> > +       git reset --hard c2 &&
> >         git -c color.advice=always pull . c1 2>err &&
> >         test_decode_color <err >decoded &&
> >         test_i18ngrep "<YELLOW>hint: " decoded &&
> > @@ -36,54 +36,60 @@ test_expect_success 'pull.rebase not set' '
> >
> >  '
> >
> > -test_expect_success 'pull.rebase not set and pull.ff=true' '
> > +test_expect_success 'pull.rebase not set (fast-forward)' '
> >         git reset --hard c0 &&
> > +       git pull . c1 2>err &&
> > +       test_i18ngrep ! "Pulling without specifying how to reconcile" err
> > +'
> > +
> > +test_expect_success 'pull.rebase not set and pull.ff=true' '
> > +       git reset --hard c2 &&
> >         test_config pull.ff true &&
> >         git pull . c1 2>err &&
> >         test_i18ngrep ! "Pulling without specifying how to reconcile" err
> >  '
> >
> >  test_expect_success 'pull.rebase not set and pull.ff=false' '
> > -       git reset --hard c0 &&
> > +       git reset --hard c2 &&
> >         test_config pull.ff false &&
> >         git pull . c1 2>err &&
> >         test_i18ngrep ! "Pulling without specifying how to reconcile" err
> >  '
> >
> >  test_expect_success 'pull.rebase not set and pull.ff=only' '
> > -       git reset --hard c0 &&
> > +       git reset --hard c2 &&
> >         test_config pull.ff only &&
> > -       git pull . c1 2>err &&
> > +       test_must_fail git pull . c1 2>err &&
>
> It makes sense to me that you'd need test_must_fail here...but why
> wasn't it needed before??  How did this test pass without it before
> this series?

Because before it was a fast-forward (from c0), not so anymore (from
c2); "pull.ff=only" fails if it's not a fast-forward.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 09/14] pull: introduce --merge option
  2020-12-04 23:27   ` Elijah Newren
@ 2020-12-05  1:06     ` Felipe Contreras
  0 siblings, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05  1:06 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 5:27 PM Elijah Newren <newren@gmail.com> wrote:
>
> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > Previously --no-rebase (which still works for backwards compatbility).
> >
> > Now we can update the default warning, and the git-pull(1) man page to
> > use --merge instead of the non-intuitive --no-rebase.
> >
> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> > ---
> >  Documentation/git-pull.txt   | 9 ++++++---
> >  builtin/pull.c               | 4 +++-
> >  t/t7601-merge-pull-config.sh | 4 ++--
> >  3 files changed, 11 insertions(+), 6 deletions(-)
> >
> > diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
> > index ad33d2472c..c220da143a 100644
> > --- a/Documentation/git-pull.txt
> > +++ b/Documentation/git-pull.txt
> > @@ -61,7 +61,7 @@ However, a non-fast-foward case looks very different.
> >  ------------
> >
> >  By default `git pull` will warn about these situations, however, most likely
> > -you would want to force a merge, which you can do with `git pull --no-rebase`.
> > +you would want to force a merge, which you can do with `git pull --merge`.
>
> I'm glad you updated all the references, but as noted earlier in the
> series I think this suggestion is problematic.

Yeah, but the danger comes straight from what "git pull" does by
default (an implicit "git pull --merge").

It's not the text that is dangerous; it's the default behavior.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 10/14] pull: add proper error with --ff-only
  2020-12-04 23:34   ` Elijah Newren
@ 2020-12-05  1:18     ` Felipe Contreras
  0 siblings, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05  1:18 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 5:34 PM Elijah Newren <newren@gmail.com> wrote:
>
> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > The current error is not user-friendly:
> >
> >   fatal: not possible to fast-forward, aborting.
> >
> > We want something that actually explains what is going on:
> >
> >   The pull was not fast-forward, please either merge or rebase.
> >   If unsure, run "git pull --merge".
>
> Sorry to be a broken record, but I don't like the suggestion in the
> second sentence.  I've said it enough times that I'll quit harping on
> each instance.

In this particular case it does make sense to remove the suggestion,
since it has nothing to do with the current "git pull" default.

The user must decide in this case.

> > The user can get rid of the warning by doing either --merge or
> > --rebase.
> >
> > Except: doing "git pull --merge" is not actually enough; we would return
> > to the previous behavior: "fatal: not possible to fast-forward, aborting."
>
> Do you mean that the changes in this patch aren't enough and that
> future patches will address this shortcoming?  Or do you mean that
> prior to this patch such a bug existed?  Or something else?

I mean this is the shortcoming of using the --ff-only approach, and
why I think a "pull.mode=ff-only" must be introduced.

This patch does as much as it can without changing the semantics of
--ff-only, and it shows the limitations of the approach, as you can
see from the failed test below, and the next patch.

It's inherent to the current behavior of --ff-only.

> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> > ---
> >  builtin/pull.c  | 34 ++++++++++++++++-----------
> >  t/t5520-pull.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 82 insertions(+), 14 deletions(-)
> >
> > diff --git a/builtin/pull.c b/builtin/pull.c
> > index 6ea95c9fc9..f54ff36b57 100644
> > --- a/builtin/pull.c
> > +++ b/builtin/pull.c
> > @@ -1015,20 +1015,26 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
> >
> >         can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);
> >
> > -       if (default_mode && !can_ff && opt_verbosity >= 0 && !opt_ff) {
> > -               advise(_("Pulling without specifying how to reconcile divergent branches is\n"
> > -                       "discouraged; you need to specify if you want a merge, or a rebase.\n"
> > -                       "You can squelch this message by running one of the following commands:\n"
> > -                       "\n"
> > -                       "  git config pull.rebase false  # merge (the default strategy)\n"
> > -                       "  git config pull.rebase true   # rebase\n"
> > -                       "  git config pull.ff only       # fast-forward only\n"
> > -                       "\n"
> > -                       "You can replace \"git config\" with \"git config --global\" to set a default\n"
> > -                       "preference for all repositories.\n"
> > -                       "If unsure, run \"git pull --merge\".\n"
> > -                       "Read \"git pull --help\" for more information."
> > -                       ));
> > +       if (!can_ff && default_mode) {
> > +               if (opt_ff && !strcmp(opt_ff, "--ff-only")) {
> > +                       die(_("The pull was not fast-forward, please either merge or rebase.\n"
> > +                               "If unsure, run \"git pull --merge\"."));
>
> This is a much better message for when the user requests --ff-only.

Right. Sans the "git pull --merge" comment :p

> > +               }
> > +               if (opt_verbosity >= 0 && !opt_ff) {
> > +                       advise(_("Pulling without specifying how to reconcile divergent branches is\n"
> > +                               "discouraged; you need to specify if you want a merge, or a rebase.\n"
> > +                               "You can squelch this message by running one of the following commands:\n"
> > +                               "\n"
> > +                               "  git config pull.rebase false  # merge (the default strategy)\n"
> > +                               "  git config pull.rebase true   # rebase\n"
> > +                               "  git config pull.ff only       # fast-forward only\n"
> > +                               "\n"
> > +                               "You can replace \"git config\" with \"git config --global\" to set a default\n"
> > +                               "preference for all repositories.\n"
> > +                               "If unsure, run \"git pull --merge\".\n"
> > +                               "Read \"git pull --help\" for more information."
> > +                               ));
> > +               }
> >         }
> >
> >         if (opt_rebase) {
> > diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
> > index 9fae07cdfa..fdd1f79b06 100755
> > --- a/t/t5520-pull.sh
> > +++ b/t/t5520-pull.sh
> > @@ -819,4 +819,66 @@ test_expect_success 'git pull --rebase against local branch' '
> >         test_cmp expect file2
> >  '
> >
> > +test_expect_success 'git pull fast-forward (ff-only)' '
> > +       test_when_finished "git checkout master && git branch -D other test" &&
> > +       test_config pull.ff only &&
> > +       git checkout -b other master &&
> > +       >new &&
> > +       git add new &&
> > +       git commit -m new &&
> > +       git checkout -b test -t other &&
> > +       git reset --hard master &&
> > +       git pull
> > +'
> > +
> > +test_expect_success 'git pull non-fast-forward (ff-only)' '
> > +       test_when_finished "git checkout master && git branch -D other test" &&
> > +       test_config pull.ff only &&
> > +       git checkout -b other master^ &&
> > +       >new &&
> > +       git add new &&
> > +       git commit -m new &&
> > +       git checkout -b test -t other &&
> > +       git reset --hard master &&
> > +       test_must_fail git pull
> > +'
> > +
> > +test_expect_failure 'git pull non-fast-forward with merge (ff-only)' '
> > +       test_when_finished "git checkout master && git branch -D other test" &&
> > +       test_config pull.ff only &&
> > +       git checkout -b other master^ &&
> > +       >new &&
> > +       git add new &&
> > +       git commit -m new &&
> > +       git checkout -b test -t other &&
> > +       git reset --hard master &&
> > +       git pull --no-rebase
>
> Do you mean `git pull --merge`?

Yes. You found all the issues I spotted in my last review after I sent
the patches.

Good eyes.

Already fixed.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 01/14] doc: pull: explain what is a fast-forward
  2020-12-04  6:16 ` [PATCH v2 01/14] doc: pull: explain what is a fast-forward Felipe Contreras
  2020-12-04 22:55   ` Elijah Newren
@ 2020-12-05  1:21   ` Jacob Keller
  1 sibling, 0 replies; 79+ messages in thread
From: Jacob Keller @ 2020-12-05  1:21 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git mailing list, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Elijah Newren,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> We want users to know what is a fast-forward in order to understand the
> default warning.
>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  Documentation/git-pull.txt | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
> index 5c3fb67c01..dc812139f4 100644
> --- a/Documentation/git-pull.txt
> +++ b/Documentation/git-pull.txt
> @@ -38,6 +38,20 @@ as set by linkgit:git-branch[1] `--track`.
>  Assume the following history exists and the current branch is
>  "`master`":
>
> +------------
> +         A---B---C master on origin
> +        /
> +    D---E master
> +------------
> +

When displayed in a regular font, this looks like it is pointing at D,
but I checked the text using a proper monospaced font (on lore) and it
is correctly pointing at E.

Makes sense.

> +Then `git pull` will merge in a fast-foward way up to the new master.
> +
> +------------
> +    D---E---A---B---C master, origin/master
> +------------
> +
> +However, a non-fast-foward case looks very different.
> +
>  ------------
>           A---B---C master on origin
>          /
> --
> 2.29.2
>

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 12/14] pull: show warning with --ff
  2020-12-04 23:41   ` Elijah Newren
@ 2020-12-05  1:25     ` Felipe Contreras
  0 siblings, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05  1:25 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 5:41 PM Elijah Newren <newren@gmail.com> wrote:
>
> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > It's unclear why --ff should remove the warning, since:
> >
> >   git pull --ff
> >
> > Is implicitly the same as:
> >
> >   git pull
> >
> > Unless of course pull.ff is specified otherwise.
> >
> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> > ---
> >  builtin/pull.c               | 2 +-
> >  t/t7601-merge-pull-config.sh | 4 ++--
> >  2 files changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/builtin/pull.c b/builtin/pull.c
> > index ebf2ac687b..e389ffcdc3 100644
> > --- a/builtin/pull.c
> > +++ b/builtin/pull.c
> > @@ -1020,7 +1020,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
> >                         die(_("The pull was not fast-forward, please either merge or rebase.\n"
> >                                 "If unsure, run \"git pull --merge\"."));
> >                 }
> > -               if (opt_verbosity >= 0 && !opt_ff) {
> > +               if (opt_verbosity >= 0 && (!opt_ff || !strcmp(opt_ff, "--ff"))) {
> >                         advise(_("Pulling without specifying how to reconcile divergent branches is\n"
> >                                 "discouraged; you need to specify if you want a merge, or a rebase.\n"
> >                                 "You can squelch this message by running one of the following commands:\n"
> > diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
> > index 1de64e6cc5..d709799f8b 100755
> > --- a/t/t7601-merge-pull-config.sh
> > +++ b/t/t7601-merge-pull-config.sh
> > @@ -46,7 +46,7 @@ test_expect_success 'pull.rebase not set and pull.ff=true' '
> >         git reset --hard c2 &&
> >         test_config pull.ff true &&
> >         git pull . c1 2>err &&
> > -       test_i18ngrep ! "Pulling without specifying how to reconcile" err
> > +       test_i18ngrep "Pulling without specifying how to reconcile" err
> >  '
> >
> >  test_expect_success 'pull.rebase not set and pull.ff=false' '
> > @@ -78,7 +78,7 @@ test_expect_success 'pull.rebase not set and --merge given' '
> >  test_expect_success 'pull.rebase not set and --ff given' '
> >         git reset --hard c2 &&
> >         git pull --ff . c1 2>err &&
> > -       test_i18ngrep ! "Pulling without specifying how to reconcile" err
> > +       test_i18ngrep "Pulling without specifying how to reconcile" err
> >  '
> >
> >  test_expect_success 'pull.rebase not set and --no-ff given' '
> > --
> > 2.29.2
>
> Ah, this answers one of my earlier questions.  I'd be tempted to move
> this earlier in the series; it seems like an obvious cleanup and helps
> explain the "opt_ff" flag that keeps coming up for readers of the
> series.

I tend to put more controversial and less useful patches later in the
series, and this is the one I was least sure of getting consensus nor
does it solve any current issues.

I just found it inconsistent.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 14/14] test: pull-options: revert unnecessary changes
  2020-12-04 23:49   ` Elijah Newren
@ 2020-12-05  1:28     ` Felipe Contreras
  0 siblings, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05  1:28 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 5:49 PM Elijah Newren <newren@gmail.com> wrote:
>
> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > Commit d18c950a69 changed these tests, but it's unclear why. Probably
> > because earlier versions of the patch series died instead of printing a
> > warning.
>
> Another case where log --pretty=reference notation would be more
> helpful in referring to commits.
>
> Looking up that commit, I see that commit made a number of other test
> changes which seem to be better motivated by the commit message and
> code changes.  I wonder if we could make that clearer in the commit
> message somehow.  Perhaps
>
> Commit d18c950a69 ("pull: warn if the user didn't say whether to
> rebase or to merge", 2020-03-09) changed a number of tests in t5521
> and added some new tests in t7601, but it is not clear why the changes
> in t5521 were made...

Fine by me.

I had a mind to do some mail archeology and find the likely reason
myself, but we all have limited time on this Earth.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-05  0:56       ` Elijah Newren
@ 2020-12-05  1:56         ` Felipe Contreras
  2020-12-05  9:23           ` Chris Torek
  2020-12-05 16:28           ` Elijah Newren
  2020-12-07  9:23         ` Felipe Contreras
  1 sibling, 2 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05  1:56 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 6:56 PM Elijah Newren <newren@gmail.com> wrote:
>
> Hi Felipe,
>
> On Fri, Dec 4, 2020 at 4:12 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > On Fri, Dec 4, 2020 at 5:00 PM Elijah Newren <newren@gmail.com> wrote:
> > >
> > > On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> > > <felipe.contreras@gmail.com> wrote:
> > > >
> > > > We want to:
> > > >
> > > > 1. Be clear about what "specifying" means; merge or rebase.
> > > > 2. Mention a direct shortcut for people that just want to get on with
> > > >    their lives: git pull --no-rebase.
> > >
> > > This is a shortcut for what?
> >
> >   git config --global pull.rebase false
> >   git pull
> >
> > It's a shorter way of saying: "do a 'git pull' like you've always done
> > but don't warn me".
> >
> > > > 3. Have a quick reference for users to understand what this
> > > >    "fast-forward" business means.
> > > >
> > > > This patch does all three.
> > > >
> > > > Thanks to the previous patch now "git pull --help" explains what a
> > > > fast-forward is, and a further patch changes --no-rebase to --merge so
> > > > it's actually user friendly.
> > > >
> > > > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> > > > ---
> > > >  builtin/pull.c | 23 ++++++++++++-----------
> > > >  1 file changed, 12 insertions(+), 11 deletions(-)
> > > >
> > > > diff --git a/builtin/pull.c b/builtin/pull.c
> > > > index 1034372f8b..22a9ffcade 100644
> > > > --- a/builtin/pull.c
> > > > +++ b/builtin/pull.c
> > > > @@ -346,17 +346,18 @@ static enum rebase_type config_get_rebase(void)
> > > >
> > > >         if (opt_verbosity >= 0 && !opt_ff) {
> > > >                 advise(_("Pulling without specifying how to reconcile divergent branches is\n"
> > > > -                        "discouraged. You can squelch this message by running one of the following\n"
> > > > -                        "commands sometime before your next pull:\n"
> > > > -                        "\n"
> > > > -                        "  git config pull.rebase false  # merge (the default strategy)\n"
> > > > -                        "  git config pull.rebase true   # rebase\n"
> > > > -                        "  git config pull.ff only       # fast-forward only\n"
> > > > -                        "\n"
> > > > -                        "You can replace \"git config\" with \"git config --global\" to set a default\n"
> > > > -                        "preference for all repositories. You can also pass --rebase, --no-rebase,\n"
> > > > -                        "or --ff-only on the command line to override the configured default per\n"
> > > > -                        "invocation.\n"));
> > > > +                       "discouraged; you need to specify if you want a merge, or a rebase.\n"
> > >
> > > ...want a merge, a rebase, or neither.
> >
> > There is no "git pull --no-merge". Years ago some people argued for a
> > "pull.mode=none" (essentially making "git pull" the same as "git
> > fetch"). But right now there's no option to do that.
> >
> > There's an option to do --ff-only, but that's still a merge.
>
> I disagree.  I'm well aware that checkout_fast_forward() (which is
> what is ultimately called to do the fast-forwarding) is in a file
> called merge.c, but that doesn't make it a merge.  I don't believe it
> was anything more than a convenient place to dump some extra code at
> the time.

Right. Maybe my mind is tainted by doing so many fast-forward "git
merge"s to update the current branch.

But in my mind "fast-forward" is not a noun, it's an adjective, so I
still expect a noun: fast-forward $what. And I don't have any other
noun to put there but "merge".

> > Perhaps: a merge, a rebase, or a fast-forward?
>
> Sure, that works; in fact, that's much better than my suggestion.  I like it.

Great.

> > > > +                       "You can squelch this message by running one of the following commands:\n"
> > > > +                       "\n"
> > > > +                       "  git config pull.rebase false  # merge (the default strategy)\n"
> > >
> > > Should this be labelled as the default given the desire to make
> > > --ff-only the default?  Perhaps I'm jumping ahead and you plan to
> > > change that later in this series.
> >
> > That's right.
> >
> > In the previous series which does indeed make "pull.mode=ff-only" the
> > default [1], I do change the warning to specify the future default
> > [2], but in that series the warnings is changed to:
> >
> >   The pull was not fast-forward, in the future you will have to choose
> > a merge, or a rebase.
> >   To squelch this message and maintain the current behavior, use:
> >
> >     git config --global pull.mode merge
> >
> >   To squelch this message and adopt the new behavior now, use:
> >
> >     git config --global push.mode ff-only
> >
> >   Falling back to old style for now (merge).
> >   Read "git pull --help" for more information.
> >
> > Since that series didn't get any traction, I decided to only implement
> > step 1: fix the current situation. And later on another series would
> > do step 2: introduce "pull.mode=ff-only" and do the preparations to
> > make it the default.
>
> I like this longer plan.

Yeah. It's a better plan, just more work for me.

> However, on the shorter scale plan...I think
> the suggestion to use "git pull --no-rebase" makes the current
> situation worse rather than fixing it.

Well, I already said I partly agree with you: in the --ff-only case
the suggestion should not be brought forward.

But in the "git pull" default case, *today* it's doing a merge. If
uttering --merge and thus making the current behavior explicit instead
of implicit seems dangerous it's because it is. But not documenting it
doesn't make it any less dangerous.

> > > > +                       "  git config pull.rebase true   # rebase\n"
> > > > +                       "  git config pull.ff only       # fast-forward only\n"
> > > > +                       "\n"
> > > > +                       "You can replace \"git config\" with \"git config --global\" to set a default\n"
> > > > +                       "preference for all repositories.\n"
> > >
> > > Good up to here.
> > >
> > > > +                       "If unsure, run \"git pull --no-rebase\".\n"
> > >
> > > Why is that safe to suggest?  The original text may not have been the
> > > easiest to parse, but this seems more problematic to me.
> >
> > Because "git pull" has been doing the same as "git pull --no-rebase"
> > for more than a decade. It's safe for people to continue with this
> > behavior for a few more months.
> >
> > Some people need to get things done today, and they are not interested
> > in future changes, nor changing their default configuration, or what
> > the warning has to say.
> >
> > They just want "git pull" to do the same as yesterday, and the year
> > before, without being bothered with an annoying warning.
> >
> > Those people can start training their fingers to do "git pull
> > --merge", and learn the problems with "git pull" later.
> >
> > We want to respect the user's time, and not force them to read the
> > warning today.
>
> The warning was added because sending users down paths that break
> things badly is a waste of user's time, and often a much bigger waste
> of user's time than making them read up on the meaning behind the two
> different choices of what kind of changes they can make.  I agree the
> warning went too far, but I fully agree with the original folks who
> put this warning here that we need to have it for at least some cases
> and that there is a decision to be made.  Though I am just one voice,
> and perhaps others will agree with you on your point here, I'll
> continue to disagree with blindly suggesting "git pull --no-rebase".

I think the warning is good. I implemented something like that years
ago, and I believe Junio did so too. It should have been implemented
differently though.

And yes, we want to annoy the users, and nudge them in the right
direction, but still leave them the *option* to easily ignore us.

I'm against forcing anyone to do anything. If the user wants to
analyze the warning, they can do so, if not, they can just do $cmd and
go about their day as usual. But they were warned.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only
  2020-12-04 23:39   ` Elijah Newren
@ 2020-12-05  4:01     ` Felipe Contreras
  2020-12-05  4:06       ` [PATCH] experiment: pull: change --ff-only and default mode Felipe Contreras
  2020-12-05 11:37       ` [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only Felipe Contreras
  0 siblings, 2 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05  4:01 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 5:39 PM Elijah Newren <newren@gmail.com> wrote:
>
> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > We want --ff-only to make sense only when no --merge or --rebase option
> > is specified.
>
> A lot of git commands have opposite options, and git allows them both
> to be specified with the last one winning.  Thus, much like
>   git log --patch --no-patch
> mean show logs without patches and
>   git log --no-patch --patch
> means show logs with patches, I would similarly expect the following
> two commands to have opposite behavior:
>   git pull --merge --no-ff
>   git pull --no-ff --merge

Good point.

Although I presume you meant --ff-only.

Taking that into consideration it may be possible to make --ff-only
work straightforwardly.

Further changes to the code are needed though. In the meantime I'm
sending a quick patch on top of this series.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH] experiment: pull: change --ff-only and default mode
  2020-12-05  4:01     ` Felipe Contreras
@ 2020-12-05  4:06       ` Felipe Contreras
  2020-12-05 17:29         ` Elijah Newren
  2020-12-05 11:37       ` [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only Felipe Contreras
  1 sibling, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05  4:06 UTC (permalink / raw)
  To: Elijah Newren; +Cc: Git Mailing List, Felipe Contreras

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/pull.c  | 40 ++++++++++++++++++++++++++--------------
 t/t5520-pull.sh | 23 +++++++++++++++++++++++
 2 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/builtin/pull.c b/builtin/pull.c
index e389ffcdc3..95ecbdaad5 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -62,6 +62,7 @@ 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;
+	if (*value != REBASE_INVALID) default_mode = 0;
 	return *value == REBASE_INVALID ? -1 : 0;
 }
 
@@ -114,6 +115,23 @@ static int opt_show_forced_updates = -1;
 static char *set_upstream;
 static struct strvec opt_fetch = STRVEC_INIT;
 
+static int parse_opt_ff_only(const struct option *opt, const char *arg, int unset)
+{
+	char **value = opt->value;
+	opt_rebase = REBASE_FALSE;
+	*value = "--ff-only";
+	return 0;
+}
+
+static int parse_opt_merge(const struct option *opt, const char *arg, int unset)
+{
+	char **value = opt->value;
+	opt_ff = NULL;
+	*value = REBASE_FALSE;
+	default_mode = 0;
+	return 0;
+}
+
 static struct option pull_options[] = {
 	/* Shared options */
 	OPT__VERBOSITY(&opt_verbosity),
@@ -131,8 +149,9 @@ static struct option pull_options[] = {
 		"(false|true|merges|preserve|interactive)",
 		N_("incorporate changes by rebasing rather than merging"),
 		PARSE_OPT_OPTARG, parse_opt_rebase),
-	OPT_SET_INT('m', "merge", &opt_rebase,
-		N_("incorporate changes by merging"), 0),
+	OPT_CALLBACK_F('m', "merge", &opt_rebase, NULL,
+		N_("incorporate changes by merging"),
+		PARSE_OPT_NOARG | PARSE_OPT_NONEG, parse_opt_merge),
 	OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,
 		N_("do not show a diffstat at the end of the merge"),
 		PARSE_OPT_NOARG | PARSE_OPT_NONEG),
@@ -161,9 +180,9 @@ static struct option pull_options[] = {
 	OPT_PASSTHRU(0, "ff", &opt_ff, NULL,
 		N_("allow fast-forward"),
 		PARSE_OPT_NOARG),
-	OPT_PASSTHRU(0, "ff-only", &opt_ff, NULL,
+	OPT_CALLBACK_F(0, "ff-only", &opt_ff, NULL,
 		N_("abort if fast-forward is not possible"),
-		PARSE_OPT_NOARG | PARSE_OPT_NONEG),
+		PARSE_OPT_NOARG | PARSE_OPT_NONEG, parse_opt_ff_only),
 	OPT_PASSTHRU(0, "verify-signatures", &opt_verify_signatures, NULL,
 		N_("verify that the named commit has a valid GPG signature"),
 		PARSE_OPT_NOARG),
@@ -924,6 +943,9 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 
 	git_config(git_pull_config, NULL);
 
+	opt_ff = xstrdup_or_null(config_get_ff());
+	opt_rebase = config_get_rebase();
+
 	argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);
 
 	if (cleanup_arg)
@@ -935,12 +957,6 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 
 	parse_repo_refspecs(argc, argv, &repo, &refspecs);
 
-	if (!opt_ff)
-		opt_ff = xstrdup_or_null(config_get_ff());
-
-	if (opt_rebase < 0)
-		opt_rebase = config_get_rebase();
-
 	if (read_cache_unmerged())
 		die_resolve_conflict("pull");
 
@@ -1037,10 +1053,6 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 		}
 	}
 
-	/* Disable --ff-only when --merge is specified */
-	if (!can_ff && !default_mode && !opt_rebase && opt_ff && !strcmp(opt_ff, "--ff-only"))
-		opt_ff = NULL;
-
 	if (opt_rebase) {
 		int ret = 0;
 		if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index f48d0f8d50..c0cfde54e1 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -881,4 +881,27 @@ test_expect_success 'git pull non-fast-forward error message' '
 	grep -q "The pull was not fast-forward" error
 '
 
+test_expect_success 'git pull --merge overrides --ffonly' '
+	test_when_finished "git checkout master && git branch -D other test" &&
+	test_config pull.ff only &&
+	git checkout -b other master^ &&
+	>new &&
+	git add new &&
+	git commit -m new &&
+	git checkout -b test -t other &&
+	git reset --hard master &&
+	git pull --ff-only --merge
+'
+
+test_expect_success 'git pull --ff-only overrides --merge' '
+	test_when_finished "git checkout master && git branch -D other test" &&
+	git checkout -b other master^ &&
+	>new &&
+	git add new &&
+	git commit -m new &&
+	git checkout -b test -t other &&
+	git reset --hard master &&
+	test_must_fail git pull --merge --ff-only
+'
+
 test_done
-- 
2.29.2


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-05  1:56         ` Felipe Contreras
@ 2020-12-05  9:23           ` Chris Torek
  2020-12-05 11:47             ` Felipe Contreras
  2020-12-05 16:28           ` Elijah Newren
  1 sibling, 1 reply; 79+ messages in thread
From: Chris Torek @ 2020-12-05  9:23 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Elijah Newren, Git Mailing List, Vít Ondruch, Alex Henrie,
	Junio C Hamano, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	Jacob Keller, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King

On Fri, Dec 4, 2020 at 5:59 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
> But in my mind "fast-forward" is not a noun, it's an adjective, so I
> still expect a noun: fast-forward $what. And I don't have any other
> noun to put there but "merge".

It's a "fast-forward operation". :-)

(The operands are branch name and hash ID.)

It's just been nouned, like "a merge" instead of "a merge commit".

> > > Perhaps: a merge, a rebase, or a fast-forward?
> >
> > Sure, that works; in fact, that's much better than my suggestion.  I like it.

I like this one too.

In a perfect world, I'd have had `git pull` be the user facing command
that does one of: fetch only, fetch-and-fast-forward, fetch-and-rebase,
or fetch-and-merge.  (Obviously one can achieve the fetch-only by
running `git fetch`, but `git fetch` is a plumbing command.)

In that same perfect world, the default probably would have been
fetch only, but fetch-and-fast-forward (or fail if not fast-forward-able)
seems like an OK default as well. But we have to deal with the
imperfect world we have. This seems like an OK way to do that.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only
  2020-12-05  4:01     ` Felipe Contreras
  2020-12-05  4:06       ` [PATCH] experiment: pull: change --ff-only and default mode Felipe Contreras
@ 2020-12-05 11:37       ` Felipe Contreras
  1 sibling, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05 11:37 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 10:01 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> On Fri, Dec 4, 2020 at 5:39 PM Elijah Newren <newren@gmail.com> wrote:
> >
> > On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> > <felipe.contreras@gmail.com> wrote:
> > >
> > > We want --ff-only to make sense only when no --merge or --rebase option
> > > is specified.
> >
> > A lot of git commands have opposite options, and git allows them both
> > to be specified with the last one winning.  Thus, much like
> >   git log --patch --no-patch
> > mean show logs without patches and
> >   git log --no-patch --patch
> > means show logs with patches, I would similarly expect the following
> > two commands to have opposite behavior:
> >   git pull --merge --no-ff
> >   git pull --no-ff --merge
>
> Good point.
>
> Although I presume you meant --ff-only.
>
> Taking that into consideration it may be possible to make --ff-only
> work straightforwardly.
>
> Further changes to the code are needed though. In the meantime I'm
> sending a quick patch on top of this series.

Nevermind.

I have implemented the changes properly and v3 is ready with some
interesting improvements, but it is still not straightforward.

Currently "git pull --ff-only --merge" fails with:

  fatal: Not possible to fast-forward, aborting.

With the proposed change --merge would override --ff-only and make the
pull essentially --no-ff.

That's still a semantic change. So there's no way around that.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-05  9:23           ` Chris Torek
@ 2020-12-05 11:47             ` Felipe Contreras
  0 siblings, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05 11:47 UTC (permalink / raw)
  To: Chris Torek
  Cc: Elijah Newren, Git Mailing List, Vít Ondruch, Alex Henrie,
	Junio C Hamano, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	Jacob Keller, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King

On Sat, Dec 5, 2020 at 3:23 AM Chris Torek <chris.torek@gmail.com> wrote:
>
> On Fri, Dec 4, 2020 at 5:59 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> > But in my mind "fast-forward" is not a noun, it's an adjective, so I
> > still expect a noun: fast-forward $what. And I don't have any other
> > noun to put there but "merge".
>
> It's a "fast-forward operation". :-)

A fast-forward operation that does what?

> It's just been nouned, like "a merge" instead of "a merge commit".

Except there's a difference between telling git: "do a fast-forward
merge", and "do a fast-forward merge commit". The latter doesn't
really make sense.

> > > > Perhaps: a merge, a rebase, or a fast-forward?
> > >
> > > Sure, that works; in fact, that's much better than my suggestion.  I like it.
>
> I like this one too.
>
> In a perfect world, I'd have had `git pull` be the user facing command
> that does one of: fetch only, fetch-and-fast-forward, fetch-and-rebase,
> or fetch-and-merge.  (Obviously one can achieve the fetch-only by
> running `git fetch`, but `git fetch` is a plumbing command.)
>
> In that same perfect world, the default probably would have been
> fetch only, but fetch-and-fast-forward (or fail if not fast-forward-able)
> seems like an OK default as well. But we have to deal with the
> imperfect world we have. This seems like an OK way to do that.

In the slightly more perfect word I'm aiming for those two modes could
be achieved with the pull.mode configuration:

* "pull.mode=none" would be the same as "fetch only"
* "pull.mode=ff-only" would be the same as "fetch-and-fast-forward"

But first this configuration has to actually be introduced. It didn't
happen in 2014, maybe it will happen this time. Who knows.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-05  1:56         ` Felipe Contreras
  2020-12-05  9:23           ` Chris Torek
@ 2020-12-05 16:28           ` Elijah Newren
  2020-12-05 21:27             ` Felipe Contreras
  1 sibling, 1 reply; 79+ messages in thread
From: Elijah Newren @ 2020-12-05 16:28 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 5:56 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> On Fri, Dec 4, 2020 at 6:56 PM Elijah Newren <newren@gmail.com> wrote:
> >
> > Hi Felipe,
> >
> > On Fri, Dec 4, 2020 at 4:12 PM Felipe Contreras
> > <felipe.contreras@gmail.com> wrote:
> > >
> > > On Fri, Dec 4, 2020 at 5:00 PM Elijah Newren <newren@gmail.com> wrote:
> > > >
> > > > On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras
> > > > <felipe.contreras@gmail.com> wrote:
[...]
> > > > > +                       "You can squelch this message by running one of the following commands:\n"
> > > > > +                       "\n"
> > > > > +                       "  git config pull.rebase false  # merge (the default strategy)\n"
> > > >
> > > > Should this be labelled as the default given the desire to make
> > > > --ff-only the default?  Perhaps I'm jumping ahead and you plan to
> > > > change that later in this series.
> > >
> > > That's right.
> > >
> > > In the previous series which does indeed make "pull.mode=ff-only" the
> > > default [1], I do change the warning to specify the future default
> > > [2], but in that series the warnings is changed to:
> > >
> > >   The pull was not fast-forward, in the future you will have to choose
> > > a merge, or a rebase.
> > >   To squelch this message and maintain the current behavior, use:
> > >
> > >     git config --global pull.mode merge
> > >
> > >   To squelch this message and adopt the new behavior now, use:
> > >
> > >     git config --global push.mode ff-only
> > >
> > >   Falling back to old style for now (merge).
> > >   Read "git pull --help" for more information.
> > >
> > > Since that series didn't get any traction, I decided to only implement
> > > step 1: fix the current situation. And later on another series would
> > > do step 2: introduce "pull.mode=ff-only" and do the preparations to
> > > make it the default.
> >
> > I like this longer plan.
>
> Yeah. It's a better plan, just more work for me.
>
> > However, on the shorter scale plan...I think
> > the suggestion to use "git pull --no-rebase" makes the current
> > situation worse rather than fixing it.
>
> Well, I already said I partly agree with you: in the --ff-only case
> the suggestion should not be brought forward.
>
> But in the "git pull" default case, *today* it's doing a merge. If
> uttering --merge and thus making the current behavior explicit instead
> of implicit seems dangerous it's because it is. But not documenting it
> doesn't make it any less dangerous.

Sounds like we agree that the future should be ff-only-as-default.  I
also agree with you that the primary problem is the current default
behavior, and I'll agree with you that documenting the current default
is okay.  However, I disagree that your wording here:

+                       "If unsure, run \"git pull --no-rebase\".\n"

does anything of the sort.  It does not mention that this is the
default behavior the users would get if they provided no flags.  More
importantly, it makes a recommendation...and one that undercuts the
point of the message.  It makes it feel like the message shouldn't
exist at all in any circumstances.  I even suspect that adding that
sentence may undercut any efforts towards changing the default to
ff-only-as-default.  While I'm a big fan of most of what you've done
in this series, I will object to its merging for as long as this
stays.  (I definitely don't have veto power or anything close to it,
just stating what my opinion is.)

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH] experiment: pull: change --ff-only and default mode
  2020-12-05  4:06       ` [PATCH] experiment: pull: change --ff-only and default mode Felipe Contreras
@ 2020-12-05 17:29         ` Elijah Newren
  2020-12-05 18:16           ` Felipe Contreras
  2020-12-07  7:34           ` Junio C Hamano
  0 siblings, 2 replies; 79+ messages in thread
From: Elijah Newren @ 2020-12-05 17:29 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Git Mailing List

On Fri, Dec 4, 2020 at 8:06 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:

This commit message should say something more than just "change x", it
should have some words about what it is change from or to.  I think
the thrust of the patch is allowing --ff-only, --merge, and --rebase
to countermand an earlier otherwise-conflicting option.  Perhaps a
commit message of the form:

In git, we sometimes allow conflicting command line options with the
last one winning, e.g.
  git log --patch --no-patch
  git log --no-patch --patch
other times we just error out when conflicting options are given, e.g.
  git checkout -b --orphan NEWBRANCH
  git checkout --orphan -b NEWBRANCH
Previously, we did neither with --no-ff, --merge, and --rebase.
Change these options to have a last-one-wins behavior.


(Although, after writing this out, I wonder if we want to die with a
conflict message instead of going the route I suggested yesterday.
I'm not certain if one is better than the other, but worth
considering.  Thoughts?)

> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---
>  builtin/pull.c  | 40 ++++++++++++++++++++++++++--------------
>  t/t5520-pull.sh | 23 +++++++++++++++++++++++
>  2 files changed, 49 insertions(+), 14 deletions(-)
>
> diff --git a/builtin/pull.c b/builtin/pull.c
> index e389ffcdc3..95ecbdaad5 100644
> --- a/builtin/pull.c
> +++ b/builtin/pull.c
> @@ -62,6 +62,7 @@ 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;
> +       if (*value != REBASE_INVALID) default_mode = 0;
>         return *value == REBASE_INVALID ? -1 : 0;
>  }
>
> @@ -114,6 +115,23 @@ static int opt_show_forced_updates = -1;
>  static char *set_upstream;
>  static struct strvec opt_fetch = STRVEC_INIT;
>
> +static int parse_opt_ff_only(const struct option *opt, const char *arg, int unset)
> +{
> +       char **value = opt->value;
> +       opt_rebase = REBASE_FALSE;
> +       *value = "--ff-only";
> +       return 0;
> +}
> +
> +static int parse_opt_merge(const struct option *opt, const char *arg, int unset)
> +{
> +       char **value = opt->value;
> +       opt_ff = NULL;
> +       *value = REBASE_FALSE;
> +       default_mode = 0;
> +       return 0;
> +}
> +
>  static struct option pull_options[] = {
>         /* Shared options */
>         OPT__VERBOSITY(&opt_verbosity),
> @@ -131,8 +149,9 @@ static struct option pull_options[] = {
>                 "(false|true|merges|preserve|interactive)",
>                 N_("incorporate changes by rebasing rather than merging"),
>                 PARSE_OPT_OPTARG, parse_opt_rebase),
> -       OPT_SET_INT('m', "merge", &opt_rebase,
> -               N_("incorporate changes by merging"), 0),
> +       OPT_CALLBACK_F('m', "merge", &opt_rebase, NULL,
> +               N_("incorporate changes by merging"),
> +               PARSE_OPT_NOARG | PARSE_OPT_NONEG, parse_opt_merge),
>         OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,
>                 N_("do not show a diffstat at the end of the merge"),
>                 PARSE_OPT_NOARG | PARSE_OPT_NONEG),
> @@ -161,9 +180,9 @@ static struct option pull_options[] = {
>         OPT_PASSTHRU(0, "ff", &opt_ff, NULL,
>                 N_("allow fast-forward"),
>                 PARSE_OPT_NOARG),
> -       OPT_PASSTHRU(0, "ff-only", &opt_ff, NULL,
> +       OPT_CALLBACK_F(0, "ff-only", &opt_ff, NULL,
>                 N_("abort if fast-forward is not possible"),
> -               PARSE_OPT_NOARG | PARSE_OPT_NONEG),
> +               PARSE_OPT_NOARG | PARSE_OPT_NONEG, parse_opt_ff_only),
>         OPT_PASSTHRU(0, "verify-signatures", &opt_verify_signatures, NULL,
>                 N_("verify that the named commit has a valid GPG signature"),
>                 PARSE_OPT_NOARG),
> @@ -924,6 +943,9 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>
>         git_config(git_pull_config, NULL);
>
> +       opt_ff = xstrdup_or_null(config_get_ff());
> +       opt_rebase = config_get_rebase();
> +
>         argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);
>
>         if (cleanup_arg)
> @@ -935,12 +957,6 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>
>         parse_repo_refspecs(argc, argv, &repo, &refspecs);
>
> -       if (!opt_ff)
> -               opt_ff = xstrdup_or_null(config_get_ff());
> -
> -       if (opt_rebase < 0)
> -               opt_rebase = config_get_rebase();
> -
>         if (read_cache_unmerged())
>                 die_resolve_conflict("pull");
>
> @@ -1037,10 +1053,6 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
>                 }
>         }
>
> -       /* Disable --ff-only when --merge is specified */
> -       if (!can_ff && !default_mode && !opt_rebase && opt_ff && !strcmp(opt_ff, "--ff-only"))
> -               opt_ff = NULL;
> -
>         if (opt_rebase) {
>                 int ret = 0;
>                 if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
> diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
> index f48d0f8d50..c0cfde54e1 100755
> --- a/t/t5520-pull.sh
> +++ b/t/t5520-pull.sh
> @@ -881,4 +881,27 @@ test_expect_success 'git pull non-fast-forward error message' '
>         grep -q "The pull was not fast-forward" error
>  '
>
> +test_expect_success 'git pull --merge overrides --ffonly' '

You're missing a hyphen there; it should be --ff-only.

> +       test_when_finished "git checkout master && git branch -D other test" &&
> +       test_config pull.ff only &&
> +       git checkout -b other master^ &&
> +       >new &&
> +       git add new &&
> +       git commit -m new &&
> +       git checkout -b test -t other &&
> +       git reset --hard master &&
> +       git pull --ff-only --merge
> +'
> +
> +test_expect_success 'git pull --ff-only overrides --merge' '
> +       test_when_finished "git checkout master && git branch -D other test" &&
> +       git checkout -b other master^ &&
> +       >new &&
> +       git add new &&
> +       git commit -m new &&
> +       git checkout -b test -t other &&
> +       git reset --hard master &&
> +       test_must_fail git pull --merge --ff-only
> +'

What about --ff-only and --rebase?  Are there already tests for those?

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH] experiment: pull: change --ff-only and default mode
  2020-12-05 17:29         ` Elijah Newren
@ 2020-12-05 18:16           ` Felipe Contreras
  2020-12-07  7:34           ` Junio C Hamano
  1 sibling, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05 18:16 UTC (permalink / raw)
  To: Elijah Newren; +Cc: Git Mailing List

On Sat, Dec 5, 2020 at 11:29 AM Elijah Newren <newren@gmail.com> wrote:
>
> On Fri, Dec 4, 2020 at 8:06 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
>
> This commit message should say something more than just "change x", it
> should have some words about what it is change from or to.  I think
> the thrust of the patch is allowing --ff-only, --merge, and --rebase
> to countermand an earlier otherwise-conflicting option.  Perhaps a
> commit message of the form:

It's not a real commit, it's just a preview at what the eventual
diffstat towards v3 might look like.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-05 16:28           ` Elijah Newren
@ 2020-12-05 21:27             ` Felipe Contreras
  2020-12-06  1:01               ` Elijah Newren
  0 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-05 21:27 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Sat, Dec 5, 2020 at 10:28 AM Elijah Newren <newren@gmail.com> wrote:
> On Fri, Dec 4, 2020 at 5:56 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:

> > Well, I already said I partly agree with you: in the --ff-only case
> > the suggestion should not be brought forward.
> >
> > But in the "git pull" default case, *today* it's doing a merge. If
> > uttering --merge and thus making the current behavior explicit instead
> > of implicit seems dangerous it's because it is. But not documenting it
> > doesn't make it any less dangerous.
>
> Sounds like we agree that the future should be ff-only-as-default.  I
> also agree with you that the primary problem is the current default
> behavior, and I'll agree with you that documenting the current default
> is okay.  However, I disagree that your wording here:
>
> +                       "If unsure, run \"git pull --no-rebase\".\n"
>
> does anything of the sort.  It does not mention that this is the
> default behavior the users would get if they provided no flags.

But that is not the warning, this is the warning:

  Pulling without specifying how to reconcile divergent branches is discouraged;
  you need to specify if you want a merge, a rebase, or a fast-forward.
  You can squelch this message by running one of the following commands:

    git config pull.rebase false  # merge (the default strategy)
    git config pull.rebase true   # rebase
    git config pull.ff only       # fast-forward only

  You can replace "git config" with "git config --global" to set a default
  preference for all repositories.
  If unsure, run "git pull --merge".
  Read "git pull --help" for more information.

This warning says:

1. There's 3 options: merge, rebase, fast-forward
2. merge is the default strategy
3. If unsure, specify --merge (the default strategy)

So taken altogether it does say what is the default strategy.

> More
> importantly, it makes a recommendation...and one that undercuts the
> point of the message.

So?

When boarding a plane the flight attendants do a safety demonstration
that passengers should pay attention to. If one passenger is not
paying attention (listening to music on headphones, and reading a
book) what should the crew do?

1. Remove the passenger's headphones and force him to pay attention to
the safety demonstration
2. Let the passenger ignore the safety demonstration

Human beings are independent agents responsible for their own actions.
You as a separate human being--a crew member--can argue that it's not
in the best interest of the passenger to ignore the safety
demonstration, and you may be right, but the passenger decisions are
still the passenger's decisions, even if they are bad.

Do you think the crew should disregard the passenger's volition and
force him to pay attention to the safety demonstration?

> It makes it feel like the message shouldn't
> exist at all in any circumstances.  I even suspect that adding that
> sentence may undercut any efforts towards changing the default to
> ff-only-as-default.  While I'm a big fan of most of what you've done
> in this series, I will object to its merging for as long as this
> stays.  (I definitely don't have veto power or anything close to it,
> just stating what my opinion is.)

The current warning should not exist at all.

The complaint from Vít Ondruch [1] that reignited this series is a
valid one. A *permanent* warning is not good. We should have a
*temporary* warning with the express purpose of notifying users of an
upcoming change.

If we have not yet decided on what should be the default (Junio seems
to have casted some doubt on the consensus [2]), and we don't have a
clear path forward to implement such change (we can't even tell users
to use "pull.ff=only", since eventually it may be
"pull.mode=ff-only"), then we must remove the warning.

It was a mistake to put a *permanent* warning before deciding to
change the default.

So, there's two options:

1. We decide on a path forward and fix the warning so it *temporarily*
explains what will happen in the future
2. We remove the *permanent* warning

Since we are already here, we might as well take advantage of that
warning and repurpose it. But in the meantime--while the git project
decides what to do, and what configurations to suggest the users to
change--we should at the very least waste as little as the user's time
as possible, and give him/her a quick opt-out.

Yes, a quick opt-out defeats the purpose of a warning, but we must
respect the users' volition. The user may be on a deadline trying to
push some changes to production before the weekend, and after a system
update be annoyed with this warning on every pull. The user may not
have time to look at the warning, decide he wants to read the warning
in the future, maybe next Monday, and thus not configure anything to
silence it.

What's wrong with a user saying "I don't have time for this now,
please tell me what to do for now, I'll look at the warning later"? If
anything for those users the configuration is the wrong thing to do,
because being in a hurry they just choose the first configuration and
forget about the warning without actually looking at it (because they
didn't have time), and it will not appear any more. By typing "git
pull --merge" the user can get rid of the warning *for now*, but the
next time he does "git pull" the warning will reappear, and at that
time perhaps the user does have the time to read it, and look at the
manpage.

Nobody likes their workflow to be interrupted and be forced to do anything.

I don't think my patches plus that suggestion for a quick opt-out are
in any way worse than the current situation. If you think they are,
then we'll just have to agree to disagree.

I quote the voice of Vít Ondruch, which I think represents the typical
user: "please select any strategy considered more appropriate and stop
warning me".

Cheers.

[1] https://lore.kernel.org/git/742df4c2-2bc5-8a4b-8de1-cd5e48718398@redhat.com/
[2] https://lore.kernel.org/git/xmqqh7p1fjml.fsf@gitster.c.googlers.com/

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-05 21:27             ` Felipe Contreras
@ 2020-12-06  1:01               ` Elijah Newren
  2020-12-06 14:31                 ` Felipe Contreras
  2020-12-07  7:26                 ` Junio C Hamano
  0 siblings, 2 replies; 79+ messages in thread
From: Elijah Newren @ 2020-12-06  1:01 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Sat, Dec 5, 2020 at 1:28 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> On Sat, Dec 5, 2020 at 10:28 AM Elijah Newren <newren@gmail.com> wrote:
> > On Fri, Dec 4, 2020 at 5:56 PM Felipe Contreras
> > <felipe.contreras@gmail.com> wrote:
>
> > > Well, I already said I partly agree with you: in the --ff-only case
> > > the suggestion should not be brought forward.
> > >
> > > But in the "git pull" default case, *today* it's doing a merge. If
> > > uttering --merge and thus making the current behavior explicit instead
> > > of implicit seems dangerous it's because it is. But not documenting it
> > > doesn't make it any less dangerous.
> >
> > Sounds like we agree that the future should be ff-only-as-default.  I
> > also agree with you that the primary problem is the current default
> > behavior, and I'll agree with you that documenting the current default
> > is okay.  However, I disagree that your wording here:
> >
> > +                       "If unsure, run \"git pull --no-rebase\".\n"
> >
> > does anything of the sort.  It does not mention that this is the
> > default behavior the users would get if they provided no flags.
>
> But that is not the warning, this is the warning:
>
>   Pulling without specifying how to reconcile divergent branches is discouraged;
>   you need to specify if you want a merge, a rebase, or a fast-forward.
>   You can squelch this message by running one of the following commands:
>
>     git config pull.rebase false  # merge (the default strategy)
>     git config pull.rebase true   # rebase
>     git config pull.ff only       # fast-forward only
>
>   You can replace "git config" with "git config --global" to set a default
>   preference for all repositories.
>   If unsure, run "git pull --merge".
>   Read "git pull --help" for more information.
>
> This warning says:
>
> 1. There's 3 options: merge, rebase, fast-forward
> 2. merge is the default strategy
> 3. If unsure, specify --merge (the default strategy)
>
> So taken altogether it does say what is the default strategy.

We don't need to take them together.  #2 by itself states the default
strategy.  I don't see why defending #3 as being for the purpose of
documenting the default strategy is helpful, since it doesn't do that.

> > More
> > importantly, it makes a recommendation...and one that undercuts the
> > point of the message.
>
> So?
>
> When boarding a plane the flight attendants do a safety demonstration
> that passengers should pay attention to. If one passenger is not
> paying attention (listening to music on headphones, and reading a
> book) what should the crew do?
>
> 1. Remove the passenger's headphones and force him to pay attention to
> the safety demonstration
> 2. Let the passenger ignore the safety demonstration
>
> Human beings are independent agents responsible for their own actions.
> You as a separate human being--a crew member--can argue that it's not
> in the best interest of the passenger to ignore the safety
> demonstration, and you may be right, but the passenger decisions are
> still the passenger's decisions, even if they are bad.
>
> Do you think the crew should disregard the passenger's volition and
> force him to pay attention to the safety demonstration?
>
> > It makes it feel like the message shouldn't
> > exist at all in any circumstances.  I even suspect that adding that
> > sentence may undercut any efforts towards changing the default to
> > ff-only-as-default.  While I'm a big fan of most of what you've done
> > in this series, I will object to its merging for as long as this
> > stays.  (I definitely don't have veto power or anything close to it,
> > just stating what my opinion is.)
>
> The current warning should not exist at all.
>
> The complaint from Vít Ondruch [1] that reignited this series is a
> valid one. A *permanent* warning is not good. We should have a
> *temporary* warning with the express purpose of notifying users of an
> upcoming change.
>
> If we have not yet decided on what should be the default (Junio seems
> to have casted some doubt on the consensus [2]), and we don't have a

Useful link there.  Based on his comments, we may want to make
--ff-only, --merge, and --rebase all be mutually exclusive and result
in an error message if more than one is specified at the command line.
(But still have the command line countermand any option set in the
config, of course).

> clear path forward to implement such change (we can't even tell users
> to use "pull.ff=only", since eventually it may be
> "pull.mode=ff-only"), then we must remove the warning.
>
> It was a mistake to put a *permanent* warning before deciding to
> change the default.
>
> So, there's two options:
>
> 1. We decide on a path forward and fix the warning so it *temporarily*
> explains what will happen in the future
> 2. We remove the *permanent* warning
>
> Since we are already here, we might as well take advantage of that
> warning and repurpose it. But in the meantime--while the git project
> decides what to do, and what configurations to suggest the users to
> change--we should at the very least waste as little as the user's time
> as possible, and give him/her a quick opt-out.
>
> Yes, a quick opt-out defeats the purpose of a warning, but we must
> respect the users' volition. The user may be on a deadline trying to
> push some changes to production before the weekend, and after a system
> update be annoyed with this warning on every pull. The user may not
> have time to look at the warning, decide he wants to read the warning
> in the future, maybe next Monday, and thus not configure anything to
> silence it.
>
> What's wrong with a user saying "I don't have time for this now,
> please tell me what to do for now, I'll look at the warning later"? If
> anything for those users the configuration is the wrong thing to do,
> because being in a hurry they just choose the first configuration and
> forget about the warning without actually looking at it (because they
> didn't have time), and it will not appear any more. By typing "git
> pull --merge" the user can get rid of the warning *for now*, but the
> next time he does "git pull" the warning will reappear, and at that
> time perhaps the user does have the time to read it, and look at the
> manpage.
>
> Nobody likes their workflow to be interrupted and be forced to do anything.
>
> I don't think my patches plus that suggestion for a quick opt-out are
> in any way worse than the current situation. If you think they are,
> then we'll just have to agree to disagree.

Yes, we can agree to disagree on this particular point.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-06  1:01               ` Elijah Newren
@ 2020-12-06 14:31                 ` Felipe Contreras
  2020-12-07  7:26                 ` Junio C Hamano
  1 sibling, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-06 14:31 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Sat, Dec 5, 2020 at 7:01 PM Elijah Newren <newren@gmail.com> wrote:
>
> On Sat, Dec 5, 2020 at 1:28 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > On Sat, Dec 5, 2020 at 10:28 AM Elijah Newren <newren@gmail.com> wrote:
> > > On Fri, Dec 4, 2020 at 5:56 PM Felipe Contreras
> > > <felipe.contreras@gmail.com> wrote:
> >
> > > > Well, I already said I partly agree with you: in the --ff-only case
> > > > the suggestion should not be brought forward.
> > > >
> > > > But in the "git pull" default case, *today* it's doing a merge. If
> > > > uttering --merge and thus making the current behavior explicit instead
> > > > of implicit seems dangerous it's because it is. But not documenting it
> > > > doesn't make it any less dangerous.
> > >
> > > Sounds like we agree that the future should be ff-only-as-default.  I
> > > also agree with you that the primary problem is the current default
> > > behavior, and I'll agree with you that documenting the current default
> > > is okay.  However, I disagree that your wording here:
> > >
> > > +                       "If unsure, run \"git pull --no-rebase\".\n"
> > >
> > > does anything of the sort.  It does not mention that this is the
> > > default behavior the users would get if they provided no flags.
> >
> > But that is not the warning, this is the warning:
> >
> >   Pulling without specifying how to reconcile divergent branches is discouraged;
> >   you need to specify if you want a merge, a rebase, or a fast-forward.
> >   You can squelch this message by running one of the following commands:
> >
> >     git config pull.rebase false  # merge (the default strategy)
> >     git config pull.rebase true   # rebase
> >     git config pull.ff only       # fast-forward only
> >
> >   You can replace "git config" with "git config --global" to set a default
> >   preference for all repositories.
> >   If unsure, run "git pull --merge".
> >   Read "git pull --help" for more information.
> >
> > This warning says:
> >
> > 1. There's 3 options: merge, rebase, fast-forward
> > 2. merge is the default strategy
> > 3. If unsure, specify --merge (the default strategy)
> >
> > So taken altogether it does say what is the default strategy.
>
> We don't need to take them together.

No, but that's what I'm proposing.

> #2 by itself states the default strategy.

Yes, with configuration, not with commands.

> I don't see why defending #3 as being for the purpose of
> documenting the default strategy is helpful, since it doesn't do that.

I disagree. It does do that, but it serves a more urgent purpose: it
tells the user how to ignore us quickly, for now.

> > The current warning should not exist at all.
> >
> > The complaint from Vít Ondruch [1] that reignited this series is a
> > valid one. A *permanent* warning is not good. We should have a
> > *temporary* warning with the express purpose of notifying users of an
> > upcoming change.
> >
> > If we have not yet decided on what should be the default (Junio seems
> > to have casted some doubt on the consensus [2]), and we don't have a
>
> Useful link there.  Based on his comments, we may want to make
> --ff-only, --merge, and --rebase all be mutually exclusive and result
> in an error message if more than one is specified at the command line.
> (But still have the command line countermand any option set in the
> config, of course).

Yes, but that's a change in behavior.

Moreover, what do you suggest this should do?

  git -c "pull.rebase=true" -c "pull.ff=only" pull

I have already tried to make pull.ff=only work in several ways. It's
just not a clean solution.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-06  1:01               ` Elijah Newren
  2020-12-06 14:31                 ` Felipe Contreras
@ 2020-12-07  7:26                 ` Junio C Hamano
  2020-12-07  9:16                   ` Felipe Contreras
  1 sibling, 1 reply; 79+ messages in thread
From: Junio C Hamano @ 2020-12-07  7:26 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Felipe Contreras, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	Jacob Keller, John Keeping, Richard Hansen, Brian M. Carlson,
	W. Trevor King

Elijah Newren <newren@gmail.com> writes:

>>   Pulling without specifying how to reconcile divergent branches is discouraged;
>>   you need to specify if you want a merge, a rebase, or a fast-forward.
>>   You can squelch this message by running one of the following commands:
>>
>>     git config pull.rebase false  # merge (the default strategy)
>>     git config pull.rebase true   # rebase
>>     git config pull.ff only       # fast-forward only
>>
>>   You can replace "git config" with "git config --global" to set a default
>>   preference for all repositories.
>>   If unsure, run "git pull --merge".
>>   Read "git pull --help" for more information.
>>
>> This warning says:
>>
>> 1. There's 3 options: merge, rebase, fast-forward
>> 2. merge is the default strategy
>> 3. If unsure, specify --merge (the default strategy)
>>
>> So taken altogether it does say what is the default strategy.
>
> We don't need to take them together.  #2 by itself states the default
> strategy.  I don't see why defending #3 as being for the purpose of
> documenting the default strategy is helpful, since it doesn't do that.

Would it work if the line were

	If unsure, run "git -c pull.rebase=false pull".

then?

The reason why I bring this up is because the first part only talks
about the choices in the terms of configuration variables, and for
those who are afraid of committing, there is no easy way, unless
they know the "git -c" single-shot mechanism, to "go ahead with one
choice in an experimental basis to see if that is what they want",
and "specify --merge" does not click well with "pull.rebase=false"
that is given in the first part.  "git pull --no-rebase" may also
work better than "git pull --merge" from that point of view, though.

But see below.


>> Do you think the crew should disregard the passenger's volition and
>> force him to pay attention to the safety demonstration?

An example that is irrelevant.  Passengers who sit on the aisle side
and clutter the floor with their luggages can pose public hazard,
and it is quite sensible for crews to remove them from the plane.  

A team member who runs "pull --[no-]rebase" pushes the result, which
may be a new history in a wrong shape, back to the shared repository
probably falls into a different category.  ... Or perhaps in the
same public hazard category?

> Useful link there.  Based on his comments, we may want to make
> --ff-only, --merge, and --rebase all be mutually exclusive and result
> in an error message if more than one is specified at the command line.

I hope "his comment" does not refer to what I said.  Redefining the
semantics of --ff-only (but not --ff=no and friends) to make it
mutually incompatible with merge/rebase was what Felipe wanted to
do, not me.

FWIW, I see the general direction as

 - When the history you are pulling is not a descendant of what you
   have on your current branch, you must show your preference
   between merging their history into yours or rebasing your history
   onto theirs.

 - In such a case, we error out, with an error message telling them
   that they must tell us which one they want in this invocation
   (e.g. with "--rebase" or "--no-rebase").  We further tell them
   that pull.rebase can be used to record their preference, if they
   almost always use the same.

	Side note: I earlier said "see below" to refer to this.  I
	think the message should offer what they can do right now
	with command line option first, and then give an option to
	configure.  IOW, the message quoted in the beginning of this
	response gives information in a wrong order.  Also,
	"discouraged" is misleading, isn't it?  When we give this
	message, we refuse to proceed until the user specifies.

	Another thing to consider is that pull.ff=only (and
	--ff-only) may be wrong choice to offer in the error message
	quoted above, if one of the objectives is to reduce the
	"annoying" message that tells the user that they must
	choose.  By definition, we do not give the message when our
	side do not have our own development, so "I could run 'pull
	--ff-only'" is a unusable knowledge to those who see the
	message and want to get out of the situation.

 - But when the history being pulled is a descendant of the current
   branch, and the user does not give us preference between merge
   and rebase (either from the command line or with configuration),
   there is no need to give such an error message---if you do not
   have your own development, we can just fast-forward the current
   branch to what we fetched from the other side.  This does not
   happen with the current system, which is what we want to fix.

 - Also when the history from the other side is a descedant and the
   user has preference, either to rebase or to merge, either from
   the command line or with configuration, we can fast-forward the
   current branch to their tip, but there are wrinkles:

   . when --ff=no is given and the choice is to merge (not rebase),
     we must create an extra merge commit.

   . when the choice is to rebase, by definition, rebasing what you
     have on top of theirs in this case is the same as fast-forwarding
     the current branch to theirs, because "what you have" is an
     empty set.

   . I am not sure how "pull --rebase --ff=no" should interact if we
     don't have our own development.  Rebasing our work on top of
     theirs is philosophically incompatible with marking where the
     side branch begins and ends with an extra commit, so it either
     should be rejected when the command line and configuration is
     parsed (i.e. regardless of the shape of the history we have at
     hand), or --ff=no gets silently ignored when --rebase is given.
     I haven't thought this one through.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH] experiment: pull: change --ff-only and default mode
  2020-12-05 17:29         ` Elijah Newren
  2020-12-05 18:16           ` Felipe Contreras
@ 2020-12-07  7:34           ` Junio C Hamano
  1 sibling, 0 replies; 79+ messages in thread
From: Junio C Hamano @ 2020-12-07  7:34 UTC (permalink / raw)
  To: Elijah Newren; +Cc: Felipe Contreras, Git Mailing List

Elijah Newren <newren@gmail.com> writes:

> On Fri, Dec 4, 2020 at 8:06 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
>
> This commit message should say something more than just "change x", it
> should have some words about what it is change from or to.  I think
> the thrust of the patch is allowing --ff-only, --merge, and --rebase
> to countermand an earlier otherwise-conflicting option.  Perhaps a
> commit message of the form:
>
> In git, we sometimes allow conflicting command line options with the
> last one winning, e.g.
>   git log --patch --no-patch
>   git log --no-patch --patch
> other times we just error out when conflicting options are given, e.g.
>   git checkout -b --orphan NEWBRANCH
>   git checkout --orphan -b NEWBRANCH
> Previously, we did neither with --no-ff, --merge, and --rebase.
> Change these options to have a last-one-wins behavior.

If the choices are clearly among --ff-only, --merge and --rebase, I
am fine with the last-one-wins change, and your explanation does
make sense.

I however am not sure how --no-ff and other --ff=<how> friends
should interact with the primary two choices.  --ff=no is used by
those who want to merge, so "--merge --ff=no" combination is a
sensible thing to accept.  The same can be said for "--merge --ff"
(fast-forward when able).  It is interesting to realize that it
would not be wrong to say "--rebase --ff" even.  When their history
we are rebasing our own work on top is a descendant of our history,
such a rebase operation ends up in fast-forwarding to their tip.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-07  7:26                 ` Junio C Hamano
@ 2020-12-07  9:16                   ` Felipe Contreras
  2020-12-07 18:16                     ` Junio C Hamano
  0 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-07  9:16 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Elijah Newren, Git Mailing List, Vít Ondruch, Alex Henrie,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Mon, Dec 7, 2020 at 1:26 AM Junio C Hamano <gitster@pobox.com> wrote:
> Elijah Newren <newren@gmail.com> writes:

> >> Do you think the crew should disregard the passenger's volition and
> >> force him to pay attention to the safety demonstration?
>
> An example that is irrelevant.  Passengers who sit on the aisle side
> and clutter the floor with their luggages can pose public hazard,
> and it is quite sensible for crews to remove them from the plane.

That's a completely different example that mixes policy with
regulations. Apples and oranges.

> A team member who runs "pull --[no-]rebase" pushes the result, which
> may be a new history in a wrong shape, back to the shared repository
> probably falls into a different category.  ... Or perhaps in the
> same public hazard category?

Yes, but if it's a public hazard or not is up to the maintainers of
specific projects. Some projects are perfectly fine with those merges.

It's the maintainer of the project that should decide what is the best
policy for the project, and instruct his/her contributors.

It's not up for individuals to decide what is a public hazard, and
it's not up to Git either. Similarly; passengers can't decide what
raises to the level of public hazzard, but neither can a flight
attendant.

> > Useful link there.  Based on his comments, we may want to make
> > --ff-only, --merge, and --rebase all be mutually exclusive and result
> > in an error message if more than one is specified at the command line.
>
> I hope "his comment" does not refer to what I said.  Redefining the
> semantics of --ff-only (but not --ff=no and friends) to make it
> mutually incompatible with merge/rebase was what Felipe wanted to
> do, not me.

That's not true.

What I want is to introduce a "pull.mode=ff-only", not change the
semantics of --ff-only.

What I have been saying is that you can't make --ff-only the default
without changing its semantics.

But since the patch series that introduced such pull.mode [1] was
completely ignored, I decided to take a shot at making --ff-only work.

You said [2]:

> > What we want to see can be done without such backward incompatible
> > changes, e.g. declaring the combination of "--ff-only" and
> > "--[no-]rebase" incompatible and/or the last one wins, I would say, and
> > I suspect Alex's RFC was an attempt to make the first step in that
> > direction.

But in all my attempts the desired result cannot be done without
backwards incompatible changes. I'm just the messenger.

To be crystal clear: I don't want to change the semantics of
--ff-only; I want to introduce a new "pull.mode=ff-only".

> FWIW, I see the general direction as
>
>  - When the history you are pulling is not a descendant of what you
>    have on your current branch, you must show your preference
>    between merging their history into yours or rebasing your history
>    onto theirs.

Agreed.

>  - In such a case, we error out, with an error message telling them
>    that they must tell us which one they want in this invocation
>    (e.g. with "--rebase" or "--no-rebase").  We further tell them
>    that pull.rebase can be used to record their preference, if they
>    almost always use the same.

Not quite. See below.

>         Side note: I earlier said "see below" to refer to this.  I
>         think the message should offer what they can do right now
>         with command line option first, and then give an option to
>         configure.  IOW, the message quoted in the beginning of this
>         response gives information in a wrong order.  Also,
>         "discouraged" is misleading, isn't it?  When we give this
>         message, we refuse to proceed until the user specifies.

That's why I keep pointing out the end goal. In the end it's not one
message, it's *two*:

You can see my suggestion for both messages in my patch series for
pull.mode [1].

When the user has specified "pull.mode=ff-only", the command dies with:

  The pull was not fast-forward, please either merge or rebase.

When the user has not specified any mode (by default), the command
would output a warning:

  The pull was not fast-forward, in the future you will have to choose a
  merge, or a rebase.

  To squelch this message and maintain the current behavior, use:

    git config --global pull.mode merge

  To squelch this message and adopt the new behavior now, use:

    git config --global push.mode ff-only

  Falling back to old style for now (merge).
  Read 'git pull --help' for more information.

But in order to reach that point we first need to decide what will be
the default mode, and how it will be configured (--ff-only or
"pull.mode=ff-only").

In the meantime this particular series is not committing for any
particular decision, and thus it's changing the warning message for
the *current* situation in which the command does not fail, but only
shows a warning. So today it's merely discouraged.

This particular patch is pretty far from the end goal. It's just patch
#2 of part 1.

>         Another thing to consider is that pull.ff=only (and
>         --ff-only) may be wrong choice to offer in the error message
>         quoted above, if one of the objectives is to reduce the
>         "annoying" message that tells the user that they must
>         choose.  By definition, we do not give the message when our
>         side do not have our own development, so "I could run 'pull
>         --ff-only'" is a unusable knowledge to those who see the
>         message and want to get out of the situation.

Those commands will squelch the warning, but won't change the
underlying nature of the warning, which is that the user must choose
to either merge or rebase.

The temporary warning will disappear, but the permanent error message will not:

  The pull was not fast-forward, please either merge or rebase.

>  - But when the history being pulled is a descendant of the current
>    branch, and the user does not give us preference between merge
>    and rebase (either from the command line or with configuration),
>    there is no need to give such an error message---if you do not
>    have your own development, we can just fast-forward the current
>    branch to what we fetched from the other side.  This does not
>    happen with the current system, which is what we want to fix.

It's not an error message, it's a warning. But yes.

>  - Also when the history from the other side is a descedant and the
>    user has preference, either to rebase or to merge, either from
>    the command line or with configuration, we can fast-forward the
>    current branch to their tip, but there are wrinkles:
>
>    . when --ff=no is given and the choice is to merge (not rebase),
>      we must create an extra merge commit.

--ff receives no arguments, it's --no-ff.

Yes.

>    . when the choice is to rebase, by definition, rebasing what you
>      have on top of theirs in this case is the same as fast-forwarding
>      the current branch to theirs, because "what you have" is an
>      empty set.

Agreed.

>    . I am not sure how "pull --rebase --ff=no" should interact if we
>      don't have our own development.  Rebasing our work on top of
>      theirs is philosophically incompatible with marking where the
>      side branch begins and ends with an extra commit, so it either
>      should be rejected when the command line and configuration is
>      parsed (i.e. regardless of the shape of the history we have at
>      hand), or --ff=no gets silently ignored when --rebase is given.
>      I haven't thought this one through.

I thought of this instance as well. In my opinion such combination
should fail. But it doesn't actually affect anything.


Just to put this series in context: it's only part 1; it does not
introduce pull.mode, and it doesn't make --ff-only the default.
There's one patch prefixed with "tentative" that changes the semantics
of --ff-only to see how it could look like when making it the default,
but in no way am I proposing that patch to be merged.

The series is entirely about improving the current situation, nothing
contentious.

In part 2 I will introduce pull.mode, which is the solution I propose,
and that would be basically rebasing [1] on top of this series
(hopefully).

I would have hoped that by this point it would have been clear why
--ff-only is not the way forward. But oh well, we'll see what happens.

Cheers.

[1] https://lore.kernel.org/git/20201125032938.786393-1-felipe.contreras@gmail.com/
[2] https://lore.kernel.org/git/xmqqpn3qfhps.fsf@gitster.c.googlers.com

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-05  0:56       ` Elijah Newren
  2020-12-05  1:56         ` Felipe Contreras
@ 2020-12-07  9:23         ` Felipe Contreras
  1 sibling, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-07  9:23 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Git Mailing List, Vít Ondruch, Alex Henrie, Junio C Hamano,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 4, 2020 at 6:56 PM Elijah Newren <newren@gmail.com> wrote:

> > > > diff --git a/builtin/pull.c b/builtin/pull.c
> > > > index 1034372f8b..22a9ffcade 100644
> > > > --- a/builtin/pull.c
> > > > +++ b/builtin/pull.c
> > > > @@ -346,17 +346,18 @@ static enum rebase_type config_get_rebase(void)
> > > >
> > > >         if (opt_verbosity >= 0 && !opt_ff) {
> > > >                 advise(_("Pulling without specifying how to reconcile divergent branches is\n"
> > > > -                        "discouraged. You can squelch this message by running one of the following\n"
> > > > -                        "commands sometime before your next pull:\n"
> > > > -                        "\n"
> > > > -                        "  git config pull.rebase false  # merge (the default strategy)\n"
> > > > -                        "  git config pull.rebase true   # rebase\n"
> > > > -                        "  git config pull.ff only       # fast-forward only\n"
> > > > -                        "\n"
> > > > -                        "You can replace \"git config\" with \"git config --global\" to set a default\n"
> > > > -                        "preference for all repositories. You can also pass --rebase, --no-rebase,\n"
> > > > -                        "or --ff-only on the command line to override the configured default per\n"
> > > > -                        "invocation.\n"));
> > > > +                       "discouraged; you need to specify if you want a merge, or a rebase.\n"
> > >
> > > ...want a merge, a rebase, or neither.
> >
> > There is no "git pull --no-merge". Years ago some people argued for a
> > "pull.mode=none" (essentially making "git pull" the same as "git
> > fetch"). But right now there's no option to do that.
> >
> > There's an option to do --ff-only, but that's still a merge.
>
> I disagree.  I'm well aware that checkout_fast_forward() (which is
> what is ultimately called to do the fast-forwarding) is in a file
> called merge.c, but that doesn't make it a merge.  I don't believe it
> was anything more than a convenient place to dump some extra code at
> the time.
>
> > Perhaps: a merge, a rebase, or a fast-forward?
>
> Sure, that works; in fact, that's much better than my suggestion.  I like it.

Actually no. If we are talking about divergent branches you cannot fast-forward.

The original text was fine.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-07  9:16                   ` Felipe Contreras
@ 2020-12-07 18:16                     ` Junio C Hamano
  2020-12-07 19:09                       ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Junio C Hamano @ 2020-12-07 18:16 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Elijah Newren, Git Mailing List, Vít Ondruch, Alex Henrie,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

Felipe Contreras <felipe.contreras@gmail.com> writes:

> When the user has specified "pull.mode=ff-only", the command dies with:
>
>   The pull was not fast-forward, please either merge or rebase.
>
> When the user has not specified any mode (by default), the command
> would output a warning:
>
>   The pull was not fast-forward, in the future you will have to choose a
>   merge, or a rebase.

I quite don't get it.  They say the same thing.  At that point the
user needs to choose between merge and rebase to move forward and
ff-only would not be a sensible choice to offer the user.

> Just to put this series in context: it's only part 1; it does not
> introduce pull.mode, and it doesn't make --ff-only the default.

I'd view the "in a non-fast-forward situation, the warning kicks in
to those who haven't chosen between merge and rebase (i.e. no
pull.rebase set to either true or false, and pull.ff not set to
only), which is a bit more gentle than the current situtation" a
good stopping point.  That state is already making ff-only the
default for unconfigured users, or you can view it as shipping "git
pull" in a shape that has the more dangerous half of its feature
disabled to avoid hurting users.  So I am not sure why you keep
saying you do not have --ff-only as the default.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-07 18:16                     ` Junio C Hamano
@ 2020-12-07 19:09                       ` Felipe Contreras
  2020-12-07 19:53                         ` Junio C Hamano
  0 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-07 19:09 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Elijah Newren, Git Mailing List, Vít Ondruch, Alex Henrie,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Mon, Dec 7, 2020 at 12:16 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Felipe Contreras <felipe.contreras@gmail.com> writes:
>
> > When the user has specified "pull.mode=ff-only", the command dies with:
> >
> >   The pull was not fast-forward, please either merge or rebase.
> >
> > When the user has not specified any mode (by default), the command
> > would output a warning:
> >
> >   The pull was not fast-forward, in the future you will have to choose a
> >   merge, or a rebase.
>
> I quite don't get it.  They say the same thing.  At that point the
> user needs to choose between merge and rebase to move forward and
> ff-only would not be a sensible choice to offer the user.

The error happens *only* when the user has explicitly set
"pull.mode=ff-only", and the pull dies. At that point; yes, the user
must choose between one or the other.

But the warning happens by default, when the user has not chosen any
mode, and the pull succeeds. The user doesn't need to choose; the pull
continues as if the user chose the "merge" mode, which is the historic
behavior.

They start by saying the same thing. But one errors out and says the
user must choose, and the other warns that in the future the user must
choose.

> > Just to put this series in context: it's only part 1; it does not
> > introduce pull.mode, and it doesn't make --ff-only the default.
>
> I'd view the "in a non-fast-forward situation, the warning kicks in
> to those who haven't chosen between merge and rebase (i.e. no
> pull.rebase set to either true or false, and pull.ff not set to
> only), which is a bit more gentle than the current situtation" a
> good stopping point.  That state is already making ff-only the
> default for unconfigured users, or you can view it as shipping "git
> pull" in a shape that has the more dangerous half of its feature
> disabled to avoid hurting users.  So I am not sure why you keep
> saying you do not have --ff-only as the default.

The warning doesn't make the pull fail, ff-only does.

On the current master this works:

  test_expect_success 'non-fast-forward (default)' '
    setup_non_ff &&
    git pull
  '

And after my patch series (part 1) it still does. The default behavior
has not changed.

I'm not sure what it is that I'm not explaining correctly.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-07 19:09                       ` Felipe Contreras
@ 2020-12-07 19:53                         ` Junio C Hamano
  2020-12-07 22:14                           ` Felipe Contreras
  2020-12-07 23:30                           ` Jacob Keller
  0 siblings, 2 replies; 79+ messages in thread
From: Junio C Hamano @ 2020-12-07 19:53 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Elijah Newren, Git Mailing List, Vít Ondruch, Alex Henrie,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

Felipe Contreras <felipe.contreras@gmail.com> writes:

> They start by saying the same thing. But one errors out and says the
> user must choose, and the other warns that in the future the user must
> choose.

Then I do not see the point in giving the warning---even in the
future they do not have to choose as long as they are merely
following along.

>> > Just to put this series in context: it's only part 1; it does not
>> > introduce pull.mode, and it doesn't make --ff-only the default.
>>
>> I'd view the "in a non-fast-forward situation, the warning kicks in
>> to those who haven't chosen between merge and rebase (i.e. no
>> pull.rebase set to either true or false, and pull.ff not set to
>> only), which is a bit more gentle than the current situtation" a
>> good stopping point.  That state is already making ff-only the
>> default for unconfigured users, or you can view it as shipping "git
>> pull" in a shape that has the more dangerous half of its feature
>> disabled to avoid hurting users.  So I am not sure why you keep
>> saying you do not have --ff-only as the default.
>
> The warning doesn't make the pull fail, ff-only does.

Then probably you are giving an error and a warning at a wrong
place.

 - When history fast-forwards, and the user hasn't chosen between
   rebase or merge, there is no need to give any warning.  Just
   succeed by fast-forwarding.

 - When history does not fast-forward and the user hasn't chosen
   between rebase or merge, whether pull.ff is set to "only" or not,
   we should fail and the error message can instruct the user to
   choose between rebase and merge; there is no "ff-only" option
   that is useful in the situation.

And that essentially makes the "ff-only" mode the safe default that
castrates one half of the feature (the more dangerous half) of "git
pull".  Why do we make it more complicated than that by warning that
the user must choose in the future?  They will see an error tell
them that when they start pulling while on their own work, and I do
not see a need to bother them before that point.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-07 19:53                         ` Junio C Hamano
@ 2020-12-07 22:14                           ` Felipe Contreras
  2020-12-07 23:30                           ` Jacob Keller
  1 sibling, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-07 22:14 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Elijah Newren, Git Mailing List, Vít Ondruch, Alex Henrie,
	Jeff King, Philip Oakley, Theodore Y . Ts'o, Jacob Keller,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Mon, Dec 7, 2020 at 1:53 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Felipe Contreras <felipe.contreras@gmail.com> writes:
>
> > They start by saying the same thing. But one errors out and says the
> > user must choose, and the other warns that in the future the user must
> > choose.
>
> Then I do not see the point in giving the warning---even in the
> future they do not have to choose as long as they are merely
> following along.

They don't. With my patch series they see the warning only when the
pull is non-fast-forward.

> >> > Just to put this series in context: it's only part 1; it does not
> >> > introduce pull.mode, and it doesn't make --ff-only the default.
> >>
> >> I'd view the "in a non-fast-forward situation, the warning kicks in
> >> to those who haven't chosen between merge and rebase (i.e. no
> >> pull.rebase set to either true or false, and pull.ff not set to
> >> only), which is a bit more gentle than the current situtation" a
> >> good stopping point.  That state is already making ff-only the
> >> default for unconfigured users, or you can view it as shipping "git
> >> pull" in a shape that has the more dangerous half of its feature
> >> disabled to avoid hurting users.  So I am not sure why you keep
> >> saying you do not have --ff-only as the default.
> >
> > The warning doesn't make the pull fail, ff-only does.
>
> Then probably you are giving an error and a warning at a wrong
> place.
>
>  - When history fast-forwards, and the user hasn't chosen between
>    rebase or merge, there is no need to give any warning.  Just
>    succeed by fast-forwarding.

Yes. That's what my patch [1] in this series does.

>  - When history does not fast-forward and the user hasn't chosen
>    between rebase or merge, whether pull.ff is set to "only" or not,
>    we should fail and the error message can instruct the user to
>    choose between rebase and merge; there is no "ff-only" option
>    that is useful in the situation.

Yes. *Eventually*, that's part 3.

> And that essentially makes the "ff-only" mode the safe default that
> castrates one half of the feature (the more dangerous half) of "git
> pull".  Why do we make it more complicated than that by warning that
> the user must choose in the future?  They will see an error tell
> them that when they start pulling while on their own work, and I do
> not see a need to bother them before that point.

Because the amount of time users have seen the correct error message
telling them about this upcoming change is *zero*.

No one is aware of this backwards-incompatible change that is
upcoming, since the current warning message doesn't specify any such
future change.

Moreover, no one has configured their pull.mode, because no one has
seen the message that tells them to do so.

And no one has had time to try out the upcoming "pull.mode=ff-only".
They haven't had time to find bugs on it, or weird interactions, or
suggestions how to improve it. Because the code has not been deployed,
and no warning has told them to tentatively enable that mode.

When the default for push.default was changed, it was a good thing
that we gave users (and ourselves) a grace period to try it out before
permanently flipping the switch. The transition went smoothly.

I think the progression of the warning is hard to see from all the
patch series. I'm sending all my patches and I will explain in a
timeline how it progresses until eventually we reach the desired end
goal.

Cheers.

[1] https://lore.kernel.org/git/20201204061623.1170745-8-felipe.contreras@gmail.com/

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-07 19:53                         ` Junio C Hamano
  2020-12-07 22:14                           ` Felipe Contreras
@ 2020-12-07 23:30                           ` Jacob Keller
  2020-12-08  2:23                             ` Junio C Hamano
  1 sibling, 1 reply; 79+ messages in thread
From: Jacob Keller @ 2020-12-07 23:30 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Felipe Contreras, Elijah Newren, Git Mailing List,
	Vít Ondruch, Alex Henrie, Jeff King, Philip Oakley,
	Theodore Y . Ts'o, John Keeping, Richard Hansen,
	Brian M. Carlson, W. Trevor King

On Mon, Dec 7, 2020 at 11:53 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Felipe Contreras <felipe.contreras@gmail.com> writes:
>
> > They start by saying the same thing. But one errors out and says the
> > user must choose, and the other warns that in the future the user must
> > choose.
>
> Then I do not see the point in giving the warning---even in the
> future they do not have to choose as long as they are merely
> following along.
>

I think the key point is that this "in the future" is referring to "a
future version of git will make this an error"

This might be better if it said something like "The pull was not
fast-forward. In a future version of git you will need to specify
whether to merge or rebase, using pull.mode"

or something similar. In theory, this warning will go away once that
future version of git changes so that pull.mode defaults to ff-only.

The difference being that a warning will allow the command to continue
doing the default of today (merging), where as an error will stop the
command essentially just after the fetch portion finishes, without
changing the branch.

Thanks,
Jake

> >> > Just to put this series in context: it's only part 1; it does not
> >> > introduce pull.mode, and it doesn't make --ff-only the default.
> >>
> >> I'd view the "in a non-fast-forward situation, the warning kicks in
> >> to those who haven't chosen between merge and rebase (i.e. no
> >> pull.rebase set to either true or false, and pull.ff not set to
> >> only), which is a bit more gentle than the current situtation" a
> >> good stopping point.  That state is already making ff-only the
> >> default for unconfigured users, or you can view it as shipping "git
> >> pull" in a shape that has the more dangerous half of its feature
> >> disabled to avoid hurting users.  So I am not sure why you keep
> >> saying you do not have --ff-only as the default.
> >
> > The warning doesn't make the pull fail, ff-only does.
>
> Then probably you are giving an error and a warning at a wrong
> place.
>
>  - When history fast-forwards, and the user hasn't chosen between
>    rebase or merge, there is no need to give any warning.  Just
>    succeed by fast-forwarding.
>

Correct.

>  - When history does not fast-forward and the user hasn't chosen
>    between rebase or merge, whether pull.ff is set to "only" or not,
>    we should fail and the error message can instruct the user to
>    choose between rebase and merge; there is no "ff-only" option
>    that is useful in the situation.
>

Yes, I understand that this is the destination Felipe wants us to end up at.

> And that essentially makes the "ff-only" mode the safe default that
> castrates one half of the feature (the more dangerous half) of "git
> pull".  Why do we make it more complicated than that by warning that
> the user must choose in the future?  They will see an error tell
> them that when they start pulling while on their own work, and I do
> not see a need to bother them before that point.

The warning would be in an earlier version of git before that is the
default. The warning is for a transition period between today when we
merge by default (with a warning) and when we fail with an error
without completing the pull. Once the default is the ff-only mode,
then the warning is no longer necessary, as we will get an error
indicating that you must choose.

Thanks,
Jake

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-07 23:30                           ` Jacob Keller
@ 2020-12-08  2:23                             ` Junio C Hamano
  2020-12-08  3:15                               ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Junio C Hamano @ 2020-12-08  2:23 UTC (permalink / raw)
  To: Jacob Keller
  Cc: Felipe Contreras, Elijah Newren, Git Mailing List,
	Vít Ondruch, Alex Henrie, Jeff King, Philip Oakley,
	Theodore Y . Ts'o, John Keeping, Richard Hansen,
	Brian M. Carlson, W. Trevor King

Jacob Keller <jacob.keller@gmail.com> writes:

> I think the key point is that this "in the future" is referring to "a
> future version of git will make this an error"
>
> This might be better if it said something like "The pull was not
> fast-forward. In a future version of git you will need to specify
> whether to merge or rebase, using pull.mode"

Oh, I've actually been assuming that the current "warn but go ahead
anyway asssuming the preference is to merge" can just be declared as
a bug (iow, there is no need to say 'in the future'---we'd fix the
bug right away).

> or something similar. In theory, this warning will go away once that
> future version of git changes so that pull.mode defaults to ff-only.
>
> The difference being that a warning will allow the command to continue
> doing the default of today (merging), where as an error will stop the
> command essentially just after the fetch portion finishes, without
> changing the branch.

Yup.  If we want to take things slow, that is fine by me as well,
but I am not sure if that is even necessary, given how annoying the
existing "loudly warn but still go ahead" behaviour is, and how easy
for existing users to have squelched the annoyance by choosing
between rebase and merge already.  I've always assumed that any
existing users who started using Git in the past several years have
already set pull.rebase to one or the other value and they won't be
affected by fixing "git pull" to just error out.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-08  2:23                             ` Junio C Hamano
@ 2020-12-08  3:15                               ` Felipe Contreras
  2020-12-08 20:16                                 ` Junio C Hamano
  0 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-08  3:15 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jacob Keller, Elijah Newren, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Mon, Dec 7, 2020 at 8:23 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Jacob Keller <jacob.keller@gmail.com> writes:
>
> > I think the key point is that this "in the future" is referring to "a
> > future version of git will make this an error"
> >
> > This might be better if it said something like "The pull was not
> > fast-forward. In a future version of git you will need to specify
> > whether to merge or rebase, using pull.mode"
>
> Oh, I've actually been assuming that the current "warn but go ahead
> anyway asssuming the preference is to merge" can just be declared as
> a bug (iow, there is no need to say 'in the future'---we'd fix the
> bug right away).

It is a bug, in my opinion. If we were not planning on changing the
default, I would say drop the warning altogether.

*But*, if we are going to change the default, the warning can be
repurposed to say "in the future this will fail". That requires other
changes though.

> > or something similar. In theory, this warning will go away once that
> > future version of git changes so that pull.mode defaults to ff-only.
> >
> > The difference being that a warning will allow the command to continue
> > doing the default of today (merging), where as an error will stop the
> > command essentially just after the fetch portion finishes, without
> > changing the branch.

Exactly. And we can choose between those behaviors with a
configuration, like it happened with push.default.

> Yup.  If we want to take things slow, that is fine by me as well,
> but I am not sure if that is even necessary, given how annoying the
> existing "loudly warn but still go ahead" behaviour is, and how easy
> for existing users to have squelched the annoyance by choosing
> between rebase and merge already.  I've always assumed that any
> existing users who started using Git in the past several years have
> already set pull.rebase to one or the other value and they won't be
> affected by fixing "git pull" to just error out.

Existing users that are using up-to-date distributions, maybe. Debian
stable is using v2.20.1. In general it's not a good idea to assume
anything about our users. Recently a user of Oh My Zsh reported an
issue with the backwards compatibility code of git-completion; he was
using v2.17 I think.

That is exemplified by the fact that this whole thread started from a
user that refused to configure pull.rebase and expected the Git
project to just do the right thing (which is basically choosing a
useful default).

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-08  3:15                               ` Felipe Contreras
@ 2020-12-08 20:16                                 ` Junio C Hamano
  2020-12-09  9:52                                   ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Junio C Hamano @ 2020-12-08 20:16 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Jacob Keller, Elijah Newren, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

Felipe Contreras <felipe.contreras@gmail.com> writes:

> That is exemplified by the fact that this whole thread started from a
> user that refused to configure pull.rebase and expected the Git
> project to just do the right thing (which is basically choosing a
> useful default).

Which is basically asking for impossible, and I do not think it is a
good idea to focus our effort to satisfy such a request in general.
There is no useful default that suits everybody in this particular
case.

The "force ff-only" approach indeed gives a very sensible default
behaviour of dying for those who haven't expressed the choice
between rebase and merge in a situation where the difference between
the two results in histories of different shapes.

But for anybody who uses git for real (read: produces his or her own
history), it would be pretty much a useless default that forces the
user to say rebase or merge every time 'git pull' is run.  That is
why I am not enthused by the pull.mode=(rebase/merge/ff-only)
configuration.  The third choice does help completeness.  When a
user asks "the documentation tells pull.mode can be set to
non-default behaviour---what value can one set it to to get the
default behaviour of not allowing any original work?", it can be
answered if we had pull.mode=ff-only.  But other than that, I do not
see any real use for the choice, which would mean in practice,
pull.mode would have only two useful values, rebase or merge.  That
does not feel a good enough reason to supersede what already exists,
which is pull.rebase=yes/no.

Perhaps there is a good reason why certain classes of users would
want to configure pull.mode=ff-only (i.e. "I might type 'git pull'
by mistake, please stop me if I did so on a branch I have real work
already.").  If that is the case, I would very much agree that it
would be awkward to express that choice in the current framework to
choose between pull.rebase=yes/no and pull.mode=(rebase/merge/ff-only)
would become a lot easier to explain.

I dunno.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-08 20:16                                 ` Junio C Hamano
@ 2020-12-09  9:52                                   ` Felipe Contreras
  2020-12-09 19:05                                     ` Elijah Newren
  0 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-09  9:52 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jacob Keller, Elijah Newren, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Tue, Dec 8, 2020 at 2:16 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Felipe Contreras <felipe.contreras@gmail.com> writes:
>
> > That is exemplified by the fact that this whole thread started from a
> > user that refused to configure pull.rebase and expected the Git
> > project to just do the right thing (which is basically choosing a
> > useful default).
>
> Which is basically asking for impossible, and I do not think it is a
> good idea to focus our effort to satisfy such a request in general.
> There is no useful default that suits everybody in this particular
> case.

I think I already made this point, but this is the nirvana fallacy
(the perfect is the enemy of the good) [1]. Just because we can't have
the perfect solution doesn't mean we can't pursue something better
than the current state.

What was asked was not a perfect solution, just a better default. If
right now the default is good enough for 20% of users, and with some
changes we can make it better for 40%... that's progress. We don't
have to wait until we have a solution for 100% of them.

> But for anybody who uses git for real (read: produces his or her own
> history), it would be pretty much a useless default that forces the
> user to say rebase or merge every time 'git pull' is run.

This is not true.

I will give you a real example.

I create a branch named "fc/margin" based on "master", I make my
changes, I push the branch to my personal repository, and create a
pull request. This is the typical triangular workflow.

Then I do "git pull [--ff-only]". What will happen? 1) As long as my
branch is not merged upstream, I will get an error, and my branch will
stay where it is. But then, 2) when my branch is finally merged to
"master" it will be fast-forwarded, so now both "fc/margin" and
"origin/master" point to the same commit.

A. Did I use git "for real"? (produce my own history)
B. Was "git pull [--ff-only]" useful in this case?

I think that one of the problems is that Git has so many different
workflows that finding another person that has your same workflow is
like finding a person with your same birthday. It's not impossible,
just takes more than a few tries.

Also, and this is not a deriding question, I'm genuinely curious: how
often do you send pull requests?

BTW, this example above is real [2]. In my particular case very often
I'm creating history, I'm just not the one pulling it.

> But other than that, I do not
> see any real use for the choice, which would mean in practice,
> pull.mode would have only two useful values, rebase or merge.  That
> does not feel a good enough reason to supersede what already exists,
> which is pull.rebase=yes/no.

The fact that you don't see the use doesn't mean the use is not there.

Why do you think this issue keeps coming back again and again, and
again? And every time it comes back people say the same thing:
"fast-forward-only merges should be the default".

Unfortunately it's not that simple. It's a rabbit hole that leads to a
cacophony of issues in git pull. However, we can fix some of them
*today*.

> Perhaps there is a good reason why certain classes of users would
> want to configure pull.mode=ff-only (i.e. "I might type 'git pull'
> by mistake, please stop me if I did so on a branch I have real work
> already.").  If that is the case, I would very much agree that it
> would be awkward to express that choice in the current framework to
> choose between pull.rebase=yes/no and pull.mode=(rebase/merge/ff-only)
> would become a lot easier to explain.

There's three options:

1. pull.ff=only (that doesn't work IMO)
2. pull.rebase=ff-only (that works, but it's kind of wonky)
3. pull.mode=ff-only (maybe it should be pull.mode=fast-forward)

But the current option (pull.mode=merge) just doesn't fly. And BTW, I
did create a poll in reddit's r/git [3], and 67% (of 789) said they
didn't specify anything, just "git pull".

So, most people simply do "git pull" and hope for the best.

Moreover, in 2014 I said if we don't fix it now (which is likely), we
will be discussing it again [4], and here we are now. And I'm saying
it again: leave the mode as "merge", we will be discussing this again.

I could do some mail archeology if you want, but this issue starts to
be mentioned at least since 2010, and virtually everyone (except one
person) agreed the default must change, even Linus Torvalds. Reading
back what Linus said [5], it's something very, *very* close to what
I'm proposing (I would argue my proposal is better).

So you let me know. Do you want me to dig a decade of discussions and
coalesce those conclusions into a summary so we can decide how to
proceed? Or should I drop the plan? Only that if we drop it, I
*guarantee* we will discuss it yet again years later.

Moreover, this is the reason why I split the series in 3. Even if you
decide you don't want to change the default, part I of the series can
still be merged *today*, and everyone would benefit.

Cheers.

[1] https://en.wikipedia.org/wiki/Nirvana_fallacy
[2] https://github.com/git/git.github.io/commit/5d90fd64d80847e3d873da43515750bc04b639e2
[3] https://www.reddit.com/r/git/comments/k6uj7c/do_you_use_git_pull/
[4] https://lore.kernel.org/git/536429e97cf5a_200c12912f094@nysa.notmuch/
[5] https://lore.kernel.org/git/CA+55aFz2Uvq4vmyjJPao5tS-uuVvKm6mbP7Uz8sdq1VMxMGJCw@mail.gmail.com/

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-09  9:52                                   ` Felipe Contreras
@ 2020-12-09 19:05                                     ` Elijah Newren
  2020-12-10  2:39                                       ` Felipe Contreras
  2020-12-10  6:45                                       ` Junio C Hamano
  0 siblings, 2 replies; 79+ messages in thread
From: Elijah Newren @ 2020-12-09 19:05 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Junio C Hamano, Jacob Keller, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

Hi,

On Wed, Dec 9, 2020 at 1:53 AM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> On Tue, Dec 8, 2020 at 2:16 PM Junio C Hamano <gitster@pobox.com> wrote:
> >
> > Felipe Contreras <felipe.contreras@gmail.com> writes:
> >
> > > That is exemplified by the fact that this whole thread started from a
> > > user that refused to configure pull.rebase and expected the Git
> > > project to just do the right thing (which is basically choosing a
> > > useful default).
> >
> > Which is basically asking for impossible, and I do not think it is a
> > good idea to focus our effort to satisfy such a request in general.
> > There is no useful default that suits everybody in this particular
> > case.
>
> I think I already made this point, but this is the nirvana fallacy
> (the perfect is the enemy of the good) [1]. Just because we can't have
> the perfect solution doesn't mean we can't pursue something better
> than the current state.
>
> What was asked was not a perfect solution, just a better default. If
> right now the default is good enough for 20% of users, and with some
> changes we can make it better for 40%... that's progress. We don't
> have to wait until we have a solution for 100% of them.
>
> > But for anybody who uses git for real (read: produces his or her own
> > history), it would be pretty much a useless default that forces the
> > user to say rebase or merge every time 'git pull' is run.
>
> This is not true.
>
> I will give you a real example.
>
> I create a branch named "fc/margin" based on "master", I make my
> changes, I push the branch to my personal repository, and create a
> pull request. This is the typical triangular workflow.
>
> Then I do "git pull [--ff-only]". What will happen? 1) As long as my
> branch is not merged upstream, I will get an error, and my branch will
> stay where it is. But then, 2) when my branch is finally merged to
> "master" it will be fast-forwarded, so now both "fc/margin" and
> "origin/master" point to the same commit.
>
> A. Did I use git "for real"? (produce my own history)
> B. Was "git pull [--ff-only]" useful in this case?
>
> I think that one of the problems is that Git has so many different
> workflows that finding another person that has your same workflow is
> like finding a person with your same birthday. It's not impossible,
> just takes more than a few tries.
>
> Also, and this is not a deriding question, I'm genuinely curious: how
> often do you send pull requests?
>
> BTW, this example above is real [2]. In my particular case very often
> I'm creating history, I'm just not the one pulling it.
>
> > But other than that, I do not
> > see any real use for the choice, which would mean in practice,
> > pull.mode would have only two useful values, rebase or merge.  That
> > does not feel a good enough reason to supersede what already exists,
> > which is pull.rebase=yes/no.
>
> The fact that you don't see the use doesn't mean the use is not there.
>
> Why do you think this issue keeps coming back again and again, and
> again? And every time it comes back people say the same thing:
> "fast-forward-only merges should be the default".
>
> Unfortunately it's not that simple. It's a rabbit hole that leads to a
> cacophony of issues in git pull. However, we can fix some of them
> *today*.
>
> > Perhaps there is a good reason why certain classes of users would
> > want to configure pull.mode=ff-only (i.e. "I might type 'git pull'
> > by mistake, please stop me if I did so on a branch I have real work
> > already.").  If that is the case, I would very much agree that it
> > would be awkward to express that choice in the current framework to
> > choose between pull.rebase=yes/no and pull.mode=(rebase/merge/ff-only)
> > would become a lot easier to explain.
>
> There's three options:
>
> 1. pull.ff=only (that doesn't work IMO)
> 2. pull.rebase=ff-only (that works, but it's kind of wonky)
> 3. pull.mode=ff-only (maybe it should be pull.mode=fast-forward)
>
> But the current option (pull.mode=merge) just doesn't fly. And BTW, I
> did create a poll in reddit's r/git [3], and 67% (of 789) said they
> didn't specify anything, just "git pull".
>
> So, most people simply do "git pull" and hope for the best.
>
> Moreover, in 2014 I said if we don't fix it now (which is likely), we
> will be discussing it again [4], and here we are now. And I'm saying
> it again: leave the mode as "merge", we will be discussing this again.
>
> I could do some mail archeology if you want, but this issue starts to
> be mentioned at least since 2010, and virtually everyone (except one
> person) agreed the default must change, even Linus Torvalds. Reading
> back what Linus said [5], it's something very, *very* close to what
> I'm proposing (I would argue my proposal is better).
>
> So you let me know. Do you want me to dig a decade of discussions and
> coalesce those conclusions into a summary so we can decide how to
> proceed? Or should I drop the plan? Only that if we drop it, I
> *guarantee* we will discuss it yet again years later.
>
> Moreover, this is the reason why I split the series in 3. Even if you
> decide you don't want to change the default, part I of the series can
> still be merged *today*, and everyone would benefit.

Have I missed some subtlety here?  This whole email appears to me to
be arguing against a strawman.  Reading Junio's other emails in this
thread[1][2], it's pretty clear he thinks the current behavior is
buggy and suggests how it should be changed.  From what I can tell,
you appear to be arguing against doing nothing and against only
accepting perfection, neither of which were positions I saw anyone
take.  In fact, the positions you argue for at length appear to
exactly match the ones he took[1][2].  What am I missing?

[1] https://lore.kernel.org/git/xmqq360h8286.fsf@gitster.c.googlers.com/
[2] https://lore.kernel.org/git/xmqqlfe99yvy.fsf@gitster.c.googlers.com/

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-09 19:05                                     ` Elijah Newren
@ 2020-12-10  2:39                                       ` Felipe Contreras
  2020-12-10  6:45                                       ` Junio C Hamano
  1 sibling, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-10  2:39 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Junio C Hamano, Jacob Keller, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

Hello,

On Wed, Dec 9, 2020 at 1:05 PM Elijah Newren <newren@gmail.com> wrote:
> On Wed, Dec 9, 2020 at 1:53 AM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:

> > I could do some mail archeology if you want, but this issue starts to
> > be mentioned at least since 2010, and virtually everyone (except one
> > person) agreed the default must change, even Linus Torvalds. Reading
> > back what Linus said [5], it's something very, *very* close to what
> > I'm proposing (I would argue my proposal is better).
> >
> > So you let me know. Do you want me to dig a decade of discussions and
> > coalesce those conclusions into a summary so we can decide how to
> > proceed? Or should I drop the plan? Only that if we drop it, I
> > *guarantee* we will discuss it yet again years later.
> >
> > Moreover, this is the reason why I split the series in 3. Even if you
> > decide you don't want to change the default, part I of the series can
> > still be merged *today*, and everyone would benefit.
>
> Have I missed some subtlety here?  This whole email appears to me to
> be arguing against a strawman.  Reading Junio's other emails in this
> thread[1][2], it's pretty clear he thinks the current behavior is
> buggy and suggests how it should be changed.  From what I can tell,
> you appear to be arguing against doing nothing and against only
> accepting perfection, neither of which were positions I saw anyone
> take.  In fact, the positions you argue for at length appear to
> exactly match the ones he took[1][2].  What am I missing?

People change their minds.

Perhaps I misinterpreted something, but when Junio said "I dunno" I
take it to mean: he is unsure my proposal "pull.mode=ff-only" makes
sense. He also said "for anybody who uses git for real, [force
-ff-only] would be pretty much a useless default", which I take it to
mean that perhaps we shouldn't change the default to that.

Back in 2013 Junio said "I now see how such a default makes sense."
[1], but we are in 2020 and such a default that made sense is not the
default.

Mind reading is a really bad habbit [2]; I don't know what other
people think, and I would not presume to know.

All I know is that the path forward is unclear. And because I
prognosticated that, I split the series in 3 parts, and I've yet to
see any objection to part I, which would improve the situation for
users *today*.

So, while we make up our collective minds, there's no reason to bother
our users with an annoying warning on *every* *single* *pull*.

Cheers.

[1] https://lore.kernel.org/git/7vli74baym.fsf@alter.siamese.dyndns.org/
[2] https://cogbtherapy.com/cbt-blog/common-cognitive-distortions-mind-reading

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-09 19:05                                     ` Elijah Newren
  2020-12-10  2:39                                       ` Felipe Contreras
@ 2020-12-10  6:45                                       ` Junio C Hamano
  2020-12-10  9:08                                         ` Felipe Contreras
  1 sibling, 1 reply; 79+ messages in thread
From: Junio C Hamano @ 2020-12-10  6:45 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Felipe Contreras, Jacob Keller, Git Mailing List,
	Vít Ondruch, Alex Henrie, Jeff King, Philip Oakley,
	Theodore Y . Ts'o, John Keeping, Richard Hansen,
	Brian M. Carlson, W. Trevor King

Elijah Newren <newren@gmail.com> writes:

> Have I missed some subtlety here?  This whole email appears to me to
> be arguing against a strawman.  Reading Junio's other emails in this
> thread[1][2], it's pretty clear he thinks the current behavior is
> buggy and suggests how it should be changed.  From what I can tell,
> you appear to be arguing against doing nothing and against only
> accepting perfection, neither of which were positions I saw anyone
> take.  In fact, the positions you argue for at length appear to
> exactly match the ones he took[1][2].  What am I missing?
>
> [1] https://lore.kernel.org/git/xmqq360h8286.fsf@gitster.c.googlers.com/
> [2] https://lore.kernel.org/git/xmqqlfe99yvy.fsf@gitster.c.googlers.com/

I tend to agree that the endgame state I want is pretty similar to
what Felipe wants.  The seeming confusion is probably due to what
exactly I mean by "default" is different from what he means.

I view the proposed "for unconfigured users, pull dies, and tells
them to choose between rebase or merge before it can continue, when
faced with a non-ff history" as a safe fallback behaviour until the
users make their choice.

It is a safe fallback to disable the more dangerous half of the
command until the user gives enough information to the command to do
its job without damaging the resulting history; it is not something
the users would actively want to choose.  

And that is what I meant by the default behaviour.

And when we stop in such a manner, it is sensible to give an error
message telling them 

 - why we are stopping,

 - what they can do to move the immediate situation forward
   (i.e. command line option that lets them choose), and

 - what they can do to make their choice permanent so that they
   would never see the command stop when facing a non-ff history
   (i.e. the configuration variables).

Up to this point, I think both of us agree with the above.

We start to differ after this point.  I would want to see only
"rebase" and "merge in the "choice" in the above list.  Felipe, if I
understand correctly, wants to add the third one, "ff-only", which
means the more dangerous half of "pull" is disabled by default.

I do not want to include that choice, as it would mean the more
familiar pull.rebase=yes/no would no longer work, and we'd need to
introduce a new variable, like pull.mode=ff-only.  It would mean for
those who use "pull" to consolidate histories on their side and
other people's side, whether they use rebase or merge, would now
have two ways to do the same thing (i.e. pull.rebase=no or
pull.mode=merge).  That is just making the end user experience more
complex than necessary.

Without introducing pull.mode, the only thing the users cannot do,
as far as I can tell, is to explicitly ask for the behaviour of an
unconfigured user (i.e. error out when faced with non-ff history)
without being told about the way to use configuration variable to
permanently record their choice.  Other than that, the existing
pull.rebase=yes/no is perfectly adequate.  Felipe seems to think
otherwise and wants not just the "safe fallback behaviour", but can
explicitly be configured using pull.mode=ff-only (and if that is not
what Felipe thinks, perhaps we are already in agreement without
realizing it).

Thinking about it again, I guess pull.rebase=yes/no plus a new
advise entry can easily give what Felipe seems to want.  We teach
"git pull", when it is not told to rebase or merge (either via the
command line --[no-]rebase or via pull.rebase configuration) and
when it sees a non-ff history, to

 - error out with a message telling the user that we are stopping,
   because the two histories needs consolidating to conclude this
   pull, but the two available ways would give vastly different
   result.

 - check the advice.pullNonFF configuration (as usual, it defaults
   to true) and if true, further tell the user that

    (1) they can either run "git pull --rebase" or "git pull
        --no-rebase",

    (2) they can configure their choice permanently with
        pull.rebase=yes/no, and

    (3) they can leave "pull" in the half-disabled state but stop
        seeing this message by setting advice.pullNonFF to false.

The last part (i.e. advice.pullnonFF) is the only new thing I said
in the various discussions on this topic (simply because I just came
up with the idea).  Everything else I've already said it elsewhere.

I dunno.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-10  6:45                                       ` Junio C Hamano
@ 2020-12-10  9:08                                         ` Felipe Contreras
  2020-12-10 10:01                                           ` Felipe Contreras
  2020-12-11  7:17                                           ` Junio C Hamano
  0 siblings, 2 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-10  9:08 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Elijah Newren, Jacob Keller, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 10, 2020 at 12:45 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Elijah Newren <newren@gmail.com> writes:
>
> > Have I missed some subtlety here?  This whole email appears to me to
> > be arguing against a strawman.  Reading Junio's other emails in this
> > thread[1][2], it's pretty clear he thinks the current behavior is
> > buggy and suggests how it should be changed.  From what I can tell,
> > you appear to be arguing against doing nothing and against only
> > accepting perfection, neither of which were positions I saw anyone
> > take.  In fact, the positions you argue for at length appear to
> > exactly match the ones he took[1][2].  What am I missing?
> >
> > [1] https://lore.kernel.org/git/xmqq360h8286.fsf@gitster.c.googlers.com/
> > [2] https://lore.kernel.org/git/xmqqlfe99yvy.fsf@gitster.c.googlers.com/
>
> I tend to agree that the endgame state I want is pretty similar to
> what Felipe wants.  The seeming confusion is probably due to what
> exactly I mean by "default" is different from what he means.
>
> I view the proposed "for unconfigured users, pull dies, and tells
> them to choose between rebase or merge before it can continue, when
> faced with a non-ff history" as a safe fallback behaviour until the
> users make their choice.
>
> It is a safe fallback to disable the more dangerous half of the
> command until the user gives enough information to the command to do
> its job without damaging the resulting history; it is not something
> the users would actively want to choose.
>
> And that is what I meant by the default behaviour.
>
> And when we stop in such a manner, it is sensible to give an error
> message telling them
>
>  - why we are stopping,
>
>  - what they can do to move the immediate situation forward
>    (i.e. command line option that lets them choose), and
>
>  - what they can do to make their choice permanent so that they
>    would never see the command stop when facing a non-ff history
>    (i.e. the configuration variables).
>
> Up to this point, I think both of us agree with the above.

I don't agree with the above.

The error I propose is just:

  The pull was not fast-forward, please either merge or rebase.

That's it. Nothing more.

I explained that was the final end goal in my list of steps [1]. I do
not think any suggestion for commands or configurations belongs in a
*permanent* error message.

Do we even have an error message that long?

> We start to differ after this point.  I would want to see only
> "rebase" and "merge in the "choice" in the above list.  Felipe, if I
> understand correctly, wants to add the third one, "ff-only", which
> means the more dangerous half of "pull" is disabled by default.

No. I don't want to present the user *any* configuration option in the
*permanent error* message, just: "please either merge or rebase".
That's it.

> I do not want to include that choice, as it would mean the more
> familiar pull.rebase=yes/no would no longer work, and we'd need to
> introduce a new variable, like pull.mode=ff-only.

Whether we present the user with that option or not doesn't matter.
"pull.rebase=yes/no", would still work. The only thing that changes is
what happens if the user does *not* set that option.

The reason "pull.mode=ff-only" needs to be introduced is that
--ff-only doesn't work. Otherwise there's no way the user cannot
select the "safe default" mode. It has absolutely nothing to do with
what we present the user with.

> Without introducing pull.mode, the only thing the users cannot do,
> as far as I can tell, is to explicitly ask for the behaviour of an
> unconfigured user (i.e. error out when faced with non-ff history)
> without being told about the way to use configuration variable to
> permanently record their choice.

That's right, which is a *crucial* thing they must have.

Part II of the proposal has these:

  pull: add pull.mode
  pull: add pull.mode=ff-only
  pull: advice of future changes

This is where we want to be for a good considerable amount of time. A
point where the user is a) warned about future changes, b) can
configure both the old and the new behavior, and c) we have time to
test and tune this new behavior (in case there are mistakes), *BEFORE*
forcing all our users to switch to this new mode (unless they haven't
configured otherwise).

This is what happened with "push.default=simple". We didn't just say:
the simple mode is the default mode, so just leave "push.default"
blank if you want this mode. No. Because in theory we might have
decided before v2.0 that another mode was to be the default, or
perhaps in v3.0 another one will. We want the user to be able to say:
this is the mode I want. Not whatever mode the Git project decides
it's better this day of the week: *this* mode.

There is nothing good about the user being unable to specify the mode
he/she wants instead of the default, even if at this moment in time
they happen to be the same.

Moreover, I can attach a patch on top of part I that skips right ahead
towards part 3, and flips the switch without any intermediary steps.
The patch is simple, but it's likely to be wrong. And I doubt anyone
has tested this patch series at this point. No amount of looking at
the code is going to spot all the problems.

People actually need to try this code.

Otherwise it's just some patches flying around that will never be
merged, and the problem will remain forever there.

> Other than that, the existing
> pull.rebase=yes/no is perfectly adequate.

You cannot specify "pull.rebase=ff-only", but I did send a patch for
that [2]. It was you the one that said it looked "quite funny" [3]:
"it looks quite funny for that single variable that controls the way
how pull works, whether rebase or merge is used, is pull.REBASE".

If you think it's fine to have this warning:

  The pull was not fast-forward, in the future you will have to choose
a merge, or a rebase.

  To quell this message you have two main options:

  1. Adopt the new behavior:

    git config --global pull.rebase ff-only

  2. Maintain the current behavior:

    git config --global pull.rebase false

  For now we will fall back to the traditional behavior (merge).
  Read "git pull --help" for more information.

For months, possibly a year, possibly until v3.0, instead of this one
(which is my proposal):

  The pull was not fast-forward, in the future you will have to choose
a merge, or a rebase.

  To quell this message you have two main options:

  1. Adopt the new behavior:

    git config --global pull.mode fast-forward

  2. Maintain the current behavior:

    git config --global pull.mode merge

  For now we will fall back to the traditional behavior (merge).
  Read "git pull --help" for more information.

By all means, let's go for that, make the decision.

But it was you who wanted to see how a pull.mode solution would look
like [4][5]. Well, this is how it looks like: 3 patches.

> Felipe seems to think
> otherwise and wants not just the "safe fallback behaviour", but can
> explicitly be configured using pull.mode=ff-only (and if that is not
> what Felipe thinks, perhaps we are already in agreement without
> realizing it).

No. It doesn't matter if it's "pull.mode=ff-only", or
"pull.rebase=ff-only", or "pull.ff=only", but one of those must turn
on the behavior that we want. And right now no option does.

> Thinking about it again, I guess pull.rebase=yes/no plus a new
> advise entry can easily give what Felipe seems to want.

It's not about what I want, it's about what the project wants. And I
think it's pretty clear what the project wants:

  1. git pull to eventually fail in non-fast-forward cases
  2. A grace period before that switch is flipped

That's it.

My proposal is the only one (so far) that gives us that.

Cheers.

[1] https://lore.kernel.org/git/CAMP44s2hUCd9qc83LReGyjy8N+u++eK6VjwGhDhrX0f0SbKmig@mail.gmail.com/
[2] https://lore.kernel.org/git/20201123224621.2573159-2-felipe.contreras@gmail.com/
[3] https://lore.kernel.org/git/xmqqim9vlkdn.fsf@gitster.c.googlers.com/
[4] https://lore.kernel.org/git/xmqqy2irjy4f.fsf@gitster.c.googlers.com/
[5] https://lore.kernel.org/git/xmqq7dqagtgx.fsf@gitster.c.googlers.com/

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-10  9:08                                         ` Felipe Contreras
@ 2020-12-10 10:01                                           ` Felipe Contreras
  2020-12-11  7:17                                           ` Junio C Hamano
  1 sibling, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-10 10:01 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Elijah Newren, Jacob Keller, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Thu, Dec 10, 2020 at 3:08 AM Felipe Contreras
<felipe.contreras@gmail.com> wrote:

> It's not about what I want, it's about what the project wants. And I
> think it's pretty clear what the project wants:
>
>   1. git pull to eventually fail in non-fast-forward cases
>   2. A grace period before that switch is flipped
>
> That's it.
>
> My proposal is the only one (so far) that gives us that.

Not to mention that part I is not even contentious. We can improve the
situation of users *today*.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-10  9:08                                         ` Felipe Contreras
  2020-12-10 10:01                                           ` Felipe Contreras
@ 2020-12-11  7:17                                           ` Junio C Hamano
  2020-12-11 11:33                                             ` Felipe Contreras
  2020-12-15  2:31                                             ` Jeff King
  1 sibling, 2 replies; 79+ messages in thread
From: Junio C Hamano @ 2020-12-11  7:17 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Elijah Newren, Jacob Keller, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

Felipe Contreras <felipe.contreras@gmail.com> writes:

>> And when we stop in such a manner, it is sensible to give an error
>> message telling them
>>
>>  - why we are stopping,
>>
>>  - what they can do to move the immediate situation forward
>>    (i.e. command line option that lets them choose), and
>>
>>  - what they can do to make their choice permanent so that they
>>    would never see the command stop when facing a non-ff history
>>    (i.e. the configuration variables).
>>
>> Up to this point, I think both of us agree with the above.
>
> I don't agree with the above.
>
> The error I propose is just:
>
>   The pull was not fast-forward, please either merge or rebase.
>
> That's it. Nothing more.

It says "why we are stopping." quite well.  It would be a good
message to use as the first part of the three-part message I
mentioned above.

> I explained that was the final end goal in my list of steps [1]. I do
> not think any suggestion for commands or configurations belongs in a
> *permanent* error message.

In the design I have in mind in the message you are responding to,
the users who haven't told their choice to Git would be the only
folks who get all three.

You want to let the user express: "I do not want to choose either
rebase or merge.  I want 'pull' to fail when it needs to deal with
non-ff history.  But I do not need to be told about command line
option and configuration every time."

I said I don't (I view that disabling half the "git pull" just a
safe fallback behaviour until the user chooses between merge and
rebase), but if we wanted to offer it as a valid choice to users, we
can do so.  We just make it possible to squelch the latter two parts
of the three-part message---you leave pull.rebase unconfigured and
squelch the latter two parts of the message, and you got the "stop
me, I do not merge or rebase, but don't even tell me how to further
configure" already.

I agree the latter two should not be part of *permanent* error
message.  And my suggestion did not intend to make them so---it
should have been quite obvious to who read the message you are
responding to through to the end and understood what it said.

Now, how would we make it possible to squelch the latter two parts?
It is not a good idea to introduce pull.mode=ff-only for that
purpose (pull.mode=rebase and pull.rebase=yes would unnecessarily
become two redundant ways to do the same thing if we added a new
pull.mode variable).

But there is an established way used in this project when we allow
squelching overly-helpful help messages, and we can apply it here as
well.  That way:

 - unconfigured folks would get all the three parts of the messages,
   just like the current system.

 - if you tell rebase or merge, you do not see any.

 - if you do not choose between rebase or merge, you can still
   squelch the latter two by setting advice.pullNonFF to false.

The last one is "keep the more dangerous half of 'git pull' disabled,
without getting told how to enable it over and over", which is what
you want to be able to specify.

> The reason "pull.mode=ff-only" needs to be introduced is that
> --ff-only doesn't work. Otherwise there's no way the user cannot
> select the "safe default" mode. It has absolutely nothing to do with
> what we present the user with.

I too initially thought that pull.mode may be needed, but probably I
was wrong.  I do think this can be done without pull.mode at all, at
least in two ways, without adding different ways to do the same
thing.

 - When pull.rebase is set to 'no' and pull.ff is set to 'only',
   "git pull" that sees a non-ff history should error out safely.
   The user is telling that their preference is to merge, but the
   difference between merge and rebase does not really matter
   because pull.ff=only would mean we forbid merges of non-ff
   history anyway.  The message you'd get would be "fatal: Not
   possible to fast-forward, aborting." though.

 - Or with the advice that hides the latter two points, a user can
   unset pull.rebase and set the advice.pullNonFF to false to get
   the same behaviour (i.e. disable the more dangerous half of
   "pull") with just the "we stopped" error message.

I think either of these are close enough to what you want, and I
think the latter gives us more flexibility in how we tone down the
message with advice.pullNonFF.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-11  7:17                                           ` Junio C Hamano
@ 2020-12-11 11:33                                             ` Felipe Contreras
  2020-12-14 21:04                                               ` Junio C Hamano
  2020-12-15  2:31                                             ` Jeff King
  1 sibling, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-11 11:33 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Elijah Newren, Jacob Keller, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

On Fri, Dec 11, 2020 at 4:02 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Felipe Contreras <felipe.contreras@gmail.com> writes:
>
> >> And when we stop in such a manner, it is sensible to give an error
> >> message telling them
> >>
> >>  - why we are stopping,
> >>
> >>  - what they can do to move the immediate situation forward
> >>    (i.e. command line option that lets them choose), and
> >>
> >>  - what they can do to make their choice permanent so that they
> >>    would never see the command stop when facing a non-ff history
> >>    (i.e. the configuration variables).
> >>
> >> Up to this point, I think both of us agree with the above.
> >
> > I don't agree with the above.
> >
> > The error I propose is just:
> >
> >   The pull was not fast-forward, please either merge or rebase.
> >
> > That's it. Nothing more.
>
> It says "why we are stopping." quite well.  It would be a good
> message to use as the first part of the three-part message I
> mentioned above.

The two key parts of the message are:

1. It is an *error*
2. It is *permanent*

> > I explained that was the final end goal in my list of steps [1]. I do
> > not think any suggestion for commands or configurations belongs in a
> > *permanent* error message.
>
> In the design I have in mind in the message you are responding to,
> the users who haven't told their choice to Git would be the only
> folks who get all three.

What would that error message look like? And do you have any other
example of the current user interface where such a condescending long
error message is displayed?

> You want to let the user express: "I do not want to choose either
> rebase or merge.  I want 'pull' to fail when it needs to deal with
> non-ff history.  But I do not need to be told about command line
> option and configuration every time."

That's right.

> I said I don't (I view that disabling half the "git pull" just a
> safe fallback behaviour until the user chooses between merge and
> rebase), but if we wanted to offer it as a valid choice to users, we
> can do so.  We just make it possible to squelch the latter two parts
> of the three-part message---you leave pull.rebase unconfigured and
> squelch the latter two parts of the message, and you got the "stop
> me, I do not merge or rebase, but don't even tell me how to further
> configure" already.
>
> I agree the latter two should not be part of *permanent* error
> message.  And my suggestion did not intend to make them so---it
> should have been quite obvious to who read the message you are
> responding to through to the end and understood what it said.

It doesn't matter (much) if it's temporary or permanent, it's still an
*error* message.

Currently it's a warning, and people are complaining, even though the
pull still works.

And you want to make it an error, and *always* fail? Even though the
user has not been warned that such a change was coming and how to
evade it?

I'm against that. I would rather do nothing than intentionally break
user experience without warning.

Johannes said he didn't mind the warning. I want the warning to
remain, just make it a different warning. You want to break his
experience without a grace period and suddenly make it an error.

> Now, how would we make it possible to squelch the latter two parts?

...

This is irrelevant.

As long as it's an error I don't care if it's short or long. I'm
against turning on an error from one version to the next.

> > The reason "pull.mode=ff-only" needs to be introduced is that
> > --ff-only doesn't work. Otherwise there's no way the user cannot
> > select the "safe default" mode. It has absolutely nothing to do with
> > what we present the user with.
>
> I too initially thought that pull.mode may be needed, but probably I
> was wrong.  I do think this can be done without pull.mode at all, at
> least in two ways, without adding different ways to do the same
> thing.
>
>  - When pull.rebase is set to 'no' and pull.ff is set to 'only',
>    "git pull" that sees a non-ff history should error out safely.
>    The user is telling that their preference is to merge, but the
>    difference between merge and rebase does not really matter
>    because pull.ff=only would mean we forbid merges of non-ff
>    history anyway.  The message you'd get would be "fatal: Not
>    possible to fast-forward, aborting." though.
>
>  - Or with the advice that hides the latter two points, a user can
>    unset pull.rebase and set the advice.pullNonFF to false to get
>    the same behaviour (i.e. disable the more dangerous half of
>    "pull") with just the "we stopped" error message.

So, after your hypothetical patch, there would be no difference between:

  git -c pull.rebase=no -c pull.ff=only pull

and:

  git -c advice.pullnonff=false pull

?

> I think either of these are close enough to what you want, and I
> think the latter gives us more flexibility in how we tone down the
> message with advice.pullNonFF.

You are missing at least two things.

I'll wait for your response.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-11 11:33                                             ` Felipe Contreras
@ 2020-12-14 21:04                                               ` Junio C Hamano
  2020-12-14 22:30                                                 ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Junio C Hamano @ 2020-12-14 21:04 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Elijah Newren, Jacob Keller, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

Felipe Contreras <felipe.contreras@gmail.com> writes:

> This is irrelevant.

Oh, now you are saying that you do not need a way to squelch these
message to help unconfigured users choose between rebase or merge?
I am confused.

> As long as it's an error I don't care if it's short or long. I'm
> against turning on an error from one version to the next.

Now you are changing your mind?  Current version and past ones do
not make it an error to pull non-ff history without choosing rebase
or merge---we go ahead and merge anyway.  I thought that in the far
future agreed between two of us, it would be turnend into an error
at some point.  There needs one version that turns it into an error
for that to happen.  Puzzled.

>> I too initially thought that pull.mode may be needed, but probably I
>> was wrong.  I do think this can be done without pull.mode at all, at
>> least in two ways, without adding different ways to do the same
>> thing.
>>
>>  - When pull.rebase is set to 'no' and pull.ff is set to 'only',
>>    "git pull" that sees a non-ff history should error out safely.
>>    The user is telling that their preference is to merge, but the
>>    difference between merge and rebase does not really matter
>>    because pull.ff=only would mean we forbid merges of non-ff
>>    history anyway.  The message you'd get would be "fatal: Not
>>    possible to fast-forward, aborting." though.
>>
>>  - Or with the advice that hides the latter two points, a user can
>>    unset pull.rebase and set the advice.pullNonFF to false to get
>>    the same behaviour (i.e. disable the more dangerous half of
>>    "pull") with just the "we stopped" error message.
>
> So, after your hypothetical patch, there would be no difference between:
>
>   git -c pull.rebase=no -c pull.ff=only pull
>
> and:
>
>   git -c advice.pullnonff=false pull
>
> ?

We do not have to or implement both, but either should give us the
"when pull sees a non-ff history, it should stop without merging or
rebasing, and the user won't be given the advice on how to choose
between merge and rebase" behaviour, I would think.

>> I think either of these are close enough to what you want, and I
>> think the latter gives us more flexibility in how we tone down the
>> message with advice.pullNonFF.
>
> You are missing at least two things.

I am guessing that the '?' above I just answered is one you wanted
to ask me, but what's the other one?

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-14 21:04                                               ` Junio C Hamano
@ 2020-12-14 22:30                                                 ` Felipe Contreras
  2020-12-14 23:14                                                   ` Junio C Hamano
  0 siblings, 1 reply; 79+ messages in thread
From: Felipe Contreras @ 2020-12-14 22:30 UTC (permalink / raw)
  To: Junio C Hamano, Felipe Contreras
  Cc: Elijah Newren, Jacob Keller, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

Junio C Hamano wrote:
> Felipe Contreras <felipe.contreras@gmail.com> writes:
> 
> > This is irrelevant.
> 
> Oh, now you are saying that you do not need a way to squelch these
> message to help unconfigured users choose between rebase or merge?
> I am confused.

We need a way to squelch the *advise* message, yes.

But this is a secondary priority. The first priority is not to break
current behavior users rely on.

> > As long as it's an error I don't care if it's short or long. I'm
> > against turning on an error from one version to the next.
> 
> Now you are changing your mind?  Current version and past ones do
> not make it an error to pull non-ff history without choosing rebase
> or merge---we go ahead and merge anyway.  I thought that in the far
> future agreed between two of us, it would be turnend into an error
> at some point.  There needs one version that turns it into an error
> for that to happen.  Puzzled.

Yes, in the future, *after* a deprecation period.

Once the users have had a chance to configure git to do what they want,
have tried the new mode, haven't had issues with the new mode, or if
they disagree with the proposed *future* behavior; complain in the
forums at their disposal.

Not before.

> >> I too initially thought that pull.mode may be needed, but probably I
> >> was wrong.  I do think this can be done without pull.mode at all, at
> >> least in two ways, without adding different ways to do the same
> >> thing.
> >>
> >>  - When pull.rebase is set to 'no' and pull.ff is set to 'only',
> >>    "git pull" that sees a non-ff history should error out safely.
> >>    The user is telling that their preference is to merge, but the
> >>    difference between merge and rebase does not really matter
> >>    because pull.ff=only would mean we forbid merges of non-ff
> >>    history anyway.  The message you'd get would be "fatal: Not
> >>    possible to fast-forward, aborting." though.
> >>
> >>  - Or with the advice that hides the latter two points, a user can
> >>    unset pull.rebase and set the advice.pullNonFF to false to get
> >>    the same behaviour (i.e. disable the more dangerous half of
> >>    "pull") with just the "we stopped" error message.
> >
> > So, after your hypothetical patch, there would be no difference between:
> >
> >   git -c pull.rebase=no -c pull.ff=only pull
> >
> > and:
> >
> >   git -c advice.pullnonff=false pull
> >
> > ?
> 
> We do not have to or implement both, but either should give us the
> "when pull sees a non-ff history, it should stop without merging or
> rebasing, and the user won't be given the advice on how to choose
> between merge and rebase" behaviour, I would think.

Right, so both should error out.

And what should these do?

  git -c pull.rebase=no -c pull.ff=only pull --merge

  git -c advice.pullnonff=false pull --merge

I'm going to answer because I think it's obvious what you would expect:
if you pass --merge, both should succeed.

Except they won't, because "git pull --ff-only --merge" fails.

Correct?

> >> I think either of these are close enough to what you want, and I
> >> think the latter gives us more flexibility in how we tone down the
> >> message with advice.pullNonFF.
> >
> > You are missing at least two things.
> 
> I am guessing that the '?' above I just answered is one you wanted
> to ask me, but what's the other one?

Yes. The other is what I explained above; we need a grace deprecation
period where we can explain to the user in a simple way what to expect
in the future.

And it's much easier to explain to the user that:

  git pull --merge -> pull.mode = merge
  git pull --rebase -> pull.mode = rebase
  git pull -> pull.mode = fast-forward

Than:

  git pull --merge -> pull.rebase = false
  git pull --rebase -> pull.rebase = true
  git pull -> pull.rebase = false + pull.ff = only

But those are not the only two. For example there's this additional
problem of how to interact with the other values of pull.rebase (other
than true and false):

  pull.mode = merge
  pull.rebase = merges

I would expect in this particular configuration that:

  git pull -> git pull --merge
  git pull --rebase -> git pull --rebase=merges

There's no way to represent that with just pull.rebase.

And there's more: some people suggested other modes in 2013, like
"pull.mode=none" (essentially "git fetch"), or
"pull.mode=merge-reverse-parents".

But the first one should be enough ("git pull --ff-only --merge" doesn't
work).

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-14 22:30                                                 ` Felipe Contreras
@ 2020-12-14 23:14                                                   ` Junio C Hamano
  2020-12-15  2:36                                                     ` Felipe Contreras
  0 siblings, 1 reply; 79+ messages in thread
From: Junio C Hamano @ 2020-12-14 23:14 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Elijah Newren, Jacob Keller, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

Felipe Contreras <felipe.contreras@gmail.com> writes:

>> We do not have to or implement both, but either should give us the
>> "when pull sees a non-ff history, it should stop without merging or
>> rebasing, and the user won't be given the advice on how to choose
>> between merge and rebase" behaviour, I would think.
>
> Right, so both should error out.

One of them, not both; the one we choose to implement would make it
fail, I would think.

> And what should these do?
>
>   git -c pull.rebase=no -c pull.ff=only pull --merge

There is no --merge, so let's reread with s/--merge/--no-rebase/;
the command line would be saying "I only want to fast-forward, or I
want the command to fail".  The advice code should not trigger
(i.e. we gave an explicit preference to merge and not to rebase, so
rebase_unspecified would be false), but the configured preference
that says "we take only fast-forward merges" will still be in effect.
If the history is fast-forward, the merge backend will happily
advance our history.  If not, the merge backend will happily fail
the pull.

If you want to countermand the configured preference from the
command line and allow a merge to be done when non-ff history is
given, what you'd need to override is not --merge/--no-rebase.  The
configuration pull.rebase=no already says you do not want rebase and
you want merge).  You want to override --ff-only, so I'd expect
"pull --ff" (or "pull --no-ff") to be how you override your
configured preference and merge in a non-ff history, either by fast
forwarding or creating an extra merge commit.

>   git -c advice.pullnonff=false pull --merge

Again with s/--merge/--no-rebase/; but that is showing the
preference not to rebase and to merge from the command line, so
shouldn't it just go ahead and merge without any advice?


> I'm going to answer because I think it's obvious what you would expect:
> if you pass --merge, both should succeed.
>
> Except they won't, because "git pull --ff-only --merge" fails.
>
> Correct?

See above.


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-11  7:17                                           ` Junio C Hamano
  2020-12-11 11:33                                             ` Felipe Contreras
@ 2020-12-15  2:31                                             ` Jeff King
  2020-12-15  3:49                                               ` Felipe Contreras
  2020-12-15 11:18                                               ` Junio C Hamano
  1 sibling, 2 replies; 79+ messages in thread
From: Jeff King @ 2020-12-15  2:31 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Felipe Contreras, Elijah Newren, Jacob Keller, Git Mailing List,
	Vít Ondruch, Alex Henrie, Philip Oakley,
	Theodore Y . Ts'o, John Keeping, Richard Hansen,
	Brian M. Carlson, W. Trevor King

On Thu, Dec 10, 2020 at 11:17:01PM -0800, Junio C Hamano wrote:

> You want to let the user express: "I do not want to choose either
> rebase or merge.  I want 'pull' to fail when it needs to deal with
> non-ff history.  But I do not need to be told about command line
> option and configuration every time."
> 
> I said I don't (I view that disabling half the "git pull" just a
> safe fallback behaviour until the user chooses between merge and
> rebase), but if we wanted to offer it as a valid choice to users, we
> can do so.  We just make it possible to squelch the latter two parts
> of the three-part message---you leave pull.rebase unconfigured and
> squelch the latter two parts of the message, and you got the "stop
> me, I do not merge or rebase, but don't even tell me how to further
> configure" already.

FWIW, I would be such a user who would want to squelch the error but
keep the ff-only behavior (and have been doing so for years via
pull.ff=only).

I primarily use "git pull" only with branches where I am tracking
upstream work, but don't have any of my own (e.g., if I do all of my
work on topic branches, I may still keep a "master" branch that mirrors
"origin/master", and use "git checkout master && git pull" to
fast-forward it).

So I think this is a valuable thing to have. And it does work just fine
already, without pull.mode. The reasons to care about pull.mode (IMHO)
are mostly about explaining it:

  - it isn't respected with rebase. So if you set pull.rebase=true, now
    pull.ff=only does nothing. This is arguably confusing, though I
    doubt it comes up much in practice.

  - having a single tri-state of merge/rebase/error for "what do I do
    when pulling a non-fast-forward merge" is conceptually simple and
    easy to explain.

So I like pull.mode in that sense. But it is also weighed against the
fact that we'd still have to support pull.rebase, and we'd still have to
support pull.ff, and explain how those interact with pull.mode (and I
think any new error in this area must be squelched by those existing
variables, or it would be a regression for people who already picked
their default long ago).

> But there is an established way used in this project when we allow
> squelching overly-helpful help messages, and we can apply it here as
> well.  That way:
> 
>  - unconfigured folks would get all the three parts of the messages,
>    just like the current system.
> 
>  - if you tell rebase or merge, you do not see any.
> 
>  - if you do not choose between rebase or merge, you can still
>    squelch the latter two by setting advice.pullNonFF to false.
> 
> The last one is "keep the more dangerous half of 'git pull' disabled,
> without getting told how to enable it over and over", which is what
> you want to be able to specify.

Using advice.* to squelch the advice would be fine with me, provided it
was _also_ squelched by the existing config options.

Which I think is where your thinking is ending up.

-Peff

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-14 23:14                                                   ` Junio C Hamano
@ 2020-12-15  2:36                                                     ` Felipe Contreras
  0 siblings, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-15  2:36 UTC (permalink / raw)
  To: Junio C Hamano, Felipe Contreras
  Cc: Elijah Newren, Jacob Keller, Git Mailing List, Vít Ondruch,
	Alex Henrie, Jeff King, Philip Oakley, Theodore Y . Ts'o,
	John Keeping, Richard Hansen, Brian M. Carlson, W. Trevor King

Junio C Hamano wrote:
> Felipe Contreras <felipe.contreras@gmail.com> writes:
> 
> >> We do not have to or implement both, but either should give us the
> >> "when pull sees a non-ff history, it should stop without merging or
> >> rebasing, and the user won't be given the advice on how to choose
> >> between merge and rebase" behaviour, I would think.
> >
> > Right, so both should error out.
> 
> One of them, not both; the one we choose to implement would make it
> fail, I would think.

If only one of them fail, then it's impossible to tell the user:

  If you want to try the new behavior, type this command:

    git config $something

We have to go straight for the error, with no deprecation period.

> > And what should these do?
> >
> >   git -c pull.rebase=no -c pull.ff=only pull --merge
> 
> There is no --merge, so let's reread with s/--merge/--no-rebase/;

Back in 2013 everyone found it easier to speak in terms of --merge, even
you, BTW, who was the first one to send a patch with --merge [1], after
Linus suggested it [2].

> the command line would be saying "I only want to fast-forward, or I
> want the command to fail".  The advice code should not trigger
> (i.e. we gave an explicit preference to merge and not to rebase, so
> rebase_unspecified would be false), but the configured preference
> that says "we take only fast-forward merges" will still be in effect.
> If the history is fast-forward, the merge backend will happily
> advance our history.  If not, the merge backend will happily fail
> the pull.
> 
> If you want to countermand the configured preference from the
> command line and allow a merge to be done when non-ff history is
> given, what you'd need to override is not --merge/--no-rebase.  The
> configuration pull.rebase=no already says you do not want rebase and
> you want merge).  You want to override --ff-only, so I'd expect
> "pull --ff" (or "pull --no-ff") to be how you override your
> configured preference and merge in a non-ff history, either by fast
> forwarding or creating an extra merge commit.

Precisely, so you can't tell the user:

  If you want to try the new behavior, type this command:

    git config pull.ff only

Because, after the user gets the error:

  Not a fast-forward, either merge or rebase.

She cannot do:

  git pull --merge

Which is the best idiom to specify she wants a merge.

The command will still fail, even after the user has specified she wants
the new mode, and that she wants to merge in this perticular case.

> >   git -c advice.pullnonff=false pull --merge
> 
> Again with s/--merge/--no-rebase/; but that is showing the
> preference not to rebase and to merge from the command line, so
> shouldn't it just go ahead and merge without any advice?

Yes, but *before* we make this the default, what configuration get us
there today?

> > I'm going to answer because I think it's obvious what you would expect:
> > if you pass --merge, both should succeed.
> >
> > Except they won't, because "git pull --ff-only --merge" fails.
> >
> > Correct?
> 
> See above.

That's a "correct". There's no configuration today that gives us both:

 1. fail: git -c $config pull
 2. pass: git -c $config pull --merge

Like this does:

 1. fail: git -c pull.mode=fast-forward pull
 2. pass: git -c pull.mode=fast-forward pull --merge

Cheers.

[1] https://lore.kernel.org/git/7v4ncjs5az.fsf_-_@alter.siamese.dyndns.org/
[2] https://lore.kernel.org/git/CA+55aFz2Uvq4vmyjJPao5tS-uuVvKm6mbP7Uz8sdq1VMxMGJCw@mail.gmail.com/

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-15  2:31                                             ` Jeff King
@ 2020-12-15  3:49                                               ` Felipe Contreras
  2020-12-15 11:18                                               ` Junio C Hamano
  1 sibling, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-15  3:49 UTC (permalink / raw)
  To: Jeff King, Junio C Hamano
  Cc: Felipe Contreras, Elijah Newren, Jacob Keller, Git Mailing List,
	Vít Ondruch, Alex Henrie, Philip Oakley,
	Theodore Y . Ts'o, John Keeping, Richard Hansen,
	Brian M. Carlson, W. Trevor King

Jeff King wrote:
> On Thu, Dec 10, 2020 at 11:17:01PM -0800, Junio C Hamano wrote:
> 
> > You want to let the user express: "I do not want to choose either
> > rebase or merge.  I want 'pull' to fail when it needs to deal with
> > non-ff history.  But I do not need to be told about command line
> > option and configuration every time."
> > 
> > I said I don't (I view that disabling half the "git pull" just a
> > safe fallback behaviour until the user chooses between merge and
> > rebase), but if we wanted to offer it as a valid choice to users, we
> > can do so.  We just make it possible to squelch the latter two parts
> > of the three-part message---you leave pull.rebase unconfigured and
> > squelch the latter two parts of the message, and you got the "stop
> > me, I do not merge or rebase, but don't even tell me how to further
> > configure" already.
> 
> FWIW, I would be such a user who would want to squelch the error but
> keep the ff-only behavior (and have been doing so for years via
> pull.ff=only).

If you have configured pull.ff=only, you should be getting this error:

	Not possible to fast-forward, aborting.

We would like this error instead:

  Not a fast-forward, either merge or rebase.

And after that it should be obvious what this command should do with
your current configuration:

  git pull --merge

But it would fail, even after specifying you want to do a merge, because
"git pull --ff-only --merge" fails.

> So I think this is a valuable thing to have. And it does work just fine
> already, without pull.mode. The reasons to care about pull.mode (IMHO)
> are mostly about explaining it:
> 
>   - it isn't respected with rebase. So if you set pull.rebase=true, now
>     pull.ff=only does nothing. This is arguably confusing, though I
>     doubt it comes up much in practice.
> 
>   - having a single tri-state of merge/rebase/error for "what do I do
>     when pulling a non-fast-forward merge" is conceptually simple and
>     easy to explain.

Indeed. It's *mostly* about explaining it, but there's also what I
stated above:

  git -c pull.mode=fast-forward pull
  git -c pull.mode=fast-forward pull --merge

We want the first one to fail, and the second one to succeed, which
can't be done with the current "pull.ff=only".

> So I like pull.mode in that sense. But it is also weighed against the
> fact that we'd still have to support pull.rebase, and we'd still have to
> support pull.ff, and explain how those interact with pull.mode (and I
> think any new error in this area must be squelched by those existing
> variables, or it would be a regression for people who already picked
> their default long ago).

The interactions should be easy:

  * pull.rebase=false -> pull.mode=merge
  * pull.rebase=the-rest -> pull.mode=rebase
  * pull.ff=only -> pull.mode=fast-forward

(note: I'm not entirely sure of the last one)

Then, any --merge/--rebase option overrides the mode, but not so the
--ff options.

We would still like this to fail:

  git -c pull.mode=merge pull --ff-only

Right?

In other words: pull.mode is strongly linked with pull.rebase, but not so
much wih --ff*.

> > But there is an established way used in this project when we allow
> > squelching overly-helpful help messages, and we can apply it here as
> > well.  That way:
> > 
> >  - unconfigured folks would get all the three parts of the messages,
> >    just like the current system.
> > 
> >  - if you tell rebase or merge, you do not see any.
> > 
> >  - if you do not choose between rebase or merge, you can still
> >    squelch the latter two by setting advice.pullNonFF to false.
> > 
> > The last one is "keep the more dangerous half of 'git pull' disabled,
> > without getting told how to enable it over and over", which is what
> > you want to be able to specify.
> 
> Using advice.* to squelch the advice would be fine with me, provided it
> was _also_ squelched by the existing config options.
> 
> Which I think is where your thinking is ending up.

Yes. At least that's my thinking.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-15  2:31                                             ` Jeff King
  2020-12-15  3:49                                               ` Felipe Contreras
@ 2020-12-15 11:18                                               ` Junio C Hamano
  2020-12-15 12:53                                                 ` Felipe Contreras
  1 sibling, 1 reply; 79+ messages in thread
From: Junio C Hamano @ 2020-12-15 11:18 UTC (permalink / raw)
  To: Jeff King
  Cc: Felipe Contreras, Elijah Newren, Jacob Keller, Git Mailing List,
	Vít Ondruch, Alex Henrie, Philip Oakley,
	Theodore Y . Ts'o, John Keeping, Richard Hansen,
	Brian M. Carlson, W. Trevor King

Jeff King <peff@peff.net> writes:

> So I like pull.mode in that sense. But it is also weighed against the
> fact that we'd still have to support pull.rebase, and we'd still have to
> support pull.ff, and explain how those interact with pull.mode (and I
> think any new error in this area must be squelched by those existing
> variables, or it would be a regression for people who already picked
> their default long ago).

I agree that if we were starting from scratch, things would have
been much simpler; choose among three ways to reconcile histories
(merge, rebase, or ff-only), without adding --[no-]rebase, and allow
--[no-]ff only when merging (i.e. things like --ff-only --ff,
--no-ff --rebase, would be nonsense combinations).  The additional
complexity of introducing pull.mode is the primary thing I am
hesitant to support it, as we have to design and explain how
existing knobs interact with newer one.

> Using advice.* to squelch the advice would be fine with me, provided it
> was _also_ squelched by the existing config options.

Meaning "once you choose between rebase or merge, facing a non-ff
history would not trigger the advice message"?  I think that is
already the case with the released versions of Git, and I think that
is a good thing to keep.  The advice is only for unconfigured folks
who did not tell --[no-]rebase from the command line.  One bad thing
about it in the released versions is that it would trigger even when
the history fast-forwards.  The latest round of patches in 'seen'
squelches the advice when pulling a fast-forward history even for
unconfigured folks as we'd just fast-forward without erroring out.

> Which I think is where your thinking is ending up.

Pretty much.  


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 02/14] pull: improve default warning
  2020-12-15 11:18                                               ` Junio C Hamano
@ 2020-12-15 12:53                                                 ` Felipe Contreras
  0 siblings, 0 replies; 79+ messages in thread
From: Felipe Contreras @ 2020-12-15 12:53 UTC (permalink / raw)
  To: Junio C Hamano, Jeff King
  Cc: Felipe Contreras, Elijah Newren, Jacob Keller, Git Mailing List,
	Vít Ondruch, Alex Henrie, Philip Oakley,
	Theodore Y . Ts'o, John Keeping, Richard Hansen,
	Brian M. Carlson, W. Trevor King

Junio C Hamano wrote:
> Jeff King <peff@peff.net> writes:
> 
> > So I like pull.mode in that sense. But it is also weighed against the
> > fact that we'd still have to support pull.rebase, and we'd still have to
> > support pull.ff, and explain how those interact with pull.mode (and I
> > think any new error in this area must be squelched by those existing
> > variables, or it would be a regression for people who already picked
> > their default long ago).
> 
> I agree that if we were starting from scratch, things would have
> been much simpler; choose among three ways to reconcile histories
> (merge, rebase, or ff-only), without adding --[no-]rebase, and allow
> --[no-]ff only when merging (i.e. things like --ff-only --ff,
> --no-ff --rebase, would be nonsense combinations).  The additional
> complexity of introducing pull.mode is the primary thing I am
> hesitant to support it, as we have to design and explain how
> existing knobs interact with newer one.

I have already tried all the options.

If we go through a deprecation period (which I insist we must), the
options are these:

 1. Change the semantics of --ff-only (breaks backwards-compatibility)
 2. Add a "pull.rebase=ff-only" option (very weird)
 3. Add a "pull.mode" configuration (tons of advantages)

Yes, we have to map the modes to the existing knobs, but it's not complex:

 * pull.rebase = false  <=> pull.mode = merge
 * pull.rebase = true   <=> pull.mode = rebase
 * pull.rebase = *       -> pull.mode = rebase

That's it. We don't even have to map --ff-only (which has different
semantics anyway).

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 79+ messages in thread

end of thread, other threads:[~2020-12-15 12:55 UTC | newest]

Thread overview: 79+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-04  6:16 [PATCH v2 00/14] pull: default warning improvements Felipe Contreras
2020-12-04  6:16 ` [PATCH v2 01/14] doc: pull: explain what is a fast-forward Felipe Contreras
2020-12-04 22:55   ` Elijah Newren
2020-12-05  1:21   ` Jacob Keller
2020-12-04  6:16 ` [PATCH v2 02/14] pull: improve default warning Felipe Contreras
2020-12-04 22:59   ` Elijah Newren
2020-12-05  0:12     ` Felipe Contreras
2020-12-05  0:56       ` Elijah Newren
2020-12-05  1:56         ` Felipe Contreras
2020-12-05  9:23           ` Chris Torek
2020-12-05 11:47             ` Felipe Contreras
2020-12-05 16:28           ` Elijah Newren
2020-12-05 21:27             ` Felipe Contreras
2020-12-06  1:01               ` Elijah Newren
2020-12-06 14:31                 ` Felipe Contreras
2020-12-07  7:26                 ` Junio C Hamano
2020-12-07  9:16                   ` Felipe Contreras
2020-12-07 18:16                     ` Junio C Hamano
2020-12-07 19:09                       ` Felipe Contreras
2020-12-07 19:53                         ` Junio C Hamano
2020-12-07 22:14                           ` Felipe Contreras
2020-12-07 23:30                           ` Jacob Keller
2020-12-08  2:23                             ` Junio C Hamano
2020-12-08  3:15                               ` Felipe Contreras
2020-12-08 20:16                                 ` Junio C Hamano
2020-12-09  9:52                                   ` Felipe Contreras
2020-12-09 19:05                                     ` Elijah Newren
2020-12-10  2:39                                       ` Felipe Contreras
2020-12-10  6:45                                       ` Junio C Hamano
2020-12-10  9:08                                         ` Felipe Contreras
2020-12-10 10:01                                           ` Felipe Contreras
2020-12-11  7:17                                           ` Junio C Hamano
2020-12-11 11:33                                             ` Felipe Contreras
2020-12-14 21:04                                               ` Junio C Hamano
2020-12-14 22:30                                                 ` Felipe Contreras
2020-12-14 23:14                                                   ` Junio C Hamano
2020-12-15  2:36                                                     ` Felipe Contreras
2020-12-15  2:31                                             ` Jeff King
2020-12-15  3:49                                               ` Felipe Contreras
2020-12-15 11:18                                               ` Junio C Hamano
2020-12-15 12:53                                                 ` Felipe Contreras
2020-12-07  9:23         ` Felipe Contreras
2020-12-04  6:16 ` [PATCH v2 03/14] pull: refactor fast-forward check Felipe Contreras
2020-12-04  6:16 ` [PATCH v2 04/14] pull: cleanup autostash check Felipe Contreras
2020-12-04 23:07   ` Elijah Newren
2020-12-05  0:47     ` Felipe Contreras
2020-12-05  0:57       ` Elijah Newren
2020-12-04  6:16 ` [PATCH v2 05/14] pull: trivial cleanup Felipe Contreras
2020-12-04 23:09   ` Elijah Newren
2020-12-05  0:48     ` Felipe Contreras
2020-12-04  6:16 ` [PATCH v2 06/14] pull: move default warning Felipe Contreras
2020-12-04 23:18   ` Elijah Newren
2020-12-04 23:36     ` Felipe Contreras
2020-12-04  6:16 ` [PATCH v2 07/14] pull: display default warning only when non-ff Felipe Contreras
2020-12-04 23:24   ` Elijah Newren
2020-12-05  1:03     ` Felipe Contreras
2020-12-04  6:16 ` [PATCH v2 08/14] pull: trivial whitespace style fix Felipe Contreras
2020-12-04  6:16 ` [PATCH v2 09/14] pull: introduce --merge option Felipe Contreras
2020-12-04 23:27   ` Elijah Newren
2020-12-05  1:06     ` Felipe Contreras
2020-12-04  6:16 ` [PATCH v2 10/14] pull: add proper error with --ff-only Felipe Contreras
2020-12-04 23:34   ` Elijah Newren
2020-12-05  1:18     ` Felipe Contreras
2020-12-04  6:16 ` [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only Felipe Contreras
2020-12-04 23:39   ` Elijah Newren
2020-12-05  4:01     ` Felipe Contreras
2020-12-05  4:06       ` [PATCH] experiment: pull: change --ff-only and default mode Felipe Contreras
2020-12-05 17:29         ` Elijah Newren
2020-12-05 18:16           ` Felipe Contreras
2020-12-07  7:34           ` Junio C Hamano
2020-12-05 11:37       ` [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only Felipe Contreras
2020-12-04  6:16 ` [PATCH v2 12/14] pull: show warning with --ff Felipe Contreras
2020-12-04 23:41   ` Elijah Newren
2020-12-05  1:25     ` Felipe Contreras
2020-12-04  6:16 ` [PATCH v2 13/14] test: merge-pull-config: trivial cleanup Felipe Contreras
2020-12-04 23:41   ` Elijah Newren
2020-12-04  6:16 ` [PATCH v2 14/14] test: pull-options: revert unnecessary changes Felipe Contreras
2020-12-04 23:49   ` Elijah Newren
2020-12-05  1:28     ` Felipe Contreras

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.