{"thread":{"id":"54758","subject":"[PATCH v2 00/14] pull: default warning improvements","startedAt":"2020-12-04T06:17:08Z","lastAt":"2020-12-15T12:55:35Z","messageCount":79,"participants":["Felipe Contreras","Elijah Newren","Jacob Keller","Chris Torek","Junio C Hamano","Jeff King"],"isPatch":true,"patchVersion":2,"patchTotal":14},"messages":[{"id":"411301","messageId":"20201204061623.1170745-1-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":null,"subject":"[PATCH v2 00/14] pull: default warning improvements","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:09Z","receivedAt":"2020-12-04T06:17:08Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"The old thread \"Pull is Mostly Evil\" [1] came to haunt us back again.\n\nThe main solution--reject non-fast-forward merges by default--seems to have lost traction (again).\n\nThere are multiple approaches floating around, but no clear path forward.\n\nThis patch series attempts to fix as much as possible of the current situation without committing to\nany particular solution.\n\nIt does:\n\n1. Improve the current documentation\n2. Improve the current default warning\n3. Minimize the instances where we display the default warning\n4. Add a --merge option\n5. Improve the error message with --ff-only\n6. Fix the behavior of the warning with --ff\n\nAnd tentatively (and this should be the only controversial change):\n\n7. Change the semantics of -ff-only\n\nIt does not:\n\n* Introduce the suggested pull.mode\n* Change the current default (still --ff)\n\nIt is not a complete solution, but should improve the current situation.\n\n[1] https://lore.kernel.org/git/5363BB9F.40102@xiplink.com/\n\n\nFelipe Contreras (14):\n  doc: pull: explain what is a fast-forward\n  pull: improve default warning\n  pull: refactor fast-forward check\n  pull: cleanup autostash check\n  pull: trivial cleanup\n  pull: move default warning\n  pull: display default warning only when non-ff\n  pull: trivial whitespace style fix\n  pull: introduce --merge option\n  pull: add proper error with --ff-only\n  tentative: pull: change the semantics of --ff-only\n  pull: show warning with --ff\n  test: merge-pull-config: trivial cleanup\n  test: pull-options: revert unnecessary changes\n\n Documentation/git-pull.txt   | 24 ++++++++-\n builtin/pull.c               | 98 ++++++++++++++++++++++--------------\n t/t5520-pull.sh              | 62 +++++++++++++++++++++++\n t/t5521-pull-options.sh      | 22 ++++----\n t/t7601-merge-pull-config.sh | 35 +++++++------\n 5 files changed, 174 insertions(+), 67 deletions(-)\n\n-- \n2.29.2\n\n"},{"id":"411302","messageId":"20201204061623.1170745-4-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 03/14] pull: refactor fast-forward check","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:12Z","receivedAt":"2020-12-04T06:17:12Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"This way we will be able to do the check unconditionally (merge or\nrebase).\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n builtin/pull.c | 26 +++++++++++++++-----------\n 1 file changed, 15 insertions(+), 11 deletions(-)\n\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex 22a9ffcade..6279e9ee37 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -907,6 +907,20 @@ static int run_rebase(const struct object_id *curr_head,\n \treturn ret;\n }\n \n+static int get_can_ff(struct object_id *orig_head, struct object_id *orig_merge_head)\n+{\n+\tint ret;\n+\tstruct commit_list *list = NULL;\n+\tstruct commit *merge_head, *head;\n+\n+\thead = lookup_commit_reference(the_repository, orig_head);\n+\tcommit_list_insert(head, &list);\n+\tmerge_head = lookup_commit_reference(the_repository, orig_merge_head);\n+\tret = repo_is_descendant_of(the_repository, merge_head, list);\n+\tfree_commit_list(list);\n+\treturn ret;\n+}\n+\n int cmd_pull(int argc, const char **argv, const char *prefix)\n {\n \tconst char *repo, **refspecs;\n@@ -1017,22 +1031,12 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\t    submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))\n \t\t\tdie(_(\"cannot rebase with locally recorded submodule modifications\"));\n \t\tif (!autostash) {\n-\t\t\tstruct commit_list *list = NULL;\n-\t\t\tstruct commit *merge_head, *head;\n-\n-\t\t\thead = lookup_commit_reference(the_repository,\n-\t\t\t\t\t\t       &orig_head);\n-\t\t\tcommit_list_insert(head, &list);\n-\t\t\tmerge_head = lookup_commit_reference(the_repository,\n-\t\t\t\t\t\t\t     &merge_heads.oid[0]);\n-\t\t\tif (repo_is_descendant_of(the_repository,\n-\t\t\t\t\t\t  merge_head, list)) {\n+\t\t\tif (get_can_ff(&orig_head, &merge_heads.oid[0])) {\n \t\t\t\t/* we can fast-forward this without invoking rebase */\n \t\t\t\topt_ff = \"--ff-only\";\n \t\t\t\tran_ff = 1;\n \t\t\t\tret = run_merge();\n \t\t\t}\n-\t\t\tfree_commit_list(list);\n \t\t}\n \t\tif (!ran_ff)\n \t\t\tret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n-- \n2.29.2\n\n"},{"id":"411303","messageId":"20201204061623.1170745-5-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 04/14] pull: cleanup autostash check","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:13Z","receivedAt":"2020-12-04T06:17:14Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"This essentially reverts commit f15e7cf5cc.\n\nOnce commit d9f15d37f1 introduced the autostash option for the merge\nmode, it's not necessary to skip the fast-forward run_merge() when\nautostash is set.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n builtin/pull.c | 15 ++++++---------\n 1 file changed, 6 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex 6279e9ee37..c38548dab8 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -927,7 +927,6 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \tstruct oid_array merge_heads = OID_ARRAY_INIT;\n \tstruct object_id orig_head, curr_head;\n \tstruct object_id rebase_fork_point;\n-\tint autostash;\n \n \tif (!getenv(\"GIT_REFLOG_ACTION\"))\n \t\tset_reflog_message(argc, argv);\n@@ -960,8 +959,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \tif (get_oid(\"HEAD\", &orig_head))\n \t\toidclr(&orig_head);\n \n-\tautostash = config_autostash;\n \tif (opt_rebase) {\n+\t\tint autostash = config_autostash;\n \t\tif (opt_autostash != -1)\n \t\t\tautostash = opt_autostash;\n \n@@ -1030,13 +1029,11 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\t     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&\n \t\t    submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))\n \t\t\tdie(_(\"cannot rebase with locally recorded submodule modifications\"));\n-\t\tif (!autostash) {\n-\t\t\tif (get_can_ff(&orig_head, &merge_heads.oid[0])) {\n-\t\t\t\t/* we can fast-forward this without invoking rebase */\n-\t\t\t\topt_ff = \"--ff-only\";\n-\t\t\t\tran_ff = 1;\n-\t\t\t\tret = run_merge();\n-\t\t\t}\n+\t\tif (get_can_ff(&orig_head, &merge_heads.oid[0])) {\n+\t\t\t/* we can fast-forward this without invoking rebase */\n+\t\t\topt_ff = \"--ff-only\";\n+\t\t\tran_ff = 1;\n+\t\t\tret = run_merge();\n \t\t}\n \t\tif (!ran_ff)\n \t\t\tret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n-- \n2.29.2\n\n"},{"id":"411304","messageId":"20201204061623.1170745-2-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 01/14] doc: pull: explain what is a fast-forward","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:10Z","receivedAt":"2020-12-04T06:17:16Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"We want users to know what is a fast-forward in order to understand the\ndefault warning.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n Documentation/git-pull.txt | 14 ++++++++++++++\n 1 file changed, 14 insertions(+)\n\ndiff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\nindex 5c3fb67c01..dc812139f4 100644\n--- a/Documentation/git-pull.txt\n+++ b/Documentation/git-pull.txt\n@@ -38,6 +38,20 @@ as set by linkgit:git-branch[1] `--track`.\n Assume the following history exists and the current branch is\n \"`master`\":\n \n+------------\n+\t  A---B---C master on origin\n+\t /\n+    D---E master\n+------------\n+\n+Then `git pull` will merge in a fast-foward way up to the new master.\n+\n+------------\n+    D---E---A---B---C master, origin/master\n+------------\n+\n+However, a non-fast-foward case looks very different.\n+\n ------------\n \t  A---B---C master on origin\n \t /\n-- \n2.29.2\n\n"},{"id":"411305","messageId":"20201204061623.1170745-3-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:11Z","receivedAt":"2020-12-04T06:17:17Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"We want to:\n\n1. Be clear about what \"specifying\" means; merge or rebase.\n2. Mention a direct shortcut for people that just want to get on with\n   their lives: git pull --no-rebase.\n3. Have a quick reference for users to understand what this\n   \"fast-forward\" business means.\n\nThis patch does all three.\n\nThanks to the previous patch now \"git pull --help\" explains what a\nfast-forward is, and a further patch changes --no-rebase to --merge so\nit's actually user friendly.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n builtin/pull.c | 23 ++++++++++++-----------\n 1 file changed, 12 insertions(+), 11 deletions(-)\n\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex 1034372f8b..22a9ffcade 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -346,17 +346,18 @@ static enum rebase_type config_get_rebase(void)\n \n \tif (opt_verbosity >= 0 && !opt_ff) {\n \t\tadvise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n-\t\t\t \"discouraged. You can squelch this message by running one of the following\\n\"\n-\t\t\t \"commands sometime before your next pull:\\n\"\n-\t\t\t \"\\n\"\n-\t\t\t \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n-\t\t\t \"  git config pull.rebase true   # rebase\\n\"\n-\t\t\t \"  git config pull.ff only       # fast-forward only\\n\"\n-\t\t\t \"\\n\"\n-\t\t\t \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n-\t\t\t \"preference for all repositories. You can also pass --rebase, --no-rebase,\\n\"\n-\t\t\t \"or --ff-only on the command line to override the configured default per\\n\"\n-\t\t\t \"invocation.\\n\"));\n+\t\t\t\"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n+\t\t\t\"You can squelch this message by running one of the following commands:\\n\"\n+\t\t\t\"\\n\"\n+\t\t\t\"  git config pull.rebase false  # merge (the default strategy)\\n\"\n+\t\t\t\"  git config pull.rebase true   # rebase\\n\"\n+\t\t\t\"  git config pull.ff only       # fast-forward only\\n\"\n+\t\t\t\"\\n\"\n+\t\t\t\"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n+\t\t\t\"preference for all repositories.\\n\"\n+\t\t\t\"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n+\t\t\t\"Read \\\"git pull --help\\\" for more information.\"\n+\t\t\t));\n \t}\n \n \treturn REBASE_FALSE;\n-- \n2.29.2\n\n"},{"id":"411306","messageId":"20201204061623.1170745-7-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 06/14] pull: move default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:15Z","receivedAt":"2020-12-04T06:17:48Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Up to the point where can check if we can fast-forward or not.\n\nNo functional changes.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n builtin/pull.c | 39 +++++++++++++++++++++++----------------\n 1 file changed, 23 insertions(+), 16 deletions(-)\n\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex 8daba7539c..f82e214fc8 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -27,6 +27,8 @@\n #include \"commit-reach.h\"\n #include \"sequencer.h\"\n \n+static int default_mode;\n+\n /**\n  * Parses the value of --rebase. If value is a false value, returns\n  * REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is\n@@ -344,21 +346,7 @@ static enum rebase_type config_get_rebase(void)\n \tif (!git_config_get_value(\"pull.rebase\", &value))\n \t\treturn parse_config_rebase(\"pull.rebase\", value, 1);\n \n-\tif (opt_verbosity >= 0 && !opt_ff) {\n-\t\tadvise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n-\t\t\t\"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n-\t\t\t\"You can squelch this message by running one of the following commands:\\n\"\n-\t\t\t\"\\n\"\n-\t\t\t\"  git config pull.rebase false  # merge (the default strategy)\\n\"\n-\t\t\t\"  git config pull.rebase true   # rebase\\n\"\n-\t\t\t\"  git config pull.ff only       # fast-forward only\\n\"\n-\t\t\t\"\\n\"\n-\t\t\t\"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n-\t\t\t\"preference for all repositories.\\n\"\n-\t\t\t\"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n-\t\t\t\"Read \\\"git pull --help\\\" for more information.\"\n-\t\t\t));\n-\t}\n+\tdefault_mode = 1;\n \n \treturn REBASE_FALSE;\n }\n@@ -927,6 +915,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \tstruct oid_array merge_heads = OID_ARRAY_INIT;\n \tstruct object_id orig_head, curr_head;\n \tstruct object_id rebase_fork_point;\n+\tint can_ff;\n \n \tif (!getenv(\"GIT_REFLOG_ACTION\"))\n \t\tset_reflog_message(argc, argv);\n@@ -1022,6 +1011,24 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \tif (opt_rebase && merge_heads.nr > 1)\n \t\tdie(_(\"Cannot rebase onto multiple branches.\"));\n \n+\tcan_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);\n+\n+\tif (default_mode && opt_verbosity >= 0 && !opt_ff) {\n+\t\tadvise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n+\t\t\t\"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n+\t\t\t\"You can squelch this message by running one of the following commands:\\n\"\n+\t\t\t\"\\n\"\n+\t\t\t\"  git config pull.rebase false  # merge (the default strategy)\\n\"\n+\t\t\t\"  git config pull.rebase true   # rebase\\n\"\n+\t\t\t\"  git config pull.ff only       # fast-forward only\\n\"\n+\t\t\t\"\\n\"\n+\t\t\t\"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n+\t\t\t\"preference for all repositories.\\n\"\n+\t\t\t\"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n+\t\t\t\"Read \\\"git pull --help\\\" for more information.\"\n+\t\t\t));\n+\t}\n+\n \tif (opt_rebase) {\n \t\tint ret = 0;\n \t\tif ((recurse_submodules == RECURSE_SUBMODULES_ON ||\n@@ -1029,7 +1036,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\t    submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))\n \t\t\tdie(_(\"cannot rebase with locally recorded submodule modifications\"));\n \n-\t\tif (get_can_ff(&orig_head, &merge_heads.oid[0])) {\n+\t\tif (can_ff) {\n \t\t\t/* we can fast-forward this without invoking rebase */\n \t\t\topt_ff = \"--ff-only\";\n \t\t\tret = run_merge();\n-- \n2.29.2\n\n"},{"id":"411307","messageId":"20201204061623.1170745-6-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 05/14] pull: trivial cleanup","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:14Z","receivedAt":"2020-12-04T06:17:49Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"There's no need to store ran_ff. Now it's obvious from the conditionals.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n builtin/pull.c | 7 +++----\n 1 file changed, 3 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex c38548dab8..8daba7539c 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -1024,19 +1024,18 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \n \tif (opt_rebase) {\n \t\tint ret = 0;\n-\t\tint ran_ff = 0;\n \t\tif ((recurse_submodules == RECURSE_SUBMODULES_ON ||\n \t\t     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&\n \t\t    submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))\n \t\t\tdie(_(\"cannot rebase with locally recorded submodule modifications\"));\n+\n \t\tif (get_can_ff(&orig_head, &merge_heads.oid[0])) {\n \t\t\t/* we can fast-forward this without invoking rebase */\n \t\t\topt_ff = \"--ff-only\";\n-\t\t\tran_ff = 1;\n \t\t\tret = run_merge();\n-\t\t}\n-\t\tif (!ran_ff)\n+\t\t} else {\n \t\t\tret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n+\t\t}\n \n \t\tif (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||\n \t\t\t     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))\n-- \n2.29.2\n\n"},{"id":"411308","messageId":"20201204061623.1170745-9-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 08/14] pull: trivial whitespace style fix","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:17Z","receivedAt":"2020-12-04T06:17:53Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Two spaces unaligned to anything is not part of the coding-style. A\nsingle tab is.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n builtin/pull.c | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex f0b1c6bfea..b200f7544c 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -128,9 +128,9 @@ static struct option pull_options[] = {\n \t/* Options passed to git-merge or git-rebase */\n \tOPT_GROUP(N_(\"Options related to merging\")),\n \tOPT_CALLBACK_F('r', \"rebase\", &opt_rebase,\n-\t  \"(false|true|merges|preserve|interactive)\",\n-\t  N_(\"incorporate changes by rebasing rather than merging\"),\n-\t  PARSE_OPT_OPTARG, parse_opt_rebase),\n+\t\t\"(false|true|merges|preserve|interactive)\",\n+\t\tN_(\"incorporate changes by rebasing rather than merging\"),\n+\t\tPARSE_OPT_OPTARG, parse_opt_rebase),\n \tOPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,\n \t\tN_(\"do not show a diffstat at the end of the merge\"),\n \t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG),\n-- \n2.29.2\n\n"},{"id":"411309","messageId":"20201204061623.1170745-11-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 10/14] pull: add proper error with --ff-only","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:19Z","receivedAt":"2020-12-04T06:17:54Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"The current error is not user-friendly:\n\n  fatal: not possible to fast-forward, aborting.\n\nWe want something that actually explains what is going on:\n\n  The pull was not fast-forward, please either merge or rebase.\n  If unsure, run \"git pull --merge\".\n\nThe user can get rid of the warning by doing either --merge or\n--rebase.\n\nExcept: doing \"git pull --merge\" is not actually enough; we would return\nto the previous behavior: \"fatal: not possible to fast-forward, aborting.\"\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n builtin/pull.c  | 34 ++++++++++++++++-----------\n t/t5520-pull.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 82 insertions(+), 14 deletions(-)\n\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex 6ea95c9fc9..f54ff36b57 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -1015,20 +1015,26 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \n \tcan_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);\n \n-\tif (default_mode && !can_ff && opt_verbosity >= 0 && !opt_ff) {\n-\t\tadvise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n-\t\t\t\"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n-\t\t\t\"You can squelch this message by running one of the following commands:\\n\"\n-\t\t\t\"\\n\"\n-\t\t\t\"  git config pull.rebase false  # merge (the default strategy)\\n\"\n-\t\t\t\"  git config pull.rebase true   # rebase\\n\"\n-\t\t\t\"  git config pull.ff only       # fast-forward only\\n\"\n-\t\t\t\"\\n\"\n-\t\t\t\"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n-\t\t\t\"preference for all repositories.\\n\"\n-\t\t\t\"If unsure, run \\\"git pull --merge\\\".\\n\"\n-\t\t\t\"Read \\\"git pull --help\\\" for more information.\"\n-\t\t\t));\n+\tif (!can_ff && default_mode) {\n+\t\tif (opt_ff && !strcmp(opt_ff, \"--ff-only\")) {\n+\t\t\tdie(_(\"The pull was not fast-forward, please either merge or rebase.\\n\"\n+\t\t\t\t\"If unsure, run \\\"git pull --merge\\\".\"));\n+\t\t}\n+\t\tif (opt_verbosity >= 0 && !opt_ff) {\n+\t\t\tadvise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n+\t\t\t\t\"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n+\t\t\t\t\"You can squelch this message by running one of the following commands:\\n\"\n+\t\t\t\t\"\\n\"\n+\t\t\t\t\"  git config pull.rebase false  # merge (the default strategy)\\n\"\n+\t\t\t\t\"  git config pull.rebase true   # rebase\\n\"\n+\t\t\t\t\"  git config pull.ff only       # fast-forward only\\n\"\n+\t\t\t\t\"\\n\"\n+\t\t\t\t\"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n+\t\t\t\t\"preference for all repositories.\\n\"\n+\t\t\t\t\"If unsure, run \\\"git pull --merge\\\".\\n\"\n+\t\t\t\t\"Read \\\"git pull --help\\\" for more information.\"\n+\t\t\t\t));\n+\t\t}\n \t}\n \n \tif (opt_rebase) {\ndiff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\nindex 9fae07cdfa..fdd1f79b06 100755\n--- a/t/t5520-pull.sh\n+++ b/t/t5520-pull.sh\n@@ -819,4 +819,66 @@ test_expect_success 'git pull --rebase against local branch' '\n \ttest_cmp expect file2\n '\n \n+test_expect_success 'git pull fast-forward (ff-only)' '\n+\ttest_when_finished \"git checkout master && git branch -D other test\" &&\n+\ttest_config pull.ff only &&\n+\tgit checkout -b other master &&\n+\t>new &&\n+\tgit add new &&\n+\tgit commit -m new &&\n+\tgit checkout -b test -t other &&\n+\tgit reset --hard master &&\n+\tgit pull\n+'\n+\n+test_expect_success 'git pull non-fast-forward (ff-only)' '\n+\ttest_when_finished \"git checkout master && git branch -D other test\" &&\n+\ttest_config pull.ff only &&\n+\tgit checkout -b other master^ &&\n+\t>new &&\n+\tgit add new &&\n+\tgit commit -m new &&\n+\tgit checkout -b test -t other &&\n+\tgit reset --hard master &&\n+\ttest_must_fail git pull\n+'\n+\n+test_expect_failure 'git pull non-fast-forward with merge (ff-only)' '\n+\ttest_when_finished \"git checkout master && git branch -D other test\" &&\n+\ttest_config pull.ff only &&\n+\tgit checkout -b other master^ &&\n+\t>new &&\n+\tgit add new &&\n+\tgit commit -m new &&\n+\tgit checkout -b test -t other &&\n+\tgit reset --hard master &&\n+\tgit pull --no-rebase\n+'\n+\n+test_expect_success 'git pull non-fast-forward with rebase (ff-only)' '\n+\ttest_when_finished \"git checkout master && git branch -D other test\" &&\n+\ttest_config pull.ff only &&\n+\tgit checkout -b other master^ &&\n+\t>new &&\n+\tgit add new &&\n+\tgit commit -m new &&\n+\tgit checkout -b test -t other &&\n+\tgit reset --hard master &&\n+\tgit pull --rebase\n+'\n+\n+test_expect_success 'git pull non-fast-forward error message' '\n+\ttest_when_finished \"git checkout master && git branch -D other test\" &&\n+\ttest_config pull.ff only &&\n+\tgit checkout -b other master^ &&\n+\t>new &&\n+\tgit add new &&\n+\tgit commit -m new &&\n+\tgit checkout -b test -t other &&\n+\tgit reset --hard master &&\n+\ttest_must_fail git pull 2> error &&\n+\tcat error &&\n+\tgrep -q \"The pull was not fast-forward\" error\n+'\n+\n test_done\n-- \n2.29.2\n\n"},{"id":"411310","messageId":"20201204061623.1170745-13-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 12/14] pull: show warning with --ff","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:21Z","receivedAt":"2020-12-04T06:17:56Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"It's unclear why --ff should remove the warning, since:\n\n  git pull --ff\n\nIs implicitly the same as:\n\n  git pull\n\nUnless of course pull.ff is specified otherwise.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n builtin/pull.c               | 2 +-\n t/t7601-merge-pull-config.sh | 4 ++--\n 2 files changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex ebf2ac687b..e389ffcdc3 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -1020,7 +1020,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\t\tdie(_(\"The pull was not fast-forward, please either merge or rebase.\\n\"\n \t\t\t\t\"If unsure, run \\\"git pull --merge\\\".\"));\n \t\t}\n-\t\tif (opt_verbosity >= 0 && !opt_ff) {\n+\t\tif (opt_verbosity >= 0 && (!opt_ff || !strcmp(opt_ff, \"--ff\"))) {\n \t\t\tadvise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n \t\t\t\t\"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n \t\t\t\t\"You can squelch this message by running one of the following commands:\\n\"\ndiff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh\nindex 1de64e6cc5..d709799f8b 100755\n--- a/t/t7601-merge-pull-config.sh\n+++ b/t/t7601-merge-pull-config.sh\n@@ -46,7 +46,7 @@ test_expect_success 'pull.rebase not set and pull.ff=true' '\n \tgit reset --hard c2 &&\n \ttest_config pull.ff true &&\n \tgit pull . c1 2>err &&\n-\ttest_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n+\ttest_i18ngrep \"Pulling without specifying how to reconcile\" err\n '\n \n test_expect_success 'pull.rebase not set and pull.ff=false' '\n@@ -78,7 +78,7 @@ test_expect_success 'pull.rebase not set and --merge given' '\n test_expect_success 'pull.rebase not set and --ff given' '\n \tgit reset --hard c2 &&\n \tgit pull --ff . c1 2>err &&\n-\ttest_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n+\ttest_i18ngrep \"Pulling without specifying how to reconcile\" err\n '\n \n test_expect_success 'pull.rebase not set and --no-ff given' '\n-- \n2.29.2\n\n"},{"id":"411311","messageId":"20201204061623.1170745-15-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 14/14] test: pull-options: revert unnecessary changes","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:23Z","receivedAt":"2020-12-04T06:17:57Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Commit d18c950a69 changed these tests, but it's unclear why. Probably\nbecause earlier versions of the patch series died instead of printing a\nwarning.\n\nCc: Alex Henrie <alexhenrie24@gmail.com>\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n t/t5521-pull-options.sh | 22 +++++++++++-----------\n 1 file changed, 11 insertions(+), 11 deletions(-)\n\ndiff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh\nindex db1a381cd9..1a4fe2583a 100755\n--- a/t/t5521-pull-options.sh\n+++ b/t/t5521-pull-options.sh\n@@ -11,10 +11,10 @@ test_expect_success 'setup' '\n \t git commit -m one)\n '\n \n-test_expect_success 'git pull -q --no-rebase' '\n+test_expect_success 'git pull -q' '\n \tmkdir clonedq &&\n \t(cd clonedq && git init &&\n-\tgit pull -q --no-rebase \"../parent\" >out 2>err &&\n+\tgit pull -q \"../parent\" >out 2>err &&\n \ttest_must_be_empty err &&\n \ttest_must_be_empty out)\n '\n@@ -30,10 +30,10 @@ test_expect_success 'git pull -q --rebase' '\n \ttest_must_be_empty out)\n '\n \n-test_expect_success 'git pull --no-rebase' '\n+test_expect_success 'git pull' '\n \tmkdir cloned &&\n \t(cd cloned && git init &&\n-\tgit pull --no-rebase \"../parent\" >out 2>err &&\n+\tgit pull \"../parent\" >out 2>err &&\n \ttest -s err &&\n \ttest_must_be_empty out)\n '\n@@ -46,10 +46,10 @@ test_expect_success 'git pull --rebase' '\n \ttest_must_be_empty out)\n '\n \n-test_expect_success 'git pull -v --no-rebase' '\n+test_expect_success 'git pull -v' '\n \tmkdir clonedv &&\n \t(cd clonedv && git init &&\n-\tgit pull -v --no-rebase \"../parent\" >out 2>err &&\n+\tgit pull -v \"../parent\" >out 2>err &&\n \ttest -s err &&\n \ttest_must_be_empty out)\n '\n@@ -62,25 +62,25 @@ test_expect_success 'git pull -v --rebase' '\n \ttest_must_be_empty out)\n '\n \n-test_expect_success 'git pull -v -q --no-rebase' '\n+test_expect_success 'git pull -v -q' '\n \tmkdir clonedvq &&\n \t(cd clonedvq && git init &&\n-\tgit pull -v -q --no-rebase \"../parent\" >out 2>err &&\n+\tgit pull -v -q \"../parent\" >out 2>err &&\n \ttest_must_be_empty out &&\n \ttest_must_be_empty err)\n '\n \n-test_expect_success 'git pull -q -v --no-rebase' '\n+test_expect_success 'git pull -q -v' '\n \tmkdir clonedqv &&\n \t(cd clonedqv && git init &&\n-\tgit pull -q -v --no-rebase \"../parent\" >out 2>err &&\n+\tgit pull -q -v \"../parent\" >out 2>err &&\n \ttest_must_be_empty out &&\n \ttest -s err)\n '\n test_expect_success 'git pull --cleanup errors early on invalid argument' '\n \tmkdir clonedcleanup &&\n \t(cd clonedcleanup && git init &&\n-\ttest_must_fail git pull --no-rebase --cleanup invalid \"../parent\" >out 2>err &&\n+\ttest_must_fail git pull --cleanup invalid \"../parent\" >out 2>err &&\n \ttest_must_be_empty out &&\n \ttest -s err)\n '\n-- \n2.29.2\n\n"},{"id":"411312","messageId":"20201204061623.1170745-14-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 13/14] test: merge-pull-config: trivial cleanup","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:22Z","receivedAt":"2020-12-04T06:17:58Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Commit e01ae2a4a7 introduced an extra space.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n t/t7601-merge-pull-config.sh | 1 -\n 1 file changed, 1 deletion(-)\n\ndiff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh\nindex d709799f8b..8a6aae564a 100755\n--- a/t/t7601-merge-pull-config.sh\n+++ b/t/t7601-merge-pull-config.sh\n@@ -33,7 +33,6 @@ test_expect_success 'pull.rebase not set' '\n \ttest_decode_color <err >decoded &&\n \ttest_i18ngrep \"<YELLOW>hint: \" decoded &&\n \ttest_i18ngrep \"Pulling without specifying how to reconcile\" decoded\n-\n '\n \n test_expect_success 'pull.rebase not set (fast-forward)' '\n-- \n2.29.2\n\n"},{"id":"411313","messageId":"20201204061623.1170745-12-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 11/14] tentative: pull: change the semantics of --ff-only","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:20Z","receivedAt":"2020-12-04T06:17:58Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"We want --ff-only to make sense only when no --merge or --rebase option\nis specified.\n\nCurrently --rebase already ignores --ff-only (or any other --ff option),\nbut --merge fails.\n\nMake it so --ff-only is only considered in the default mode.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n builtin/pull.c  | 4 ++++\n t/t5520-pull.sh | 2 +-\n 2 files changed, 5 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex f54ff36b57..ebf2ac687b 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -1037,6 +1037,10 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\t}\n \t}\n \n+\t/* Disable --ff-only when --merge is specified */\n+\tif (!can_ff && !default_mode && !opt_rebase && opt_ff && !strcmp(opt_ff, \"--ff-only\"))\n+\t\topt_ff = NULL;\n+\n \tif (opt_rebase) {\n \t\tint ret = 0;\n \t\tif ((recurse_submodules == RECURSE_SUBMODULES_ON ||\ndiff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\nindex fdd1f79b06..eec6224fb0 100755\n--- a/t/t5520-pull.sh\n+++ b/t/t5520-pull.sh\n@@ -843,7 +843,7 @@ test_expect_success 'git pull non-fast-forward (ff-only)' '\n \ttest_must_fail git pull\n '\n \n-test_expect_failure 'git pull non-fast-forward with merge (ff-only)' '\n+test_expect_success 'git pull non-fast-forward with merge (ff-only)' '\n \ttest_when_finished \"git checkout master && git branch -D other test\" &&\n \ttest_config pull.ff only &&\n \tgit checkout -b other master^ &&\n-- \n2.29.2\n\n"},{"id":"411314","messageId":"20201204061623.1170745-8-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 07/14] pull: display default warning only when non-ff","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:16Z","receivedAt":"2020-12-04T06:17:59Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"There's no need to display the annoying warning on every pull... only\nthe ones that are not fast-forward.\n\nThis requires the tests to pick another base, so the merge is not\nfast-forward.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n Documentation/git-pull.txt   |  3 +++\n builtin/pull.c               |  2 +-\n t/t7601-merge-pull-config.sh | 28 +++++++++++++++++-----------\n 3 files changed, 21 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\nindex dc812139f4..ad33d2472c 100644\n--- a/Documentation/git-pull.txt\n+++ b/Documentation/git-pull.txt\n@@ -60,6 +60,9 @@ However, a non-fast-foward case looks very different.\n \torigin/master in your repository\n ------------\n \n+By default `git pull` will warn about these situations, however, most likely\n+you would want to force a merge, which you can do with `git pull --no-rebase`.\n+\n Then \"`git pull`\" will fetch and replay the changes from the remote\n `master` branch since it diverged from the local `master` (i.e., `E`)\n until its current commit (`C`) on top of `master` and record the\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex f82e214fc8..f0b1c6bfea 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -1013,7 +1013,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \n \tcan_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);\n \n-\tif (default_mode && opt_verbosity >= 0 && !opt_ff) {\n+\tif (default_mode && !can_ff && opt_verbosity >= 0 && !opt_ff) {\n \t\tadvise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n \t\t\t\"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n \t\t\t\"You can squelch this message by running one of the following commands:\\n\"\ndiff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh\nindex 6774e9d86f..6b4adab8b1 100755\n--- a/t/t7601-merge-pull-config.sh\n+++ b/t/t7601-merge-pull-config.sh\n@@ -28,7 +28,7 @@ test_expect_success 'setup' '\n '\n \n test_expect_success 'pull.rebase not set' '\n-\tgit reset --hard c0 &&\n+\tgit reset --hard c2 &&\n \tgit -c color.advice=always pull . c1 2>err &&\n \ttest_decode_color <err >decoded &&\n \ttest_i18ngrep \"<YELLOW>hint: \" decoded &&\n@@ -36,54 +36,60 @@ test_expect_success 'pull.rebase not set' '\n \n '\n \n-test_expect_success 'pull.rebase not set and pull.ff=true' '\n+test_expect_success 'pull.rebase not set (fast-forward)' '\n \tgit reset --hard c0 &&\n+\tgit pull . c1 2>err &&\n+\ttest_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n+'\n+\n+test_expect_success 'pull.rebase not set and pull.ff=true' '\n+\tgit reset --hard c2 &&\n \ttest_config pull.ff true &&\n \tgit pull . c1 2>err &&\n \ttest_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n '\n \n test_expect_success 'pull.rebase not set and pull.ff=false' '\n-\tgit reset --hard c0 &&\n+\tgit reset --hard c2 &&\n \ttest_config pull.ff false &&\n \tgit pull . c1 2>err &&\n \ttest_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n '\n \n test_expect_success 'pull.rebase not set and pull.ff=only' '\n-\tgit reset --hard c0 &&\n+\tgit reset --hard c2 &&\n \ttest_config pull.ff only &&\n-\tgit pull . c1 2>err &&\n+\ttest_must_fail git pull . c1 2>err &&\n \ttest_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n '\n \n test_expect_success 'pull.rebase not set and --rebase given' '\n-\tgit reset --hard c0 &&\n+\tgit reset --hard c2 &&\n \tgit pull --rebase . c1 2>err &&\n \ttest_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n '\n \n test_expect_success 'pull.rebase not set and --no-rebase given' '\n-\tgit reset --hard c0 &&\n+\tgit reset --hard c2 &&\n \tgit pull --no-rebase . c1 2>err &&\n \ttest_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n '\n \n test_expect_success 'pull.rebase not set and --ff given' '\n-\tgit reset --hard c0 &&\n+\tgit reset --hard c2 &&\n \tgit pull --ff . c1 2>err &&\n \ttest_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n '\n \n test_expect_success 'pull.rebase not set and --no-ff given' '\n-\tgit reset --hard c0 &&\n+\tgit reset --hard c2 &&\n \tgit pull --no-ff . c1 2>err &&\n \ttest_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n '\n \n test_expect_success 'pull.rebase not set and --ff-only given' '\n-\tgit reset --hard c0 &&\n-\tgit pull --ff-only . c1 2>err &&\n+\tgit reset --hard c2 &&\n+\ttest_must_fail git pull --ff-only . c1 2>err &&\n \ttest_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n '\n \n-- \n2.29.2\n\n"},{"id":"411315","messageId":"20201204061623.1170745-10-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-1-felipe.contreras@gmail.com","subject":"[PATCH v2 09/14] pull: introduce --merge option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T06:16:18Z","receivedAt":"2020-12-04T06:18:00Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Previously --no-rebase (which still works for backwards compatbility).\n\nNow we can update the default warning, and the git-pull(1) man page to\nuse --merge instead of the non-intuitive --no-rebase.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n Documentation/git-pull.txt   | 9 ++++++---\n builtin/pull.c               | 4 +++-\n t/t7601-merge-pull-config.sh | 4 ++--\n 3 files changed, 11 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\nindex ad33d2472c..c220da143a 100644\n--- a/Documentation/git-pull.txt\n+++ b/Documentation/git-pull.txt\n@@ -61,7 +61,7 @@ However, a non-fast-foward case looks very different.\n ------------\n \n By default `git pull` will warn about these situations, however, most likely\n-you would want to force a merge, which you can do with `git pull --no-rebase`.\n+you would want to force a merge, which you can do with `git pull --merge`.\n \n Then \"`git pull`\" will fetch and replay the changes from the remote\n `master` branch since it diverged from the local `master` (i.e., `E`)\n@@ -148,8 +148,11 @@ It rewrites history, which does not bode well when you\n published that history already.  Do *not* use this option\n unless you have read linkgit:git-rebase[1] carefully.\n \n---no-rebase::\n-\tOverride earlier --rebase.\n+-m::\n+--merge::\n+\tForce a merge.\n++\n+Previously this was --no-rebase, but that usage has been deprecated.\n \n Options related to fetching\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex b200f7544c..6ea95c9fc9 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -131,6 +131,8 @@ static struct option pull_options[] = {\n \t\t\"(false|true|merges|preserve|interactive)\",\n \t\tN_(\"incorporate changes by rebasing rather than merging\"),\n \t\tPARSE_OPT_OPTARG, parse_opt_rebase),\n+\tOPT_SET_INT('m', \"merge\", &opt_rebase,\n+\t\tN_(\"incorporate changes by merging\"), 0),\n \tOPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,\n \t\tN_(\"do not show a diffstat at the end of the merge\"),\n \t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG),\n@@ -1024,7 +1026,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\t\t\"\\n\"\n \t\t\t\"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n \t\t\t\"preference for all repositories.\\n\"\n-\t\t\t\"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n+\t\t\t\"If unsure, run \\\"git pull --merge\\\".\\n\"\n \t\t\t\"Read \\\"git pull --help\\\" for more information.\"\n \t\t\t));\n \t}\ndiff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh\nindex 6b4adab8b1..1de64e6cc5 100755\n--- a/t/t7601-merge-pull-config.sh\n+++ b/t/t7601-merge-pull-config.sh\n@@ -69,9 +69,9 @@ test_expect_success 'pull.rebase not set and --rebase given' '\n \ttest_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n '\n \n-test_expect_success 'pull.rebase not set and --no-rebase given' '\n+test_expect_success 'pull.rebase not set and --merge given' '\n \tgit reset --hard c2 &&\n-\tgit pull --no-rebase . c1 2>err &&\n+\tgit pull --merge . c1 2>err &&\n \ttest_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n '\n \n-- \n2.29.2\n\n"},{"id":"411416","messageId":"CABPp-BEsmNv1=yKGZj8kH9EGjnLkeo0+hJvog_b1pYex-59ScQ@mail.gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-2-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 01/14] doc: pull: explain what is a fast-forward","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-04T22:55:08Z","receivedAt":"2020-12-04T22:56:07Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> We want users to know what is a fast-forward in order to understand the\n> default warning.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  Documentation/git-pull.txt | 14 ++++++++++++++\n>  1 file changed, 14 insertions(+)\n>\n> diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\n> index 5c3fb67c01..dc812139f4 100644\n> --- a/Documentation/git-pull.txt\n> +++ b/Documentation/git-pull.txt\n> @@ -38,6 +38,20 @@ as set by linkgit:git-branch[1] `--track`.\n>  Assume the following history exists and the current branch is\n>  \"`master`\":\n>\n> +------------\n> +         A---B---C master on origin\n> +        /\n> +    D---E master\n> +------------\n> +\n> +Then `git pull` will merge in a fast-foward way up to the new master.\n> +\n> +------------\n> +    D---E---A---B---C master, origin/master\n> +------------\n> +\n> +However, a non-fast-foward case looks very different.\n> +\n>  ------------\n>           A---B---C master on origin\n>          /\n> --\n> 2.29.2\n\nMakes sense to me.\n"},{"id":"411417","messageId":"CABPp-BFdjj=+4jk0vo=kpNc6ug1=UgtKfXJZkseyyxut2VB=Uw@mail.gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-3-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-04T22:59:53Z","receivedAt":"2020-12-04T23:00:47Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> We want to:\n>\n> 1. Be clear about what \"specifying\" means; merge or rebase.\n> 2. Mention a direct shortcut for people that just want to get on with\n>    their lives: git pull --no-rebase.\n\nThis is a shortcut for what?\n\n> 3. Have a quick reference for users to understand what this\n>    \"fast-forward\" business means.\n>\n> This patch does all three.\n>\n> Thanks to the previous patch now \"git pull --help\" explains what a\n> fast-forward is, and a further patch changes --no-rebase to --merge so\n> it's actually user friendly.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  builtin/pull.c | 23 ++++++++++++-----------\n>  1 file changed, 12 insertions(+), 11 deletions(-)\n>\n> diff --git a/builtin/pull.c b/builtin/pull.c\n> index 1034372f8b..22a9ffcade 100644\n> --- a/builtin/pull.c\n> +++ b/builtin/pull.c\n> @@ -346,17 +346,18 @@ static enum rebase_type config_get_rebase(void)\n>\n>         if (opt_verbosity >= 0 && !opt_ff) {\n>                 advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n> -                        \"discouraged. You can squelch this message by running one of the following\\n\"\n> -                        \"commands sometime before your next pull:\\n\"\n> -                        \"\\n\"\n> -                        \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> -                        \"  git config pull.rebase true   # rebase\\n\"\n> -                        \"  git config pull.ff only       # fast-forward only\\n\"\n> -                        \"\\n\"\n> -                        \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> -                        \"preference for all repositories. You can also pass --rebase, --no-rebase,\\n\"\n> -                        \"or --ff-only on the command line to override the configured default per\\n\"\n> -                        \"invocation.\\n\"));\n> +                       \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n\n...want a merge, a rebase, or neither.\n\n> +                       \"You can squelch this message by running one of the following commands:\\n\"\n> +                       \"\\n\"\n> +                       \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n\nShould this be labelled as the default given the desire to make\n--ff-only the default?  Perhaps I'm jumping ahead and you plan to\nchange that later in this series.\n\n> +                       \"  git config pull.rebase true   # rebase\\n\"\n> +                       \"  git config pull.ff only       # fast-forward only\\n\"\n> +                       \"\\n\"\n> +                       \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> +                       \"preference for all repositories.\\n\"\n\nGood up to here.\n\n> +                       \"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n\nWhy is that safe to suggest?  The original text may not have been the\neasiest to parse, but this seems more problematic to me.\n\n> +                       \"Read \\\"git pull --help\\\" for more information.\"\n\nNice addition.\n\n\n> +                       ));\n>         }\n>\n>         return REBASE_FALSE;\n> --\n> 2.29.2\n>\n"},{"id":"411418","messageId":"CABPp-BHjzzhqQW8YY5podav+TU8Eixhp7g-VrQ-tva-0ztAtvA@mail.gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-5-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 04/14] pull: cleanup autostash check","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-04T23:07:24Z","receivedAt":"2020-12-04T23:08:33Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> This essentially reverts commit f15e7cf5cc.\n>\n> Once commit d9f15d37f1 introduced the autostash option for the merge\n> mode, it's not necessary to skip the fast-forward run_merge() when\n> autostash is set.\n\nIt helps reviewers and future code readers if you provide a little\ncontext when referring to commits, making use of git log's\n--pretty=reference option to get the output.  So, for example, here\nyour commit would read:\n\n\"\"\"\nThis essentially reverts commit f15e7cf5cc (pull: ff --rebase\n--autostash works in dirty repo, 2017-06-01).\n\nOnce commit d9f15d37f1 (pull: pass --autostash to merge, 2020-04-07)\nintroduced the autostash option for the merge\nmode, it's not necessary to skip the fast-forward run_merge() when\nautostash is set.\n\"\"\"\n\nI still found it slightly hard to follow the explanation even with the\nadded summaries, though.  An extra sentence at the end of the second\nparagraph to make it clear what is being changed (\"So, change the code\nto fast-forward even when autostash is set.\") seems to help.\n\n\n\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  builtin/pull.c | 15 ++++++---------\n>  1 file changed, 6 insertions(+), 9 deletions(-)\n>\n> diff --git a/builtin/pull.c b/builtin/pull.c\n> index 6279e9ee37..c38548dab8 100644\n> --- a/builtin/pull.c\n> +++ b/builtin/pull.c\n> @@ -927,7 +927,6 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>         struct oid_array merge_heads = OID_ARRAY_INIT;\n>         struct object_id orig_head, curr_head;\n>         struct object_id rebase_fork_point;\n> -       int autostash;\n>\n>         if (!getenv(\"GIT_REFLOG_ACTION\"))\n>                 set_reflog_message(argc, argv);\n> @@ -960,8 +959,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>         if (get_oid(\"HEAD\", &orig_head))\n>                 oidclr(&orig_head);\n>\n> -       autostash = config_autostash;\n>         if (opt_rebase) {\n> +               int autostash = config_autostash;\n>                 if (opt_autostash != -1)\n>                         autostash = opt_autostash;\n>\n> @@ -1030,13 +1029,11 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>                      recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&\n>                     submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))\n>                         die(_(\"cannot rebase with locally recorded submodule modifications\"));\n> -               if (!autostash) {\n> -                       if (get_can_ff(&orig_head, &merge_heads.oid[0])) {\n> -                               /* we can fast-forward this without invoking rebase */\n> -                               opt_ff = \"--ff-only\";\n> -                               ran_ff = 1;\n> -                               ret = run_merge();\n> -                       }\n> +               if (get_can_ff(&orig_head, &merge_heads.oid[0])) {\n> +                       /* we can fast-forward this without invoking rebase */\n> +                       opt_ff = \"--ff-only\";\n> +                       ran_ff = 1;\n> +                       ret = run_merge();\n>                 }\n>                 if (!ran_ff)\n>                         ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n> --\n> 2.29.2\n>\n"},{"id":"411419","messageId":"CABPp-BHs-eaJcTMcOPEsDx7PbBfoM0Uf7-vWi33OVOcTEgAgmg@mail.gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-6-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 05/14] pull: trivial cleanup","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-04T23:09:12Z","receivedAt":"2020-12-04T23:10:21Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> There's no need to store ran_ff. Now it's obvious from the conditionals.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  builtin/pull.c | 7 +++----\n>  1 file changed, 3 insertions(+), 4 deletions(-)\n>\n> diff --git a/builtin/pull.c b/builtin/pull.c\n> index c38548dab8..8daba7539c 100644\n> --- a/builtin/pull.c\n> +++ b/builtin/pull.c\n> @@ -1024,19 +1024,18 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>\n>         if (opt_rebase) {\n>                 int ret = 0;\n> -               int ran_ff = 0;\n>                 if ((recurse_submodules == RECURSE_SUBMODULES_ON ||\n>                      recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&\n>                     submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))\n>                         die(_(\"cannot rebase with locally recorded submodule modifications\"));\n> +\nspurious change?\n\n(It does make it look nicer, though.)\n\n>                 if (get_can_ff(&orig_head, &merge_heads.oid[0])) {\n>                         /* we can fast-forward this without invoking rebase */\n>                         opt_ff = \"--ff-only\";\n> -                       ran_ff = 1;\n>                         ret = run_merge();\n> -               }\n> -               if (!ran_ff)\n> +               } else {\n>                         ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n> +               }\n>\n>                 if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||\n>                              recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))\n> --\n> 2.29.2\n\nYeah, reads better to me after this cleanup.\n"},{"id":"411423","messageId":"CABPp-BHH0baiECvtvVOoHR82upJ1C+0hy-ukS9Hi2ZFHh19nOg@mail.gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-7-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 06/14] pull: move default warning","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-04T23:18:48Z","receivedAt":"2020-12-04T23:19:41Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> Up to the point where can check if we can fast-forward or not.\n\nSeem to be missing some subjects in that sentence.  ;-)  Perhaps:\n\nMove the default warning to the point where we can check if we can\nfast-forward or not.\n\n> No functional changes.\n\nYou didn't explain the reasoning for the change here, though I suspect\nit makes it easier to change the default to ff-only later.  However,\nlooking over the patch and pulling up the code, I actually find it\npretty odd that this warning was in a function named\nconfig_get_rebase().  The warning is not rebase-specific, and so\nclearly does not belong there.  And for such a function name, the only\nkinds of warnings I'd expect are ones where the user configured some\noption but set it to a value that cannot make sense.  So it all around\nseems like the wrong place to me, and I find your patch to be a good\ncleanup.  It would benefit from a slightly improved commit message\nthough.  :-)\n\n\n\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  builtin/pull.c | 39 +++++++++++++++++++++++----------------\n>  1 file changed, 23 insertions(+), 16 deletions(-)\n>\n> diff --git a/builtin/pull.c b/builtin/pull.c\n> index 8daba7539c..f82e214fc8 100644\n> --- a/builtin/pull.c\n> +++ b/builtin/pull.c\n> @@ -27,6 +27,8 @@\n>  #include \"commit-reach.h\"\n>  #include \"sequencer.h\"\n>\n> +static int default_mode;\n> +\n>  /**\n>   * Parses the value of --rebase. If value is a false value, returns\n>   * REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is\n> @@ -344,21 +346,7 @@ static enum rebase_type config_get_rebase(void)\n>         if (!git_config_get_value(\"pull.rebase\", &value))\n>                 return parse_config_rebase(\"pull.rebase\", value, 1);\n>\n> -       if (opt_verbosity >= 0 && !opt_ff) {\n> -               advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n> -                       \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n> -                       \"You can squelch this message by running one of the following commands:\\n\"\n> -                       \"\\n\"\n> -                       \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> -                       \"  git config pull.rebase true   # rebase\\n\"\n> -                       \"  git config pull.ff only       # fast-forward only\\n\"\n> -                       \"\\n\"\n> -                       \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> -                       \"preference for all repositories.\\n\"\n> -                       \"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n> -                       \"Read \\\"git pull --help\\\" for more information.\"\n> -                       ));\n> -       }\n> +       default_mode = 1;\n>\n>         return REBASE_FALSE;\n>  }\n> @@ -927,6 +915,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>         struct oid_array merge_heads = OID_ARRAY_INIT;\n>         struct object_id orig_head, curr_head;\n>         struct object_id rebase_fork_point;\n> +       int can_ff;\n>\n>         if (!getenv(\"GIT_REFLOG_ACTION\"))\n>                 set_reflog_message(argc, argv);\n> @@ -1022,6 +1011,24 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>         if (opt_rebase && merge_heads.nr > 1)\n>                 die(_(\"Cannot rebase onto multiple branches.\"));\n>\n> +       can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);\n> +\n> +       if (default_mode && opt_verbosity >= 0 && !opt_ff) {\n> +               advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n> +                       \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n> +                       \"You can squelch this message by running one of the following commands:\\n\"\n> +                       \"\\n\"\n> +                       \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> +                       \"  git config pull.rebase true   # rebase\\n\"\n> +                       \"  git config pull.ff only       # fast-forward only\\n\"\n> +                       \"\\n\"\n> +                       \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> +                       \"preference for all repositories.\\n\"\n> +                       \"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n> +                       \"Read \\\"git pull --help\\\" for more information.\"\n> +                       ));\n> +       }\n> +\n>         if (opt_rebase) {\n>                 int ret = 0;\n>                 if ((recurse_submodules == RECURSE_SUBMODULES_ON ||\n> @@ -1029,7 +1036,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>                     submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))\n>                         die(_(\"cannot rebase with locally recorded submodule modifications\"));\n>\n> -               if (get_can_ff(&orig_head, &merge_heads.oid[0])) {\n> +               if (can_ff) {\n>                         /* we can fast-forward this without invoking rebase */\n>                         opt_ff = \"--ff-only\";\n>                         ret = run_merge();\n> --\n> 2.29.2\n>\n"},{"id":"411426","messageId":"CABPp-BEdgwcueYC1OWd3LtJaGPLgLcdkezGEqeKo7mVfx=C6Jg@mail.gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-8-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 07/14] pull: display default warning only when non-ff","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-04T23:24:22Z","receivedAt":"2020-12-04T23:25:16Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> There's no need to display the annoying warning on every pull... only\n> the ones that are not fast-forward.\n\nI like this.  :-)\n\n> This requires the tests to pick another base, so the merge is not\n> fast-forward.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  Documentation/git-pull.txt   |  3 +++\n>  builtin/pull.c               |  2 +-\n>  t/t7601-merge-pull-config.sh | 28 +++++++++++++++++-----------\n>  3 files changed, 21 insertions(+), 12 deletions(-)\n>\n> diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\n> index dc812139f4..ad33d2472c 100644\n> --- a/Documentation/git-pull.txt\n> +++ b/Documentation/git-pull.txt\n> @@ -60,6 +60,9 @@ However, a non-fast-foward case looks very different.\n>         origin/master in your repository\n>  ------------\n>\n> +By default `git pull` will warn about these situations, however, most likely\n> +you would want to force a merge, which you can do with `git pull --no-rebase`.\n> +\n\nEverything in this sentence after the first comma seems dangerous to\nme for a number of workflows.\n\n>  Then \"`git pull`\" will fetch and replay the changes from the remote\n>  `master` branch since it diverged from the local `master` (i.e., `E`)\n>  until its current commit (`C`) on top of `master` and record the\n> diff --git a/builtin/pull.c b/builtin/pull.c\n> index f82e214fc8..f0b1c6bfea 100644\n> --- a/builtin/pull.c\n> +++ b/builtin/pull.c\n> @@ -1013,7 +1013,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>\n>         can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);\n>\n> -       if (default_mode && opt_verbosity >= 0 && !opt_ff) {\n> +       if (default_mode && !can_ff && opt_verbosity >= 0 && !opt_ff) {\n>                 advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n>                         \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n>                         \"You can squelch this message by running one of the following commands:\\n\"\n> diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh\n> index 6774e9d86f..6b4adab8b1 100755\n> --- a/t/t7601-merge-pull-config.sh\n> +++ b/t/t7601-merge-pull-config.sh\n> @@ -28,7 +28,7 @@ test_expect_success 'setup' '\n>  '\n>\n>  test_expect_success 'pull.rebase not set' '\n> -       git reset --hard c0 &&\n> +       git reset --hard c2 &&\n>         git -c color.advice=always pull . c1 2>err &&\n>         test_decode_color <err >decoded &&\n>         test_i18ngrep \"<YELLOW>hint: \" decoded &&\n> @@ -36,54 +36,60 @@ test_expect_success 'pull.rebase not set' '\n>\n>  '\n>\n> -test_expect_success 'pull.rebase not set and pull.ff=true' '\n> +test_expect_success 'pull.rebase not set (fast-forward)' '\n>         git reset --hard c0 &&\n> +       git pull . c1 2>err &&\n> +       test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n> +'\n> +\n> +test_expect_success 'pull.rebase not set and pull.ff=true' '\n> +       git reset --hard c2 &&\n>         test_config pull.ff true &&\n>         git pull . c1 2>err &&\n>         test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n>  '\n>\n>  test_expect_success 'pull.rebase not set and pull.ff=false' '\n> -       git reset --hard c0 &&\n> +       git reset --hard c2 &&\n>         test_config pull.ff false &&\n>         git pull . c1 2>err &&\n>         test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n>  '\n>\n>  test_expect_success 'pull.rebase not set and pull.ff=only' '\n> -       git reset --hard c0 &&\n> +       git reset --hard c2 &&\n>         test_config pull.ff only &&\n> -       git pull . c1 2>err &&\n> +       test_must_fail git pull . c1 2>err &&\n\nIt makes sense to me that you'd need test_must_fail here...but why\nwasn't it needed before??  How did this test pass without it before\nthis series?\n\n>         test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n>  '\n>\n>  test_expect_success 'pull.rebase not set and --rebase given' '\n> -       git reset --hard c0 &&\n> +       git reset --hard c2 &&\n>         git pull --rebase . c1 2>err &&\n>         test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n>  '\n>\n>  test_expect_success 'pull.rebase not set and --no-rebase given' '\n> -       git reset --hard c0 &&\n> +       git reset --hard c2 &&\n>         git pull --no-rebase . c1 2>err &&\n>         test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n>  '\n>\n>  test_expect_success 'pull.rebase not set and --ff given' '\n> -       git reset --hard c0 &&\n> +       git reset --hard c2 &&\n>         git pull --ff . c1 2>err &&\n>         test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n>  '\n>\n>  test_expect_success 'pull.rebase not set and --no-ff given' '\n> -       git reset --hard c0 &&\n> +       git reset --hard c2 &&\n>         git pull --no-ff . c1 2>err &&\n>         test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n>  '\n>\n>  test_expect_success 'pull.rebase not set and --ff-only given' '\n> -       git reset --hard c0 &&\n> -       git pull --ff-only . c1 2>err &&\n> +       git reset --hard c2 &&\n> +       test_must_fail git pull --ff-only . c1 2>err &&\n\nSame question; how did this test pass before without the test_must_fail??\n\n\n>         test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n>  '\n>\n> --\n> 2.29.2\n"},{"id":"411427","messageId":"CABPp-BGndfbF=QcCox13kik4B9F7Bgn7k2ToFRkGsh0dJ4K0HA@mail.gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-10-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 09/14] pull: introduce --merge option","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-04T23:27:35Z","receivedAt":"2020-12-04T23:29:30Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> Previously --no-rebase (which still works for backwards compatbility).\n>\n> Now we can update the default warning, and the git-pull(1) man page to\n> use --merge instead of the non-intuitive --no-rebase.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  Documentation/git-pull.txt   | 9 ++++++---\n>  builtin/pull.c               | 4 +++-\n>  t/t7601-merge-pull-config.sh | 4 ++--\n>  3 files changed, 11 insertions(+), 6 deletions(-)\n>\n> diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\n> index ad33d2472c..c220da143a 100644\n> --- a/Documentation/git-pull.txt\n> +++ b/Documentation/git-pull.txt\n> @@ -61,7 +61,7 @@ However, a non-fast-foward case looks very different.\n>  ------------\n>\n>  By default `git pull` will warn about these situations, however, most likely\n> -you would want to force a merge, which you can do with `git pull --no-rebase`.\n> +you would want to force a merge, which you can do with `git pull --merge`.\n\nI'm glad you updated all the references, but as noted earlier in the\nseries I think this suggestion is problematic.\n\n>\n>  Then \"`git pull`\" will fetch and replay the changes from the remote\n>  `master` branch since it diverged from the local `master` (i.e., `E`)\n> @@ -148,8 +148,11 @@ It rewrites history, which does not bode well when you\n>  published that history already.  Do *not* use this option\n>  unless you have read linkgit:git-rebase[1] carefully.\n>\n> ---no-rebase::\n> -       Override earlier --rebase.\n> +-m::\n> +--merge::\n> +       Force a merge.\n> ++\n> +Previously this was --no-rebase, but that usage has been deprecated.\n>\n>  Options related to fetching\n>  ~~~~~~~~~~~~~~~~~~~~~~~~~~~\n> diff --git a/builtin/pull.c b/builtin/pull.c\n> index b200f7544c..6ea95c9fc9 100644\n> --- a/builtin/pull.c\n> +++ b/builtin/pull.c\n> @@ -131,6 +131,8 @@ static struct option pull_options[] = {\n>                 \"(false|true|merges|preserve|interactive)\",\n>                 N_(\"incorporate changes by rebasing rather than merging\"),\n>                 PARSE_OPT_OPTARG, parse_opt_rebase),\n> +       OPT_SET_INT('m', \"merge\", &opt_rebase,\n> +               N_(\"incorporate changes by merging\"), 0),\n>         OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,\n>                 N_(\"do not show a diffstat at the end of the merge\"),\n>                 PARSE_OPT_NOARG | PARSE_OPT_NONEG),\n> @@ -1024,7 +1026,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>                         \"\\n\"\n>                         \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n>                         \"preference for all repositories.\\n\"\n> -                       \"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n> +                       \"If unsure, run \\\"git pull --merge\\\".\\n\"\n\nThis was the other problematic copy of that suggestion.\n\n>                         \"Read \\\"git pull --help\\\" for more information.\"\n>                         ));\n>         }\n> diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh\n> index 6b4adab8b1..1de64e6cc5 100755\n> --- a/t/t7601-merge-pull-config.sh\n> +++ b/t/t7601-merge-pull-config.sh\n> @@ -69,9 +69,9 @@ test_expect_success 'pull.rebase not set and --rebase given' '\n>         test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n>  '\n>\n> -test_expect_success 'pull.rebase not set and --no-rebase given' '\n> +test_expect_success 'pull.rebase not set and --merge given' '\n>         git reset --hard c2 &&\n> -       git pull --no-rebase . c1 2>err &&\n> +       git pull --merge . c1 2>err &&\n>         test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n>  '\n>\n> --\n> 2.29.2\n\nI very much like the change in this patch, other than the obvious\ncouple places where you are just tweaking an earlier problematic\nsuggestion.\n"},{"id":"411428","messageId":"CABPp-BGftkZqJ1GuB-7-7PCo3zOYn_Rr1yu4wv6hwtDea5_oYw@mail.gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-11-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 10/14] pull: add proper error with --ff-only","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-04T23:34:27Z","receivedAt":"2020-12-04T23:35:26Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> The current error is not user-friendly:\n>\n>   fatal: not possible to fast-forward, aborting.\n>\n> We want something that actually explains what is going on:\n>\n>   The pull was not fast-forward, please either merge or rebase.\n>   If unsure, run \"git pull --merge\".\n\nSorry to be a broken record, but I don't like the suggestion in the\nsecond sentence.  I've said it enough times that I'll quit harping on\neach instance.\n\n> The user can get rid of the warning by doing either --merge or\n> --rebase.\n>\n> Except: doing \"git pull --merge\" is not actually enough; we would return\n> to the previous behavior: \"fatal: not possible to fast-forward, aborting.\"\n\nDo you mean that the changes in this patch aren't enough and that\nfuture patches will address this shortcoming?  Or do you mean that\nprior to this patch such a bug existed?  Or something else?\n\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  builtin/pull.c  | 34 ++++++++++++++++-----------\n>  t/t5520-pull.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++\n>  2 files changed, 82 insertions(+), 14 deletions(-)\n>\n> diff --git a/builtin/pull.c b/builtin/pull.c\n> index 6ea95c9fc9..f54ff36b57 100644\n> --- a/builtin/pull.c\n> +++ b/builtin/pull.c\n> @@ -1015,20 +1015,26 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>\n>         can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);\n>\n> -       if (default_mode && !can_ff && opt_verbosity >= 0 && !opt_ff) {\n> -               advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n> -                       \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n> -                       \"You can squelch this message by running one of the following commands:\\n\"\n> -                       \"\\n\"\n> -                       \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> -                       \"  git config pull.rebase true   # rebase\\n\"\n> -                       \"  git config pull.ff only       # fast-forward only\\n\"\n> -                       \"\\n\"\n> -                       \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> -                       \"preference for all repositories.\\n\"\n> -                       \"If unsure, run \\\"git pull --merge\\\".\\n\"\n> -                       \"Read \\\"git pull --help\\\" for more information.\"\n> -                       ));\n> +       if (!can_ff && default_mode) {\n> +               if (opt_ff && !strcmp(opt_ff, \"--ff-only\")) {\n> +                       die(_(\"The pull was not fast-forward, please either merge or rebase.\\n\"\n> +                               \"If unsure, run \\\"git pull --merge\\\".\"));\n\nThis is a much better message for when the user requests --ff-only.\n\n> +               }\n> +               if (opt_verbosity >= 0 && !opt_ff) {\n> +                       advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n> +                               \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n> +                               \"You can squelch this message by running one of the following commands:\\n\"\n> +                               \"\\n\"\n> +                               \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> +                               \"  git config pull.rebase true   # rebase\\n\"\n> +                               \"  git config pull.ff only       # fast-forward only\\n\"\n> +                               \"\\n\"\n> +                               \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> +                               \"preference for all repositories.\\n\"\n> +                               \"If unsure, run \\\"git pull --merge\\\".\\n\"\n> +                               \"Read \\\"git pull --help\\\" for more information.\"\n> +                               ));\n> +               }\n>         }\n>\n>         if (opt_rebase) {\n> diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\n> index 9fae07cdfa..fdd1f79b06 100755\n> --- a/t/t5520-pull.sh\n> +++ b/t/t5520-pull.sh\n> @@ -819,4 +819,66 @@ test_expect_success 'git pull --rebase against local branch' '\n>         test_cmp expect file2\n>  '\n>\n> +test_expect_success 'git pull fast-forward (ff-only)' '\n> +       test_when_finished \"git checkout master && git branch -D other test\" &&\n> +       test_config pull.ff only &&\n> +       git checkout -b other master &&\n> +       >new &&\n> +       git add new &&\n> +       git commit -m new &&\n> +       git checkout -b test -t other &&\n> +       git reset --hard master &&\n> +       git pull\n> +'\n> +\n> +test_expect_success 'git pull non-fast-forward (ff-only)' '\n> +       test_when_finished \"git checkout master && git branch -D other test\" &&\n> +       test_config pull.ff only &&\n> +       git checkout -b other master^ &&\n> +       >new &&\n> +       git add new &&\n> +       git commit -m new &&\n> +       git checkout -b test -t other &&\n> +       git reset --hard master &&\n> +       test_must_fail git pull\n> +'\n> +\n> +test_expect_failure 'git pull non-fast-forward with merge (ff-only)' '\n> +       test_when_finished \"git checkout master && git branch -D other test\" &&\n> +       test_config pull.ff only &&\n> +       git checkout -b other master^ &&\n> +       >new &&\n> +       git add new &&\n> +       git commit -m new &&\n> +       git checkout -b test -t other &&\n> +       git reset --hard master &&\n> +       git pull --no-rebase\n\nDo you mean `git pull --merge`?\n\n\n> +'\n> +\n> +test_expect_success 'git pull non-fast-forward with rebase (ff-only)' '\n> +       test_when_finished \"git checkout master && git branch -D other test\" &&\n> +       test_config pull.ff only &&\n> +       git checkout -b other master^ &&\n> +       >new &&\n> +       git add new &&\n> +       git commit -m new &&\n> +       git checkout -b test -t other &&\n> +       git reset --hard master &&\n> +       git pull --rebase\n> +'\n> +\n> +test_expect_success 'git pull non-fast-forward error message' '\n> +       test_when_finished \"git checkout master && git branch -D other test\" &&\n> +       test_config pull.ff only &&\n> +       git checkout -b other master^ &&\n> +       >new &&\n> +       git add new &&\n> +       git commit -m new &&\n> +       git checkout -b test -t other &&\n> +       git reset --hard master &&\n> +       test_must_fail git pull 2> error &&\n> +       cat error &&\n> +       grep -q \"The pull was not fast-forward\" error\n> +'\n> +\n>  test_done\n> --\n> 2.29.2\n"},{"id":"411429","messageId":"CAMP44s2T4HSVAwx6D3sO5c8b_tSKT174eASTjmb61kKmm=JcwQ@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BHH0baiECvtvVOoHR82upJ1C+0hy-ukS9Hi2ZFHh19nOg@mail.gmail.com","subject":"Re: [PATCH v2 06/14] pull: move default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-04T23:36:28Z","receivedAt":"2020-12-04T23:37:28Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 4, 2020 at 5:18 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> >\n> > Up to the point where can check if we can fast-forward or not.\n>\n> Seem to be missing some subjects in that sentence.  ;-)  Perhaps:\n>\n> Move the default warning to the point where we can check if we can\n> fast-forward or not.\n\nYes, I missed a \"we\".\n\nI usually continue what I said in the subject, but lately while\nreviewing my own patches in lore.kernel.org I've found it hard to\nunderstand the first paragraph since it's not easy to find the\nsubject.\n\nMaybe I should stop doing that.\n\n> > No functional changes.\n>\n> You didn't explain the reasoning for the change here, though I suspect\n> it makes it easier to change the default to ff-only later.\n\nRight, I noticed that after the nth time I reviewed the series.\n\nIt's not actually to change the default to ff-only, it's mainly to\ndisplay the annoying warning only when a non-fast-forward pull is\nbeing attempted.\n\nI'll add that to the commit message.\n\n> However,\n> looking over the patch and pulling up the code, I actually find it\n> pretty odd that this warning was in a function named\n> config_get_rebase().  The warning is not rebase-specific, and so\n> clearly does not belong there.  And for such a function name, the only\n> kinds of warnings I'd expect are ones where the user configured some\n> option but set it to a value that cannot make sense.  So it all around\n> seems like the wrong place to me, and I find your patch to be a good\n> cleanup.  It would benefit from a slightly improved commit message\n> though.  :-)\n\nIndeed. The only reason it's there is that it's the only place we know\nthe user has not done either --rebase, or --merge (--no-rebase), or\nthe config equivalents.\n\nI fixed that by introducing a default_mode flag, but in other patch\nseries I replace default_mode with a check for REBASE_DEFAULT (which\ndoesn't exist yet).\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"411430","messageId":"CABPp-BG0WWvk96T757WMx=004qVqkf+SU8m3cCZsb1feTZJ80Q@mail.gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-12-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-04T23:39:19Z","receivedAt":"2020-12-04T23:40:27Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> We want --ff-only to make sense only when no --merge or --rebase option\n> is specified.\n\nA lot of git commands have opposite options, and git allows them both\nto be specified with the last one winning.  Thus, much like\n  git log --patch --no-patch\nmean show logs without patches and\n  git log --no-patch --patch\nmeans show logs with patches, I would similarly expect the following\ntwo commands to have opposite behavior:\n  git pull --merge --no-ff\n  git pull --no-ff --merge\n\n\n> Currently --rebase already ignores --ff-only (or any other --ff option),\n> but --merge fails.\n>\n> Make it so --ff-only is only considered in the default mode.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  builtin/pull.c  | 4 ++++\n>  t/t5520-pull.sh | 2 +-\n>  2 files changed, 5 insertions(+), 1 deletion(-)\n>\n> diff --git a/builtin/pull.c b/builtin/pull.c\n> index f54ff36b57..ebf2ac687b 100644\n> --- a/builtin/pull.c\n> +++ b/builtin/pull.c\n> @@ -1037,6 +1037,10 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>                 }\n>         }\n>\n> +       /* Disable --ff-only when --merge is specified */\n> +       if (!can_ff && !default_mode && !opt_rebase && opt_ff && !strcmp(opt_ff, \"--ff-only\"))\n> +               opt_ff = NULL;\n> +\n>         if (opt_rebase) {\n>                 int ret = 0;\n>                 if ((recurse_submodules == RECURSE_SUBMODULES_ON ||\n> diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\n> index fdd1f79b06..eec6224fb0 100755\n> --- a/t/t5520-pull.sh\n> +++ b/t/t5520-pull.sh\n> @@ -843,7 +843,7 @@ test_expect_success 'git pull non-fast-forward (ff-only)' '\n>         test_must_fail git pull\n>  '\n>\n> -test_expect_failure 'git pull non-fast-forward with merge (ff-only)' '\n> +test_expect_success 'git pull non-fast-forward with merge (ff-only)' '\n>         test_when_finished \"git checkout master && git branch -D other test\" &&\n>         test_config pull.ff only &&\n>         git checkout -b other master^ &&\n> --\n> 2.29.2\n>\n"},{"id":"411431","messageId":"CABPp-BE5zvCAmfHE_1_D3boMg5rMcU0iyJJp+yiLwSu2DsySLg@mail.gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-13-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 12/14] pull: show warning with --ff","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-04T23:41:20Z","receivedAt":"2020-12-04T23:42:14Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> It's unclear why --ff should remove the warning, since:\n>\n>   git pull --ff\n>\n> Is implicitly the same as:\n>\n>   git pull\n>\n> Unless of course pull.ff is specified otherwise.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  builtin/pull.c               | 2 +-\n>  t/t7601-merge-pull-config.sh | 4 ++--\n>  2 files changed, 3 insertions(+), 3 deletions(-)\n>\n> diff --git a/builtin/pull.c b/builtin/pull.c\n> index ebf2ac687b..e389ffcdc3 100644\n> --- a/builtin/pull.c\n> +++ b/builtin/pull.c\n> @@ -1020,7 +1020,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>                         die(_(\"The pull was not fast-forward, please either merge or rebase.\\n\"\n>                                 \"If unsure, run \\\"git pull --merge\\\".\"));\n>                 }\n> -               if (opt_verbosity >= 0 && !opt_ff) {\n> +               if (opt_verbosity >= 0 && (!opt_ff || !strcmp(opt_ff, \"--ff\"))) {\n>                         advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n>                                 \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n>                                 \"You can squelch this message by running one of the following commands:\\n\"\n> diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh\n> index 1de64e6cc5..d709799f8b 100755\n> --- a/t/t7601-merge-pull-config.sh\n> +++ b/t/t7601-merge-pull-config.sh\n> @@ -46,7 +46,7 @@ test_expect_success 'pull.rebase not set and pull.ff=true' '\n>         git reset --hard c2 &&\n>         test_config pull.ff true &&\n>         git pull . c1 2>err &&\n> -       test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n> +       test_i18ngrep \"Pulling without specifying how to reconcile\" err\n>  '\n>\n>  test_expect_success 'pull.rebase not set and pull.ff=false' '\n> @@ -78,7 +78,7 @@ test_expect_success 'pull.rebase not set and --merge given' '\n>  test_expect_success 'pull.rebase not set and --ff given' '\n>         git reset --hard c2 &&\n>         git pull --ff . c1 2>err &&\n> -       test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n> +       test_i18ngrep \"Pulling without specifying how to reconcile\" err\n>  '\n>\n>  test_expect_success 'pull.rebase not set and --no-ff given' '\n> --\n> 2.29.2\n\nAh, this answers one of my earlier questions.  I'd be tempted to move\nthis earlier in the series; it seems like an obvious cleanup and helps\nexplain the \"opt_ff\" flag that keeps coming up for readers of the\nseries.\n"},{"id":"411432","messageId":"CABPp-BFQXV+FdYXqCzN0LtxrK2zYLux66EPKJ8UumBSo5qgJqA@mail.gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-14-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 13/14] test: merge-pull-config: trivial cleanup","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-04T23:41:55Z","receivedAt":"2020-12-04T23:43:03Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> Commit e01ae2a4a7 introduced an extra space.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  t/t7601-merge-pull-config.sh | 1 -\n>  1 file changed, 1 deletion(-)\n>\n> diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh\n> index d709799f8b..8a6aae564a 100755\n> --- a/t/t7601-merge-pull-config.sh\n> +++ b/t/t7601-merge-pull-config.sh\n> @@ -33,7 +33,6 @@ test_expect_success 'pull.rebase not set' '\n>         test_decode_color <err >decoded &&\n>         test_i18ngrep \"<YELLOW>hint: \" decoded &&\n>         test_i18ngrep \"Pulling without specifying how to reconcile\" decoded\n> -\n>  '\n>\n>  test_expect_success 'pull.rebase not set (fast-forward)' '\n> --\n> 2.29.2\n\nIndeed, quite obvious and simple.\n"},{"id":"411433","messageId":"CABPp-BEfxvkuVsDR9duwg1QCMxV9O4RqGF_rm2NuiStczggQoA@mail.gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-15-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 14/14] test: pull-options: revert unnecessary changes","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-04T23:49:12Z","receivedAt":"2020-12-04T23:50:21Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> Commit d18c950a69 changed these tests, but it's unclear why. Probably\n> because earlier versions of the patch series died instead of printing a\n> warning.\n\nAnother case where log --pretty=reference notation would be more\nhelpful in referring to commits.\n\nLooking up that commit, I see that commit made a number of other test\nchanges which seem to be better motivated by the commit message and\ncode changes.  I wonder if we could make that clearer in the commit\nmessage somehow.  Perhaps\n\nCommit d18c950a69 (\"pull: warn if the user didn't say whether to\nrebase or to merge\", 2020-03-09) changed a number of tests in t5521\nand added some new tests in t7601, but it is not clear why the changes\nin t5521 were made...\n\n\n>\n> Cc: Alex Henrie <alexhenrie24@gmail.com>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  t/t5521-pull-options.sh | 22 +++++++++++-----------\n>  1 file changed, 11 insertions(+), 11 deletions(-)\n>\n> diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh\n> index db1a381cd9..1a4fe2583a 100755\n> --- a/t/t5521-pull-options.sh\n> +++ b/t/t5521-pull-options.sh\n> @@ -11,10 +11,10 @@ test_expect_success 'setup' '\n>          git commit -m one)\n>  '\n>\n> -test_expect_success 'git pull -q --no-rebase' '\n> +test_expect_success 'git pull -q' '\n>         mkdir clonedq &&\n>         (cd clonedq && git init &&\n> -       git pull -q --no-rebase \"../parent\" >out 2>err &&\n> +       git pull -q \"../parent\" >out 2>err &&\n>         test_must_be_empty err &&\n>         test_must_be_empty out)\n>  '\n> @@ -30,10 +30,10 @@ test_expect_success 'git pull -q --rebase' '\n>         test_must_be_empty out)\n>  '\n>\n> -test_expect_success 'git pull --no-rebase' '\n> +test_expect_success 'git pull' '\n>         mkdir cloned &&\n>         (cd cloned && git init &&\n> -       git pull --no-rebase \"../parent\" >out 2>err &&\n> +       git pull \"../parent\" >out 2>err &&\n>         test -s err &&\n>         test_must_be_empty out)\n>  '\n> @@ -46,10 +46,10 @@ test_expect_success 'git pull --rebase' '\n>         test_must_be_empty out)\n>  '\n>\n> -test_expect_success 'git pull -v --no-rebase' '\n> +test_expect_success 'git pull -v' '\n>         mkdir clonedv &&\n>         (cd clonedv && git init &&\n> -       git pull -v --no-rebase \"../parent\" >out 2>err &&\n> +       git pull -v \"../parent\" >out 2>err &&\n>         test -s err &&\n>         test_must_be_empty out)\n>  '\n> @@ -62,25 +62,25 @@ test_expect_success 'git pull -v --rebase' '\n>         test_must_be_empty out)\n>  '\n>\n> -test_expect_success 'git pull -v -q --no-rebase' '\n> +test_expect_success 'git pull -v -q' '\n>         mkdir clonedvq &&\n>         (cd clonedvq && git init &&\n> -       git pull -v -q --no-rebase \"../parent\" >out 2>err &&\n> +       git pull -v -q \"../parent\" >out 2>err &&\n>         test_must_be_empty out &&\n>         test_must_be_empty err)\n>  '\n>\n> -test_expect_success 'git pull -q -v --no-rebase' '\n> +test_expect_success 'git pull -q -v' '\n>         mkdir clonedqv &&\n>         (cd clonedqv && git init &&\n> -       git pull -q -v --no-rebase \"../parent\" >out 2>err &&\n> +       git pull -q -v \"../parent\" >out 2>err &&\n>         test_must_be_empty out &&\n>         test -s err)\n>  '\n>  test_expect_success 'git pull --cleanup errors early on invalid argument' '\n>         mkdir clonedcleanup &&\n>         (cd clonedcleanup && git init &&\n> -       test_must_fail git pull --no-rebase --cleanup invalid \"../parent\" >out 2>err &&\n> +       test_must_fail git pull --cleanup invalid \"../parent\" >out 2>err &&\n>         test_must_be_empty out &&\n>         test -s err)\n>  '\n> --\n> 2.29.2\n>\n"},{"id":"411434","messageId":"CAMP44s1eTc4+tbULbyz5ENgbcN4tOVBA3Z-4GS4yMpciUD_1Hw@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BFdjj=+4jk0vo=kpNc6ug1=UgtKfXJZkseyyxut2VB=Uw@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T00:12:47Z","receivedAt":"2020-12-05T00:13:57Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 4, 2020 at 5:00 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> >\n> > We want to:\n> >\n> > 1. Be clear about what \"specifying\" means; merge or rebase.\n> > 2. Mention a direct shortcut for people that just want to get on with\n> >    their lives: git pull --no-rebase.\n>\n> This is a shortcut for what?\n\n  git config --global pull.rebase false\n  git pull\n\nIt's a shorter way of saying: \"do a 'git pull' like you've always done\nbut don't warn me\".\n\n> > 3. Have a quick reference for users to understand what this\n> >    \"fast-forward\" business means.\n> >\n> > This patch does all three.\n> >\n> > Thanks to the previous patch now \"git pull --help\" explains what a\n> > fast-forward is, and a further patch changes --no-rebase to --merge so\n> > it's actually user friendly.\n> >\n> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> > ---\n> >  builtin/pull.c | 23 ++++++++++++-----------\n> >  1 file changed, 12 insertions(+), 11 deletions(-)\n> >\n> > diff --git a/builtin/pull.c b/builtin/pull.c\n> > index 1034372f8b..22a9ffcade 100644\n> > --- a/builtin/pull.c\n> > +++ b/builtin/pull.c\n> > @@ -346,17 +346,18 @@ static enum rebase_type config_get_rebase(void)\n> >\n> >         if (opt_verbosity >= 0 && !opt_ff) {\n> >                 advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n> > -                        \"discouraged. You can squelch this message by running one of the following\\n\"\n> > -                        \"commands sometime before your next pull:\\n\"\n> > -                        \"\\n\"\n> > -                        \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> > -                        \"  git config pull.rebase true   # rebase\\n\"\n> > -                        \"  git config pull.ff only       # fast-forward only\\n\"\n> > -                        \"\\n\"\n> > -                        \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> > -                        \"preference for all repositories. You can also pass --rebase, --no-rebase,\\n\"\n> > -                        \"or --ff-only on the command line to override the configured default per\\n\"\n> > -                        \"invocation.\\n\"));\n> > +                       \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n>\n> ...want a merge, a rebase, or neither.\n\nThere is no \"git pull --no-merge\". Years ago some people argued for a\n\"pull.mode=none\" (essentially making \"git pull\" the same as \"git\nfetch\"). But right now there's no option to do that.\n\nThere's an option to do --ff-only, but that's still a merge.\n\nPerhaps: a merge, a rebase, or a fast-forward?\n\n> > +                       \"You can squelch this message by running one of the following commands:\\n\"\n> > +                       \"\\n\"\n> > +                       \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n>\n> Should this be labelled as the default given the desire to make\n> --ff-only the default?  Perhaps I'm jumping ahead and you plan to\n> change that later in this series.\n\nThat's right.\n\nIn the previous series which does indeed make \"pull.mode=ff-only\" the\ndefault [1], I do change the warning to specify the future default\n[2], but in that series the warnings is changed to:\n\n  The pull was not fast-forward, in the future you will have to choose\na merge, or a rebase.\n  To squelch this message and maintain the current behavior, use:\n\n    git config --global pull.mode merge\n\n  To squelch this message and adopt the new behavior now, use:\n\n    git config --global push.mode ff-only\n\n  Falling back to old style for now (merge).\n  Read \"git pull --help\" for more information.\n\nSince that series didn't get any traction, I decided to only implement\nstep 1: fix the current situation. And later on another series would\ndo step 2: introduce \"pull.mode=ff-only\" and do the preparations to\nmake it the default.\n\n> > +                       \"  git config pull.rebase true   # rebase\\n\"\n> > +                       \"  git config pull.ff only       # fast-forward only\\n\"\n> > +                       \"\\n\"\n> > +                       \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> > +                       \"preference for all repositories.\\n\"\n>\n> Good up to here.\n>\n> > +                       \"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n>\n> Why is that safe to suggest?  The original text may not have been the\n> easiest to parse, but this seems more problematic to me.\n\nBecause \"git pull\" has been doing the same as \"git pull --no-rebase\"\nfor more than a decade. It's safe for people to continue with this\nbehavior for a few more months.\n\nSome people need to get things done today, and they are not interested\nin future changes, nor changing their default configuration, or what\nthe warning has to say.\n\nThey just want \"git pull\" to do the same as yesterday, and the year\nbefore, without being bothered with an annoying warning.\n\nThose people can start training their fingers to do \"git pull\n--merge\", and learn the problems with \"git pull\" later.\n\nWe want to respect the user's time, and not force them to read the\nwarning today.\n\n> > +                       \"Read \\\"git pull --help\\\" for more information.\"\n>\n> Nice addition.\n\nEspecially since now it explains what a fast-forward is.\n\n-- \nFelipe Contreras\n"},{"id":"411435","messageId":"CAMP44s0D42s=q8TJqxwswOHb4PO-NW6SEUt-LwfvqiGgvkre9A@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BHjzzhqQW8YY5podav+TU8Eixhp7g-VrQ-tva-0ztAtvA@mail.gmail.com","subject":"Re: [PATCH v2 04/14] pull: cleanup autostash check","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T00:47:22Z","receivedAt":"2020-12-05T00:48:45Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 4, 2020 at 5:07 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> >\n> > This essentially reverts commit f15e7cf5cc.\n> >\n> > Once commit d9f15d37f1 introduced the autostash option for the merge\n> > mode, it's not necessary to skip the fast-forward run_merge() when\n> > autostash is set.\n>\n> It helps reviewers and future code readers if you provide a little\n> context when referring to commits, making use of git log's\n> --pretty=reference option to get the output.\n\nYes, I actually have this alias:\n\n  short = show --quiet --format='%C(auto)%h (%s)%C(reset)'\n\nWhich shows almost the same thing. I've updated it to\n--format=reference. Thanks for the suggestion.\n\nAnd I usually add those descriptions.\n\n> So, for example, here\n> your commit would read:\n>\n> \"\"\"\n> This essentially reverts commit f15e7cf5cc (pull: ff --rebase\n> --autostash works in dirty repo, 2017-06-01).\n>\n> Once commit d9f15d37f1 (pull: pass --autostash to merge, 2020-04-07)\n> introduced the autostash option for the merge\n> mode, it's not necessary to skip the fast-forward run_merge() when\n> autostash is set.\n> \"\"\"\n>\n> I still found it slightly hard to follow the explanation even with the\n> added summaries, though.\n\nAnd that's the reason I didn't add them. You need to look at both the\ncommits to understand why one cancels the other. In my opinion in this\nparticular case the description only makes the text harder to read.\n\nProbably some better $subjects like f15e7cf5cc (pull: skip ff merge\nshortcut on --rebase --autostash) would have helped.\n\n> An extra sentence at the end of the second\n> paragraph to make it clear what is being changed (\"So, change the code\n> to fast-forward even when autostash is set.\") seems to help.\n\nOK. That's implied by \"it's not necessary to skip the fast-forward\"\nbut it's better to be explicit.\n\nHow about this:\n\nCurrently \"git pull --rebase\" takes a shortcut in the case a\nfast-forward merge is possible; run_merge() is called with --ff-only.\n\nHowever, \"git merge\" didn't have an --autostash option, so, when \"git\npull --rebase --autostash\" was called *and* the fast-forward merge\nshortcut was taken, then the pull failed.\n\nThis was fixed in commit f15e7cf5cc (pull: ff --rebase --autostash\nworks in dirty repo, 2017-06-01) by simply skipping the fast-forward\nmerge shortcut.\n\nLater on \"git merge\" learned the --autostash option [a03b55530a\n(merge: teach --autostash option, 2020-04-07)], and so did \"git pull\"\n[d9f15d37f1 (pull: pass --autostash to merge, 2020-04-07)].\n\nTherefore it's not necessary to skip the fast-forward merge shortcut\nanymore when called with --rebase --autostash.\n\nLet's always take the fast-forward merge shortcut by essentially\nreverting f15e7cf5cc.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"411436","messageId":"CAMP44s3rtFWqaZz3Mg1yGuk+PwQeLJg0=TeLWbi6LDpSB9Rp4Q@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BHs-eaJcTMcOPEsDx7PbBfoM0Uf7-vWi33OVOcTEgAgmg@mail.gmail.com","subject":"Re: [PATCH v2 05/14] pull: trivial cleanup","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T00:48:53Z","receivedAt":"2020-12-05T00:50:49Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 4, 2020 at 5:09 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> >\n> > There's no need to store ran_ff. Now it's obvious from the conditionals.\n> >\n> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> > ---\n> >  builtin/pull.c | 7 +++----\n> >  1 file changed, 3 insertions(+), 4 deletions(-)\n> >\n> > diff --git a/builtin/pull.c b/builtin/pull.c\n> > index c38548dab8..8daba7539c 100644\n> > --- a/builtin/pull.c\n> > +++ b/builtin/pull.c\n> > @@ -1024,19 +1024,18 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n> >\n> >         if (opt_rebase) {\n> >                 int ret = 0;\n> > -               int ran_ff = 0;\n> >                 if ((recurse_submodules == RECURSE_SUBMODULES_ON ||\n> >                      recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&\n> >                     submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))\n> >                         die(_(\"cannot rebase with locally recorded submodule modifications\"));\n> > +\n> spurious change?\n>\n> (It does make it look nicer, though.)\n\nNope. Was intentional.\n\n> >                 if (get_can_ff(&orig_head, &merge_heads.oid[0])) {\n> >                         /* we can fast-forward this without invoking rebase */\n> >                         opt_ff = \"--ff-only\";\n> > -                       ran_ff = 1;\n> >                         ret = run_merge();\n> > -               }\n> > -               if (!ran_ff)\n> > +               } else {\n> >                         ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n> > +               }\n> >\n> >                 if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||\n> >                              recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))\n> > --\n> > 2.29.2\n>\n> Yeah, reads better to me after this cleanup.\n\n-- \nFelipe Contreras\n"},{"id":"411437","messageId":"CABPp-BFwWBLdFPsKi3o9hznFtAeWWfhNAyuymPS4BhMAHpnSfw@mail.gmail.com","threadId":"54758","inReplyTo":"CAMP44s1eTc4+tbULbyz5ENgbcN4tOVBA3Z-4GS4yMpciUD_1Hw@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-05T00:56:14Z","receivedAt":"2020-12-05T00:57:08Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"Hi Felipe,\n\nOn Fri, Dec 4, 2020 at 4:12 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> On Fri, Dec 4, 2020 at 5:00 PM Elijah Newren <newren@gmail.com> wrote:\n> >\n> > On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> > <felipe.contreras@gmail.com> wrote:\n> > >\n> > > We want to:\n> > >\n> > > 1. Be clear about what \"specifying\" means; merge or rebase.\n> > > 2. Mention a direct shortcut for people that just want to get on with\n> > >    their lives: git pull --no-rebase.\n> >\n> > This is a shortcut for what?\n>\n>   git config --global pull.rebase false\n>   git pull\n>\n> It's a shorter way of saying: \"do a 'git pull' like you've always done\n> but don't warn me\".\n>\n> > > 3. Have a quick reference for users to understand what this\n> > >    \"fast-forward\" business means.\n> > >\n> > > This patch does all three.\n> > >\n> > > Thanks to the previous patch now \"git pull --help\" explains what a\n> > > fast-forward is, and a further patch changes --no-rebase to --merge so\n> > > it's actually user friendly.\n> > >\n> > > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> > > ---\n> > >  builtin/pull.c | 23 ++++++++++++-----------\n> > >  1 file changed, 12 insertions(+), 11 deletions(-)\n> > >\n> > > diff --git a/builtin/pull.c b/builtin/pull.c\n> > > index 1034372f8b..22a9ffcade 100644\n> > > --- a/builtin/pull.c\n> > > +++ b/builtin/pull.c\n> > > @@ -346,17 +346,18 @@ static enum rebase_type config_get_rebase(void)\n> > >\n> > >         if (opt_verbosity >= 0 && !opt_ff) {\n> > >                 advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n> > > -                        \"discouraged. You can squelch this message by running one of the following\\n\"\n> > > -                        \"commands sometime before your next pull:\\n\"\n> > > -                        \"\\n\"\n> > > -                        \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> > > -                        \"  git config pull.rebase true   # rebase\\n\"\n> > > -                        \"  git config pull.ff only       # fast-forward only\\n\"\n> > > -                        \"\\n\"\n> > > -                        \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> > > -                        \"preference for all repositories. You can also pass --rebase, --no-rebase,\\n\"\n> > > -                        \"or --ff-only on the command line to override the configured default per\\n\"\n> > > -                        \"invocation.\\n\"));\n> > > +                       \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n> >\n> > ...want a merge, a rebase, or neither.\n>\n> There is no \"git pull --no-merge\". Years ago some people argued for a\n> \"pull.mode=none\" (essentially making \"git pull\" the same as \"git\n> fetch\"). But right now there's no option to do that.\n>\n> There's an option to do --ff-only, but that's still a merge.\n\nI disagree.  I'm well aware that checkout_fast_forward() (which is\nwhat is ultimately called to do the fast-forwarding) is in a file\ncalled merge.c, but that doesn't make it a merge.  I don't believe it\nwas anything more than a convenient place to dump some extra code at\nthe time.\n\n> Perhaps: a merge, a rebase, or a fast-forward?\n\nSure, that works; in fact, that's much better than my suggestion.  I like it.\n\n> > > +                       \"You can squelch this message by running one of the following commands:\\n\"\n> > > +                       \"\\n\"\n> > > +                       \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> >\n> > Should this be labelled as the default given the desire to make\n> > --ff-only the default?  Perhaps I'm jumping ahead and you plan to\n> > change that later in this series.\n>\n> That's right.\n>\n> In the previous series which does indeed make \"pull.mode=ff-only\" the\n> default [1], I do change the warning to specify the future default\n> [2], but in that series the warnings is changed to:\n>\n>   The pull was not fast-forward, in the future you will have to choose\n> a merge, or a rebase.\n>   To squelch this message and maintain the current behavior, use:\n>\n>     git config --global pull.mode merge\n>\n>   To squelch this message and adopt the new behavior now, use:\n>\n>     git config --global push.mode ff-only\n>\n>   Falling back to old style for now (merge).\n>   Read \"git pull --help\" for more information.\n>\n> Since that series didn't get any traction, I decided to only implement\n> step 1: fix the current situation. And later on another series would\n> do step 2: introduce \"pull.mode=ff-only\" and do the preparations to\n> make it the default.\n\nI like this longer plan.  However, on the shorter scale plan...I think\nthe suggestion to use \"git pull --no-rebase\" makes the current\nsituation worse rather than fixing it.\n\n> > > +                       \"  git config pull.rebase true   # rebase\\n\"\n> > > +                       \"  git config pull.ff only       # fast-forward only\\n\"\n> > > +                       \"\\n\"\n> > > +                       \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> > > +                       \"preference for all repositories.\\n\"\n> >\n> > Good up to here.\n> >\n> > > +                       \"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n> >\n> > Why is that safe to suggest?  The original text may not have been the\n> > easiest to parse, but this seems more problematic to me.\n>\n> Because \"git pull\" has been doing the same as \"git pull --no-rebase\"\n> for more than a decade. It's safe for people to continue with this\n> behavior for a few more months.\n>\n> Some people need to get things done today, and they are not interested\n> in future changes, nor changing their default configuration, or what\n> the warning has to say.\n>\n> They just want \"git pull\" to do the same as yesterday, and the year\n> before, without being bothered with an annoying warning.\n>\n> Those people can start training their fingers to do \"git pull\n> --merge\", and learn the problems with \"git pull\" later.\n>\n> We want to respect the user's time, and not force them to read the\n> warning today.\n\nThe warning was added because sending users down paths that break\nthings badly is a waste of user's time, and often a much bigger waste\nof user's time than making them read up on the meaning behind the two\ndifferent choices of what kind of changes they can make.  I agree the\nwarning went too far, but I fully agree with the original folks who\nput this warning here that we need to have it for at least some cases\nand that there is a decision to be made.  Though I am just one voice,\nand perhaps others will agree with you on your point here, I'll\ncontinue to disagree with blindly suggesting \"git pull --no-rebase\".\n\n> > > +                       \"Read \\\"git pull --help\\\" for more information.\"\n> >\n> > Nice addition.\n>\n> Especially since now it explains what a fast-forward is.\n\nIndeed.  :-)\n"},{"id":"411438","messageId":"CABPp-BEsQWsHMAmwc3gmJnXcS+aR-FtoMJxBRQ=BpARP49-L-Q@mail.gmail.com","threadId":"54758","inReplyTo":"CAMP44s0D42s=q8TJqxwswOHb4PO-NW6SEUt-LwfvqiGgvkre9A@mail.gmail.com","subject":"Re: [PATCH v2 04/14] pull: cleanup autostash check","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-05T00:57:59Z","receivedAt":"2020-12-05T00:59:15Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Dec 4, 2020 at 4:47 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> On Fri, Dec 4, 2020 at 5:07 PM Elijah Newren <newren@gmail.com> wrote:\n> >\n> > On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> > <felipe.contreras@gmail.com> wrote:\n> > >\n> > > This essentially reverts commit f15e7cf5cc.\n> > >\n> > > Once commit d9f15d37f1 introduced the autostash option for the merge\n> > > mode, it's not necessary to skip the fast-forward run_merge() when\n> > > autostash is set.\n> >\n> > It helps reviewers and future code readers if you provide a little\n> > context when referring to commits, making use of git log's\n> > --pretty=reference option to get the output.\n>\n> Yes, I actually have this alias:\n>\n>   short = show --quiet --format='%C(auto)%h (%s)%C(reset)'\n>\n> Which shows almost the same thing. I've updated it to\n> --format=reference. Thanks for the suggestion.\n>\n> And I usually add those descriptions.\n>\n> > So, for example, here\n> > your commit would read:\n> >\n> > \"\"\"\n> > This essentially reverts commit f15e7cf5cc (pull: ff --rebase\n> > --autostash works in dirty repo, 2017-06-01).\n> >\n> > Once commit d9f15d37f1 (pull: pass --autostash to merge, 2020-04-07)\n> > introduced the autostash option for the merge\n> > mode, it's not necessary to skip the fast-forward run_merge() when\n> > autostash is set.\n> > \"\"\"\n> >\n> > I still found it slightly hard to follow the explanation even with the\n> > added summaries, though.\n>\n> And that's the reason I didn't add them. You need to look at both the\n> commits to understand why one cancels the other. In my opinion in this\n> particular case the description only makes the text harder to read.\n>\n> Probably some better $subjects like f15e7cf5cc (pull: skip ff merge\n> shortcut on --rebase --autostash) would have helped.\n>\n> > An extra sentence at the end of the second\n> > paragraph to make it clear what is being changed (\"So, change the code\n> > to fast-forward even when autostash is set.\") seems to help.\n>\n> OK. That's implied by \"it's not necessary to skip the fast-forward\"\n> but it's better to be explicit.\n>\n> How about this:\n>\n> Currently \"git pull --rebase\" takes a shortcut in the case a\n> fast-forward merge is possible; run_merge() is called with --ff-only.\n>\n> However, \"git merge\" didn't have an --autostash option, so, when \"git\n> pull --rebase --autostash\" was called *and* the fast-forward merge\n> shortcut was taken, then the pull failed.\n>\n> This was fixed in commit f15e7cf5cc (pull: ff --rebase --autostash\n> works in dirty repo, 2017-06-01) by simply skipping the fast-forward\n> merge shortcut.\n>\n> Later on \"git merge\" learned the --autostash option [a03b55530a\n> (merge: teach --autostash option, 2020-04-07)], and so did \"git pull\"\n> [d9f15d37f1 (pull: pass --autostash to merge, 2020-04-07)].\n>\n> Therefore it's not necessary to skip the fast-forward merge shortcut\n> anymore when called with --rebase --autostash.\n>\n> Let's always take the fast-forward merge shortcut by essentially\n> reverting f15e7cf5cc.\n\nYes, very nice!  Thanks.\n\nElijah\n"},{"id":"411439","messageId":"CAMP44s1KtTP20bVimXkY7b_obGFD6E2ObuQEeYWEuRBDyWH18g@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BEdgwcueYC1OWd3LtJaGPLgLcdkezGEqeKo7mVfx=C6Jg@mail.gmail.com","subject":"Re: [PATCH v2 07/14] pull: display default warning only when non-ff","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T01:03:25Z","receivedAt":"2020-12-05T01:04:34Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 4, 2020 at 5:24 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> >\n> > There's no need to display the annoying warning on every pull... only\n> > the ones that are not fast-forward.\n>\n> I like this.  :-)\n>\n> > This requires the tests to pick another base, so the merge is not\n> > fast-forward.\n> >\n> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> > ---\n> >  Documentation/git-pull.txt   |  3 +++\n> >  builtin/pull.c               |  2 +-\n> >  t/t7601-merge-pull-config.sh | 28 +++++++++++++++++-----------\n> >  3 files changed, 21 insertions(+), 12 deletions(-)\n> >\n> > diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\n> > index dc812139f4..ad33d2472c 100644\n> > --- a/Documentation/git-pull.txt\n> > +++ b/Documentation/git-pull.txt\n> > @@ -60,6 +60,9 @@ However, a non-fast-foward case looks very different.\n> >         origin/master in your repository\n> >  ------------\n> >\n> > +By default `git pull` will warn about these situations, however, most likely\n> > +you would want to force a merge, which you can do with `git pull --no-rebase`.\n> > +\n>\n> Everything in this sentence after the first comma seems dangerous to\n> me for a number of workflows.\n\nAnd this is precisely the reason why the default of \"git pull\" must be\nchanged to --ff-only (or similar).\n\nBut today \"git pull\" by default is the equivalent of \"git pull\n--merge\". We need to explain to users why the warning is there, and\nthat \"git pull\" is doing an implicit \"git pull --merge\", and if they\ndo it explicitly they can get rid of the warning.\n\nLater on when the default is changed to --ff-only this text can be\nupdated to something less dangerous.\n\nBut not explaining what \"git pull\" is doing today by default will not\nmake it any less dangerous.\n\n> >  Then \"`git pull`\" will fetch and replay the changes from the remote\n> >  `master` branch since it diverged from the local `master` (i.e., `E`)\n> >  until its current commit (`C`) on top of `master` and record the\n> > diff --git a/builtin/pull.c b/builtin/pull.c\n> > index f82e214fc8..f0b1c6bfea 100644\n> > --- a/builtin/pull.c\n> > +++ b/builtin/pull.c\n> > @@ -1013,7 +1013,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n> >\n> >         can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);\n> >\n> > -       if (default_mode && opt_verbosity >= 0 && !opt_ff) {\n> > +       if (default_mode && !can_ff && opt_verbosity >= 0 && !opt_ff) {\n> >                 advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n> >                         \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n> >                         \"You can squelch this message by running one of the following commands:\\n\"\n> > diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh\n> > index 6774e9d86f..6b4adab8b1 100755\n> > --- a/t/t7601-merge-pull-config.sh\n> > +++ b/t/t7601-merge-pull-config.sh\n> > @@ -28,7 +28,7 @@ test_expect_success 'setup' '\n> >  '\n> >\n> >  test_expect_success 'pull.rebase not set' '\n> > -       git reset --hard c0 &&\n> > +       git reset --hard c2 &&\n> >         git -c color.advice=always pull . c1 2>err &&\n> >         test_decode_color <err >decoded &&\n> >         test_i18ngrep \"<YELLOW>hint: \" decoded &&\n> > @@ -36,54 +36,60 @@ test_expect_success 'pull.rebase not set' '\n> >\n> >  '\n> >\n> > -test_expect_success 'pull.rebase not set and pull.ff=true' '\n> > +test_expect_success 'pull.rebase not set (fast-forward)' '\n> >         git reset --hard c0 &&\n> > +       git pull . c1 2>err &&\n> > +       test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n> > +'\n> > +\n> > +test_expect_success 'pull.rebase not set and pull.ff=true' '\n> > +       git reset --hard c2 &&\n> >         test_config pull.ff true &&\n> >         git pull . c1 2>err &&\n> >         test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n> >  '\n> >\n> >  test_expect_success 'pull.rebase not set and pull.ff=false' '\n> > -       git reset --hard c0 &&\n> > +       git reset --hard c2 &&\n> >         test_config pull.ff false &&\n> >         git pull . c1 2>err &&\n> >         test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n> >  '\n> >\n> >  test_expect_success 'pull.rebase not set and pull.ff=only' '\n> > -       git reset --hard c0 &&\n> > +       git reset --hard c2 &&\n> >         test_config pull.ff only &&\n> > -       git pull . c1 2>err &&\n> > +       test_must_fail git pull . c1 2>err &&\n>\n> It makes sense to me that you'd need test_must_fail here...but why\n> wasn't it needed before??  How did this test pass without it before\n> this series?\n\nBecause before it was a fast-forward (from c0), not so anymore (from\nc2); \"pull.ff=only\" fails if it's not a fast-forward.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"411440","messageId":"CAMP44s3rPy0N5s6KiegmuKvyvveDgrBxv6w+Qp3OXVm5QzNaKg@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BGndfbF=QcCox13kik4B9F7Bgn7k2ToFRkGsh0dJ4K0HA@mail.gmail.com","subject":"Re: [PATCH v2 09/14] pull: introduce --merge option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T01:06:17Z","receivedAt":"2020-12-05T01:07:16Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 4, 2020 at 5:27 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> >\n> > Previously --no-rebase (which still works for backwards compatbility).\n> >\n> > Now we can update the default warning, and the git-pull(1) man page to\n> > use --merge instead of the non-intuitive --no-rebase.\n> >\n> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> > ---\n> >  Documentation/git-pull.txt   | 9 ++++++---\n> >  builtin/pull.c               | 4 +++-\n> >  t/t7601-merge-pull-config.sh | 4 ++--\n> >  3 files changed, 11 insertions(+), 6 deletions(-)\n> >\n> > diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\n> > index ad33d2472c..c220da143a 100644\n> > --- a/Documentation/git-pull.txt\n> > +++ b/Documentation/git-pull.txt\n> > @@ -61,7 +61,7 @@ However, a non-fast-foward case looks very different.\n> >  ------------\n> >\n> >  By default `git pull` will warn about these situations, however, most likely\n> > -you would want to force a merge, which you can do with `git pull --no-rebase`.\n> > +you would want to force a merge, which you can do with `git pull --merge`.\n>\n> I'm glad you updated all the references, but as noted earlier in the\n> series I think this suggestion is problematic.\n\nYeah, but the danger comes straight from what \"git pull\" does by\ndefault (an implicit \"git pull --merge\").\n\nIt's not the text that is dangerous; it's the default behavior.\n\n-- \nFelipe Contreras\n"},{"id":"411441","messageId":"CAMP44s34qZcHPfjgD-eu2onWQCEoH_s5oUCZSeqy0qjijYub1A@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BGftkZqJ1GuB-7-7PCo3zOYn_Rr1yu4wv6hwtDea5_oYw@mail.gmail.com","subject":"Re: [PATCH v2 10/14] pull: add proper error with --ff-only","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T01:18:55Z","receivedAt":"2020-12-05T01:19:55Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 4, 2020 at 5:34 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> >\n> > The current error is not user-friendly:\n> >\n> >   fatal: not possible to fast-forward, aborting.\n> >\n> > We want something that actually explains what is going on:\n> >\n> >   The pull was not fast-forward, please either merge or rebase.\n> >   If unsure, run \"git pull --merge\".\n>\n> Sorry to be a broken record, but I don't like the suggestion in the\n> second sentence.  I've said it enough times that I'll quit harping on\n> each instance.\n\nIn this particular case it does make sense to remove the suggestion,\nsince it has nothing to do with the current \"git pull\" default.\n\nThe user must decide in this case.\n\n> > The user can get rid of the warning by doing either --merge or\n> > --rebase.\n> >\n> > Except: doing \"git pull --merge\" is not actually enough; we would return\n> > to the previous behavior: \"fatal: not possible to fast-forward, aborting.\"\n>\n> Do you mean that the changes in this patch aren't enough and that\n> future patches will address this shortcoming?  Or do you mean that\n> prior to this patch such a bug existed?  Or something else?\n\nI mean this is the shortcoming of using the --ff-only approach, and\nwhy I think a \"pull.mode=ff-only\" must be introduced.\n\nThis patch does as much as it can without changing the semantics of\n--ff-only, and it shows the limitations of the approach, as you can\nsee from the failed test below, and the next patch.\n\nIt's inherent to the current behavior of --ff-only.\n\n> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> > ---\n> >  builtin/pull.c  | 34 ++++++++++++++++-----------\n> >  t/t5520-pull.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++\n> >  2 files changed, 82 insertions(+), 14 deletions(-)\n> >\n> > diff --git a/builtin/pull.c b/builtin/pull.c\n> > index 6ea95c9fc9..f54ff36b57 100644\n> > --- a/builtin/pull.c\n> > +++ b/builtin/pull.c\n> > @@ -1015,20 +1015,26 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n> >\n> >         can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);\n> >\n> > -       if (default_mode && !can_ff && opt_verbosity >= 0 && !opt_ff) {\n> > -               advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n> > -                       \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n> > -                       \"You can squelch this message by running one of the following commands:\\n\"\n> > -                       \"\\n\"\n> > -                       \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> > -                       \"  git config pull.rebase true   # rebase\\n\"\n> > -                       \"  git config pull.ff only       # fast-forward only\\n\"\n> > -                       \"\\n\"\n> > -                       \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> > -                       \"preference for all repositories.\\n\"\n> > -                       \"If unsure, run \\\"git pull --merge\\\".\\n\"\n> > -                       \"Read \\\"git pull --help\\\" for more information.\"\n> > -                       ));\n> > +       if (!can_ff && default_mode) {\n> > +               if (opt_ff && !strcmp(opt_ff, \"--ff-only\")) {\n> > +                       die(_(\"The pull was not fast-forward, please either merge or rebase.\\n\"\n> > +                               \"If unsure, run \\\"git pull --merge\\\".\"));\n>\n> This is a much better message for when the user requests --ff-only.\n\nRight. Sans the \"git pull --merge\" comment :p\n\n> > +               }\n> > +               if (opt_verbosity >= 0 && !opt_ff) {\n> > +                       advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n> > +                               \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n> > +                               \"You can squelch this message by running one of the following commands:\\n\"\n> > +                               \"\\n\"\n> > +                               \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> > +                               \"  git config pull.rebase true   # rebase\\n\"\n> > +                               \"  git config pull.ff only       # fast-forward only\\n\"\n> > +                               \"\\n\"\n> > +                               \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> > +                               \"preference for all repositories.\\n\"\n> > +                               \"If unsure, run \\\"git pull --merge\\\".\\n\"\n> > +                               \"Read \\\"git pull --help\\\" for more information.\"\n> > +                               ));\n> > +               }\n> >         }\n> >\n> >         if (opt_rebase) {\n> > diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\n> > index 9fae07cdfa..fdd1f79b06 100755\n> > --- a/t/t5520-pull.sh\n> > +++ b/t/t5520-pull.sh\n> > @@ -819,4 +819,66 @@ test_expect_success 'git pull --rebase against local branch' '\n> >         test_cmp expect file2\n> >  '\n> >\n> > +test_expect_success 'git pull fast-forward (ff-only)' '\n> > +       test_when_finished \"git checkout master && git branch -D other test\" &&\n> > +       test_config pull.ff only &&\n> > +       git checkout -b other master &&\n> > +       >new &&\n> > +       git add new &&\n> > +       git commit -m new &&\n> > +       git checkout -b test -t other &&\n> > +       git reset --hard master &&\n> > +       git pull\n> > +'\n> > +\n> > +test_expect_success 'git pull non-fast-forward (ff-only)' '\n> > +       test_when_finished \"git checkout master && git branch -D other test\" &&\n> > +       test_config pull.ff only &&\n> > +       git checkout -b other master^ &&\n> > +       >new &&\n> > +       git add new &&\n> > +       git commit -m new &&\n> > +       git checkout -b test -t other &&\n> > +       git reset --hard master &&\n> > +       test_must_fail git pull\n> > +'\n> > +\n> > +test_expect_failure 'git pull non-fast-forward with merge (ff-only)' '\n> > +       test_when_finished \"git checkout master && git branch -D other test\" &&\n> > +       test_config pull.ff only &&\n> > +       git checkout -b other master^ &&\n> > +       >new &&\n> > +       git add new &&\n> > +       git commit -m new &&\n> > +       git checkout -b test -t other &&\n> > +       git reset --hard master &&\n> > +       git pull --no-rebase\n>\n> Do you mean `git pull --merge`?\n\nYes. You found all the issues I spotted in my last review after I sent\nthe patches.\n\nGood eyes.\n\nAlready fixed.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"411442","messageId":"CA+P7+xo+op4F+hbeDM8NG4jSGL=4UiCwxkxG2E8BSdfDh1LGZw@mail.gmail.com","threadId":"54758","inReplyTo":"20201204061623.1170745-2-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 01/14] doc: pull: explain what is a fast-forward","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2020-12-05T01:21:24Z","receivedAt":"2020-12-05T01:22:31Z","isPatch":true,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> We want users to know what is a fast-forward in order to understand the\n> default warning.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  Documentation/git-pull.txt | 14 ++++++++++++++\n>  1 file changed, 14 insertions(+)\n>\n> diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\n> index 5c3fb67c01..dc812139f4 100644\n> --- a/Documentation/git-pull.txt\n> +++ b/Documentation/git-pull.txt\n> @@ -38,6 +38,20 @@ as set by linkgit:git-branch[1] `--track`.\n>  Assume the following history exists and the current branch is\n>  \"`master`\":\n>\n> +------------\n> +         A---B---C master on origin\n> +        /\n> +    D---E master\n> +------------\n> +\n\nWhen displayed in a regular font, this looks like it is pointing at D,\nbut I checked the text using a proper monospaced font (on lore) and it\nis correctly pointing at E.\n\nMakes sense.\n\n> +Then `git pull` will merge in a fast-foward way up to the new master.\n> +\n> +------------\n> +    D---E---A---B---C master, origin/master\n> +------------\n> +\n> +However, a non-fast-foward case looks very different.\n> +\n>  ------------\n>           A---B---C master on origin\n>          /\n> --\n> 2.29.2\n>\n"},{"id":"411443","messageId":"CAMP44s2dRQRZDOooDKQSyEobaDD_z7Q0zmqmVMYSK5G7t0p5SQ@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BE5zvCAmfHE_1_D3boMg5rMcU0iyJJp+yiLwSu2DsySLg@mail.gmail.com","subject":"Re: [PATCH v2 12/14] pull: show warning with --ff","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T01:25:54Z","receivedAt":"2020-12-05T01:26:48Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 4, 2020 at 5:41 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> >\n> > It's unclear why --ff should remove the warning, since:\n> >\n> >   git pull --ff\n> >\n> > Is implicitly the same as:\n> >\n> >   git pull\n> >\n> > Unless of course pull.ff is specified otherwise.\n> >\n> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> > ---\n> >  builtin/pull.c               | 2 +-\n> >  t/t7601-merge-pull-config.sh | 4 ++--\n> >  2 files changed, 3 insertions(+), 3 deletions(-)\n> >\n> > diff --git a/builtin/pull.c b/builtin/pull.c\n> > index ebf2ac687b..e389ffcdc3 100644\n> > --- a/builtin/pull.c\n> > +++ b/builtin/pull.c\n> > @@ -1020,7 +1020,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n> >                         die(_(\"The pull was not fast-forward, please either merge or rebase.\\n\"\n> >                                 \"If unsure, run \\\"git pull --merge\\\".\"));\n> >                 }\n> > -               if (opt_verbosity >= 0 && !opt_ff) {\n> > +               if (opt_verbosity >= 0 && (!opt_ff || !strcmp(opt_ff, \"--ff\"))) {\n> >                         advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n> >                                 \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n> >                                 \"You can squelch this message by running one of the following commands:\\n\"\n> > diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh\n> > index 1de64e6cc5..d709799f8b 100755\n> > --- a/t/t7601-merge-pull-config.sh\n> > +++ b/t/t7601-merge-pull-config.sh\n> > @@ -46,7 +46,7 @@ test_expect_success 'pull.rebase not set and pull.ff=true' '\n> >         git reset --hard c2 &&\n> >         test_config pull.ff true &&\n> >         git pull . c1 2>err &&\n> > -       test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n> > +       test_i18ngrep \"Pulling without specifying how to reconcile\" err\n> >  '\n> >\n> >  test_expect_success 'pull.rebase not set and pull.ff=false' '\n> > @@ -78,7 +78,7 @@ test_expect_success 'pull.rebase not set and --merge given' '\n> >  test_expect_success 'pull.rebase not set and --ff given' '\n> >         git reset --hard c2 &&\n> >         git pull --ff . c1 2>err &&\n> > -       test_i18ngrep ! \"Pulling without specifying how to reconcile\" err\n> > +       test_i18ngrep \"Pulling without specifying how to reconcile\" err\n> >  '\n> >\n> >  test_expect_success 'pull.rebase not set and --no-ff given' '\n> > --\n> > 2.29.2\n>\n> Ah, this answers one of my earlier questions.  I'd be tempted to move\n> this earlier in the series; it seems like an obvious cleanup and helps\n> explain the \"opt_ff\" flag that keeps coming up for readers of the\n> series.\n\nI tend to put more controversial and less useful patches later in the\nseries, and this is the one I was least sure of getting consensus nor\ndoes it solve any current issues.\n\nI just found it inconsistent.\n\n-- \nFelipe Contreras\n"},{"id":"411444","messageId":"CAMP44s1-Q=3AN8o03gncQZtExewYqwvKos1o1k1Ap8CcGKn23A@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BEfxvkuVsDR9duwg1QCMxV9O4RqGF_rm2NuiStczggQoA@mail.gmail.com","subject":"Re: [PATCH v2 14/14] test: pull-options: revert unnecessary changes","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T01:28:26Z","receivedAt":"2020-12-05T01:29:35Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 4, 2020 at 5:49 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> >\n> > Commit d18c950a69 changed these tests, but it's unclear why. Probably\n> > because earlier versions of the patch series died instead of printing a\n> > warning.\n>\n> Another case where log --pretty=reference notation would be more\n> helpful in referring to commits.\n>\n> Looking up that commit, I see that commit made a number of other test\n> changes which seem to be better motivated by the commit message and\n> code changes.  I wonder if we could make that clearer in the commit\n> message somehow.  Perhaps\n>\n> Commit d18c950a69 (\"pull: warn if the user didn't say whether to\n> rebase or to merge\", 2020-03-09) changed a number of tests in t5521\n> and added some new tests in t7601, but it is not clear why the changes\n> in t5521 were made...\n\nFine by me.\n\nI had a mind to do some mail archeology and find the likely reason\nmyself, but we all have limited time on this Earth.\n\n-- \nFelipe Contreras\n"},{"id":"411487","messageId":"CAMP44s1=aZL7BMKSjzKJ7qYqg-usScwzRUJmaOhsCGvQ4ieYow@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BFwWBLdFPsKi3o9hznFtAeWWfhNAyuymPS4BhMAHpnSfw@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T01:56:23Z","receivedAt":"2020-12-05T01:57:23Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 4, 2020 at 6:56 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> Hi Felipe,\n>\n> On Fri, Dec 4, 2020 at 4:12 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> >\n> > On Fri, Dec 4, 2020 at 5:00 PM Elijah Newren <newren@gmail.com> wrote:\n> > >\n> > > On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> > > <felipe.contreras@gmail.com> wrote:\n> > > >\n> > > > We want to:\n> > > >\n> > > > 1. Be clear about what \"specifying\" means; merge or rebase.\n> > > > 2. Mention a direct shortcut for people that just want to get on with\n> > > >    their lives: git pull --no-rebase.\n> > >\n> > > This is a shortcut for what?\n> >\n> >   git config --global pull.rebase false\n> >   git pull\n> >\n> > It's a shorter way of saying: \"do a 'git pull' like you've always done\n> > but don't warn me\".\n> >\n> > > > 3. Have a quick reference for users to understand what this\n> > > >    \"fast-forward\" business means.\n> > > >\n> > > > This patch does all three.\n> > > >\n> > > > Thanks to the previous patch now \"git pull --help\" explains what a\n> > > > fast-forward is, and a further patch changes --no-rebase to --merge so\n> > > > it's actually user friendly.\n> > > >\n> > > > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> > > > ---\n> > > >  builtin/pull.c | 23 ++++++++++++-----------\n> > > >  1 file changed, 12 insertions(+), 11 deletions(-)\n> > > >\n> > > > diff --git a/builtin/pull.c b/builtin/pull.c\n> > > > index 1034372f8b..22a9ffcade 100644\n> > > > --- a/builtin/pull.c\n> > > > +++ b/builtin/pull.c\n> > > > @@ -346,17 +346,18 @@ static enum rebase_type config_get_rebase(void)\n> > > >\n> > > >         if (opt_verbosity >= 0 && !opt_ff) {\n> > > >                 advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n> > > > -                        \"discouraged. You can squelch this message by running one of the following\\n\"\n> > > > -                        \"commands sometime before your next pull:\\n\"\n> > > > -                        \"\\n\"\n> > > > -                        \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> > > > -                        \"  git config pull.rebase true   # rebase\\n\"\n> > > > -                        \"  git config pull.ff only       # fast-forward only\\n\"\n> > > > -                        \"\\n\"\n> > > > -                        \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> > > > -                        \"preference for all repositories. You can also pass --rebase, --no-rebase,\\n\"\n> > > > -                        \"or --ff-only on the command line to override the configured default per\\n\"\n> > > > -                        \"invocation.\\n\"));\n> > > > +                       \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n> > >\n> > > ...want a merge, a rebase, or neither.\n> >\n> > There is no \"git pull --no-merge\". Years ago some people argued for a\n> > \"pull.mode=none\" (essentially making \"git pull\" the same as \"git\n> > fetch\"). But right now there's no option to do that.\n> >\n> > There's an option to do --ff-only, but that's still a merge.\n>\n> I disagree.  I'm well aware that checkout_fast_forward() (which is\n> what is ultimately called to do the fast-forwarding) is in a file\n> called merge.c, but that doesn't make it a merge.  I don't believe it\n> was anything more than a convenient place to dump some extra code at\n> the time.\n\nRight. Maybe my mind is tainted by doing so many fast-forward \"git\nmerge\"s to update the current branch.\n\nBut in my mind \"fast-forward\" is not a noun, it's an adjective, so I\nstill expect a noun: fast-forward $what. And I don't have any other\nnoun to put there but \"merge\".\n\n> > Perhaps: a merge, a rebase, or a fast-forward?\n>\n> Sure, that works; in fact, that's much better than my suggestion.  I like it.\n\nGreat.\n\n> > > > +                       \"You can squelch this message by running one of the following commands:\\n\"\n> > > > +                       \"\\n\"\n> > > > +                       \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> > >\n> > > Should this be labelled as the default given the desire to make\n> > > --ff-only the default?  Perhaps I'm jumping ahead and you plan to\n> > > change that later in this series.\n> >\n> > That's right.\n> >\n> > In the previous series which does indeed make \"pull.mode=ff-only\" the\n> > default [1], I do change the warning to specify the future default\n> > [2], but in that series the warnings is changed to:\n> >\n> >   The pull was not fast-forward, in the future you will have to choose\n> > a merge, or a rebase.\n> >   To squelch this message and maintain the current behavior, use:\n> >\n> >     git config --global pull.mode merge\n> >\n> >   To squelch this message and adopt the new behavior now, use:\n> >\n> >     git config --global push.mode ff-only\n> >\n> >   Falling back to old style for now (merge).\n> >   Read \"git pull --help\" for more information.\n> >\n> > Since that series didn't get any traction, I decided to only implement\n> > step 1: fix the current situation. And later on another series would\n> > do step 2: introduce \"pull.mode=ff-only\" and do the preparations to\n> > make it the default.\n>\n> I like this longer plan.\n\nYeah. It's a better plan, just more work for me.\n\n> However, on the shorter scale plan...I think\n> the suggestion to use \"git pull --no-rebase\" makes the current\n> situation worse rather than fixing it.\n\nWell, I already said I partly agree with you: in the --ff-only case\nthe suggestion should not be brought forward.\n\nBut in the \"git pull\" default case, *today* it's doing a merge. If\nuttering --merge and thus making the current behavior explicit instead\nof implicit seems dangerous it's because it is. But not documenting it\ndoesn't make it any less dangerous.\n\n> > > > +                       \"  git config pull.rebase true   # rebase\\n\"\n> > > > +                       \"  git config pull.ff only       # fast-forward only\\n\"\n> > > > +                       \"\\n\"\n> > > > +                       \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> > > > +                       \"preference for all repositories.\\n\"\n> > >\n> > > Good up to here.\n> > >\n> > > > +                       \"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n> > >\n> > > Why is that safe to suggest?  The original text may not have been the\n> > > easiest to parse, but this seems more problematic to me.\n> >\n> > Because \"git pull\" has been doing the same as \"git pull --no-rebase\"\n> > for more than a decade. It's safe for people to continue with this\n> > behavior for a few more months.\n> >\n> > Some people need to get things done today, and they are not interested\n> > in future changes, nor changing their default configuration, or what\n> > the warning has to say.\n> >\n> > They just want \"git pull\" to do the same as yesterday, and the year\n> > before, without being bothered with an annoying warning.\n> >\n> > Those people can start training their fingers to do \"git pull\n> > --merge\", and learn the problems with \"git pull\" later.\n> >\n> > We want to respect the user's time, and not force them to read the\n> > warning today.\n>\n> The warning was added because sending users down paths that break\n> things badly is a waste of user's time, and often a much bigger waste\n> of user's time than making them read up on the meaning behind the two\n> different choices of what kind of changes they can make.  I agree the\n> warning went too far, but I fully agree with the original folks who\n> put this warning here that we need to have it for at least some cases\n> and that there is a decision to be made.  Though I am just one voice,\n> and perhaps others will agree with you on your point here, I'll\n> continue to disagree with blindly suggesting \"git pull --no-rebase\".\n\nI think the warning is good. I implemented something like that years\nago, and I believe Junio did so too. It should have been implemented\ndifferently though.\n\nAnd yes, we want to annoy the users, and nudge them in the right\ndirection, but still leave them the *option* to easily ignore us.\n\nI'm against forcing anyone to do anything. If the user wants to\nanalyze the warning, they can do so, if not, they can just do $cmd and\ngo about their day as usual. But they were warned.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"411489","messageId":"CAMP44s1wFPQ0mEExYUQfxYx2AjMZS2=zL5ihfjp3qjp+EfNe9Q@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BG0WWvk96T757WMx=004qVqkf+SU8m3cCZsb1feTZJ80Q@mail.gmail.com","subject":"Re: [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T04:01:06Z","receivedAt":"2020-12-05T04:02:15Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 4, 2020 at 5:39 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> >\n> > We want --ff-only to make sense only when no --merge or --rebase option\n> > is specified.\n>\n> A lot of git commands have opposite options, and git allows them both\n> to be specified with the last one winning.  Thus, much like\n>   git log --patch --no-patch\n> mean show logs without patches and\n>   git log --no-patch --patch\n> means show logs with patches, I would similarly expect the following\n> two commands to have opposite behavior:\n>   git pull --merge --no-ff\n>   git pull --no-ff --merge\n\nGood point.\n\nAlthough I presume you meant --ff-only.\n\nTaking that into consideration it may be possible to make --ff-only\nwork straightforwardly.\n\nFurther changes to the code are needed though. In the meantime I'm\nsending a quick patch on top of this series.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"411490","messageId":"20201205040644.1259845-1-felipe.contreras@gmail.com","threadId":"54758","inReplyTo":"CAMP44s1wFPQ0mEExYUQfxYx2AjMZS2=zL5ihfjp3qjp+EfNe9Q@mail.gmail.com","subject":"[PATCH] experiment: pull: change --ff-only and default mode","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T04:06:43Z","receivedAt":"2020-12-05T04:07:34Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n builtin/pull.c  | 40 ++++++++++++++++++++++++++--------------\n t/t5520-pull.sh | 23 +++++++++++++++++++++++\n 2 files changed, 49 insertions(+), 14 deletions(-)\n\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex e389ffcdc3..95ecbdaad5 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -62,6 +62,7 @@ static int parse_opt_rebase(const struct option *opt, const char *arg, int unset\n \t\t*value = parse_config_rebase(\"--rebase\", arg, 0);\n \telse\n \t\t*value = unset ? REBASE_FALSE : REBASE_TRUE;\n+\tif (*value != REBASE_INVALID) default_mode = 0;\n \treturn *value == REBASE_INVALID ? -1 : 0;\n }\n \n@@ -114,6 +115,23 @@ static int opt_show_forced_updates = -1;\n static char *set_upstream;\n static struct strvec opt_fetch = STRVEC_INIT;\n \n+static int parse_opt_ff_only(const struct option *opt, const char *arg, int unset)\n+{\n+\tchar **value = opt->value;\n+\topt_rebase = REBASE_FALSE;\n+\t*value = \"--ff-only\";\n+\treturn 0;\n+}\n+\n+static int parse_opt_merge(const struct option *opt, const char *arg, int unset)\n+{\n+\tchar **value = opt->value;\n+\topt_ff = NULL;\n+\t*value = REBASE_FALSE;\n+\tdefault_mode = 0;\n+\treturn 0;\n+}\n+\n static struct option pull_options[] = {\n \t/* Shared options */\n \tOPT__VERBOSITY(&opt_verbosity),\n@@ -131,8 +149,9 @@ static struct option pull_options[] = {\n \t\t\"(false|true|merges|preserve|interactive)\",\n \t\tN_(\"incorporate changes by rebasing rather than merging\"),\n \t\tPARSE_OPT_OPTARG, parse_opt_rebase),\n-\tOPT_SET_INT('m', \"merge\", &opt_rebase,\n-\t\tN_(\"incorporate changes by merging\"), 0),\n+\tOPT_CALLBACK_F('m', \"merge\", &opt_rebase, NULL,\n+\t\tN_(\"incorporate changes by merging\"),\n+\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG, parse_opt_merge),\n \tOPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,\n \t\tN_(\"do not show a diffstat at the end of the merge\"),\n \t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG),\n@@ -161,9 +180,9 @@ static struct option pull_options[] = {\n \tOPT_PASSTHRU(0, \"ff\", &opt_ff, NULL,\n \t\tN_(\"allow fast-forward\"),\n \t\tPARSE_OPT_NOARG),\n-\tOPT_PASSTHRU(0, \"ff-only\", &opt_ff, NULL,\n+\tOPT_CALLBACK_F(0, \"ff-only\", &opt_ff, NULL,\n \t\tN_(\"abort if fast-forward is not possible\"),\n-\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG),\n+\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG, parse_opt_ff_only),\n \tOPT_PASSTHRU(0, \"verify-signatures\", &opt_verify_signatures, NULL,\n \t\tN_(\"verify that the named commit has a valid GPG signature\"),\n \t\tPARSE_OPT_NOARG),\n@@ -924,6 +943,9 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_pull_config, NULL);\n \n+\topt_ff = xstrdup_or_null(config_get_ff());\n+\topt_rebase = config_get_rebase();\n+\n \targc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);\n \n \tif (cleanup_arg)\n@@ -935,12 +957,6 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \n \tparse_repo_refspecs(argc, argv, &repo, &refspecs);\n \n-\tif (!opt_ff)\n-\t\topt_ff = xstrdup_or_null(config_get_ff());\n-\n-\tif (opt_rebase < 0)\n-\t\topt_rebase = config_get_rebase();\n-\n \tif (read_cache_unmerged())\n \t\tdie_resolve_conflict(\"pull\");\n \n@@ -1037,10 +1053,6 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\t}\n \t}\n \n-\t/* Disable --ff-only when --merge is specified */\n-\tif (!can_ff && !default_mode && !opt_rebase && opt_ff && !strcmp(opt_ff, \"--ff-only\"))\n-\t\topt_ff = NULL;\n-\n \tif (opt_rebase) {\n \t\tint ret = 0;\n \t\tif ((recurse_submodules == RECURSE_SUBMODULES_ON ||\ndiff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\nindex f48d0f8d50..c0cfde54e1 100755\n--- a/t/t5520-pull.sh\n+++ b/t/t5520-pull.sh\n@@ -881,4 +881,27 @@ test_expect_success 'git pull non-fast-forward error message' '\n \tgrep -q \"The pull was not fast-forward\" error\n '\n \n+test_expect_success 'git pull --merge overrides --ffonly' '\n+\ttest_when_finished \"git checkout master && git branch -D other test\" &&\n+\ttest_config pull.ff only &&\n+\tgit checkout -b other master^ &&\n+\t>new &&\n+\tgit add new &&\n+\tgit commit -m new &&\n+\tgit checkout -b test -t other &&\n+\tgit reset --hard master &&\n+\tgit pull --ff-only --merge\n+'\n+\n+test_expect_success 'git pull --ff-only overrides --merge' '\n+\ttest_when_finished \"git checkout master && git branch -D other test\" &&\n+\tgit checkout -b other master^ &&\n+\t>new &&\n+\tgit add new &&\n+\tgit commit -m new &&\n+\tgit checkout -b test -t other &&\n+\tgit reset --hard master &&\n+\ttest_must_fail git pull --merge --ff-only\n+'\n+\n test_done\n-- \n2.29.2\n\n"},{"id":"411499","messageId":"CAPx1Gvf2SZdY_huOGieXD0kJaEn38gsaAiXrV==YxL1-x81dPg@mail.gmail.com","threadId":"54758","inReplyTo":"CAMP44s1=aZL7BMKSjzKJ7qYqg-usScwzRUJmaOhsCGvQ4ieYow@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Chris Torek","fromEmail":"chris.torek@gmail.com","sentAt":"2020-12-05T09:23:05Z","receivedAt":"2020-12-05T09:26:54Z","isPatch":true,"sender":{"key":"chris.torek@gmail.com","avatar":"https://avatars.githubusercontent.com/u/16826774?v=4"},"body":"On Fri, Dec 4, 2020 at 5:59 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n> But in my mind \"fast-forward\" is not a noun, it's an adjective, so I\n> still expect a noun: fast-forward $what. And I don't have any other\n> noun to put there but \"merge\".\n\nIt's a \"fast-forward operation\". :-)\n\n(The operands are branch name and hash ID.)\n\nIt's just been nouned, like \"a merge\" instead of \"a merge commit\".\n\n> > > Perhaps: a merge, a rebase, or a fast-forward?\n> >\n> > Sure, that works; in fact, that's much better than my suggestion.  I like it.\n\nI like this one too.\n\nIn a perfect world, I'd have had `git pull` be the user facing command\nthat does one of: fetch only, fetch-and-fast-forward, fetch-and-rebase,\nor fetch-and-merge.  (Obviously one can achieve the fetch-only by\nrunning `git fetch`, but `git fetch` is a plumbing command.)\n\nIn that same perfect world, the default probably would have been\nfetch only, but fetch-and-fast-forward (or fail if not fast-forward-able)\nseems like an OK default as well. But we have to deal with the\nimperfect world we have. This seems like an OK way to do that.\n"},{"id":"411502","messageId":"CAMP44s3RcsFeE4qLC49GwipfxsB97c55TnxHK-dCGd3hEH5TVw@mail.gmail.com","threadId":"54758","inReplyTo":"CAMP44s1wFPQ0mEExYUQfxYx2AjMZS2=zL5ihfjp3qjp+EfNe9Q@mail.gmail.com","subject":"Re: [PATCH v2 11/14] tentative: pull: change the semantics of --ff-only","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T11:37:58Z","receivedAt":"2020-12-05T11:41:08Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 4, 2020 at 10:01 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> On Fri, Dec 4, 2020 at 5:39 PM Elijah Newren <newren@gmail.com> wrote:\n> >\n> > On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> > <felipe.contreras@gmail.com> wrote:\n> > >\n> > > We want --ff-only to make sense only when no --merge or --rebase option\n> > > is specified.\n> >\n> > A lot of git commands have opposite options, and git allows them both\n> > to be specified with the last one winning.  Thus, much like\n> >   git log --patch --no-patch\n> > mean show logs without patches and\n> >   git log --no-patch --patch\n> > means show logs with patches, I would similarly expect the following\n> > two commands to have opposite behavior:\n> >   git pull --merge --no-ff\n> >   git pull --no-ff --merge\n>\n> Good point.\n>\n> Although I presume you meant --ff-only.\n>\n> Taking that into consideration it may be possible to make --ff-only\n> work straightforwardly.\n>\n> Further changes to the code are needed though. In the meantime I'm\n> sending a quick patch on top of this series.\n\nNevermind.\n\nI have implemented the changes properly and v3 is ready with some\ninteresting improvements, but it is still not straightforward.\n\nCurrently \"git pull --ff-only --merge\" fails with:\n\n  fatal: Not possible to fast-forward, aborting.\n\nWith the proposed change --merge would override --ff-only and make the\npull essentially --no-ff.\n\nThat's still a semantic change. So there's no way around that.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"411504","messageId":"CABPp-BE7B5hn3Fc4zD1o+qoqihJqCut=R1TP_fxMXW42+6iL+w@mail.gmail.com","threadId":"54758","inReplyTo":"20201205040644.1259845-1-felipe.contreras@gmail.com","subject":"Re: [PATCH] experiment: pull: change --ff-only and default mode","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-05T17:29:01Z","receivedAt":"2020-12-05T17:42:35Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Dec 4, 2020 at 8:06 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n\nThis commit message should say something more than just \"change x\", it\nshould have some words about what it is change from or to.  I think\nthe thrust of the patch is allowing --ff-only, --merge, and --rebase\nto countermand an earlier otherwise-conflicting option.  Perhaps a\ncommit message of the form:\n\nIn git, we sometimes allow conflicting command line options with the\nlast one winning, e.g.\n  git log --patch --no-patch\n  git log --no-patch --patch\nother times we just error out when conflicting options are given, e.g.\n  git checkout -b --orphan NEWBRANCH\n  git checkout --orphan -b NEWBRANCH\nPreviously, we did neither with --no-ff, --merge, and --rebase.\nChange these options to have a last-one-wins behavior.\n\n\n(Although, after writing this out, I wonder if we want to die with a\nconflict message instead of going the route I suggested yesterday.\nI'm not certain if one is better than the other, but worth\nconsidering.  Thoughts?)\n\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  builtin/pull.c  | 40 ++++++++++++++++++++++++++--------------\n>  t/t5520-pull.sh | 23 +++++++++++++++++++++++\n>  2 files changed, 49 insertions(+), 14 deletions(-)\n>\n> diff --git a/builtin/pull.c b/builtin/pull.c\n> index e389ffcdc3..95ecbdaad5 100644\n> --- a/builtin/pull.c\n> +++ b/builtin/pull.c\n> @@ -62,6 +62,7 @@ static int parse_opt_rebase(const struct option *opt, const char *arg, int unset\n>                 *value = parse_config_rebase(\"--rebase\", arg, 0);\n>         else\n>                 *value = unset ? REBASE_FALSE : REBASE_TRUE;\n> +       if (*value != REBASE_INVALID) default_mode = 0;\n>         return *value == REBASE_INVALID ? -1 : 0;\n>  }\n>\n> @@ -114,6 +115,23 @@ static int opt_show_forced_updates = -1;\n>  static char *set_upstream;\n>  static struct strvec opt_fetch = STRVEC_INIT;\n>\n> +static int parse_opt_ff_only(const struct option *opt, const char *arg, int unset)\n> +{\n> +       char **value = opt->value;\n> +       opt_rebase = REBASE_FALSE;\n> +       *value = \"--ff-only\";\n> +       return 0;\n> +}\n> +\n> +static int parse_opt_merge(const struct option *opt, const char *arg, int unset)\n> +{\n> +       char **value = opt->value;\n> +       opt_ff = NULL;\n> +       *value = REBASE_FALSE;\n> +       default_mode = 0;\n> +       return 0;\n> +}\n> +\n>  static struct option pull_options[] = {\n>         /* Shared options */\n>         OPT__VERBOSITY(&opt_verbosity),\n> @@ -131,8 +149,9 @@ static struct option pull_options[] = {\n>                 \"(false|true|merges|preserve|interactive)\",\n>                 N_(\"incorporate changes by rebasing rather than merging\"),\n>                 PARSE_OPT_OPTARG, parse_opt_rebase),\n> -       OPT_SET_INT('m', \"merge\", &opt_rebase,\n> -               N_(\"incorporate changes by merging\"), 0),\n> +       OPT_CALLBACK_F('m', \"merge\", &opt_rebase, NULL,\n> +               N_(\"incorporate changes by merging\"),\n> +               PARSE_OPT_NOARG | PARSE_OPT_NONEG, parse_opt_merge),\n>         OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,\n>                 N_(\"do not show a diffstat at the end of the merge\"),\n>                 PARSE_OPT_NOARG | PARSE_OPT_NONEG),\n> @@ -161,9 +180,9 @@ static struct option pull_options[] = {\n>         OPT_PASSTHRU(0, \"ff\", &opt_ff, NULL,\n>                 N_(\"allow fast-forward\"),\n>                 PARSE_OPT_NOARG),\n> -       OPT_PASSTHRU(0, \"ff-only\", &opt_ff, NULL,\n> +       OPT_CALLBACK_F(0, \"ff-only\", &opt_ff, NULL,\n>                 N_(\"abort if fast-forward is not possible\"),\n> -               PARSE_OPT_NOARG | PARSE_OPT_NONEG),\n> +               PARSE_OPT_NOARG | PARSE_OPT_NONEG, parse_opt_ff_only),\n>         OPT_PASSTHRU(0, \"verify-signatures\", &opt_verify_signatures, NULL,\n>                 N_(\"verify that the named commit has a valid GPG signature\"),\n>                 PARSE_OPT_NOARG),\n> @@ -924,6 +943,9 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>\n>         git_config(git_pull_config, NULL);\n>\n> +       opt_ff = xstrdup_or_null(config_get_ff());\n> +       opt_rebase = config_get_rebase();\n> +\n>         argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);\n>\n>         if (cleanup_arg)\n> @@ -935,12 +957,6 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>\n>         parse_repo_refspecs(argc, argv, &repo, &refspecs);\n>\n> -       if (!opt_ff)\n> -               opt_ff = xstrdup_or_null(config_get_ff());\n> -\n> -       if (opt_rebase < 0)\n> -               opt_rebase = config_get_rebase();\n> -\n>         if (read_cache_unmerged())\n>                 die_resolve_conflict(\"pull\");\n>\n> @@ -1037,10 +1053,6 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>                 }\n>         }\n>\n> -       /* Disable --ff-only when --merge is specified */\n> -       if (!can_ff && !default_mode && !opt_rebase && opt_ff && !strcmp(opt_ff, \"--ff-only\"))\n> -               opt_ff = NULL;\n> -\n>         if (opt_rebase) {\n>                 int ret = 0;\n>                 if ((recurse_submodules == RECURSE_SUBMODULES_ON ||\n> diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\n> index f48d0f8d50..c0cfde54e1 100755\n> --- a/t/t5520-pull.sh\n> +++ b/t/t5520-pull.sh\n> @@ -881,4 +881,27 @@ test_expect_success 'git pull non-fast-forward error message' '\n>         grep -q \"The pull was not fast-forward\" error\n>  '\n>\n> +test_expect_success 'git pull --merge overrides --ffonly' '\n\nYou're missing a hyphen there; it should be --ff-only.\n\n> +       test_when_finished \"git checkout master && git branch -D other test\" &&\n> +       test_config pull.ff only &&\n> +       git checkout -b other master^ &&\n> +       >new &&\n> +       git add new &&\n> +       git commit -m new &&\n> +       git checkout -b test -t other &&\n> +       git reset --hard master &&\n> +       git pull --ff-only --merge\n> +'\n> +\n> +test_expect_success 'git pull --ff-only overrides --merge' '\n> +       test_when_finished \"git checkout master && git branch -D other test\" &&\n> +       git checkout -b other master^ &&\n> +       >new &&\n> +       git add new &&\n> +       git commit -m new &&\n> +       git checkout -b test -t other &&\n> +       git reset --hard master &&\n> +       test_must_fail git pull --merge --ff-only\n> +'\n\nWhat about --ff-only and --rebase?  Are there already tests for those?\n"},{"id":"411507","messageId":"CAMP44s0NzvQzEutWvhAz2ytH+nKK=8GOHnLjEUe-QgZ7vo2Ttg@mail.gmail.com","threadId":"54758","inReplyTo":"CAPx1Gvf2SZdY_huOGieXD0kJaEn38gsaAiXrV==YxL1-x81dPg@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T11:47:31Z","receivedAt":"2020-12-05T18:41:45Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Sat, Dec 5, 2020 at 3:23 AM Chris Torek <chris.torek@gmail.com> wrote:\n>\n> On Fri, Dec 4, 2020 at 5:59 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> > But in my mind \"fast-forward\" is not a noun, it's an adjective, so I\n> > still expect a noun: fast-forward $what. And I don't have any other\n> > noun to put there but \"merge\".\n>\n> It's a \"fast-forward operation\". :-)\n\nA fast-forward operation that does what?\n\n> It's just been nouned, like \"a merge\" instead of \"a merge commit\".\n\nExcept there's a difference between telling git: \"do a fast-forward\nmerge\", and \"do a fast-forward merge commit\". The latter doesn't\nreally make sense.\n\n> > > > Perhaps: a merge, a rebase, or a fast-forward?\n> > >\n> > > Sure, that works; in fact, that's much better than my suggestion.  I like it.\n>\n> I like this one too.\n>\n> In a perfect world, I'd have had `git pull` be the user facing command\n> that does one of: fetch only, fetch-and-fast-forward, fetch-and-rebase,\n> or fetch-and-merge.  (Obviously one can achieve the fetch-only by\n> running `git fetch`, but `git fetch` is a plumbing command.)\n>\n> In that same perfect world, the default probably would have been\n> fetch only, but fetch-and-fast-forward (or fail if not fast-forward-able)\n> seems like an OK default as well. But we have to deal with the\n> imperfect world we have. This seems like an OK way to do that.\n\nIn the slightly more perfect word I'm aiming for those two modes could\nbe achieved with the pull.mode configuration:\n\n* \"pull.mode=none\" would be the same as \"fetch only\"\n* \"pull.mode=ff-only\" would be the same as \"fetch-and-fast-forward\"\n\nBut first this configuration has to actually be introduced. It didn't\nhappen in 2014, maybe it will happen this time. Who knows.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"411509","messageId":"CAMP44s12DENe7KcSxzRAL_u0YZV10o_okzm5fKkjz0W59NrATA@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BE7B5hn3Fc4zD1o+qoqihJqCut=R1TP_fxMXW42+6iL+w@mail.gmail.com","subject":"Re: [PATCH] experiment: pull: change --ff-only and default mode","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T18:16:52Z","receivedAt":"2020-12-05T18:42:34Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Sat, Dec 5, 2020 at 11:29 AM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Fri, Dec 4, 2020 at 8:06 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n>\n> This commit message should say something more than just \"change x\", it\n> should have some words about what it is change from or to.  I think\n> the thrust of the patch is allowing --ff-only, --merge, and --rebase\n> to countermand an earlier otherwise-conflicting option.  Perhaps a\n> commit message of the form:\n\nIt's not a real commit, it's just a preview at what the eventual\ndiffstat towards v3 might look like.\n\n-- \nFelipe Contreras\n"},{"id":"411510","messageId":"CABPp-BF4rXBOKsn8bG6y3QUEtNVV9K2Pk5NmwrU5818CqhRt_Q@mail.gmail.com","threadId":"54758","inReplyTo":"CAMP44s1=aZL7BMKSjzKJ7qYqg-usScwzRUJmaOhsCGvQ4ieYow@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-05T16:28:16Z","receivedAt":"2020-12-05T18:43:15Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Dec 4, 2020 at 5:56 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> On Fri, Dec 4, 2020 at 6:56 PM Elijah Newren <newren@gmail.com> wrote:\n> >\n> > Hi Felipe,\n> >\n> > On Fri, Dec 4, 2020 at 4:12 PM Felipe Contreras\n> > <felipe.contreras@gmail.com> wrote:\n> > >\n> > > On Fri, Dec 4, 2020 at 5:00 PM Elijah Newren <newren@gmail.com> wrote:\n> > > >\n> > > > On Thu, Dec 3, 2020 at 10:16 PM Felipe Contreras\n> > > > <felipe.contreras@gmail.com> wrote:\n[...]\n> > > > > +                       \"You can squelch this message by running one of the following commands:\\n\"\n> > > > > +                       \"\\n\"\n> > > > > +                       \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> > > >\n> > > > Should this be labelled as the default given the desire to make\n> > > > --ff-only the default?  Perhaps I'm jumping ahead and you plan to\n> > > > change that later in this series.\n> > >\n> > > That's right.\n> > >\n> > > In the previous series which does indeed make \"pull.mode=ff-only\" the\n> > > default [1], I do change the warning to specify the future default\n> > > [2], but in that series the warnings is changed to:\n> > >\n> > >   The pull was not fast-forward, in the future you will have to choose\n> > > a merge, or a rebase.\n> > >   To squelch this message and maintain the current behavior, use:\n> > >\n> > >     git config --global pull.mode merge\n> > >\n> > >   To squelch this message and adopt the new behavior now, use:\n> > >\n> > >     git config --global push.mode ff-only\n> > >\n> > >   Falling back to old style for now (merge).\n> > >   Read \"git pull --help\" for more information.\n> > >\n> > > Since that series didn't get any traction, I decided to only implement\n> > > step 1: fix the current situation. And later on another series would\n> > > do step 2: introduce \"pull.mode=ff-only\" and do the preparations to\n> > > make it the default.\n> >\n> > I like this longer plan.\n>\n> Yeah. It's a better plan, just more work for me.\n>\n> > However, on the shorter scale plan...I think\n> > the suggestion to use \"git pull --no-rebase\" makes the current\n> > situation worse rather than fixing it.\n>\n> Well, I already said I partly agree with you: in the --ff-only case\n> the suggestion should not be brought forward.\n>\n> But in the \"git pull\" default case, *today* it's doing a merge. If\n> uttering --merge and thus making the current behavior explicit instead\n> of implicit seems dangerous it's because it is. But not documenting it\n> doesn't make it any less dangerous.\n\nSounds like we agree that the future should be ff-only-as-default.  I\nalso agree with you that the primary problem is the current default\nbehavior, and I'll agree with you that documenting the current default\nis okay.  However, I disagree that your wording here:\n\n+                       \"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n\ndoes anything of the sort.  It does not mention that this is the\ndefault behavior the users would get if they provided no flags.  More\nimportantly, it makes a recommendation...and one that undercuts the\npoint of the message.  It makes it feel like the message shouldn't\nexist at all in any circumstances.  I even suspect that adding that\nsentence may undercut any efforts towards changing the default to\nff-only-as-default.  While I'm a big fan of most of what you've done\nin this series, I will object to its merging for as long as this\nstays.  (I definitely don't have veto power or anything close to it,\njust stating what my opinion is.)\n"},{"id":"411534","messageId":"CAMP44s2L24jhCG9ps72--ZiJkXUovR726jCf8JTLHAs0jV7Whg@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BF4rXBOKsn8bG6y3QUEtNVV9K2Pk5NmwrU5818CqhRt_Q@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-05T21:27:57Z","receivedAt":"2020-12-05T21:29:13Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Sat, Dec 5, 2020 at 10:28 AM Elijah Newren <newren@gmail.com> wrote:\n> On Fri, Dec 4, 2020 at 5:56 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n\n> > Well, I already said I partly agree with you: in the --ff-only case\n> > the suggestion should not be brought forward.\n> >\n> > But in the \"git pull\" default case, *today* it's doing a merge. If\n> > uttering --merge and thus making the current behavior explicit instead\n> > of implicit seems dangerous it's because it is. But not documenting it\n> > doesn't make it any less dangerous.\n>\n> Sounds like we agree that the future should be ff-only-as-default.  I\n> also agree with you that the primary problem is the current default\n> behavior, and I'll agree with you that documenting the current default\n> is okay.  However, I disagree that your wording here:\n>\n> +                       \"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n>\n> does anything of the sort.  It does not mention that this is the\n> default behavior the users would get if they provided no flags.\n\nBut that is not the warning, this is the warning:\n\n  Pulling without specifying how to reconcile divergent branches is discouraged;\n  you need to specify if you want a merge, a rebase, or a fast-forward.\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.\n\nThis warning says:\n\n1. There's 3 options: merge, rebase, fast-forward\n2. merge is the default strategy\n3. If unsure, specify --merge (the default strategy)\n\nSo taken altogether it does say what is the default strategy.\n\n> More\n> importantly, it makes a recommendation...and one that undercuts the\n> point of the message.\n\nSo?\n\nWhen boarding a plane the flight attendants do a safety demonstration\nthat passengers should pay attention to. If one passenger is not\npaying attention (listening to music on headphones, and reading a\nbook) what should the crew do?\n\n1. Remove the passenger's headphones and force him to pay attention to\nthe safety demonstration\n2. Let the passenger ignore the safety demonstration\n\nHuman beings are independent agents responsible for their own actions.\nYou as a separate human being--a crew member--can argue that it's not\nin the best interest of the passenger to ignore the safety\ndemonstration, and you may be right, but the passenger decisions are\nstill the passenger's decisions, even if they are bad.\n\nDo you think the crew should disregard the passenger's volition and\nforce him to pay attention to the safety demonstration?\n\n> It makes it feel like the message shouldn't\n> exist at all in any circumstances.  I even suspect that adding that\n> sentence may undercut any efforts towards changing the default to\n> ff-only-as-default.  While I'm a big fan of most of what you've done\n> in this series, I will object to its merging for as long as this\n> stays.  (I definitely don't have veto power or anything close to it,\n> just stating what my opinion is.)\n\nThe current warning should not exist at all.\n\nThe complaint from Vít Ondruch [1] that reignited this series is a\nvalid one. A *permanent* warning is not good. We should have a\n*temporary* warning with the express purpose of notifying users of an\nupcoming change.\n\nIf we have not yet decided on what should be the default (Junio seems\nto have casted some doubt on the consensus [2]), and we don't have a\nclear path forward to implement such change (we can't even tell users\nto use \"pull.ff=only\", since eventually it may be\n\"pull.mode=ff-only\"), then we must remove the warning.\n\nIt was a mistake to put a *permanent* warning before deciding to\nchange the default.\n\nSo, there's two options:\n\n1. We decide on a path forward and fix the warning so it *temporarily*\nexplains what will happen in the future\n2. We remove the *permanent* warning\n\nSince we are already here, we might as well take advantage of that\nwarning and repurpose it. But in the meantime--while the git project\ndecides what to do, and what configurations to suggest the users to\nchange--we should at the very least waste as little as the user's time\nas possible, and give him/her a quick opt-out.\n\nYes, a quick opt-out defeats the purpose of a warning, but we must\nrespect the users' volition. The user may be on a deadline trying to\npush some changes to production before the weekend, and after a system\nupdate be annoyed with this warning on every pull. The user may not\nhave time to look at the warning, decide he wants to read the warning\nin the future, maybe next Monday, and thus not configure anything to\nsilence it.\n\nWhat's wrong with a user saying \"I don't have time for this now,\nplease tell me what to do for now, I'll look at the warning later\"? If\nanything for those users the configuration is the wrong thing to do,\nbecause being in a hurry they just choose the first configuration and\nforget about the warning without actually looking at it (because they\ndidn't have time), and it will not appear any more. By typing \"git\npull --merge\" the user can get rid of the warning *for now*, but the\nnext time he does \"git pull\" the warning will reappear, and at that\ntime perhaps the user does have the time to read it, and look at the\nmanpage.\n\nNobody likes their workflow to be interrupted and be forced to do anything.\n\nI don't think my patches plus that suggestion for a quick opt-out are\nin any way worse than the current situation. If you think they are,\nthen we'll just have to agree to disagree.\n\nI quote the voice of Vít Ondruch, which I think represents the typical\nuser: \"please select any strategy considered more appropriate and stop\nwarning me\".\n\nCheers.\n\n[1] https://lore.kernel.org/git/742df4c2-2bc5-8a4b-8de1-cd5e48718398@redhat.com/\n[2] https://lore.kernel.org/git/xmqqh7p1fjml.fsf@gitster.c.googlers.com/\n\n-- \nFelipe Contreras\n"},{"id":"411544","messageId":"CABPp-BGdNt8TBMTE9zvaicF5AtvyTBhpiJXqkuZc7mBLGbw0Qw@mail.gmail.com","threadId":"54758","inReplyTo":"CAMP44s2L24jhCG9ps72--ZiJkXUovR726jCf8JTLHAs0jV7Whg@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-06T01:01:36Z","receivedAt":"2020-12-06T01:02:30Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Sat, Dec 5, 2020 at 1:28 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> On Sat, Dec 5, 2020 at 10:28 AM Elijah Newren <newren@gmail.com> wrote:\n> > On Fri, Dec 4, 2020 at 5:56 PM Felipe Contreras\n> > <felipe.contreras@gmail.com> wrote:\n>\n> > > Well, I already said I partly agree with you: in the --ff-only case\n> > > the suggestion should not be brought forward.\n> > >\n> > > But in the \"git pull\" default case, *today* it's doing a merge. If\n> > > uttering --merge and thus making the current behavior explicit instead\n> > > of implicit seems dangerous it's because it is. But not documenting it\n> > > doesn't make it any less dangerous.\n> >\n> > Sounds like we agree that the future should be ff-only-as-default.  I\n> > also agree with you that the primary problem is the current default\n> > behavior, and I'll agree with you that documenting the current default\n> > is okay.  However, I disagree that your wording here:\n> >\n> > +                       \"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n> >\n> > does anything of the sort.  It does not mention that this is the\n> > default behavior the users would get if they provided no flags.\n>\n> But that is not the warning, this is the warning:\n>\n>   Pulling without specifying how to reconcile divergent branches is discouraged;\n>   you need to specify if you want a merge, a rebase, or a fast-forward.\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.\n>\n> This warning says:\n>\n> 1. There's 3 options: merge, rebase, fast-forward\n> 2. merge is the default strategy\n> 3. If unsure, specify --merge (the default strategy)\n>\n> So taken altogether it does say what is the default strategy.\n\nWe don't need to take them together.  #2 by itself states the default\nstrategy.  I don't see why defending #3 as being for the purpose of\ndocumenting the default strategy is helpful, since it doesn't do that.\n\n> > More\n> > importantly, it makes a recommendation...and one that undercuts the\n> > point of the message.\n>\n> So?\n>\n> When boarding a plane the flight attendants do a safety demonstration\n> that passengers should pay attention to. If one passenger is not\n> paying attention (listening to music on headphones, and reading a\n> book) what should the crew do?\n>\n> 1. Remove the passenger's headphones and force him to pay attention to\n> the safety demonstration\n> 2. Let the passenger ignore the safety demonstration\n>\n> Human beings are independent agents responsible for their own actions.\n> You as a separate human being--a crew member--can argue that it's not\n> in the best interest of the passenger to ignore the safety\n> demonstration, and you may be right, but the passenger decisions are\n> still the passenger's decisions, even if they are bad.\n>\n> Do you think the crew should disregard the passenger's volition and\n> force him to pay attention to the safety demonstration?\n>\n> > It makes it feel like the message shouldn't\n> > exist at all in any circumstances.  I even suspect that adding that\n> > sentence may undercut any efforts towards changing the default to\n> > ff-only-as-default.  While I'm a big fan of most of what you've done\n> > in this series, I will object to its merging for as long as this\n> > stays.  (I definitely don't have veto power or anything close to it,\n> > just stating what my opinion is.)\n>\n> The current warning should not exist at all.\n>\n> The complaint from Vít Ondruch [1] that reignited this series is a\n> valid one. A *permanent* warning is not good. We should have a\n> *temporary* warning with the express purpose of notifying users of an\n> upcoming change.\n>\n> If we have not yet decided on what should be the default (Junio seems\n> to have casted some doubt on the consensus [2]), and we don't have a\n\nUseful link there.  Based on his comments, we may want to make\n--ff-only, --merge, and --rebase all be mutually exclusive and result\nin an error message if more than one is specified at the command line.\n(But still have the command line countermand any option set in the\nconfig, of course).\n\n> clear path forward to implement such change (we can't even tell users\n> to use \"pull.ff=only\", since eventually it may be\n> \"pull.mode=ff-only\"), then we must remove the warning.\n>\n> It was a mistake to put a *permanent* warning before deciding to\n> change the default.\n>\n> So, there's two options:\n>\n> 1. We decide on a path forward and fix the warning so it *temporarily*\n> explains what will happen in the future\n> 2. We remove the *permanent* warning\n>\n> Since we are already here, we might as well take advantage of that\n> warning and repurpose it. But in the meantime--while the git project\n> decides what to do, and what configurations to suggest the users to\n> change--we should at the very least waste as little as the user's time\n> as possible, and give him/her a quick opt-out.\n>\n> Yes, a quick opt-out defeats the purpose of a warning, but we must\n> respect the users' volition. The user may be on a deadline trying to\n> push some changes to production before the weekend, and after a system\n> update be annoyed with this warning on every pull. The user may not\n> have time to look at the warning, decide he wants to read the warning\n> in the future, maybe next Monday, and thus not configure anything to\n> silence it.\n>\n> What's wrong with a user saying \"I don't have time for this now,\n> please tell me what to do for now, I'll look at the warning later\"? If\n> anything for those users the configuration is the wrong thing to do,\n> because being in a hurry they just choose the first configuration and\n> forget about the warning without actually looking at it (because they\n> didn't have time), and it will not appear any more. By typing \"git\n> pull --merge\" the user can get rid of the warning *for now*, but the\n> next time he does \"git pull\" the warning will reappear, and at that\n> time perhaps the user does have the time to read it, and look at the\n> manpage.\n>\n> Nobody likes their workflow to be interrupted and be forced to do anything.\n>\n> I don't think my patches plus that suggestion for a quick opt-out are\n> in any way worse than the current situation. If you think they are,\n> then we'll just have to agree to disagree.\n\nYes, we can agree to disagree on this particular point.\n"},{"id":"411563","messageId":"CAMP44s2fCnjJSp2fzSq5is0LR6GDPP+wnM9r3kz=U65c7h_UPg@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BGdNt8TBMTE9zvaicF5AtvyTBhpiJXqkuZc7mBLGbw0Qw@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-06T14:31:41Z","receivedAt":"2020-12-06T14:32:41Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Sat, Dec 5, 2020 at 7:01 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Sat, Dec 5, 2020 at 1:28 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> >\n> > On Sat, Dec 5, 2020 at 10:28 AM Elijah Newren <newren@gmail.com> wrote:\n> > > On Fri, Dec 4, 2020 at 5:56 PM Felipe Contreras\n> > > <felipe.contreras@gmail.com> wrote:\n> >\n> > > > Well, I already said I partly agree with you: in the --ff-only case\n> > > > the suggestion should not be brought forward.\n> > > >\n> > > > But in the \"git pull\" default case, *today* it's doing a merge. If\n> > > > uttering --merge and thus making the current behavior explicit instead\n> > > > of implicit seems dangerous it's because it is. But not documenting it\n> > > > doesn't make it any less dangerous.\n> > >\n> > > Sounds like we agree that the future should be ff-only-as-default.  I\n> > > also agree with you that the primary problem is the current default\n> > > behavior, and I'll agree with you that documenting the current default\n> > > is okay.  However, I disagree that your wording here:\n> > >\n> > > +                       \"If unsure, run \\\"git pull --no-rebase\\\".\\n\"\n> > >\n> > > does anything of the sort.  It does not mention that this is the\n> > > default behavior the users would get if they provided no flags.\n> >\n> > But that is not the warning, this is the warning:\n> >\n> >   Pulling without specifying how to reconcile divergent branches is discouraged;\n> >   you need to specify if you want a merge, a rebase, or a fast-forward.\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.\n> >\n> > This warning says:\n> >\n> > 1. There's 3 options: merge, rebase, fast-forward\n> > 2. merge is the default strategy\n> > 3. If unsure, specify --merge (the default strategy)\n> >\n> > So taken altogether it does say what is the default strategy.\n>\n> We don't need to take them together.\n\nNo, but that's what I'm proposing.\n\n> #2 by itself states the default strategy.\n\nYes, with configuration, not with commands.\n\n> I don't see why defending #3 as being for the purpose of\n> documenting the default strategy is helpful, since it doesn't do that.\n\nI disagree. It does do that, but it serves a more urgent purpose: it\ntells the user how to ignore us quickly, for now.\n\n> > The current warning should not exist at all.\n> >\n> > The complaint from Vít Ondruch [1] that reignited this series is a\n> > valid one. A *permanent* warning is not good. We should have a\n> > *temporary* warning with the express purpose of notifying users of an\n> > upcoming change.\n> >\n> > If we have not yet decided on what should be the default (Junio seems\n> > to have casted some doubt on the consensus [2]), and we don't have a\n>\n> Useful link there.  Based on his comments, we may want to make\n> --ff-only, --merge, and --rebase all be mutually exclusive and result\n> in an error message if more than one is specified at the command line.\n> (But still have the command line countermand any option set in the\n> config, of course).\n\nYes, but that's a change in behavior.\n\nMoreover, what do you suggest this should do?\n\n  git -c \"pull.rebase=true\" -c \"pull.ff=only\" pull\n\nI have already tried to make pull.ff=only work in several ways. It's\njust not a clean solution.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"411585","messageId":"xmqqeek2cc14.fsf@gitster.c.googlers.com","threadId":"54758","inReplyTo":"CABPp-BGdNt8TBMTE9zvaicF5AtvyTBhpiJXqkuZc7mBLGbw0Qw@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-12-07T07:26:15Z","receivedAt":"2020-12-07T07:27:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n>>   Pulling without specifying how to reconcile divergent branches is discouraged;\n>>   you need to specify if you want a merge, a rebase, or a fast-forward.\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.\n>>\n>> This warning says:\n>>\n>> 1. There's 3 options: merge, rebase, fast-forward\n>> 2. merge is the default strategy\n>> 3. If unsure, specify --merge (the default strategy)\n>>\n>> So taken altogether it does say what is the default strategy.\n>\n> We don't need to take them together.  #2 by itself states the default\n> strategy.  I don't see why defending #3 as being for the purpose of\n> documenting the default strategy is helpful, since it doesn't do that.\n\nWould it work if the line were\n\n\tIf unsure, run \"git -c pull.rebase=false pull\".\n\nthen?\n\nThe reason why I bring this up is because the first part only talks\nabout the choices in the terms of configuration variables, and for\nthose who are afraid of committing, there is no easy way, unless\nthey know the \"git -c\" single-shot mechanism, to \"go ahead with one\nchoice in an experimental basis to see if that is what they want\",\nand \"specify --merge\" does not click well with \"pull.rebase=false\"\nthat is given in the first part.  \"git pull --no-rebase\" may also\nwork better than \"git pull --merge\" from that point of view, though.\n\nBut see below.\n\n\n>> Do you think the crew should disregard the passenger's volition and\n>> force him to pay attention to the safety demonstration?\n\nAn example that is irrelevant.  Passengers who sit on the aisle side\nand clutter the floor with their luggages can pose public hazard,\nand it is quite sensible for crews to remove them from the plane.  \n\nA team member who runs \"pull --[no-]rebase\" pushes the result, which\nmay be a new history in a wrong shape, back to the shared repository\nprobably falls into a different category.  ... Or perhaps in the\nsame public hazard category?\n\n> Useful link there.  Based on his comments, we may want to make\n> --ff-only, --merge, and --rebase all be mutually exclusive and result\n> in an error message if more than one is specified at the command line.\n\nI hope \"his comment\" does not refer to what I said.  Redefining the\nsemantics of --ff-only (but not --ff=no and friends) to make it\nmutually incompatible with merge/rebase was what Felipe wanted to\ndo, not me.\n\nFWIW, I see the general direction as\n\n - When the history you are pulling is not a descendant of what you\n   have on your current branch, you must show your preference\n   between merging their history into yours or rebasing your history\n   onto theirs.\n\n - In such a case, we error out, with an error message telling them\n   that they must tell us which one they want in this invocation\n   (e.g. with \"--rebase\" or \"--no-rebase\").  We further tell them\n   that pull.rebase can be used to record their preference, if they\n   almost always use the same.\n\n\tSide note: I earlier said \"see below\" to refer to this.  I\n\tthink the message should offer what they can do right now\n\twith command line option first, and then give an option to\n\tconfigure.  IOW, the message quoted in the beginning of this\n\tresponse gives information in a wrong order.  Also,\n\t\"discouraged\" is misleading, isn't it?  When we give this\n\tmessage, we refuse to proceed until the user specifies.\n\n\tAnother thing to consider is that pull.ff=only (and\n\t--ff-only) may be wrong choice to offer in the error message\n\tquoted above, if one of the objectives is to reduce the\n\t\"annoying\" message that tells the user that they must\n\tchoose.  By definition, we do not give the message when our\n\tside do not have our own development, so \"I could run 'pull\n\t--ff-only'\" is a unusable knowledge to those who see the\n\tmessage and want to get out of the situation.\n\n - But when the history being pulled is a descendant of the current\n   branch, and the user does not give us preference between merge\n   and rebase (either from the command line or with configuration),\n   there is no need to give such an error message---if you do not\n   have your own development, we can just fast-forward the current\n   branch to what we fetched from the other side.  This does not\n   happen with the current system, which is what we want to fix.\n\n - Also when the history from the other side is a descedant and the\n   user has preference, either to rebase or to merge, either from\n   the command line or with configuration, we can fast-forward the\n   current branch to their tip, but there are wrinkles:\n\n   . when --ff=no is given and the choice is to merge (not rebase),\n     we must create an extra merge commit.\n\n   . when the choice is to rebase, by definition, rebasing what you\n     have on top of theirs in this case is the same as fast-forwarding\n     the current branch to theirs, because \"what you have\" is an\n     empty set.\n\n   . I am not sure how \"pull --rebase --ff=no\" should interact if we\n     don't have our own development.  Rebasing our work on top of\n     theirs is philosophically incompatible with marking where the\n     side branch begins and ends with an extra commit, so it either\n     should be rejected when the command line and configuration is\n     parsed (i.e. regardless of the shape of the history we have at\n     hand), or --ff=no gets silently ignored when --rebase is given.\n     I haven't thought this one through.\n"},{"id":"411587","messageId":"xmqqa6uqcbnd.fsf@gitster.c.googlers.com","threadId":"54758","inReplyTo":"CABPp-BE7B5hn3Fc4zD1o+qoqihJqCut=R1TP_fxMXW42+6iL+w@mail.gmail.com","subject":"Re: [PATCH] experiment: pull: change --ff-only and default mode","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-12-07T07:34:30Z","receivedAt":"2020-12-07T07:35:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> On Fri, Dec 4, 2020 at 8:06 PM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n>\n> This commit message should say something more than just \"change x\", it\n> should have some words about what it is change from or to.  I think\n> the thrust of the patch is allowing --ff-only, --merge, and --rebase\n> to countermand an earlier otherwise-conflicting option.  Perhaps a\n> commit message of the form:\n>\n> In git, we sometimes allow conflicting command line options with the\n> last one winning, e.g.\n>   git log --patch --no-patch\n>   git log --no-patch --patch\n> other times we just error out when conflicting options are given, e.g.\n>   git checkout -b --orphan NEWBRANCH\n>   git checkout --orphan -b NEWBRANCH\n> Previously, we did neither with --no-ff, --merge, and --rebase.\n> Change these options to have a last-one-wins behavior.\n\nIf the choices are clearly among --ff-only, --merge and --rebase, I\nam fine with the last-one-wins change, and your explanation does\nmake sense.\n\nI however am not sure how --no-ff and other --ff=<how> friends\nshould interact with the primary two choices.  --ff=no is used by\nthose who want to merge, so \"--merge --ff=no\" combination is a\nsensible thing to accept.  The same can be said for \"--merge --ff\"\n(fast-forward when able).  It is interesting to realize that it\nwould not be wrong to say \"--rebase --ff\" even.  When their history\nwe are rebasing our own work on top is a descendant of our history,\nsuch a rebase operation ends up in fast-forwarding to their tip.\n"},{"id":"411595","messageId":"CAMP44s2XFQoda_PMULWha-rj9HhNfEddO5fikmswk9=AWN4RCw@mail.gmail.com","threadId":"54758","inReplyTo":"xmqqeek2cc14.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-07T09:16:14Z","receivedAt":"2020-12-07T09:17:15Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Mon, Dec 7, 2020 at 1:26 AM Junio C Hamano <gitster@pobox.com> wrote:\n> Elijah Newren <newren@gmail.com> writes:\n\n> >> Do you think the crew should disregard the passenger's volition and\n> >> force him to pay attention to the safety demonstration?\n>\n> An example that is irrelevant.  Passengers who sit on the aisle side\n> and clutter the floor with their luggages can pose public hazard,\n> and it is quite sensible for crews to remove them from the plane.\n\nThat's a completely different example that mixes policy with\nregulations. Apples and oranges.\n\n> A team member who runs \"pull --[no-]rebase\" pushes the result, which\n> may be a new history in a wrong shape, back to the shared repository\n> probably falls into a different category.  ... Or perhaps in the\n> same public hazard category?\n\nYes, but if it's a public hazard or not is up to the maintainers of\nspecific projects. Some projects are perfectly fine with those merges.\n\nIt's the maintainer of the project that should decide what is the best\npolicy for the project, and instruct his/her contributors.\n\nIt's not up for individuals to decide what is a public hazard, and\nit's not up to Git either. Similarly; passengers can't decide what\nraises to the level of public hazzard, but neither can a flight\nattendant.\n\n> > Useful link there.  Based on his comments, we may want to make\n> > --ff-only, --merge, and --rebase all be mutually exclusive and result\n> > in an error message if more than one is specified at the command line.\n>\n> I hope \"his comment\" does not refer to what I said.  Redefining the\n> semantics of --ff-only (but not --ff=no and friends) to make it\n> mutually incompatible with merge/rebase was what Felipe wanted to\n> do, not me.\n\nThat's not true.\n\nWhat I want is to introduce a \"pull.mode=ff-only\", not change the\nsemantics of --ff-only.\n\nWhat I have been saying is that you can't make --ff-only the default\nwithout changing its semantics.\n\nBut since the patch series that introduced such pull.mode [1] was\ncompletely ignored, I decided to take a shot at making --ff-only work.\n\nYou said [2]:\n\n> > What we want to see can be done without such backward incompatible\n> > changes, e.g. declaring the combination of \"--ff-only\" and\n> > \"--[no-]rebase\" incompatible and/or the last one wins, I would say, and\n> > I suspect Alex's RFC was an attempt to make the first step in that\n> > direction.\n\nBut in all my attempts the desired result cannot be done without\nbackwards incompatible changes. I'm just the messenger.\n\nTo be crystal clear: I don't want to change the semantics of\n--ff-only; I want to introduce a new \"pull.mode=ff-only\".\n\n> FWIW, I see the general direction as\n>\n>  - When the history you are pulling is not a descendant of what you\n>    have on your current branch, you must show your preference\n>    between merging their history into yours or rebasing your history\n>    onto theirs.\n\nAgreed.\n\n>  - In such a case, we error out, with an error message telling them\n>    that they must tell us which one they want in this invocation\n>    (e.g. with \"--rebase\" or \"--no-rebase\").  We further tell them\n>    that pull.rebase can be used to record their preference, if they\n>    almost always use the same.\n\nNot quite. See below.\n\n>         Side note: I earlier said \"see below\" to refer to this.  I\n>         think the message should offer what they can do right now\n>         with command line option first, and then give an option to\n>         configure.  IOW, the message quoted in the beginning of this\n>         response gives information in a wrong order.  Also,\n>         \"discouraged\" is misleading, isn't it?  When we give this\n>         message, we refuse to proceed until the user specifies.\n\nThat's why I keep pointing out the end goal. In the end it's not one\nmessage, it's *two*:\n\nYou can see my suggestion for both messages in my patch series for\npull.mode [1].\n\nWhen the user has specified \"pull.mode=ff-only\", the command dies with:\n\n  The pull was not fast-forward, please either merge or rebase.\n\nWhen the user has not specified any mode (by default), the command\nwould output a warning:\n\n  The pull was not fast-forward, in the future you will have to choose a\n  merge, or a rebase.\n\n  To squelch this message and maintain the current behavior, use:\n\n    git config --global pull.mode merge\n\n  To squelch this message and adopt the new behavior now, use:\n\n    git config --global push.mode ff-only\n\n  Falling back to old style for now (merge).\n  Read 'git pull --help' for more information.\n\nBut in order to reach that point we first need to decide what will be\nthe default mode, and how it will be configured (--ff-only or\n\"pull.mode=ff-only\").\n\nIn the meantime this particular series is not committing for any\nparticular decision, and thus it's changing the warning message for\nthe *current* situation in which the command does not fail, but only\nshows a warning. So today it's merely discouraged.\n\nThis particular patch is pretty far from the end goal. It's just patch\n#2 of part 1.\n\n>         Another thing to consider is that pull.ff=only (and\n>         --ff-only) may be wrong choice to offer in the error message\n>         quoted above, if one of the objectives is to reduce the\n>         \"annoying\" message that tells the user that they must\n>         choose.  By definition, we do not give the message when our\n>         side do not have our own development, so \"I could run 'pull\n>         --ff-only'\" is a unusable knowledge to those who see the\n>         message and want to get out of the situation.\n\nThose commands will squelch the warning, but won't change the\nunderlying nature of the warning, which is that the user must choose\nto either merge or rebase.\n\nThe temporary warning will disappear, but the permanent error message will not:\n\n  The pull was not fast-forward, please either merge or rebase.\n\n>  - But when the history being pulled is a descendant of the current\n>    branch, and the user does not give us preference between merge\n>    and rebase (either from the command line or with configuration),\n>    there is no need to give such an error message---if you do not\n>    have your own development, we can just fast-forward the current\n>    branch to what we fetched from the other side.  This does not\n>    happen with the current system, which is what we want to fix.\n\nIt's not an error message, it's a warning. But yes.\n\n>  - Also when the history from the other side is a descedant and the\n>    user has preference, either to rebase or to merge, either from\n>    the command line or with configuration, we can fast-forward the\n>    current branch to their tip, but there are wrinkles:\n>\n>    . when --ff=no is given and the choice is to merge (not rebase),\n>      we must create an extra merge commit.\n\n--ff receives no arguments, it's --no-ff.\n\nYes.\n\n>    . when the choice is to rebase, by definition, rebasing what you\n>      have on top of theirs in this case is the same as fast-forwarding\n>      the current branch to theirs, because \"what you have\" is an\n>      empty set.\n\nAgreed.\n\n>    . I am not sure how \"pull --rebase --ff=no\" should interact if we\n>      don't have our own development.  Rebasing our work on top of\n>      theirs is philosophically incompatible with marking where the\n>      side branch begins and ends with an extra commit, so it either\n>      should be rejected when the command line and configuration is\n>      parsed (i.e. regardless of the shape of the history we have at\n>      hand), or --ff=no gets silently ignored when --rebase is given.\n>      I haven't thought this one through.\n\nI thought of this instance as well. In my opinion such combination\nshould fail. But it doesn't actually affect anything.\n\n\nJust to put this series in context: it's only part 1; it does not\nintroduce pull.mode, and it doesn't make --ff-only the default.\nThere's one patch prefixed with \"tentative\" that changes the semantics\nof --ff-only to see how it could look like when making it the default,\nbut in no way am I proposing that patch to be merged.\n\nThe series is entirely about improving the current situation, nothing\ncontentious.\n\nIn part 2 I will introduce pull.mode, which is the solution I propose,\nand that would be basically rebasing [1] on top of this series\n(hopefully).\n\nI would have hoped that by this point it would have been clear why\n--ff-only is not the way forward. But oh well, we'll see what happens.\n\nCheers.\n\n[1] https://lore.kernel.org/git/20201125032938.786393-1-felipe.contreras@gmail.com/\n[2] https://lore.kernel.org/git/xmqqpn3qfhps.fsf@gitster.c.googlers.com\n\n-- \nFelipe Contreras\n"},{"id":"411597","messageId":"CAMP44s2zxrf6u6Dxr+GvKJqYdF6jF4BwPqXm4rG_OvRXk9Rm-A@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BFwWBLdFPsKi3o9hznFtAeWWfhNAyuymPS4BhMAHpnSfw@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-07T09:23:49Z","receivedAt":"2020-12-07T09:24:49Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 4, 2020 at 6:56 PM Elijah Newren <newren@gmail.com> wrote:\n\n> > > > diff --git a/builtin/pull.c b/builtin/pull.c\n> > > > index 1034372f8b..22a9ffcade 100644\n> > > > --- a/builtin/pull.c\n> > > > +++ b/builtin/pull.c\n> > > > @@ -346,17 +346,18 @@ static enum rebase_type config_get_rebase(void)\n> > > >\n> > > >         if (opt_verbosity >= 0 && !opt_ff) {\n> > > >                 advise(_(\"Pulling without specifying how to reconcile divergent branches is\\n\"\n> > > > -                        \"discouraged. You can squelch this message by running one of the following\\n\"\n> > > > -                        \"commands sometime before your next pull:\\n\"\n> > > > -                        \"\\n\"\n> > > > -                        \"  git config pull.rebase false  # merge (the default strategy)\\n\"\n> > > > -                        \"  git config pull.rebase true   # rebase\\n\"\n> > > > -                        \"  git config pull.ff only       # fast-forward only\\n\"\n> > > > -                        \"\\n\"\n> > > > -                        \"You can replace \\\"git config\\\" with \\\"git config --global\\\" to set a default\\n\"\n> > > > -                        \"preference for all repositories. You can also pass --rebase, --no-rebase,\\n\"\n> > > > -                        \"or --ff-only on the command line to override the configured default per\\n\"\n> > > > -                        \"invocation.\\n\"));\n> > > > +                       \"discouraged; you need to specify if you want a merge, or a rebase.\\n\"\n> > >\n> > > ...want a merge, a rebase, or neither.\n> >\n> > There is no \"git pull --no-merge\". Years ago some people argued for a\n> > \"pull.mode=none\" (essentially making \"git pull\" the same as \"git\n> > fetch\"). But right now there's no option to do that.\n> >\n> > There's an option to do --ff-only, but that's still a merge.\n>\n> I disagree.  I'm well aware that checkout_fast_forward() (which is\n> what is ultimately called to do the fast-forwarding) is in a file\n> called merge.c, but that doesn't make it a merge.  I don't believe it\n> was anything more than a convenient place to dump some extra code at\n> the time.\n>\n> > Perhaps: a merge, a rebase, or a fast-forward?\n>\n> Sure, that works; in fact, that's much better than my suggestion.  I like it.\n\nActually no. If we are talking about divergent branches you cannot fast-forward.\n\nThe original text was fine.\n\n-- \nFelipe Contreras\n"},{"id":"411609","messageId":"xmqqpn3lbhxn.fsf@gitster.c.googlers.com","threadId":"54758","inReplyTo":"CAMP44s2XFQoda_PMULWha-rj9HhNfEddO5fikmswk9=AWN4RCw@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-12-07T18:16:20Z","receivedAt":"2020-12-07T18:17:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> When the user has specified \"pull.mode=ff-only\", the command dies with:\n>\n>   The pull was not fast-forward, please either merge or rebase.\n>\n> When the user has not specified any mode (by default), the command\n> would output a warning:\n>\n>   The pull was not fast-forward, in the future you will have to choose a\n>   merge, or a rebase.\n\nI quite don't get it.  They say the same thing.  At that point the\nuser needs to choose between merge and rebase to move forward and\nff-only would not be a sensible choice to offer the user.\n\n> Just to put this series in context: it's only part 1; it does not\n> introduce pull.mode, and it doesn't make --ff-only the default.\n\nI'd view the \"in a non-fast-forward situation, the warning kicks in\nto those who haven't chosen between merge and rebase (i.e. no\npull.rebase set to either true or false, and pull.ff not set to\nonly), which is a bit more gentle than the current situtation\" a\ngood stopping point.  That state is already making ff-only the\ndefault for unconfigured users, or you can view it as shipping \"git\npull\" in a shape that has the more dangerous half of its feature\ndisabled to avoid hurting users.  So I am not sure why you keep\nsaying you do not have --ff-only as the default.\n"},{"id":"411624","messageId":"CAMP44s2nmVnXiBA8S=vHBZznuRNKKe=xGOEBJ80MYhA_XCqNkg@mail.gmail.com","threadId":"54758","inReplyTo":"xmqqpn3lbhxn.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-07T19:09:22Z","receivedAt":"2020-12-07T19:10:54Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Mon, Dec 7, 2020 at 12:16 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n> > When the user has specified \"pull.mode=ff-only\", the command dies with:\n> >\n> >   The pull was not fast-forward, please either merge or rebase.\n> >\n> > When the user has not specified any mode (by default), the command\n> > would output a warning:\n> >\n> >   The pull was not fast-forward, in the future you will have to choose a\n> >   merge, or a rebase.\n>\n> I quite don't get it.  They say the same thing.  At that point the\n> user needs to choose between merge and rebase to move forward and\n> ff-only would not be a sensible choice to offer the user.\n\nThe error happens *only* when the user has explicitly set\n\"pull.mode=ff-only\", and the pull dies. At that point; yes, the user\nmust choose between one or the other.\n\nBut the warning happens by default, when the user has not chosen any\nmode, and the pull succeeds. The user doesn't need to choose; the pull\ncontinues as if the user chose the \"merge\" mode, which is the historic\nbehavior.\n\nThey start by saying the same thing. But one errors out and says the\nuser must choose, and the other warns that in the future the user must\nchoose.\n\n> > Just to put this series in context: it's only part 1; it does not\n> > introduce pull.mode, and it doesn't make --ff-only the default.\n>\n> I'd view the \"in a non-fast-forward situation, the warning kicks in\n> to those who haven't chosen between merge and rebase (i.e. no\n> pull.rebase set to either true or false, and pull.ff not set to\n> only), which is a bit more gentle than the current situtation\" a\n> good stopping point.  That state is already making ff-only the\n> default for unconfigured users, or you can view it as shipping \"git\n> pull\" in a shape that has the more dangerous half of its feature\n> disabled to avoid hurting users.  So I am not sure why you keep\n> saying you do not have --ff-only as the default.\n\nThe warning doesn't make the pull fail, ff-only does.\n\nOn the current master this works:\n\n  test_expect_success 'non-fast-forward (default)' '\n    setup_non_ff &&\n    git pull\n  '\n\nAnd after my patch series (part 1) it still does. The default behavior\nhas not changed.\n\nI'm not sure what it is that I'm not explaining correctly.\n\n-- \nFelipe Contreras\n"},{"id":"411641","messageId":"xmqqlfe99yvy.fsf@gitster.c.googlers.com","threadId":"54758","inReplyTo":"CAMP44s2nmVnXiBA8S=vHBZznuRNKKe=xGOEBJ80MYhA_XCqNkg@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-12-07T19:53:05Z","receivedAt":"2020-12-07T19:54:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> They start by saying the same thing. But one errors out and says the\n> user must choose, and the other warns that in the future the user must\n> choose.\n\nThen I do not see the point in giving the warning---even in the\nfuture they do not have to choose as long as they are merely\nfollowing along.\n\n>> > Just to put this series in context: it's only part 1; it does not\n>> > introduce pull.mode, and it doesn't make --ff-only the default.\n>>\n>> I'd view the \"in a non-fast-forward situation, the warning kicks in\n>> to those who haven't chosen between merge and rebase (i.e. no\n>> pull.rebase set to either true or false, and pull.ff not set to\n>> only), which is a bit more gentle than the current situtation\" a\n>> good stopping point.  That state is already making ff-only the\n>> default for unconfigured users, or you can view it as shipping \"git\n>> pull\" in a shape that has the more dangerous half of its feature\n>> disabled to avoid hurting users.  So I am not sure why you keep\n>> saying you do not have --ff-only as the default.\n>\n> The warning doesn't make the pull fail, ff-only does.\n\nThen probably you are giving an error and a warning at a wrong\nplace.\n\n - When history fast-forwards, and the user hasn't chosen between\n   rebase or merge, there is no need to give any warning.  Just\n   succeed by fast-forwarding.\n\n - When history does not fast-forward and the user hasn't chosen\n   between rebase or merge, whether pull.ff is set to \"only\" or not,\n   we should fail and the error message can instruct the user to\n   choose between rebase and merge; there is no \"ff-only\" option\n   that is useful in the situation.\n\nAnd that essentially makes the \"ff-only\" mode the safe default that\ncastrates one half of the feature (the more dangerous half) of \"git\npull\".  Why do we make it more complicated than that by warning that\nthe user must choose in the future?  They will see an error tell\nthem that when they start pulling while on their own work, and I do\nnot see a need to bother them before that point.\n"},{"id":"411650","messageId":"CAMP44s3FRkdS9j=B0ht0Uviy4XE43PbObjXRk7hekRGPyoVCpg@mail.gmail.com","threadId":"54758","inReplyTo":"xmqqlfe99yvy.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-07T22:14:10Z","receivedAt":"2020-12-07T22:15:23Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Mon, Dec 7, 2020 at 1:53 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n> > They start by saying the same thing. But one errors out and says the\n> > user must choose, and the other warns that in the future the user must\n> > choose.\n>\n> Then I do not see the point in giving the warning---even in the\n> future they do not have to choose as long as they are merely\n> following along.\n\nThey don't. With my patch series they see the warning only when the\npull is non-fast-forward.\n\n> >> > Just to put this series in context: it's only part 1; it does not\n> >> > introduce pull.mode, and it doesn't make --ff-only the default.\n> >>\n> >> I'd view the \"in a non-fast-forward situation, the warning kicks in\n> >> to those who haven't chosen between merge and rebase (i.e. no\n> >> pull.rebase set to either true or false, and pull.ff not set to\n> >> only), which is a bit more gentle than the current situtation\" a\n> >> good stopping point.  That state is already making ff-only the\n> >> default for unconfigured users, or you can view it as shipping \"git\n> >> pull\" in a shape that has the more dangerous half of its feature\n> >> disabled to avoid hurting users.  So I am not sure why you keep\n> >> saying you do not have --ff-only as the default.\n> >\n> > The warning doesn't make the pull fail, ff-only does.\n>\n> Then probably you are giving an error and a warning at a wrong\n> place.\n>\n>  - When history fast-forwards, and the user hasn't chosen between\n>    rebase or merge, there is no need to give any warning.  Just\n>    succeed by fast-forwarding.\n\nYes. That's what my patch [1] in this series does.\n\n>  - When history does not fast-forward and the user hasn't chosen\n>    between rebase or merge, whether pull.ff is set to \"only\" or not,\n>    we should fail and the error message can instruct the user to\n>    choose between rebase and merge; there is no \"ff-only\" option\n>    that is useful in the situation.\n\nYes. *Eventually*, that's part 3.\n\n> And that essentially makes the \"ff-only\" mode the safe default that\n> castrates one half of the feature (the more dangerous half) of \"git\n> pull\".  Why do we make it more complicated than that by warning that\n> the user must choose in the future?  They will see an error tell\n> them that when they start pulling while on their own work, and I do\n> not see a need to bother them before that point.\n\nBecause the amount of time users have seen the correct error message\ntelling them about this upcoming change is *zero*.\n\nNo one is aware of this backwards-incompatible change that is\nupcoming, since the current warning message doesn't specify any such\nfuture change.\n\nMoreover, no one has configured their pull.mode, because no one has\nseen the message that tells them to do so.\n\nAnd no one has had time to try out the upcoming \"pull.mode=ff-only\".\nThey haven't had time to find bugs on it, or weird interactions, or\nsuggestions how to improve it. Because the code has not been deployed,\nand no warning has told them to tentatively enable that mode.\n\nWhen the default for push.default was changed, it was a good thing\nthat we gave users (and ourselves) a grace period to try it out before\npermanently flipping the switch. The transition went smoothly.\n\nI think the progression of the warning is hard to see from all the\npatch series. I'm sending all my patches and I will explain in a\ntimeline how it progresses until eventually we reach the desired end\ngoal.\n\nCheers.\n\n[1] https://lore.kernel.org/git/20201204061623.1170745-8-felipe.contreras@gmail.com/\n\n-- \nFelipe Contreras\n"},{"id":"411656","messageId":"CA+P7+xp=UGd0iK8uLxnqH0iycrxo--8on3d0Z+jsuyhpV-fVew@mail.gmail.com","threadId":"54758","inReplyTo":"xmqqlfe99yvy.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2020-12-07T23:30:04Z","receivedAt":"2020-12-07T23:30:58Z","isPatch":true,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Mon, Dec 7, 2020 at 11:53 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n> > They start by saying the same thing. But one errors out and says the\n> > user must choose, and the other warns that in the future the user must\n> > choose.\n>\n> Then I do not see the point in giving the warning---even in the\n> future they do not have to choose as long as they are merely\n> following along.\n>\n\nI think the key point is that this \"in the future\" is referring to \"a\nfuture version of git will make this an error\"\n\nThis might be better if it said something like \"The pull was not\nfast-forward. In a future version of git you will need to specify\nwhether to merge or rebase, using pull.mode\"\n\nor something similar. In theory, this warning will go away once that\nfuture version of git changes so that pull.mode defaults to ff-only.\n\nThe difference being that a warning will allow the command to continue\ndoing the default of today (merging), where as an error will stop the\ncommand essentially just after the fetch portion finishes, without\nchanging the branch.\n\nThanks,\nJake\n\n> >> > Just to put this series in context: it's only part 1; it does not\n> >> > introduce pull.mode, and it doesn't make --ff-only the default.\n> >>\n> >> I'd view the \"in a non-fast-forward situation, the warning kicks in\n> >> to those who haven't chosen between merge and rebase (i.e. no\n> >> pull.rebase set to either true or false, and pull.ff not set to\n> >> only), which is a bit more gentle than the current situtation\" a\n> >> good stopping point.  That state is already making ff-only the\n> >> default for unconfigured users, or you can view it as shipping \"git\n> >> pull\" in a shape that has the more dangerous half of its feature\n> >> disabled to avoid hurting users.  So I am not sure why you keep\n> >> saying you do not have --ff-only as the default.\n> >\n> > The warning doesn't make the pull fail, ff-only does.\n>\n> Then probably you are giving an error and a warning at a wrong\n> place.\n>\n>  - When history fast-forwards, and the user hasn't chosen between\n>    rebase or merge, there is no need to give any warning.  Just\n>    succeed by fast-forwarding.\n>\n\nCorrect.\n\n>  - When history does not fast-forward and the user hasn't chosen\n>    between rebase or merge, whether pull.ff is set to \"only\" or not,\n>    we should fail and the error message can instruct the user to\n>    choose between rebase and merge; there is no \"ff-only\" option\n>    that is useful in the situation.\n>\n\nYes, I understand that this is the destination Felipe wants us to end up at.\n\n> And that essentially makes the \"ff-only\" mode the safe default that\n> castrates one half of the feature (the more dangerous half) of \"git\n> pull\".  Why do we make it more complicated than that by warning that\n> the user must choose in the future?  They will see an error tell\n> them that when they start pulling while on their own work, and I do\n> not see a need to bother them before that point.\n\nThe warning would be in an earlier version of git before that is the\ndefault. The warning is for a transition period between today when we\nmerge by default (with a warning) and when we fail with an error\nwithout completing the pull. Once the default is the ff-only mode,\nthen the warning is no longer necessary, as we will get an error\nindicating that you must choose.\n\nThanks,\nJake\n"},{"id":"411709","messageId":"xmqq360h8286.fsf@gitster.c.googlers.com","threadId":"54758","inReplyTo":"CA+P7+xp=UGd0iK8uLxnqH0iycrxo--8on3d0Z+jsuyhpV-fVew@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-12-08T02:23:53Z","receivedAt":"2020-12-08T02:24:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jacob Keller <jacob.keller@gmail.com> writes:\n\n> I think the key point is that this \"in the future\" is referring to \"a\n> future version of git will make this an error\"\n>\n> This might be better if it said something like \"The pull was not\n> fast-forward. In a future version of git you will need to specify\n> whether to merge or rebase, using pull.mode\"\n\nOh, I've actually been assuming that the current \"warn but go ahead\nanyway asssuming the preference is to merge\" can just be declared as\na bug (iow, there is no need to say 'in the future'---we'd fix the\nbug right away).\n\n> or something similar. In theory, this warning will go away once that\n> future version of git changes so that pull.mode defaults to ff-only.\n>\n> The difference being that a warning will allow the command to continue\n> doing the default of today (merging), where as an error will stop the\n> command essentially just after the fetch portion finishes, without\n> changing the branch.\n\nYup.  If we want to take things slow, that is fine by me as well,\nbut I am not sure if that is even necessary, given how annoying the\nexisting \"loudly warn but still go ahead\" behaviour is, and how easy\nfor existing users to have squelched the annoyance by choosing\nbetween rebase and merge already.  I've always assumed that any\nexisting users who started using Git in the past several years have\nalready set pull.rebase to one or the other value and they won't be\naffected by fixing \"git pull\" to just error out.\n"},{"id":"411712","messageId":"CAMP44s3KCoDfRXzarJw5AE7UsY-=eP6GbHzdDcdrs2rsw5tL+w@mail.gmail.com","threadId":"54758","inReplyTo":"xmqq360h8286.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-08T03:15:05Z","receivedAt":"2020-12-08T03:16:11Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Mon, Dec 7, 2020 at 8:23 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Jacob Keller <jacob.keller@gmail.com> writes:\n>\n> > I think the key point is that this \"in the future\" is referring to \"a\n> > future version of git will make this an error\"\n> >\n> > This might be better if it said something like \"The pull was not\n> > fast-forward. In a future version of git you will need to specify\n> > whether to merge or rebase, using pull.mode\"\n>\n> Oh, I've actually been assuming that the current \"warn but go ahead\n> anyway asssuming the preference is to merge\" can just be declared as\n> a bug (iow, there is no need to say 'in the future'---we'd fix the\n> bug right away).\n\nIt is a bug, in my opinion. If we were not planning on changing the\ndefault, I would say drop the warning altogether.\n\n*But*, if we are going to change the default, the warning can be\nrepurposed to say \"in the future this will fail\". That requires other\nchanges though.\n\n> > or something similar. In theory, this warning will go away once that\n> > future version of git changes so that pull.mode defaults to ff-only.\n> >\n> > The difference being that a warning will allow the command to continue\n> > doing the default of today (merging), where as an error will stop the\n> > command essentially just after the fetch portion finishes, without\n> > changing the branch.\n\nExactly. And we can choose between those behaviors with a\nconfiguration, like it happened with push.default.\n\n> Yup.  If we want to take things slow, that is fine by me as well,\n> but I am not sure if that is even necessary, given how annoying the\n> existing \"loudly warn but still go ahead\" behaviour is, and how easy\n> for existing users to have squelched the annoyance by choosing\n> between rebase and merge already.  I've always assumed that any\n> existing users who started using Git in the past several years have\n> already set pull.rebase to one or the other value and they won't be\n> affected by fixing \"git pull\" to just error out.\n\nExisting users that are using up-to-date distributions, maybe. Debian\nstable is using v2.20.1. In general it's not a good idea to assume\nanything about our users. Recently a user of Oh My Zsh reported an\nissue with the backwards compatibility code of git-completion; he was\nusing v2.17 I think.\n\nThat is exemplified by the fact that this whole thread started from a\nuser that refused to configure pull.rebase and expected the Git\nproject to just do the right thing (which is basically choosing a\nuseful default).\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"411730","messageId":"xmqqy2i86ok1.fsf@gitster.c.googlers.com","threadId":"54758","inReplyTo":"CAMP44s3KCoDfRXzarJw5AE7UsY-=eP6GbHzdDcdrs2rsw5tL+w@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-12-08T20:16:46Z","receivedAt":"2020-12-08T20:17:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> That is exemplified by the fact that this whole thread started from a\n> user that refused to configure pull.rebase and expected the Git\n> project to just do the right thing (which is basically choosing a\n> useful default).\n\nWhich is basically asking for impossible, and I do not think it is a\ngood idea to focus our effort to satisfy such a request in general.\nThere is no useful default that suits everybody in this particular\ncase.\n\nThe \"force ff-only\" approach indeed gives a very sensible default\nbehaviour of dying for those who haven't expressed the choice\nbetween rebase and merge in a situation where the difference between\nthe two results in histories of different shapes.\n\nBut for anybody who uses git for real (read: produces his or her own\nhistory), it would be pretty much a useless default that forces the\nuser to say rebase or merge every time 'git pull' is run.  That is\nwhy I am not enthused by the pull.mode=(rebase/merge/ff-only)\nconfiguration.  The third choice does help completeness.  When a\nuser asks \"the documentation tells pull.mode can be set to\nnon-default behaviour---what value can one set it to to get the\ndefault behaviour of not allowing any original work?\", it can be\nanswered if we had pull.mode=ff-only.  But other than that, I do not\nsee any real use for the choice, which would mean in practice,\npull.mode would have only two useful values, rebase or merge.  That\ndoes not feel a good enough reason to supersede what already exists,\nwhich is pull.rebase=yes/no.\n\nPerhaps there is a good reason why certain classes of users would\nwant to configure pull.mode=ff-only (i.e. \"I might type 'git pull'\nby mistake, please stop me if I did so on a branch I have real work\nalready.\").  If that is the case, I would very much agree that it\nwould be awkward to express that choice in the current framework to\nchoose between pull.rebase=yes/no and pull.mode=(rebase/merge/ff-only)\nwould become a lot easier to explain.\n\nI dunno.\n"},{"id":"411833","messageId":"CAMP44s13YFZeOMz6V5sPdOnLXD-v3aQZiP7vvXXNfQLZP4Puwg@mail.gmail.com","threadId":"54758","inReplyTo":"xmqqy2i86ok1.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-09T09:52:49Z","receivedAt":"2020-12-09T09:53:44Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Tue, Dec 8, 2020 at 2:16 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n> > That is exemplified by the fact that this whole thread started from a\n> > user that refused to configure pull.rebase and expected the Git\n> > project to just do the right thing (which is basically choosing a\n> > useful default).\n>\n> Which is basically asking for impossible, and I do not think it is a\n> good idea to focus our effort to satisfy such a request in general.\n> There is no useful default that suits everybody in this particular\n> case.\n\nI think I already made this point, but this is the nirvana fallacy\n(the perfect is the enemy of the good) [1]. Just because we can't have\nthe perfect solution doesn't mean we can't pursue something better\nthan the current state.\n\nWhat was asked was not a perfect solution, just a better default. If\nright now the default is good enough for 20% of users, and with some\nchanges we can make it better for 40%... that's progress. We don't\nhave to wait until we have a solution for 100% of them.\n\n> But for anybody who uses git for real (read: produces his or her own\n> history), it would be pretty much a useless default that forces the\n> user to say rebase or merge every time 'git pull' is run.\n\nThis is not true.\n\nI will give you a real example.\n\nI create a branch named \"fc/margin\" based on \"master\", I make my\nchanges, I push the branch to my personal repository, and create a\npull request. This is the typical triangular workflow.\n\nThen I do \"git pull [--ff-only]\". What will happen? 1) As long as my\nbranch is not merged upstream, I will get an error, and my branch will\nstay where it is. But then, 2) when my branch is finally merged to\n\"master\" it will be fast-forwarded, so now both \"fc/margin\" and\n\"origin/master\" point to the same commit.\n\nA. Did I use git \"for real\"? (produce my own history)\nB. Was \"git pull [--ff-only]\" useful in this case?\n\nI think that one of the problems is that Git has so many different\nworkflows that finding another person that has your same workflow is\nlike finding a person with your same birthday. It's not impossible,\njust takes more than a few tries.\n\nAlso, and this is not a deriding question, I'm genuinely curious: how\noften do you send pull requests?\n\nBTW, this example above is real [2]. In my particular case very often\nI'm creating history, I'm just not the one pulling it.\n\n> But other than that, I do not\n> see any real use for the choice, which would mean in practice,\n> pull.mode would have only two useful values, rebase or merge.  That\n> does not feel a good enough reason to supersede what already exists,\n> which is pull.rebase=yes/no.\n\nThe fact that you don't see the use doesn't mean the use is not there.\n\nWhy do you think this issue keeps coming back again and again, and\nagain? And every time it comes back people say the same thing:\n\"fast-forward-only merges should be the default\".\n\nUnfortunately it's not that simple. It's a rabbit hole that leads to a\ncacophony of issues in git pull. However, we can fix some of them\n*today*.\n\n> Perhaps there is a good reason why certain classes of users would\n> want to configure pull.mode=ff-only (i.e. \"I might type 'git pull'\n> by mistake, please stop me if I did so on a branch I have real work\n> already.\").  If that is the case, I would very much agree that it\n> would be awkward to express that choice in the current framework to\n> choose between pull.rebase=yes/no and pull.mode=(rebase/merge/ff-only)\n> would become a lot easier to explain.\n\nThere's three options:\n\n1. pull.ff=only (that doesn't work IMO)\n2. pull.rebase=ff-only (that works, but it's kind of wonky)\n3. pull.mode=ff-only (maybe it should be pull.mode=fast-forward)\n\nBut the current option (pull.mode=merge) just doesn't fly. And BTW, I\ndid create a poll in reddit's r/git [3], and 67% (of 789) said they\ndidn't specify anything, just \"git pull\".\n\nSo, most people simply do \"git pull\" and hope for the best.\n\nMoreover, in 2014 I said if we don't fix it now (which is likely), we\nwill be discussing it again [4], and here we are now. And I'm saying\nit again: leave the mode as \"merge\", we will be discussing this again.\n\nI could do some mail archeology if you want, but this issue starts to\nbe mentioned at least since 2010, and virtually everyone (except one\nperson) agreed the default must change, even Linus Torvalds. Reading\nback what Linus said [5], it's something very, *very* close to what\nI'm proposing (I would argue my proposal is better).\n\nSo you let me know. Do you want me to dig a decade of discussions and\ncoalesce those conclusions into a summary so we can decide how to\nproceed? Or should I drop the plan? Only that if we drop it, I\n*guarantee* we will discuss it yet again years later.\n\nMoreover, this is the reason why I split the series in 3. Even if you\ndecide you don't want to change the default, part I of the series can\nstill be merged *today*, and everyone would benefit.\n\nCheers.\n\n[1] https://en.wikipedia.org/wiki/Nirvana_fallacy\n[2] https://github.com/git/git.github.io/commit/5d90fd64d80847e3d873da43515750bc04b639e2\n[3] https://www.reddit.com/r/git/comments/k6uj7c/do_you_use_git_pull/\n[4] https://lore.kernel.org/git/536429e97cf5a_200c12912f094@nysa.notmuch/\n[5] https://lore.kernel.org/git/CA+55aFz2Uvq4vmyjJPao5tS-uuVvKm6mbP7Uz8sdq1VMxMGJCw@mail.gmail.com/\n\n-- \nFelipe Contreras\n"},{"id":"411894","messageId":"CABPp-BGZcmHhge7JnM12baL_86yV-+7z4kkvFwUUrP+db8QD8Q@mail.gmail.com","threadId":"54758","inReplyTo":"CAMP44s13YFZeOMz6V5sPdOnLXD-v3aQZiP7vvXXNfQLZP4Puwg@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-12-09T19:05:11Z","receivedAt":"2020-12-09T19:06:37Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"Hi,\n\nOn Wed, Dec 9, 2020 at 1:53 AM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n>\n> On Tue, Dec 8, 2020 at 2:16 PM Junio C Hamano <gitster@pobox.com> wrote:\n> >\n> > Felipe Contreras <felipe.contreras@gmail.com> writes:\n> >\n> > > That is exemplified by the fact that this whole thread started from a\n> > > user that refused to configure pull.rebase and expected the Git\n> > > project to just do the right thing (which is basically choosing a\n> > > useful default).\n> >\n> > Which is basically asking for impossible, and I do not think it is a\n> > good idea to focus our effort to satisfy such a request in general.\n> > There is no useful default that suits everybody in this particular\n> > case.\n>\n> I think I already made this point, but this is the nirvana fallacy\n> (the perfect is the enemy of the good) [1]. Just because we can't have\n> the perfect solution doesn't mean we can't pursue something better\n> than the current state.\n>\n> What was asked was not a perfect solution, just a better default. If\n> right now the default is good enough for 20% of users, and with some\n> changes we can make it better for 40%... that's progress. We don't\n> have to wait until we have a solution for 100% of them.\n>\n> > But for anybody who uses git for real (read: produces his or her own\n> > history), it would be pretty much a useless default that forces the\n> > user to say rebase or merge every time 'git pull' is run.\n>\n> This is not true.\n>\n> I will give you a real example.\n>\n> I create a branch named \"fc/margin\" based on \"master\", I make my\n> changes, I push the branch to my personal repository, and create a\n> pull request. This is the typical triangular workflow.\n>\n> Then I do \"git pull [--ff-only]\". What will happen? 1) As long as my\n> branch is not merged upstream, I will get an error, and my branch will\n> stay where it is. But then, 2) when my branch is finally merged to\n> \"master\" it will be fast-forwarded, so now both \"fc/margin\" and\n> \"origin/master\" point to the same commit.\n>\n> A. Did I use git \"for real\"? (produce my own history)\n> B. Was \"git pull [--ff-only]\" useful in this case?\n>\n> I think that one of the problems is that Git has so many different\n> workflows that finding another person that has your same workflow is\n> like finding a person with your same birthday. It's not impossible,\n> just takes more than a few tries.\n>\n> Also, and this is not a deriding question, I'm genuinely curious: how\n> often do you send pull requests?\n>\n> BTW, this example above is real [2]. In my particular case very often\n> I'm creating history, I'm just not the one pulling it.\n>\n> > But other than that, I do not\n> > see any real use for the choice, which would mean in practice,\n> > pull.mode would have only two useful values, rebase or merge.  That\n> > does not feel a good enough reason to supersede what already exists,\n> > which is pull.rebase=yes/no.\n>\n> The fact that you don't see the use doesn't mean the use is not there.\n>\n> Why do you think this issue keeps coming back again and again, and\n> again? And every time it comes back people say the same thing:\n> \"fast-forward-only merges should be the default\".\n>\n> Unfortunately it's not that simple. It's a rabbit hole that leads to a\n> cacophony of issues in git pull. However, we can fix some of them\n> *today*.\n>\n> > Perhaps there is a good reason why certain classes of users would\n> > want to configure pull.mode=ff-only (i.e. \"I might type 'git pull'\n> > by mistake, please stop me if I did so on a branch I have real work\n> > already.\").  If that is the case, I would very much agree that it\n> > would be awkward to express that choice in the current framework to\n> > choose between pull.rebase=yes/no and pull.mode=(rebase/merge/ff-only)\n> > would become a lot easier to explain.\n>\n> There's three options:\n>\n> 1. pull.ff=only (that doesn't work IMO)\n> 2. pull.rebase=ff-only (that works, but it's kind of wonky)\n> 3. pull.mode=ff-only (maybe it should be pull.mode=fast-forward)\n>\n> But the current option (pull.mode=merge) just doesn't fly. And BTW, I\n> did create a poll in reddit's r/git [3], and 67% (of 789) said they\n> didn't specify anything, just \"git pull\".\n>\n> So, most people simply do \"git pull\" and hope for the best.\n>\n> Moreover, in 2014 I said if we don't fix it now (which is likely), we\n> will be discussing it again [4], and here we are now. And I'm saying\n> it again: leave the mode as \"merge\", we will be discussing this again.\n>\n> I could do some mail archeology if you want, but this issue starts to\n> be mentioned at least since 2010, and virtually everyone (except one\n> person) agreed the default must change, even Linus Torvalds. Reading\n> back what Linus said [5], it's something very, *very* close to what\n> I'm proposing (I would argue my proposal is better).\n>\n> So you let me know. Do you want me to dig a decade of discussions and\n> coalesce those conclusions into a summary so we can decide how to\n> proceed? Or should I drop the plan? Only that if we drop it, I\n> *guarantee* we will discuss it yet again years later.\n>\n> Moreover, this is the reason why I split the series in 3. Even if you\n> decide you don't want to change the default, part I of the series can\n> still be merged *today*, and everyone would benefit.\n\nHave I missed some subtlety here?  This whole email appears to me to\nbe arguing against a strawman.  Reading Junio's other emails in this\nthread[1][2], it's pretty clear he thinks the current behavior is\nbuggy and suggests how it should be changed.  From what I can tell,\nyou appear to be arguing against doing nothing and against only\naccepting perfection, neither of which were positions I saw anyone\ntake.  In fact, the positions you argue for at length appear to\nexactly match the ones he took[1][2].  What am I missing?\n\n[1] https://lore.kernel.org/git/xmqq360h8286.fsf@gitster.c.googlers.com/\n[2] https://lore.kernel.org/git/xmqqlfe99yvy.fsf@gitster.c.googlers.com/\n"},{"id":"411974","messageId":"CAMP44s2zEi7WqiwZMN8CRzjQ+1CjPpagpTqhAtX9Vx4a5XKoWg@mail.gmail.com","threadId":"54758","inReplyTo":"CABPp-BGZcmHhge7JnM12baL_86yV-+7z4kkvFwUUrP+db8QD8Q@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-10T02:39:07Z","receivedAt":"2020-12-10T02:40:24Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Hello,\n\nOn Wed, Dec 9, 2020 at 1:05 PM Elijah Newren <newren@gmail.com> wrote:\n> On Wed, Dec 9, 2020 at 1:53 AM Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n\n> > I could do some mail archeology if you want, but this issue starts to\n> > be mentioned at least since 2010, and virtually everyone (except one\n> > person) agreed the default must change, even Linus Torvalds. Reading\n> > back what Linus said [5], it's something very, *very* close to what\n> > I'm proposing (I would argue my proposal is better).\n> >\n> > So you let me know. Do you want me to dig a decade of discussions and\n> > coalesce those conclusions into a summary so we can decide how to\n> > proceed? Or should I drop the plan? Only that if we drop it, I\n> > *guarantee* we will discuss it yet again years later.\n> >\n> > Moreover, this is the reason why I split the series in 3. Even if you\n> > decide you don't want to change the default, part I of the series can\n> > still be merged *today*, and everyone would benefit.\n>\n> Have I missed some subtlety here?  This whole email appears to me to\n> be arguing against a strawman.  Reading Junio's other emails in this\n> thread[1][2], it's pretty clear he thinks the current behavior is\n> buggy and suggests how it should be changed.  From what I can tell,\n> you appear to be arguing against doing nothing and against only\n> accepting perfection, neither of which were positions I saw anyone\n> take.  In fact, the positions you argue for at length appear to\n> exactly match the ones he took[1][2].  What am I missing?\n\nPeople change their minds.\n\nPerhaps I misinterpreted something, but when Junio said \"I dunno\" I\ntake it to mean: he is unsure my proposal \"pull.mode=ff-only\" makes\nsense. He also said \"for anybody who uses git for real, [force\n-ff-only] would be pretty much a useless default\", which I take it to\nmean that perhaps we shouldn't change the default to that.\n\nBack in 2013 Junio said \"I now see how such a default makes sense.\"\n[1], but we are in 2020 and such a default that made sense is not the\ndefault.\n\nMind reading is a really bad habbit [2]; I don't know what other\npeople think, and I would not presume to know.\n\nAll I know is that the path forward is unclear. And because I\nprognosticated that, I split the series in 3 parts, and I've yet to\nsee any objection to part I, which would improve the situation for\nusers *today*.\n\nSo, while we make up our collective minds, there's no reason to bother\nour users with an annoying warning on *every* *single* *pull*.\n\nCheers.\n\n[1] https://lore.kernel.org/git/7vli74baym.fsf@alter.siamese.dyndns.org/\n[2] https://cogbtherapy.com/cbt-blog/common-cognitive-distortions-mind-reading\n\n-- \nFelipe Contreras\n"},{"id":"411981","messageId":"xmqqy2i6w45c.fsf@gitster.c.googlers.com","threadId":"54758","inReplyTo":"CABPp-BGZcmHhge7JnM12baL_86yV-+7z4kkvFwUUrP+db8QD8Q@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-12-10T06:45:19Z","receivedAt":"2020-12-10T06:46:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> Have I missed some subtlety here?  This whole email appears to me to\n> be arguing against a strawman.  Reading Junio's other emails in this\n> thread[1][2], it's pretty clear he thinks the current behavior is\n> buggy and suggests how it should be changed.  From what I can tell,\n> you appear to be arguing against doing nothing and against only\n> accepting perfection, neither of which were positions I saw anyone\n> take.  In fact, the positions you argue for at length appear to\n> exactly match the ones he took[1][2].  What am I missing?\n>\n> [1] https://lore.kernel.org/git/xmqq360h8286.fsf@gitster.c.googlers.com/\n> [2] https://lore.kernel.org/git/xmqqlfe99yvy.fsf@gitster.c.googlers.com/\n\nI tend to agree that the endgame state I want is pretty similar to\nwhat Felipe wants.  The seeming confusion is probably due to what\nexactly I mean by \"default\" is different from what he means.\n\nI view the proposed \"for unconfigured users, pull dies, and tells\nthem to choose between rebase or merge before it can continue, when\nfaced with a non-ff history\" as a safe fallback behaviour until the\nusers make their choice.\n\nIt is a safe fallback to disable the more dangerous half of the\ncommand until the user gives enough information to the command to do\nits job without damaging the resulting history; it is not something\nthe users would actively want to choose.  \n\nAnd that is what I meant by the default behaviour.\n\nAnd when we stop in such a manner, it is sensible to give an error\nmessage telling them \n\n - why we are stopping,\n\n - what they can do to move the immediate situation forward\n   (i.e. command line option that lets them choose), and\n\n - what they can do to make their choice permanent so that they\n   would never see the command stop when facing a non-ff history\n   (i.e. the configuration variables).\n\nUp to this point, I think both of us agree with the above.\n\nWe start to differ after this point.  I would want to see only\n\"rebase\" and \"merge in the \"choice\" in the above list.  Felipe, if I\nunderstand correctly, wants to add the third one, \"ff-only\", which\nmeans the more dangerous half of \"pull\" is disabled by default.\n\nI do not want to include that choice, as it would mean the more\nfamiliar pull.rebase=yes/no would no longer work, and we'd need to\nintroduce a new variable, like pull.mode=ff-only.  It would mean for\nthose who use \"pull\" to consolidate histories on their side and\nother people's side, whether they use rebase or merge, would now\nhave two ways to do the same thing (i.e. pull.rebase=no or\npull.mode=merge).  That is just making the end user experience more\ncomplex than necessary.\n\nWithout introducing pull.mode, the only thing the users cannot do,\nas far as I can tell, is to explicitly ask for the behaviour of an\nunconfigured user (i.e. error out when faced with non-ff history)\nwithout being told about the way to use configuration variable to\npermanently record their choice.  Other than that, the existing\npull.rebase=yes/no is perfectly adequate.  Felipe seems to think\notherwise and wants not just the \"safe fallback behaviour\", but can\nexplicitly be configured using pull.mode=ff-only (and if that is not\nwhat Felipe thinks, perhaps we are already in agreement without\nrealizing it).\n\nThinking about it again, I guess pull.rebase=yes/no plus a new\nadvise entry can easily give what Felipe seems to want.  We teach\n\"git pull\", when it is not told to rebase or merge (either via the\ncommand line --[no-]rebase or via pull.rebase configuration) and\nwhen it sees a non-ff history, to\n\n - error out with a message telling the user that we are stopping,\n   because the two histories needs consolidating to conclude this\n   pull, but the two available ways would give vastly different\n   result.\n\n - check the advice.pullNonFF configuration (as usual, it defaults\n   to true) and if true, further tell the user that\n\n    (1) they can either run \"git pull --rebase\" or \"git pull\n        --no-rebase\",\n\n    (2) they can configure their choice permanently with\n        pull.rebase=yes/no, and\n\n    (3) they can leave \"pull\" in the half-disabled state but stop\n        seeing this message by setting advice.pullNonFF to false.\n\nThe last part (i.e. advice.pullnonFF) is the only new thing I said\nin the various discussions on this topic (simply because I just came\nup with the idea).  Everything else I've already said it elsewhere.\n\nI dunno.\n"},{"id":"411985","messageId":"CAMP44s3NNDL+zJjaukV9D2dJyU=ugSrnWz9o-whO9hKnBTxAow@mail.gmail.com","threadId":"54758","inReplyTo":"xmqqy2i6w45c.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-10T09:08:59Z","receivedAt":"2020-12-10T09:10:09Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, Dec 10, 2020 at 12:45 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Elijah Newren <newren@gmail.com> writes:\n>\n> > Have I missed some subtlety here?  This whole email appears to me to\n> > be arguing against a strawman.  Reading Junio's other emails in this\n> > thread[1][2], it's pretty clear he thinks the current behavior is\n> > buggy and suggests how it should be changed.  From what I can tell,\n> > you appear to be arguing against doing nothing and against only\n> > accepting perfection, neither of which were positions I saw anyone\n> > take.  In fact, the positions you argue for at length appear to\n> > exactly match the ones he took[1][2].  What am I missing?\n> >\n> > [1] https://lore.kernel.org/git/xmqq360h8286.fsf@gitster.c.googlers.com/\n> > [2] https://lore.kernel.org/git/xmqqlfe99yvy.fsf@gitster.c.googlers.com/\n>\n> I tend to agree that the endgame state I want is pretty similar to\n> what Felipe wants.  The seeming confusion is probably due to what\n> exactly I mean by \"default\" is different from what he means.\n>\n> I view the proposed \"for unconfigured users, pull dies, and tells\n> them to choose between rebase or merge before it can continue, when\n> faced with a non-ff history\" as a safe fallback behaviour until the\n> users make their choice.\n>\n> It is a safe fallback to disable the more dangerous half of the\n> command until the user gives enough information to the command to do\n> its job without damaging the resulting history; it is not something\n> the users would actively want to choose.\n>\n> And that is what I meant by the default behaviour.\n>\n> And when we stop in such a manner, it is sensible to give an error\n> message telling them\n>\n>  - why we are stopping,\n>\n>  - what they can do to move the immediate situation forward\n>    (i.e. command line option that lets them choose), and\n>\n>  - what they can do to make their choice permanent so that they\n>    would never see the command stop when facing a non-ff history\n>    (i.e. the configuration variables).\n>\n> Up to this point, I think both of us agree with the above.\n\nI don't agree with the above.\n\nThe error I propose is just:\n\n  The pull was not fast-forward, please either merge or rebase.\n\nThat's it. Nothing more.\n\nI explained that was the final end goal in my list of steps [1]. I do\nnot think any suggestion for commands or configurations belongs in a\n*permanent* error message.\n\nDo we even have an error message that long?\n\n> We start to differ after this point.  I would want to see only\n> \"rebase\" and \"merge in the \"choice\" in the above list.  Felipe, if I\n> understand correctly, wants to add the third one, \"ff-only\", which\n> means the more dangerous half of \"pull\" is disabled by default.\n\nNo. I don't want to present the user *any* configuration option in the\n*permanent error* message, just: \"please either merge or rebase\".\nThat's it.\n\n> I do not want to include that choice, as it would mean the more\n> familiar pull.rebase=yes/no would no longer work, and we'd need to\n> introduce a new variable, like pull.mode=ff-only.\n\nWhether we present the user with that option or not doesn't matter.\n\"pull.rebase=yes/no\", would still work. The only thing that changes is\nwhat happens if the user does *not* set that option.\n\nThe reason \"pull.mode=ff-only\" needs to be introduced is that\n--ff-only doesn't work. Otherwise there's no way the user cannot\nselect the \"safe default\" mode. It has absolutely nothing to do with\nwhat we present the user with.\n\n> Without introducing pull.mode, the only thing the users cannot do,\n> as far as I can tell, is to explicitly ask for the behaviour of an\n> unconfigured user (i.e. error out when faced with non-ff history)\n> without being told about the way to use configuration variable to\n> permanently record their choice.\n\nThat's right, which is a *crucial* thing they must have.\n\nPart II of the proposal has these:\n\n  pull: add pull.mode\n  pull: add pull.mode=ff-only\n  pull: advice of future changes\n\nThis is where we want to be for a good considerable amount of time. A\npoint where the user is a) warned about future changes, b) can\nconfigure both the old and the new behavior, and c) we have time to\ntest and tune this new behavior (in case there are mistakes), *BEFORE*\nforcing all our users to switch to this new mode (unless they haven't\nconfigured otherwise).\n\nThis is what happened with \"push.default=simple\". We didn't just say:\nthe simple mode is the default mode, so just leave \"push.default\"\nblank if you want this mode. No. Because in theory we might have\ndecided before v2.0 that another mode was to be the default, or\nperhaps in v3.0 another one will. We want the user to be able to say:\nthis is the mode I want. Not whatever mode the Git project decides\nit's better this day of the week: *this* mode.\n\nThere is nothing good about the user being unable to specify the mode\nhe/she wants instead of the default, even if at this moment in time\nthey happen to be the same.\n\nMoreover, I can attach a patch on top of part I that skips right ahead\ntowards part 3, and flips the switch without any intermediary steps.\nThe patch is simple, but it's likely to be wrong. And I doubt anyone\nhas tested this patch series at this point. No amount of looking at\nthe code is going to spot all the problems.\n\nPeople actually need to try this code.\n\nOtherwise it's just some patches flying around that will never be\nmerged, and the problem will remain forever there.\n\n> Other than that, the existing\n> pull.rebase=yes/no is perfectly adequate.\n\nYou cannot specify \"pull.rebase=ff-only\", but I did send a patch for\nthat [2]. It was you the one that said it looked \"quite funny\" [3]:\n\"it looks quite funny for that single variable that controls the way\nhow pull works, whether rebase or merge is used, is pull.REBASE\".\n\nIf you think it's fine to have this warning:\n\n  The pull was not fast-forward, in the future you will have to choose\na merge, or a rebase.\n\n  To quell this message you have two main options:\n\n  1. Adopt the new behavior:\n\n    git config --global pull.rebase ff-only\n\n  2. Maintain the current behavior:\n\n    git config --global pull.rebase false\n\n  For now we will fall back to the traditional behavior (merge).\n  Read \"git pull --help\" for more information.\n\nFor months, possibly a year, possibly until v3.0, instead of this one\n(which is my proposal):\n\n  The pull was not fast-forward, in the future you will have to choose\na merge, or a rebase.\n\n  To quell this message you have two main options:\n\n  1. Adopt the new behavior:\n\n    git config --global pull.mode fast-forward\n\n  2. Maintain the current behavior:\n\n    git config --global pull.mode merge\n\n  For now we will fall back to the traditional behavior (merge).\n  Read \"git pull --help\" for more information.\n\nBy all means, let's go for that, make the decision.\n\nBut it was you who wanted to see how a pull.mode solution would look\nlike [4][5]. Well, this is how it looks like: 3 patches.\n\n> Felipe seems to think\n> otherwise and wants not just the \"safe fallback behaviour\", but can\n> explicitly be configured using pull.mode=ff-only (and if that is not\n> what Felipe thinks, perhaps we are already in agreement without\n> realizing it).\n\nNo. It doesn't matter if it's \"pull.mode=ff-only\", or\n\"pull.rebase=ff-only\", or \"pull.ff=only\", but one of those must turn\non the behavior that we want. And right now no option does.\n\n> Thinking about it again, I guess pull.rebase=yes/no plus a new\n> advise entry can easily give what Felipe seems to want.\n\nIt's not about what I want, it's about what the project wants. And I\nthink it's pretty clear what the project wants:\n\n  1. git pull to eventually fail in non-fast-forward cases\n  2. A grace period before that switch is flipped\n\nThat's it.\n\nMy proposal is the only one (so far) that gives us that.\n\nCheers.\n\n[1] https://lore.kernel.org/git/CAMP44s2hUCd9qc83LReGyjy8N+u++eK6VjwGhDhrX0f0SbKmig@mail.gmail.com/\n[2] https://lore.kernel.org/git/20201123224621.2573159-2-felipe.contreras@gmail.com/\n[3] https://lore.kernel.org/git/xmqqim9vlkdn.fsf@gitster.c.googlers.com/\n[4] https://lore.kernel.org/git/xmqqy2irjy4f.fsf@gitster.c.googlers.com/\n[5] https://lore.kernel.org/git/xmqq7dqagtgx.fsf@gitster.c.googlers.com/\n\n-- \nFelipe Contreras\n"},{"id":"411986","messageId":"CAMP44s3KAn-cSt0nD+kN+FAYceMZvyMsG4zj6cBfMfxzOzDFxw@mail.gmail.com","threadId":"54758","inReplyTo":"CAMP44s3NNDL+zJjaukV9D2dJyU=ugSrnWz9o-whO9hKnBTxAow@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-10T10:01:06Z","receivedAt":"2020-12-10T10:02:15Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, Dec 10, 2020 at 3:08 AM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n\n> It's not about what I want, it's about what the project wants. And I\n> think it's pretty clear what the project wants:\n>\n>   1. git pull to eventually fail in non-fast-forward cases\n>   2. A grace period before that switch is flipped\n>\n> That's it.\n>\n> My proposal is the only one (so far) that gives us that.\n\nNot to mention that part I is not even contentious. We can improve the\nsituation of users *today*.\n\n-- \nFelipe Contreras\n"},{"id":"412065","messageId":"xmqqtussirsl.fsf@gitster.c.googlers.com","threadId":"54758","inReplyTo":"CAMP44s3NNDL+zJjaukV9D2dJyU=ugSrnWz9o-whO9hKnBTxAow@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-12-11T07:17:01Z","receivedAt":"2020-12-11T10:04:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n>> And when we stop in such a manner, it is sensible to give an error\n>> message telling them\n>>\n>>  - why we are stopping,\n>>\n>>  - what they can do to move the immediate situation forward\n>>    (i.e. command line option that lets them choose), and\n>>\n>>  - what they can do to make their choice permanent so that they\n>>    would never see the command stop when facing a non-ff history\n>>    (i.e. the configuration variables).\n>>\n>> Up to this point, I think both of us agree with the above.\n>\n> I don't agree with the above.\n>\n> The error I propose is just:\n>\n>   The pull was not fast-forward, please either merge or rebase.\n>\n> That's it. Nothing more.\n\nIt says \"why we are stopping.\" quite well.  It would be a good\nmessage to use as the first part of the three-part message I\nmentioned above.\n\n> I explained that was the final end goal in my list of steps [1]. I do\n> not think any suggestion for commands or configurations belongs in a\n> *permanent* error message.\n\nIn the design I have in mind in the message you are responding to,\nthe users who haven't told their choice to Git would be the only\nfolks who get all three.\n\nYou want to let the user express: \"I do not want to choose either\nrebase or merge.  I want 'pull' to fail when it needs to deal with\nnon-ff history.  But I do not need to be told about command line\noption and configuration every time.\"\n\nI said I don't (I view that disabling half the \"git pull\" just a\nsafe fallback behaviour until the user chooses between merge and\nrebase), but if we wanted to offer it as a valid choice to users, we\ncan do so.  We just make it possible to squelch the latter two parts\nof the three-part message---you leave pull.rebase unconfigured and\nsquelch the latter two parts of the message, and you got the \"stop\nme, I do not merge or rebase, but don't even tell me how to further\nconfigure\" already.\n\nI agree the latter two should not be part of *permanent* error\nmessage.  And my suggestion did not intend to make them so---it\nshould have been quite obvious to who read the message you are\nresponding to through to the end and understood what it said.\n\nNow, how would we make it possible to squelch the latter two parts?\nIt is not a good idea to introduce pull.mode=ff-only for that\npurpose (pull.mode=rebase and pull.rebase=yes would unnecessarily\nbecome two redundant ways to do the same thing if we added a new\npull.mode variable).\n\nBut there is an established way used in this project when we allow\nsquelching overly-helpful help messages, and we can apply it here as\nwell.  That way:\n\n - unconfigured folks would get all the three parts of the messages,\n   just like the current system.\n\n - if you tell rebase or merge, you do not see any.\n\n - if you do not choose between rebase or merge, you can still\n   squelch the latter two by setting advice.pullNonFF to false.\n\nThe last one is \"keep the more dangerous half of 'git pull' disabled,\nwithout getting told how to enable it over and over\", which is what\nyou want to be able to specify.\n\n> The reason \"pull.mode=ff-only\" needs to be introduced is that\n> --ff-only doesn't work. Otherwise there's no way the user cannot\n> select the \"safe default\" mode. It has absolutely nothing to do with\n> what we present the user with.\n\nI too initially thought that pull.mode may be needed, but probably I\nwas wrong.  I do think this can be done without pull.mode at all, at\nleast in two ways, without adding different ways to do the same\nthing.\n\n - When pull.rebase is set to 'no' and pull.ff is set to 'only',\n   \"git pull\" that sees a non-ff history should error out safely.\n   The user is telling that their preference is to merge, but the\n   difference between merge and rebase does not really matter\n   because pull.ff=only would mean we forbid merges of non-ff\n   history anyway.  The message you'd get would be \"fatal: Not\n   possible to fast-forward, aborting.\" though.\n\n - Or with the advice that hides the latter two points, a user can\n   unset pull.rebase and set the advice.pullNonFF to false to get\n   the same behaviour (i.e. disable the more dangerous half of\n   \"pull\") with just the \"we stopped\" error message.\n\nI think either of these are close enough to what you want, and I\nthink the latter gives us more flexibility in how we tone down the\nmessage with advice.pullNonFF.\n"},{"id":"412070","messageId":"CAMP44s3CcNAT4dFogyo61zV+D1pZ-0K+1rDBk_BUk-RYVUW0RQ@mail.gmail.com","threadId":"54758","inReplyTo":"xmqqtussirsl.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-11T11:33:35Z","receivedAt":"2020-12-11T11:35:45Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Dec 11, 2020 at 4:02 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n> >> And when we stop in such a manner, it is sensible to give an error\n> >> message telling them\n> >>\n> >>  - why we are stopping,\n> >>\n> >>  - what they can do to move the immediate situation forward\n> >>    (i.e. command line option that lets them choose), and\n> >>\n> >>  - what they can do to make their choice permanent so that they\n> >>    would never see the command stop when facing a non-ff history\n> >>    (i.e. the configuration variables).\n> >>\n> >> Up to this point, I think both of us agree with the above.\n> >\n> > I don't agree with the above.\n> >\n> > The error I propose is just:\n> >\n> >   The pull was not fast-forward, please either merge or rebase.\n> >\n> > That's it. Nothing more.\n>\n> It says \"why we are stopping.\" quite well.  It would be a good\n> message to use as the first part of the three-part message I\n> mentioned above.\n\nThe two key parts of the message are:\n\n1. It is an *error*\n2. It is *permanent*\n\n> > I explained that was the final end goal in my list of steps [1]. I do\n> > not think any suggestion for commands or configurations belongs in a\n> > *permanent* error message.\n>\n> In the design I have in mind in the message you are responding to,\n> the users who haven't told their choice to Git would be the only\n> folks who get all three.\n\nWhat would that error message look like? And do you have any other\nexample of the current user interface where such a condescending long\nerror message is displayed?\n\n> You want to let the user express: \"I do not want to choose either\n> rebase or merge.  I want 'pull' to fail when it needs to deal with\n> non-ff history.  But I do not need to be told about command line\n> option and configuration every time.\"\n\nThat's right.\n\n> I said I don't (I view that disabling half the \"git pull\" just a\n> safe fallback behaviour until the user chooses between merge and\n> rebase), but if we wanted to offer it as a valid choice to users, we\n> can do so.  We just make it possible to squelch the latter two parts\n> of the three-part message---you leave pull.rebase unconfigured and\n> squelch the latter two parts of the message, and you got the \"stop\n> me, I do not merge or rebase, but don't even tell me how to further\n> configure\" already.\n>\n> I agree the latter two should not be part of *permanent* error\n> message.  And my suggestion did not intend to make them so---it\n> should have been quite obvious to who read the message you are\n> responding to through to the end and understood what it said.\n\nIt doesn't matter (much) if it's temporary or permanent, it's still an\n*error* message.\n\nCurrently it's a warning, and people are complaining, even though the\npull still works.\n\nAnd you want to make it an error, and *always* fail? Even though the\nuser has not been warned that such a change was coming and how to\nevade it?\n\nI'm against that. I would rather do nothing than intentionally break\nuser experience without warning.\n\nJohannes said he didn't mind the warning. I want the warning to\nremain, just make it a different warning. You want to break his\nexperience without a grace period and suddenly make it an error.\n\n> Now, how would we make it possible to squelch the latter two parts?\n\n...\n\nThis is irrelevant.\n\nAs long as it's an error I don't care if it's short or long. I'm\nagainst turning on an error from one version to the next.\n\n> > The reason \"pull.mode=ff-only\" needs to be introduced is that\n> > --ff-only doesn't work. Otherwise there's no way the user cannot\n> > select the \"safe default\" mode. It has absolutely nothing to do with\n> > what we present the user with.\n>\n> I too initially thought that pull.mode may be needed, but probably I\n> was wrong.  I do think this can be done without pull.mode at all, at\n> least in two ways, without adding different ways to do the same\n> thing.\n>\n>  - When pull.rebase is set to 'no' and pull.ff is set to 'only',\n>    \"git pull\" that sees a non-ff history should error out safely.\n>    The user is telling that their preference is to merge, but the\n>    difference between merge and rebase does not really matter\n>    because pull.ff=only would mean we forbid merges of non-ff\n>    history anyway.  The message you'd get would be \"fatal: Not\n>    possible to fast-forward, aborting.\" though.\n>\n>  - Or with the advice that hides the latter two points, a user can\n>    unset pull.rebase and set the advice.pullNonFF to false to get\n>    the same behaviour (i.e. disable the more dangerous half of\n>    \"pull\") with just the \"we stopped\" error message.\n\nSo, after your hypothetical patch, there would be no difference between:\n\n  git -c pull.rebase=no -c pull.ff=only pull\n\nand:\n\n  git -c advice.pullnonff=false pull\n\n?\n\n> I think either of these are close enough to what you want, and I\n> think the latter gives us more flexibility in how we tone down the\n> message with advice.pullNonFF.\n\nYou are missing at least two things.\n\nI'll wait for your response.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"412206","messageId":"xmqqh7ooje03.fsf@gitster.c.googlers.com","threadId":"54758","inReplyTo":"CAMP44s3CcNAT4dFogyo61zV+D1pZ-0K+1rDBk_BUk-RYVUW0RQ@mail.gmail.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-12-14T21:04:28Z","receivedAt":"2020-12-14T21:05:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> This is irrelevant.\n\nOh, now you are saying that you do not need a way to squelch these\nmessage to help unconfigured users choose between rebase or merge?\nI am confused.\n\n> As long as it's an error I don't care if it's short or long. I'm\n> against turning on an error from one version to the next.\n\nNow you are changing your mind?  Current version and past ones do\nnot make it an error to pull non-ff history without choosing rebase\nor merge---we go ahead and merge anyway.  I thought that in the far\nfuture agreed between two of us, it would be turnend into an error\nat some point.  There needs one version that turns it into an error\nfor that to happen.  Puzzled.\n\n>> I too initially thought that pull.mode may be needed, but probably I\n>> was wrong.  I do think this can be done without pull.mode at all, at\n>> least in two ways, without adding different ways to do the same\n>> thing.\n>>\n>>  - When pull.rebase is set to 'no' and pull.ff is set to 'only',\n>>    \"git pull\" that sees a non-ff history should error out safely.\n>>    The user is telling that their preference is to merge, but the\n>>    difference between merge and rebase does not really matter\n>>    because pull.ff=only would mean we forbid merges of non-ff\n>>    history anyway.  The message you'd get would be \"fatal: Not\n>>    possible to fast-forward, aborting.\" though.\n>>\n>>  - Or with the advice that hides the latter two points, a user can\n>>    unset pull.rebase and set the advice.pullNonFF to false to get\n>>    the same behaviour (i.e. disable the more dangerous half of\n>>    \"pull\") with just the \"we stopped\" error message.\n>\n> So, after your hypothetical patch, there would be no difference between:\n>\n>   git -c pull.rebase=no -c pull.ff=only pull\n>\n> and:\n>\n>   git -c advice.pullnonff=false pull\n>\n> ?\n\nWe do not have to or implement both, but either should give us the\n\"when pull sees a non-ff history, it should stop without merging or\nrebasing, and the user won't be given the advice on how to choose\nbetween merge and rebase\" behaviour, I would think.\n\n>> I think either of these are close enough to what you want, and I\n>> think the latter gives us more flexibility in how we tone down the\n>> message with advice.pullNonFF.\n>\n> You are missing at least two things.\n\nI am guessing that the '?' above I just answered is one you wanted\nto ask me, but what's the other one?\n"},{"id":"412210","messageId":"5fd7e77c78e06_d59852083e@natae.notmuch","threadId":"54758","inReplyTo":"xmqqh7ooje03.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-14T22:30:20Z","receivedAt":"2020-12-14T22:31:24Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Junio C Hamano wrote:\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n> \n> > This is irrelevant.\n> \n> Oh, now you are saying that you do not need a way to squelch these\n> message to help unconfigured users choose between rebase or merge?\n> I am confused.\n\nWe need a way to squelch the *advise* message, yes.\n\nBut this is a secondary priority. The first priority is not to break\ncurrent behavior users rely on.\n\n> > As long as it's an error I don't care if it's short or long. I'm\n> > against turning on an error from one version to the next.\n> \n> Now you are changing your mind?  Current version and past ones do\n> not make it an error to pull non-ff history without choosing rebase\n> or merge---we go ahead and merge anyway.  I thought that in the far\n> future agreed between two of us, it would be turnend into an error\n> at some point.  There needs one version that turns it into an error\n> for that to happen.  Puzzled.\n\nYes, in the future, *after* a deprecation period.\n\nOnce the users have had a chance to configure git to do what they want,\nhave tried the new mode, haven't had issues with the new mode, or if\nthey disagree with the proposed *future* behavior; complain in the\nforums at their disposal.\n\nNot before.\n\n> >> I too initially thought that pull.mode may be needed, but probably I\n> >> was wrong.  I do think this can be done without pull.mode at all, at\n> >> least in two ways, without adding different ways to do the same\n> >> thing.\n> >>\n> >>  - When pull.rebase is set to 'no' and pull.ff is set to 'only',\n> >>    \"git pull\" that sees a non-ff history should error out safely.\n> >>    The user is telling that their preference is to merge, but the\n> >>    difference between merge and rebase does not really matter\n> >>    because pull.ff=only would mean we forbid merges of non-ff\n> >>    history anyway.  The message you'd get would be \"fatal: Not\n> >>    possible to fast-forward, aborting.\" though.\n> >>\n> >>  - Or with the advice that hides the latter two points, a user can\n> >>    unset pull.rebase and set the advice.pullNonFF to false to get\n> >>    the same behaviour (i.e. disable the more dangerous half of\n> >>    \"pull\") with just the \"we stopped\" error message.\n> >\n> > So, after your hypothetical patch, there would be no difference between:\n> >\n> >   git -c pull.rebase=no -c pull.ff=only pull\n> >\n> > and:\n> >\n> >   git -c advice.pullnonff=false pull\n> >\n> > ?\n> \n> We do not have to or implement both, but either should give us the\n> \"when pull sees a non-ff history, it should stop without merging or\n> rebasing, and the user won't be given the advice on how to choose\n> between merge and rebase\" behaviour, I would think.\n\nRight, so both should error out.\n\nAnd what should these do?\n\n  git -c pull.rebase=no -c pull.ff=only pull --merge\n\n  git -c advice.pullnonff=false pull --merge\n\nI'm going to answer because I think it's obvious what you would expect:\nif you pass --merge, both should succeed.\n\nExcept they won't, because \"git pull --ff-only --merge\" fails.\n\nCorrect?\n\n> >> I think either of these are close enough to what you want, and I\n> >> think the latter gives us more flexibility in how we tone down the\n> >> message with advice.pullNonFF.\n> >\n> > You are missing at least two things.\n> \n> I am guessing that the '?' above I just answered is one you wanted\n> to ask me, but what's the other one?\n\nYes. The other is what I explained above; we need a grace deprecation\nperiod where we can explain to the user in a simple way what to expect\nin the future.\n\nAnd it's much easier to explain to the user that:\n\n  git pull --merge -> pull.mode = merge\n  git pull --rebase -> pull.mode = rebase\n  git pull -> pull.mode = fast-forward\n\nThan:\n\n  git pull --merge -> pull.rebase = false\n  git pull --rebase -> pull.rebase = true\n  git pull -> pull.rebase = false + pull.ff = only\n\nBut those are not the only two. For example there's this additional\nproblem of how to interact with the other values of pull.rebase (other\nthan true and false):\n\n  pull.mode = merge\n  pull.rebase = merges\n\nI would expect in this particular configuration that:\n\n  git pull -> git pull --merge\n  git pull --rebase -> git pull --rebase=merges\n\nThere's no way to represent that with just pull.rebase.\n\nAnd there's more: some people suggested other modes in 2013, like\n\"pull.mode=none\" (essentially \"git fetch\"), or\n\"pull.mode=merge-reverse-parents\".\n\nBut the first one should be enough (\"git pull --ff-only --merge\" doesn't\nwork).\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"412216","messageId":"xmqqzh2g9e0r.fsf@gitster.c.googlers.com","threadId":"54758","inReplyTo":"5fd7e77c78e06_d59852083e@natae.notmuch","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-12-14T23:14:12Z","receivedAt":"2020-12-14T23:15:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n>> We do not have to or implement both, but either should give us the\n>> \"when pull sees a non-ff history, it should stop without merging or\n>> rebasing, and the user won't be given the advice on how to choose\n>> between merge and rebase\" behaviour, I would think.\n>\n> Right, so both should error out.\n\nOne of them, not both; the one we choose to implement would make it\nfail, I would think.\n\n> And what should these do?\n>\n>   git -c pull.rebase=no -c pull.ff=only pull --merge\n\nThere is no --merge, so let's reread with s/--merge/--no-rebase/;\nthe command line would be saying \"I only want to fast-forward, or I\nwant the command to fail\".  The advice code should not trigger\n(i.e. we gave an explicit preference to merge and not to rebase, so\nrebase_unspecified would be false), but the configured preference\nthat says \"we take only fast-forward merges\" will still be in effect.\nIf the history is fast-forward, the merge backend will happily\nadvance our history.  If not, the merge backend will happily fail\nthe pull.\n\nIf you want to countermand the configured preference from the\ncommand line and allow a merge to be done when non-ff history is\ngiven, what you'd need to override is not --merge/--no-rebase.  The\nconfiguration pull.rebase=no already says you do not want rebase and\nyou want merge).  You want to override --ff-only, so I'd expect\n\"pull --ff\" (or \"pull --no-ff\") to be how you override your\nconfigured preference and merge in a non-ff history, either by fast\nforwarding or creating an extra merge commit.\n\n>   git -c advice.pullnonff=false pull --merge\n\nAgain with s/--merge/--no-rebase/; but that is showing the\npreference not to rebase and to merge from the command line, so\nshouldn't it just go ahead and merge without any advice?\n\n\n> I'm going to answer because I think it's obvious what you would expect:\n> if you pass --merge, both should succeed.\n>\n> Except they won't, because \"git pull --ff-only --merge\" fails.\n>\n> Correct?\n\nSee above.\n\n"},{"id":"412229","messageId":"X9ggAxk/z0D9Qom+@coredump.intra.peff.net","threadId":"54758","inReplyTo":"xmqqtussirsl.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2020-12-15T02:31:31Z","receivedAt":"2020-12-15T02:34:02Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Dec 10, 2020 at 11:17:01PM -0800, Junio C Hamano wrote:\n\n> You want to let the user express: \"I do not want to choose either\n> rebase or merge.  I want 'pull' to fail when it needs to deal with\n> non-ff history.  But I do not need to be told about command line\n> option and configuration every time.\"\n> \n> I said I don't (I view that disabling half the \"git pull\" just a\n> safe fallback behaviour until the user chooses between merge and\n> rebase), but if we wanted to offer it as a valid choice to users, we\n> can do so.  We just make it possible to squelch the latter two parts\n> of the three-part message---you leave pull.rebase unconfigured and\n> squelch the latter two parts of the message, and you got the \"stop\n> me, I do not merge or rebase, but don't even tell me how to further\n> configure\" already.\n\nFWIW, I would be such a user who would want to squelch the error but\nkeep the ff-only behavior (and have been doing so for years via\npull.ff=only).\n\nI primarily use \"git pull\" only with branches where I am tracking\nupstream work, but don't have any of my own (e.g., if I do all of my\nwork on topic branches, I may still keep a \"master\" branch that mirrors\n\"origin/master\", and use \"git checkout master && git pull\" to\nfast-forward it).\n\nSo I think this is a valuable thing to have. And it does work just fine\nalready, without pull.mode. The reasons to care about pull.mode (IMHO)\nare mostly about explaining it:\n\n  - it isn't respected with rebase. So if you set pull.rebase=true, now\n    pull.ff=only does nothing. This is arguably confusing, though I\n    doubt it comes up much in practice.\n\n  - having a single tri-state of merge/rebase/error for \"what do I do\n    when pulling a non-fast-forward merge\" is conceptually simple and\n    easy to explain.\n\nSo I like pull.mode in that sense. But it is also weighed against the\nfact that we'd still have to support pull.rebase, and we'd still have to\nsupport pull.ff, and explain how those interact with pull.mode (and I\nthink any new error in this area must be squelched by those existing\nvariables, or it would be a regression for people who already picked\ntheir default long ago).\n\n> But there is an established way used in this project when we allow\n> squelching overly-helpful help messages, and we can apply it here as\n> well.  That way:\n> \n>  - unconfigured folks would get all the three parts of the messages,\n>    just like the current system.\n> \n>  - if you tell rebase or merge, you do not see any.\n> \n>  - if you do not choose between rebase or merge, you can still\n>    squelch the latter two by setting advice.pullNonFF to false.\n> \n> The last one is \"keep the more dangerous half of 'git pull' disabled,\n> without getting told how to enable it over and over\", which is what\n> you want to be able to specify.\n\nUsing advice.* to squelch the advice would be fine with me, provided it\nwas _also_ squelched by the existing config options.\n\nWhich I think is where your thinking is ending up.\n\n-Peff\n"},{"id":"412230","messageId":"5fd8213598c33_d7c4820837@natae.notmuch","threadId":"54758","inReplyTo":"xmqqzh2g9e0r.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-15T02:36:37Z","receivedAt":"2020-12-15T02:37:59Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Junio C Hamano wrote:\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n> \n> >> We do not have to or implement both, but either should give us the\n> >> \"when pull sees a non-ff history, it should stop without merging or\n> >> rebasing, and the user won't be given the advice on how to choose\n> >> between merge and rebase\" behaviour, I would think.\n> >\n> > Right, so both should error out.\n> \n> One of them, not both; the one we choose to implement would make it\n> fail, I would think.\n\nIf only one of them fail, then it's impossible to tell the user:\n\n  If you want to try the new behavior, type this command:\n\n    git config $something\n\nWe have to go straight for the error, with no deprecation period.\n\n> > And what should these do?\n> >\n> >   git -c pull.rebase=no -c pull.ff=only pull --merge\n> \n> There is no --merge, so let's reread with s/--merge/--no-rebase/;\n\nBack in 2013 everyone found it easier to speak in terms of --merge, even\nyou, BTW, who was the first one to send a patch with --merge [1], after\nLinus suggested it [2].\n\n> the command line would be saying \"I only want to fast-forward, or I\n> want the command to fail\".  The advice code should not trigger\n> (i.e. we gave an explicit preference to merge and not to rebase, so\n> rebase_unspecified would be false), but the configured preference\n> that says \"we take only fast-forward merges\" will still be in effect.\n> If the history is fast-forward, the merge backend will happily\n> advance our history.  If not, the merge backend will happily fail\n> the pull.\n> \n> If you want to countermand the configured preference from the\n> command line and allow a merge to be done when non-ff history is\n> given, what you'd need to override is not --merge/--no-rebase.  The\n> configuration pull.rebase=no already says you do not want rebase and\n> you want merge).  You want to override --ff-only, so I'd expect\n> \"pull --ff\" (or \"pull --no-ff\") to be how you override your\n> configured preference and merge in a non-ff history, either by fast\n> forwarding or creating an extra merge commit.\n\nPrecisely, so you can't tell the user:\n\n  If you want to try the new behavior, type this command:\n\n    git config pull.ff only\n\nBecause, after the user gets the error:\n\n  Not a fast-forward, either merge or rebase.\n\nShe cannot do:\n\n  git pull --merge\n\nWhich is the best idiom to specify she wants a merge.\n\nThe command will still fail, even after the user has specified she wants\nthe new mode, and that she wants to merge in this perticular case.\n\n> >   git -c advice.pullnonff=false pull --merge\n> \n> Again with s/--merge/--no-rebase/; but that is showing the\n> preference not to rebase and to merge from the command line, so\n> shouldn't it just go ahead and merge without any advice?\n\nYes, but *before* we make this the default, what configuration get us\nthere today?\n\n> > I'm going to answer because I think it's obvious what you would expect:\n> > if you pass --merge, both should succeed.\n> >\n> > Except they won't, because \"git pull --ff-only --merge\" fails.\n> >\n> > Correct?\n> \n> See above.\n\nThat's a \"correct\". There's no configuration today that gives us both:\n\n 1. fail: git -c $config pull\n 2. pass: git -c $config pull --merge\n\nLike this does:\n\n 1. fail: git -c pull.mode=fast-forward pull\n 2. pass: git -c pull.mode=fast-forward pull --merge\n\nCheers.\n\n[1] https://lore.kernel.org/git/7v4ncjs5az.fsf_-_@alter.siamese.dyndns.org/\n[2] https://lore.kernel.org/git/CA+55aFz2Uvq4vmyjJPao5tS-uuVvKm6mbP7Uz8sdq1VMxMGJCw@mail.gmail.com/\n\n-- \nFelipe Contreras\n"},{"id":"412240","messageId":"5fd8324d70ae5_d7c48208fa@natae.notmuch","threadId":"54758","inReplyTo":"X9ggAxk/z0D9Qom+@coredump.intra.peff.net","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-15T03:49:33Z","receivedAt":"2020-12-15T03:50:59Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Jeff King wrote:\n> On Thu, Dec 10, 2020 at 11:17:01PM -0800, Junio C Hamano wrote:\n> \n> > You want to let the user express: \"I do not want to choose either\n> > rebase or merge.  I want 'pull' to fail when it needs to deal with\n> > non-ff history.  But I do not need to be told about command line\n> > option and configuration every time.\"\n> > \n> > I said I don't (I view that disabling half the \"git pull\" just a\n> > safe fallback behaviour until the user chooses between merge and\n> > rebase), but if we wanted to offer it as a valid choice to users, we\n> > can do so.  We just make it possible to squelch the latter two parts\n> > of the three-part message---you leave pull.rebase unconfigured and\n> > squelch the latter two parts of the message, and you got the \"stop\n> > me, I do not merge or rebase, but don't even tell me how to further\n> > configure\" already.\n> \n> FWIW, I would be such a user who would want to squelch the error but\n> keep the ff-only behavior (and have been doing so for years via\n> pull.ff=only).\n\nIf you have configured pull.ff=only, you should be getting this error:\n\n\tNot possible to fast-forward, aborting.\n\nWe would like this error instead:\n\n  Not a fast-forward, either merge or rebase.\n\nAnd after that it should be obvious what this command should do with\nyour current configuration:\n\n  git pull --merge\n\nBut it would fail, even after specifying you want to do a merge, because\n\"git pull --ff-only --merge\" fails.\n\n> So I think this is a valuable thing to have. And it does work just fine\n> already, without pull.mode. The reasons to care about pull.mode (IMHO)\n> are mostly about explaining it:\n> \n>   - it isn't respected with rebase. So if you set pull.rebase=true, now\n>     pull.ff=only does nothing. This is arguably confusing, though I\n>     doubt it comes up much in practice.\n> \n>   - having a single tri-state of merge/rebase/error for \"what do I do\n>     when pulling a non-fast-forward merge\" is conceptually simple and\n>     easy to explain.\n\nIndeed. It's *mostly* about explaining it, but there's also what I\nstated above:\n\n  git -c pull.mode=fast-forward pull\n  git -c pull.mode=fast-forward pull --merge\n\nWe want the first one to fail, and the second one to succeed, which\ncan't be done with the current \"pull.ff=only\".\n\n> So I like pull.mode in that sense. But it is also weighed against the\n> fact that we'd still have to support pull.rebase, and we'd still have to\n> support pull.ff, and explain how those interact with pull.mode (and I\n> think any new error in this area must be squelched by those existing\n> variables, or it would be a regression for people who already picked\n> their default long ago).\n\nThe interactions should be easy:\n\n  * pull.rebase=false -> pull.mode=merge\n  * pull.rebase=the-rest -> pull.mode=rebase\n  * pull.ff=only -> pull.mode=fast-forward\n\n(note: I'm not entirely sure of the last one)\n\nThen, any --merge/--rebase option overrides the mode, but not so the\n--ff options.\n\nWe would still like this to fail:\n\n  git -c pull.mode=merge pull --ff-only\n\nRight?\n\nIn other words: pull.mode is strongly linked with pull.rebase, but not so\nmuch wih --ff*.\n\n> > But there is an established way used in this project when we allow\n> > squelching overly-helpful help messages, and we can apply it here as\n> > well.  That way:\n> > \n> >  - unconfigured folks would get all the three parts of the messages,\n> >    just like the current system.\n> > \n> >  - if you tell rebase or merge, you do not see any.\n> > \n> >  - if you do not choose between rebase or merge, you can still\n> >    squelch the latter two by setting advice.pullNonFF to false.\n> > \n> > The last one is \"keep the more dangerous half of 'git pull' disabled,\n> > without getting told how to enable it over and over\", which is what\n> > you want to be able to specify.\n> \n> Using advice.* to squelch the advice would be fine with me, provided it\n> was _also_ squelched by the existing config options.\n> \n> Which I think is where your thinking is ending up.\n\nYes. At least that's my thinking.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"412254","messageId":"xmqqh7on8gia.fsf@gitster.c.googlers.com","threadId":"54758","inReplyTo":"X9ggAxk/z0D9Qom+@coredump.intra.peff.net","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-12-15T11:18:05Z","receivedAt":"2020-12-15T11:19:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> So I like pull.mode in that sense. But it is also weighed against the\n> fact that we'd still have to support pull.rebase, and we'd still have to\n> support pull.ff, and explain how those interact with pull.mode (and I\n> think any new error in this area must be squelched by those existing\n> variables, or it would be a regression for people who already picked\n> their default long ago).\n\nI agree that if we were starting from scratch, things would have\nbeen much simpler; choose among three ways to reconcile histories\n(merge, rebase, or ff-only), without adding --[no-]rebase, and allow\n--[no-]ff only when merging (i.e. things like --ff-only --ff,\n--no-ff --rebase, would be nonsense combinations).  The additional\ncomplexity of introducing pull.mode is the primary thing I am\nhesitant to support it, as we have to design and explain how\nexisting knobs interact with newer one.\n\n> Using advice.* to squelch the advice would be fine with me, provided it\n> was _also_ squelched by the existing config options.\n\nMeaning \"once you choose between rebase or merge, facing a non-ff\nhistory would not trigger the advice message\"?  I think that is\nalready the case with the released versions of Git, and I think that\nis a good thing to keep.  The advice is only for unconfigured folks\nwho did not tell --[no-]rebase from the command line.  One bad thing\nabout it in the released versions is that it would trigger even when\nthe history fast-forwards.  The latest round of patches in 'seen'\nsquelches the advice when pulling a fast-forward history even for\nunconfigured folks as we'd just fast-forward without erroring out.\n\n> Which I think is where your thinking is ending up.\n\nPretty much.  \n\n"},{"id":"412256","messageId":"5fd8b1d5d4d7c_190cd7208b@natae.notmuch","threadId":"54758","inReplyTo":"xmqqh7on8gia.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 02/14] pull: improve default warning","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-12-15T12:53:41Z","receivedAt":"2020-12-15T12:55:35Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Junio C Hamano wrote:\n> Jeff King <peff@peff.net> writes:\n> \n> > So I like pull.mode in that sense. But it is also weighed against the\n> > fact that we'd still have to support pull.rebase, and we'd still have to\n> > support pull.ff, and explain how those interact with pull.mode (and I\n> > think any new error in this area must be squelched by those existing\n> > variables, or it would be a regression for people who already picked\n> > their default long ago).\n> \n> I agree that if we were starting from scratch, things would have\n> been much simpler; choose among three ways to reconcile histories\n> (merge, rebase, or ff-only), without adding --[no-]rebase, and allow\n> --[no-]ff only when merging (i.e. things like --ff-only --ff,\n> --no-ff --rebase, would be nonsense combinations).  The additional\n> complexity of introducing pull.mode is the primary thing I am\n> hesitant to support it, as we have to design and explain how\n> existing knobs interact with newer one.\n\nI have already tried all the options.\n\nIf we go through a deprecation period (which I insist we must), the\noptions are these:\n\n 1. Change the semantics of --ff-only (breaks backwards-compatibility)\n 2. Add a \"pull.rebase=ff-only\" option (very weird)\n 3. Add a \"pull.mode\" configuration (tons of advantages)\n\nYes, we have to map the modes to the existing knobs, but it's not complex:\n\n * pull.rebase = false  <=> pull.mode = merge\n * pull.rebase = true   <=> pull.mode = rebase\n * pull.rebase = *       -> pull.mode = rebase\n\nThat's it. We don't even have to map --ff-only (which has different\nsemantics anyway).\n\nCheers.\n\n-- \nFelipe Contreras\n"}]}