{"thread":{"id":"36539","subject":"[PATCH v5 0/6] Reject non-ff pulls by default","startedAt":"2014-04-29T11:17:00Z","lastAt":"2014-04-30T20:26:27Z","messageCount":19,"participants":["Felipe Contreras","Marat Radchenko","Philip Oakley","Junio C Hamano","Richard Hansen"],"isPatch":true,"patchVersion":5,"patchTotal":6},"messages":[{"id":"240161","messageId":"1398770226-9686-1-git-send-email-felipe.contreras@gmail.com","threadId":"36539","inReplyTo":null,"subject":"[PATCH v5 0/6] Reject non-ff pulls by default","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2014-04-29T11:17:00Z","receivedAt":"2014-04-29T11:17:00Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"It is very typical for Git newcomers to inadvertently create merges and worst:\ninadvertently pushing them. This is one of the reasons many experienced users\nprefer to avoid 'git pull', and recommend newcomers to avoid it as well.\n\nTo avoid these problems and keep 'git pull' useful, it has been agreed that\n'git pull' should barf by default if the merge is non-fast-forward.\nUnfortunately this breaks backwards-compatibility, so we need to be careful\nabout the error messages we give, and that we provide enough information to our\nusers to move forward without distrupting their workflow too much.\n\nWith the proper error messages and documentation, it has been agreed that the\nnew behavior is OK.\n\nThese are the steps needed to achieve this:\n\n4) Only allow fast-forward merges by default\n\nWe could pass --ff-only to `git merge`, however, if we do that we'll get an error like this:\n\n  Not possible to fast-forward, aborting.\n\nThis is not friendly; we want an error that is user-friendly:\n\n  The pull was not fast-forward, please either merge or rebase.\n  If unsure, run 'git pull --merge'.\n\nWhen we do this we want to give the users the option to go back to the previous\nbehavior, so a new configuration is needed.\n\n3) Add merge-ff-only config\n\nThis option would trigger a check inside `git pull` itself, and error out with\nthe aforementioned message if it's not possible to do a fast-forward merge.\n\nHowever, this option conflicts with --rebase, and --no-rebase. Solution below.\n\n2) Add --merge option\n\nSince we have a message that says \"If unsure, run 'git pull --merge'\", which is\nmore friendly than 'git pull --no-rebase', we should add this option, and\ndeprecate --no-rebase.\n\nHowever, the documentation would become confusing if --merge is configured in\npull.rebase, instead, we want something like this:\n\n  See `pull.mode`, `branch.<name>.pullmode` in linkgit:git-config[1] if you want\n  to make `git pull` always use `--merge`.\n\n1) Rename pull.rename to pull.mode and\n   branch.<name>.rebase to branch.<name>.pullmode\n\nThis way the configurations and options remain consistent:\n\n  git pull --merge\n  pull.mode = merge\n  branch.<name>.pullmode = merge\n\n  git pull --rebase\n  pull.mode = rebase\n  branch.<name>.pullmode = rebase\n\n  git pull --rebase=preserve\n  pull.mode = rebase-preserve\n  branch.<name>.pullmode = rebase-preserve\n\n  git pull\n  pull.mode = merge-ff-only\n  branch.<name>.pullmode = merge-ff-only\n \nThis patch series does all the steps mentioned, but in reverse order, and in\naddition updates the tests to use the new configurations instead.\n\n\nFelipe Contreras (6):\n  pull: rename pull.rename to pull.mode\n  pull: migrate all the tests to pull.mode\n  pull: refactor $rebase variable into $mode\n  pull: add --merge option\n  pull: add merge-ff-only option\n  pull: only allow ff merges by default\n\n Documentation/config.txt     |  37 ++++++++-------\n Documentation/git-pull.txt   |  28 ++++++++++--\n branch.c                     |   4 +-\n builtin/remote.c             |  14 +++++-\n git-pull.sh                  | 105 ++++++++++++++++++++++++++++++++-----------\n t/t3200-branch.sh            |  40 ++++++++---------\n t/t4013-diff-various.sh      |   2 +-\n t/t5500-fetch-pack.sh        |   2 +-\n t/t5505-remote.sh            |   2 +-\n t/t5520-pull.sh              |  90 ++++++++++++++++++++++++-------------\n t/t5524-pull-msg.sh          |   2 +-\n t/t5601-clone.sh             |   4 +-\n t/t5700-clone-reference.sh   |   4 +-\n t/t6022-merge-rename.sh      |  20 ++++-----\n t/t6026-merge-attr.sh        |   2 +-\n t/t6029-merge-subtree.sh     |   6 +--\n t/t6037-merge-ours-theirs.sh |  10 ++---\n 17 files changed, 245 insertions(+), 127 deletions(-)\n\n-- \n1.9.2+fc1.3.gade8541\n"},{"id":"240162","messageId":"1398770226-9686-2-git-send-email-felipe.contreras@gmail.com","threadId":"36539","inReplyTo":"1398770226-9686-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v5 1/6] pull: rename pull.rename to pull.mode","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2014-04-29T11:17:01Z","receivedAt":"2014-04-29T11:17:01Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Also 'branch.<name>.rebase' to 'branch.<name>.pullmode'.\n\nThis way 'pull.mode' can be set to 'merge', and the default can be\nsomething else.\n\nThe old configurations still work, but get deprecated.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n Documentation/config.txt   | 34 +++++++++++++++++-----------------\n Documentation/git-pull.txt |  2 +-\n branch.c                   |  4 ++--\n builtin/remote.c           | 14 ++++++++++++--\n git-pull.sh                | 39 +++++++++++++++++++++++++++++++++++++--\n t/t3200-branch.sh          | 40 ++++++++++++++++++++--------------------\n t/t5601-clone.sh           |  4 ++--\n 7 files changed, 91 insertions(+), 46 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex c26a7c8..5978d35 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -708,7 +708,7 @@ branch.autosetupmerge::\n branch.autosetuprebase::\n \tWhen a new branch is created with 'git branch' or 'git checkout'\n \tthat tracks another branch, this variable tells Git to set\n-\tup pull to rebase instead of merge (see \"branch.<name>.rebase\").\n+\tup pull to rebase instead of merge (see \"branch.<name>.pullmode\").\n \tWhen `never`, rebase is never automatically set to true.\n \tWhen `local`, rebase is set to true for tracked branches of\n \tother local branches.\n@@ -764,15 +764,15 @@ branch.<name>.mergeoptions::\n \toption values containing whitespace characters are currently not\n \tsupported.\n \n-branch.<name>.rebase::\n-\tWhen true, rebase the branch <name> on top of the fetched branch,\n-\tinstead of merging the default branch from the default remote when\n-\t\"git pull\" is run. See \"pull.rebase\" for doing this in a non\n-\tbranch-specific manner.\n+branch.<name>.pullmode::\n+\tWhen \"git pull\" is run, this determines if it would either merge or\n+\trebase the fetched branch. The possible values are 'merge',\n+\t'rebase', and 'rebase-preserve'. See \"pull.mode\" for doing this in a\n+\tnon branch-specific manner.\n +\n-\tWhen preserve, also pass `--preserve-merges` along to 'git rebase'\n-\tso that locally committed merge commits will not be flattened\n-\tby running 'git pull'.\n+\tWhen 'rebase-preserve', also pass `--preserve-merges` along to\n+\t'git rebase' so that locally committed merge commits will not be\n+\tflattened by running 'git pull'.\n +\n *NOTE*: this is a possibly dangerous operation; do *not* use\n it unless you understand the implications (see linkgit:git-rebase[1]\n@@ -1881,15 +1881,15 @@ pretty.<name>::\n \tNote that an alias with the same name as a built-in format\n \twill be silently ignored.\n \n-pull.rebase::\n-\tWhen true, rebase branches on top of the fetched branch, instead\n-\tof merging the default branch from the default remote when \"git\n-\tpull\" is run. See \"branch.<name>.rebase\" for setting this on a\n-\tper-branch basis.\n+pull.mode::\n+\tWhen \"git pull\" is run, this determines if it would either merge or\n+\trebase the fetched branch. The possible values are 'merge',\n+\t'rebase', and 'rebase-preserve'. See \"branch.<name>.pullmode\" for doing\n+\tthis in a non branch-specific manner.\n +\n-\tWhen preserve, also pass `--preserve-merges` along to 'git rebase'\n-\tso that locally committed merge commits will not be flattened\n-\tby running 'git pull'.\n+\tWhen 'rebase-preserve', also pass `--preserve-merges` along to\n+\t'git rebase' so that locally committed merge commits will not be\n+\tflattened by running 'git pull'.\n +\n *NOTE*: this is a possibly dangerous operation; do *not* use\n it unless you understand the implications (see linkgit:git-rebase[1]\ndiff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\nindex 200eb22..9a91b9f 100644\n--- a/Documentation/git-pull.txt\n+++ b/Documentation/git-pull.txt\n@@ -117,7 +117,7 @@ locally created merge commits will not be flattened.\n +\n When false, merge the current branch into the upstream branch.\n +\n-See `pull.rebase`, `branch.<name>.rebase` and `branch.autosetuprebase` in\n+See `pull.mode`, `branch.<name>.pullmode` and `branch.autosetuprebase` in\n linkgit:git-config[1] if you want to make `git pull` always use\n `--rebase` instead of merging.\n +\ndiff --git a/branch.c b/branch.c\nindex 723a36b..63ce671 100644\n--- a/branch.c\n+++ b/branch.c\n@@ -71,8 +71,8 @@ void install_branch_config(int flag, const char *local, const char *origin, cons\n \n \tif (rebasing) {\n \t\tstrbuf_reset(&key);\n-\t\tstrbuf_addf(&key, \"branch.%s.rebase\", local);\n-\t\tgit_config_set(key.buf, \"true\");\n+\t\tstrbuf_addf(&key, \"branch.%s.pullmode\", local);\n+\t\tgit_config_set(key.buf, \"rebase\");\n \t}\n \tstrbuf_release(&key);\n \ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex b3ab4cf..46d3c4d 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -264,7 +264,7 @@ static int config_read_branches(const char *key, const char *value, void *cb)\n \t\tchar *name;\n \t\tstruct string_list_item *item;\n \t\tstruct branch_info *info;\n-\t\tenum { REMOTE, MERGE, REBASE } type;\n+\t\tenum { REMOTE, MERGE, REBASE, PULLMODE } type;\n \n \t\tkey += 7;\n \t\tif (ends_with(key, \".remote\")) {\n@@ -276,6 +276,9 @@ static int config_read_branches(const char *key, const char *value, void *cb)\n \t\t} else if (ends_with(key, \".rebase\")) {\n \t\t\tname = xstrndup(key, strlen(key) - 7);\n \t\t\ttype = REBASE;\n+\t\t} else if (ends_with(key, \".pullmode\")) {\n+\t\t\tname = xstrndup(key, strlen(key) - 9);\n+\t\t\ttype = PULLMODE;\n \t\t} else\n \t\t\treturn 0;\n \n@@ -299,12 +302,19 @@ static int config_read_branches(const char *key, const char *value, void *cb)\n \t\t\t\tspace = strchr(value, ' ');\n \t\t\t}\n \t\t\tstring_list_append(&info->merge, xstrdup(value));\n-\t\t} else {\n+\t\t} else if (type == REBASE) {\n \t\t\tint v = git_config_maybe_bool(orig_key, value);\n \t\t\tif (v >= 0)\n \t\t\t\tinfo->rebase = v;\n \t\t\telse if (!strcmp(value, \"preserve\"))\n \t\t\t\tinfo->rebase = 1;\n+\t\t} else {\n+\t\t\tif (!strcmp(value, \"rebase\"))\n+\t\t\t\tinfo->rebase = 1;\n+\t\t\telse if (!strcmp(value, \"merge\"))\n+\t\t\t\tinfo->rebase = 0;\n+\t\t\telse if (!strcmp(value, \"rebase-preserve\"))\n+\t\t\t\tinfo->rebase = 1;\n \t\t}\n \t}\n \treturn 0;\ndiff --git a/git-pull.sh b/git-pull.sh\nindex 0a5aa2c..d4e25f1 100755\n--- a/git-pull.sh\n+++ b/git-pull.sh\n@@ -15,6 +15,10 @@ require_work_tree_exists\n cd_to_toplevel\n \n \n+warn () {\n+\tprintf >&2 '%s\\n' \"$*\"\n+}\n+\n die_conflict () {\n     git diff-index --cached --name-status -r --ignore-submodules HEAD --\n     if [ $(git config --bool --get advice.resolveConflict || echo true) = \"true\" ]; then\n@@ -47,10 +51,41 @@ log_arg= verbosity= progress= recurse_submodules= verify_signatures=\n merge_args= edit= rebase_args=\n curr_branch=$(git symbolic-ref -q HEAD)\n curr_branch_short=\"${curr_branch#refs/heads/}\"\n-rebase=$(bool_or_string_config branch.$curr_branch_short.rebase)\n+mode=$(git config branch.${curr_branch_short}.pullmode)\n+if test -z \"$mode\"\n+then\n+\tmode=$(git config pull.mode)\n+fi\n+case \"$mode\" in\n+merge)\n+\trebase=\"false\"\n+\t;;\n+rebase)\n+\trebase=\"true\"\n+\t;;\n+rebase-preserve)\n+\trebase=\"preserve\"\n+\t;;\n+'')\n+\t;;\n+*)\n+\techo \"Invalid value for 'mode'\"\n+\tusage\n+\texit 1\n+\t;;\n+esac\n if test -z \"$rebase\"\n then\n-\trebase=$(bool_or_string_config pull.rebase)\n+\trebase=$(bool_or_string_config branch.$curr_branch_short.rebase)\n+\tif test -z \"$rebase\"\n+\tthen\n+\t\trebase=$(bool_or_string_config pull.rebase)\n+\tfi\n+\tif test -n \"$rebase\"\n+\tthen\n+\t\twarn \"$(gettext \"The configurations pull.rebase and branch.<name>.rebase are deprecated.\")\"\n+\t\twarn \"$(gettext \"Please use pull.mode and branch.<name>.pullmode instead.\")\"\n+\tfi\n fi\n dry_run=\n while :\ndiff --git a/t/t3200-branch.sh b/t/t3200-branch.sh\nindex fcdb867..b79aa75 100755\n--- a/t/t3200-branch.sh\n+++ b/t/t3200-branch.sh\n@@ -559,7 +559,7 @@ test_expect_success 'autosetuprebase local on a tracked local branch' '\n \tgit branch --track myr1 mybase &&\n \ttest \"$(git config branch.myr1.remote)\" = . &&\n \ttest \"$(git config branch.myr1.merge)\" = refs/heads/mybase &&\n-\ttest \"$(git config branch.myr1.rebase)\" = true\n+\ttest \"$(git config branch.myr1.pullmode)\" = rebase\n '\n \n test_expect_success 'autosetuprebase always on a tracked local branch' '\n@@ -571,7 +571,7 @@ test_expect_success 'autosetuprebase always on a tracked local branch' '\n \tgit branch --track myr2 mybase &&\n \ttest \"$(git config branch.myr2.remote)\" = . &&\n \ttest \"$(git config branch.myr2.merge)\" = refs/heads/mybase &&\n-\ttest \"$(git config branch.myr2.rebase)\" = true\n+\ttest \"$(git config branch.myr2.pullmode)\" = rebase\n '\n \n test_expect_success 'autosetuprebase remote on a tracked local branch' '\n@@ -583,7 +583,7 @@ test_expect_success 'autosetuprebase remote on a tracked local branch' '\n \tgit branch --track myr3 mybase2 &&\n \ttest \"$(git config branch.myr3.remote)\" = . &&\n \ttest \"$(git config branch.myr3.merge)\" = refs/heads/mybase2 &&\n-\t! test \"$(git config branch.myr3.rebase)\" = true\n+\t! test \"$(git config branch.myr3.pullmode)\" = rebase\n '\n \n test_expect_success 'autosetuprebase never on a tracked local branch' '\n@@ -595,7 +595,7 @@ test_expect_success 'autosetuprebase never on a tracked local branch' '\n \tgit branch --track myr4 mybase2 &&\n \ttest \"$(git config branch.myr4.remote)\" = . &&\n \ttest \"$(git config branch.myr4.merge)\" = refs/heads/mybase2 &&\n-\t! test \"$(git config branch.myr4.rebase)\" = true\n+\t! test \"$(git config branch.myr4.pullmode)\" = rebase\n '\n \n test_expect_success 'autosetuprebase local on a tracked remote branch' '\n@@ -606,7 +606,7 @@ test_expect_success 'autosetuprebase local on a tracked remote branch' '\n \tgit branch --track myr5 local/master &&\n \ttest \"$(git config branch.myr5.remote)\" = local &&\n \ttest \"$(git config branch.myr5.merge)\" = refs/heads/master &&\n-\t! test \"$(git config branch.myr5.rebase)\" = true\n+\t! test \"$(git config branch.myr5.pullmode)\" = rebase\n '\n \n test_expect_success 'autosetuprebase never on a tracked remote branch' '\n@@ -617,7 +617,7 @@ test_expect_success 'autosetuprebase never on a tracked remote branch' '\n \tgit branch --track myr6 local/master &&\n \ttest \"$(git config branch.myr6.remote)\" = local &&\n \ttest \"$(git config branch.myr6.merge)\" = refs/heads/master &&\n-\t! test \"$(git config branch.myr6.rebase)\" = true\n+\t! test \"$(git config branch.myr6.pullmode)\" = rebase\n '\n \n test_expect_success 'autosetuprebase remote on a tracked remote branch' '\n@@ -628,7 +628,7 @@ test_expect_success 'autosetuprebase remote on a tracked remote branch' '\n \tgit branch --track myr7 local/master &&\n \ttest \"$(git config branch.myr7.remote)\" = local &&\n \ttest \"$(git config branch.myr7.merge)\" = refs/heads/master &&\n-\ttest \"$(git config branch.myr7.rebase)\" = true\n+\ttest \"$(git config branch.myr7.pullmode)\" = rebase\n '\n \n test_expect_success 'autosetuprebase always on a tracked remote branch' '\n@@ -639,7 +639,7 @@ test_expect_success 'autosetuprebase always on a tracked remote branch' '\n \tgit branch --track myr8 local/master &&\n \ttest \"$(git config branch.myr8.remote)\" = local &&\n \ttest \"$(git config branch.myr8.merge)\" = refs/heads/master &&\n-\ttest \"$(git config branch.myr8.rebase)\" = true\n+\ttest \"$(git config branch.myr8.pullmode)\" = rebase\n '\n \n test_expect_success 'autosetuprebase unconfigured on a tracked remote branch' '\n@@ -650,7 +650,7 @@ test_expect_success 'autosetuprebase unconfigured on a tracked remote branch' '\n \tgit branch --track myr9 local/master &&\n \ttest \"$(git config branch.myr9.remote)\" = local &&\n \ttest \"$(git config branch.myr9.merge)\" = refs/heads/master &&\n-\ttest \"z$(git config branch.myr9.rebase)\" = z\n+\ttest \"z$(git config branch.myr9.pullmode)\" = z\n '\n \n test_expect_success 'autosetuprebase unconfigured on a tracked local branch' '\n@@ -661,7 +661,7 @@ test_expect_success 'autosetuprebase unconfigured on a tracked local branch' '\n \tgit branch --track myr10 mybase2 &&\n \ttest \"$(git config branch.myr10.remote)\" = . &&\n \ttest \"$(git config branch.myr10.merge)\" = refs/heads/mybase2 &&\n-\ttest \"z$(git config branch.myr10.rebase)\" = z\n+\ttest \"z$(git config branch.myr10.pullmode)\" = z\n '\n \n test_expect_success 'autosetuprebase unconfigured on untracked local branch' '\n@@ -671,7 +671,7 @@ test_expect_success 'autosetuprebase unconfigured on untracked local branch' '\n \tgit branch --no-track myr11 mybase2 &&\n \ttest \"z$(git config branch.myr11.remote)\" = z &&\n \ttest \"z$(git config branch.myr11.merge)\" = z &&\n-\ttest \"z$(git config branch.myr11.rebase)\" = z\n+\ttest \"z$(git config branch.myr11.pullmode)\" = z\n '\n \n test_expect_success 'autosetuprebase unconfigured on untracked remote branch' '\n@@ -681,7 +681,7 @@ test_expect_success 'autosetuprebase unconfigured on untracked remote branch' '\n \tgit branch --no-track myr12 local/master &&\n \ttest \"z$(git config branch.myr12.remote)\" = z &&\n \ttest \"z$(git config branch.myr12.merge)\" = z &&\n-\ttest \"z$(git config branch.myr12.rebase)\" = z\n+\ttest \"z$(git config branch.myr12.pullmode)\" = z\n '\n \n test_expect_success 'autosetuprebase never on an untracked local branch' '\n@@ -692,7 +692,7 @@ test_expect_success 'autosetuprebase never on an untracked local branch' '\n \tgit branch --no-track myr13 mybase2 &&\n \ttest \"z$(git config branch.myr13.remote)\" = z &&\n \ttest \"z$(git config branch.myr13.merge)\" = z &&\n-\ttest \"z$(git config branch.myr13.rebase)\" = z\n+\ttest \"z$(git config branch.myr13.pullmode)\" = z\n '\n \n test_expect_success 'autosetuprebase local on an untracked local branch' '\n@@ -703,7 +703,7 @@ test_expect_success 'autosetuprebase local on an untracked local branch' '\n \tgit branch --no-track myr14 mybase2 &&\n \ttest \"z$(git config branch.myr14.remote)\" = z &&\n \ttest \"z$(git config branch.myr14.merge)\" = z &&\n-\ttest \"z$(git config branch.myr14.rebase)\" = z\n+\ttest \"z$(git config branch.myr14.pullmode)\" = z\n '\n \n test_expect_success 'autosetuprebase remote on an untracked local branch' '\n@@ -714,7 +714,7 @@ test_expect_success 'autosetuprebase remote on an untracked local branch' '\n \tgit branch --no-track myr15 mybase2 &&\n \ttest \"z$(git config branch.myr15.remote)\" = z &&\n \ttest \"z$(git config branch.myr15.merge)\" = z &&\n-\ttest \"z$(git config branch.myr15.rebase)\" = z\n+\ttest \"z$(git config branch.myr15.pullmode)\" = z\n '\n \n test_expect_success 'autosetuprebase always on an untracked local branch' '\n@@ -725,7 +725,7 @@ test_expect_success 'autosetuprebase always on an untracked local branch' '\n \tgit branch --no-track myr16 mybase2 &&\n \ttest \"z$(git config branch.myr16.remote)\" = z &&\n \ttest \"z$(git config branch.myr16.merge)\" = z &&\n-\ttest \"z$(git config branch.myr16.rebase)\" = z\n+\ttest \"z$(git config branch.myr16.pullmode)\" = z\n '\n \n test_expect_success 'autosetuprebase never on an untracked remote branch' '\n@@ -736,7 +736,7 @@ test_expect_success 'autosetuprebase never on an untracked remote branch' '\n \tgit branch --no-track myr17 local/master &&\n \ttest \"z$(git config branch.myr17.remote)\" = z &&\n \ttest \"z$(git config branch.myr17.merge)\" = z &&\n-\ttest \"z$(git config branch.myr17.rebase)\" = z\n+\ttest \"z$(git config branch.myr17.pullmode)\" = z\n '\n \n test_expect_success 'autosetuprebase local on an untracked remote branch' '\n@@ -747,7 +747,7 @@ test_expect_success 'autosetuprebase local on an untracked remote branch' '\n \tgit branch --no-track myr18 local/master &&\n \ttest \"z$(git config branch.myr18.remote)\" = z &&\n \ttest \"z$(git config branch.myr18.merge)\" = z &&\n-\ttest \"z$(git config branch.myr18.rebase)\" = z\n+\ttest \"z$(git config branch.myr18.pullmode)\" = z\n '\n \n test_expect_success 'autosetuprebase remote on an untracked remote branch' '\n@@ -758,7 +758,7 @@ test_expect_success 'autosetuprebase remote on an untracked remote branch' '\n \tgit branch --no-track myr19 local/master &&\n \ttest \"z$(git config branch.myr19.remote)\" = z &&\n \ttest \"z$(git config branch.myr19.merge)\" = z &&\n-\ttest \"z$(git config branch.myr19.rebase)\" = z\n+\ttest \"z$(git config branch.myr19.pullmode)\" = z\n '\n \n test_expect_success 'autosetuprebase always on an untracked remote branch' '\n@@ -769,7 +769,7 @@ test_expect_success 'autosetuprebase always on an untracked remote branch' '\n \tgit branch --no-track myr20 local/master &&\n \ttest \"z$(git config branch.myr20.remote)\" = z &&\n \ttest \"z$(git config branch.myr20.merge)\" = z &&\n-\ttest \"z$(git config branch.myr20.rebase)\" = z\n+\ttest \"z$(git config branch.myr20.pullmode)\" = z\n '\n \n test_expect_success 'autosetuprebase always on detached HEAD' '\ndiff --git a/t/t5601-clone.sh b/t/t5601-clone.sh\nindex 5e67035..0e91b67 100755\n--- a/t/t5601-clone.sh\n+++ b/t/t5601-clone.sh\n@@ -191,8 +191,8 @@ test_expect_success 'clone respects global branch.autosetuprebase' '\n \t\trm -fr dst &&\n \t\tgit clone src dst &&\n \t\tcd dst &&\n-\t\tactual=\"z$(git config branch.master.rebase)\" &&\n-\t\ttest ztrue = $actual\n+\t\tactual=\"$(git config branch.master.pullmode)\" &&\n+\t\ttest \"$actual\" = rebase\n \t)\n '\n \n-- \n1.9.2+fc1.3.gade8541\n"},{"id":"240163","messageId":"1398770226-9686-3-git-send-email-felipe.contreras@gmail.com","threadId":"36539","inReplyTo":"1398770226-9686-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v5 2/6] pull: migrate all the tests to pull.mode","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2014-04-29T11:17:02Z","receivedAt":"2014-04-29T11:17:02Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"And branch.$name.pullmode.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n t/t5505-remote.sh |  2 +-\n t/t5520-pull.sh   | 54 +++++++++++++++++++++++-------------------------------\n 2 files changed, 24 insertions(+), 32 deletions(-)\n\ndiff --git a/t/t5505-remote.sh b/t/t5505-remote.sh\nindex ac79dd9..76376e4 100755\n--- a/t/t5505-remote.sh\n+++ b/t/t5505-remote.sh\n@@ -181,7 +181,7 @@ test_expect_success 'show' '\n \t\tgit branch -d -r origin/master &&\n \t\tgit config --add remote.two.url ../two &&\n \t\tgit config --add remote.two.pushurl ../three &&\n-\t\tgit config branch.rebase.rebase true &&\n+\t\tgit config branch.rebase.pullmode rebase &&\n \t\tgit config branch.octopus.merge \"topic-a topic-b topic-c\" &&\n \t\t(\n \t\t\tcd ../one &&\ndiff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\nindex 227d293..01ad17a 100755\n--- a/t/t5520-pull.sh\n+++ b/t/t5520-pull.sh\n@@ -123,26 +123,26 @@ test_expect_success '--rebase' '\n \ttest $(git rev-parse HEAD^) = $(git rev-parse copy) &&\n \ttest new = $(git show HEAD:file2)\n '\n-test_expect_success 'pull.rebase' '\n+test_expect_success 'pull.mode=rebase' '\n \tgit reset --hard before-rebase &&\n-\ttest_config pull.rebase true &&\n+\ttest_config pull.mode rebase &&\n \tgit pull . copy &&\n \ttest $(git rev-parse HEAD^) = $(git rev-parse copy) &&\n \ttest new = $(git show HEAD:file2)\n '\n \n-test_expect_success 'branch.to-rebase.rebase' '\n+test_expect_success 'branch.to-rebase.pullmode=rebase' '\n \tgit reset --hard before-rebase &&\n-\ttest_config branch.to-rebase.rebase true &&\n+\ttest_config branch.to-rebase.pullmode rebase &&\n \tgit pull . copy &&\n \ttest $(git rev-parse HEAD^) = $(git rev-parse copy) &&\n \ttest new = $(git show HEAD:file2)\n '\n \n-test_expect_success 'branch.to-rebase.rebase should override pull.rebase' '\n+test_expect_success 'branch.to-rebase.pullmode should override pull.mode' '\n \tgit reset --hard before-rebase &&\n-\ttest_config pull.rebase true &&\n-\ttest_config branch.to-rebase.rebase false &&\n+\ttest_config pull.mode merge &&\n+\ttest_config branch.to-rebase.pullmode merge &&\n \tgit pull . copy &&\n \ttest $(git rev-parse HEAD^) != $(git rev-parse copy) &&\n \ttest new = $(git show HEAD:file2)\n@@ -150,7 +150,7 @@ test_expect_success 'branch.to-rebase.rebase should override pull.rebase' '\n \n # add a feature branch, keep-merge, that is merged into master, so the\n # test can try preserving the merge commit (or not) with various\n-# --rebase flags/pull.rebase settings.\n+# --rebase flags/pull.mode settings.\n test_expect_success 'preserve merge setup' '\n \tgit reset --hard before-rebase &&\n \tgit checkout -b keep-merge second^ &&\n@@ -160,48 +160,40 @@ test_expect_success 'preserve merge setup' '\n \tgit tag before-preserve-rebase\n '\n \n-test_expect_success 'pull.rebase=false create a new merge commit' '\n+test_expect_success 'pull.mode=merge create a new merge commit' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase false &&\n+\ttest_config pull.mode merge &&\n \tgit pull . copy &&\n \ttest $(git rev-parse HEAD^1) = $(git rev-parse before-preserve-rebase) &&\n \ttest $(git rev-parse HEAD^2) = $(git rev-parse copy) &&\n \ttest file3 = $(git show HEAD:file3.t)\n '\n \n-test_expect_success 'pull.rebase=true flattens keep-merge' '\n+test_expect_success 'pull.mode=rebase flattens keep-merge' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase true &&\n+\ttest_config pull.mode rebase &&\n \tgit pull . copy &&\n \ttest $(git rev-parse HEAD^^) = $(git rev-parse copy) &&\n \ttest file3 = $(git show HEAD:file3.t)\n '\n \n-test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' '\n+test_expect_success 'pull.mode=rebase-preserve rebases and merges keep-merge' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase 1 &&\n-\tgit pull . copy &&\n-\ttest $(git rev-parse HEAD^^) = $(git rev-parse copy) &&\n-\ttest file3 = $(git show HEAD:file3.t)\n-'\n-\n-test_expect_success 'pull.rebase=preserve rebases and merges keep-merge' '\n-\tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase preserve &&\n+\ttest_config pull.mode rebase-preserve &&\n \tgit pull . copy &&\n \ttest $(git rev-parse HEAD^^) = $(git rev-parse copy) &&\n \ttest $(git rev-parse HEAD^2) = $(git rev-parse keep-merge)\n '\n \n-test_expect_success 'pull.rebase=invalid fails' '\n+test_expect_success 'pull.mode=invalid fails' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase invalid &&\n+\ttest_config pull.mode invalid &&\n \t! git pull . copy\n '\n \n test_expect_success '--rebase=false create a new merge commit' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase true &&\n+\ttest_config pull.mode rebase &&\n \tgit pull --rebase=false . copy &&\n \ttest $(git rev-parse HEAD^1) = $(git rev-parse before-preserve-rebase) &&\n \ttest $(git rev-parse HEAD^2) = $(git rev-parse copy) &&\n@@ -210,7 +202,7 @@ test_expect_success '--rebase=false create a new merge commit' '\n \n test_expect_success '--rebase=true rebases and flattens keep-merge' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase preserve &&\n+\ttest_config pull.mode rebase-preserve &&\n \tgit pull --rebase=true . copy &&\n \ttest $(git rev-parse HEAD^^) = $(git rev-parse copy) &&\n \ttest file3 = $(git show HEAD:file3.t)\n@@ -218,7 +210,7 @@ test_expect_success '--rebase=true rebases and flattens keep-merge' '\n \n test_expect_success '--rebase=preserve rebases and merges keep-merge' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase true &&\n+\ttest_config pull.mode rebase &&\n \tgit pull --rebase=preserve . copy &&\n \ttest $(git rev-parse HEAD^^) = $(git rev-parse copy) &&\n \ttest $(git rev-parse HEAD^2) = $(git rev-parse keep-merge)\n@@ -229,9 +221,9 @@ test_expect_success '--rebase=invalid fails' '\n \t! git pull --rebase=invalid . copy\n '\n \n-test_expect_success '--rebase overrides pull.rebase=preserve and flattens keep-merge' '\n+test_expect_success '--rebase overrides pull.mode=rebase-preserve and flattens keep-merge' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase preserve &&\n+\ttest_config pull.mode rebase-preserve &&\n \tgit pull --rebase . copy &&\n \ttest $(git rev-parse HEAD^^) = $(git rev-parse copy) &&\n \ttest file3 = $(git show HEAD:file3.t)\n@@ -279,7 +271,7 @@ test_expect_success 'rebased upstream + fetch + pull --rebase' '\n \n '\n \n-test_expect_success 'pull --rebase dies early with dirty working directory' '\n+test_expect_success 'pull --mode=rebase dies early with dirty working directory' '\n \n \tgit checkout to-rebase &&\n \tgit update-ref refs/remotes/me/copy copy^ &&\n@@ -287,7 +279,7 @@ test_expect_success 'pull --rebase dies early with dirty working directory' '\n \tgit rebase --onto $COPY copy &&\n \ttest_config branch.to-rebase.remote me &&\n \ttest_config branch.to-rebase.merge refs/heads/copy &&\n-\ttest_config branch.to-rebase.rebase true &&\n+\ttest_config branch.to-rebase.pullmode rebase &&\n \techo dirty >> file &&\n \tgit add file &&\n \ttest_must_fail git pull &&\n-- \n1.9.2+fc1.3.gade8541\n"},{"id":"240164","messageId":"1398770226-9686-4-git-send-email-felipe.contreras@gmail.com","threadId":"36539","inReplyTo":"1398770226-9686-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v5 3/6] pull: refactor $rebase variable into $mode","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2014-04-29T11:17:03Z","receivedAt":"2014-04-29T11:17:03Z","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 git-pull.sh | 65 ++++++++++++++++++++++++++++++++-----------------------------\n 1 file changed, 34 insertions(+), 31 deletions(-)\n\ndiff --git a/git-pull.sh b/git-pull.sh\nindex d4e25f1..3dfd856 100755\n--- a/git-pull.sh\n+++ b/git-pull.sh\n@@ -57,16 +57,11 @@ then\n \tmode=$(git config pull.mode)\n fi\n case \"$mode\" in\n-merge)\n-\trebase=\"false\"\n-\t;;\n-rebase)\n-\trebase=\"true\"\n+merge|rebase|'')\n \t;;\n rebase-preserve)\n-\trebase=\"preserve\"\n-\t;;\n-'')\n+\tmode=\"rebase\"\n+\trebase_args=\"--preserve-merges\"\n \t;;\n *)\n \techo \"Invalid value for 'mode'\"\n@@ -74,7 +69,8 @@ rebase-preserve)\n \texit 1\n \t;;\n esac\n-if test -z \"$rebase\"\n+\n+if test -z \"$mode\"\n then\n \trebase=$(bool_or_string_config branch.$curr_branch_short.rebase)\n \tif test -z \"$rebase\"\n@@ -153,10 +149,10 @@ do\n \t\trebase=\"${1#*=}\"\n \t\t;;\n \t-r|--r|--re|--reb|--reba|--rebas|--rebase)\n-\t\trebase=true\n+\t\tmode=rebase\n \t\t;;\n \t--no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)\n-\t\trebase=false\n+\t\tmode=\n \t\t;;\n \t--recurse-submodules)\n \t\trecurse_submodules=--recurse-submodules\n@@ -187,19 +183,26 @@ do\n \tshift\n done\n \n-case \"$rebase\" in\n-preserve)\n-\trebase=true\n-\trebase_args=--preserve-merges\n-\t;;\n-true|false|'')\n-\t;;\n-*)\n-\techo \"Invalid value for --rebase, should be true, false, or preserve\"\n-\tusage\n-\texit 1\n-\t;;\n-esac\n+if test -n \"$rebase\"\n+then\n+\tcase \"$rebase\" in\n+\ttrue)\n+\t\tmode=\"rebase\"\n+\t\t;;\n+\tfalse)\n+\t\tmode=\"merge\"\n+\t\t;;\n+\tpreserve)\n+\t\tmode=\"rebase\"\n+\t\trebase_args=--preserve-merges\n+\t\t;;\n+\t*)\n+\t\techo \"Invalid value for --rebase, should be true, false, or preserve\"\n+\t\tusage\n+\t\texit 1\n+\t\t;;\n+\tesac\n+fi\n \n error_on_no_merge_candidates () {\n \texec >&2\n@@ -213,7 +216,7 @@ error_on_no_merge_candidates () {\n \t\tesac\n \tdone\n \n-\tif test true = \"$rebase\"\n+\tif test \"$mode\" = rebase\n \tthen\n \t\top_type=rebase\n \t\top_prep=against\n@@ -226,7 +229,7 @@ error_on_no_merge_candidates () {\n \tremote=$(git config \"branch.$curr_branch_short.remote\")\n \n \tif [ $# -gt 1 ]; then\n-\t\tif [ \"$rebase\" = true ]; then\n+\t\tif [ \"$mode\" = rebase ]; then\n \t\t\tprintf \"There is no candidate for rebasing against \"\n \t\telse\n \t\t\tprintf \"There are no candidates for merging \"\n@@ -249,7 +252,7 @@ error_on_no_merge_candidates () {\n \texit 1\n }\n \n-test true = \"$rebase\" && {\n+test \"$mode\" = rebase && {\n \tif ! git rev-parse -q --verify HEAD >/dev/null\n \tthen\n \t\t# On an unborn branch\n@@ -306,7 +309,7 @@ case \"$merge_head\" in\n \tthen\n \t\tdie \"$(gettext \"Cannot merge multiple branches into empty head\")\"\n \tfi\n-\tif test true = \"$rebase\"\n+\tif test \"$mode\" = rebase\n \tthen\n \t\tdie \"$(gettext \"Cannot rebase onto multiple branches\")\"\n \tfi\n@@ -327,7 +330,7 @@ then\n \texit\n fi\n \n-if test true = \"$rebase\"\n+if test \"$mode\" = rebase\n then\n \to=$(git show-branch --merge-base $curr_branch $merge_head $oldremoteref)\n \tif test \"$oldremoteref\" = \"$o\"\n@@ -337,8 +340,8 @@ then\n fi\n \n merge_name=$(git fmt-merge-msg $log_arg <\"$GIT_DIR/FETCH_HEAD\") || exit\n-case \"$rebase\" in\n-true)\n+case \"$mode\" in\n+rebase)\n \teval=\"git-rebase $diffstat $strategy_args $merge_args $rebase_args $verbosity\"\n \teval=\"$eval --onto $merge_head ${oldremoteref:-$merge_head}\"\n \t;;\n-- \n1.9.2+fc1.3.gade8541\n"},{"id":"240165","messageId":"1398770226-9686-5-git-send-email-felipe.contreras@gmail.com","threadId":"36539","inReplyTo":"1398770226-9686-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v5 4/6] pull: add --merge option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2014-04-29T11:17:04Z","receivedAt":"2014-04-29T11:17:04Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Also, deprecate --no-rebase since there's no need for it any more.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n Documentation/git-pull.txt | 8 ++++++--\n git-pull.sh                | 6 +++++-\n 2 files changed, 11 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\nindex 9a91b9f..767bca3 100644\n--- a/Documentation/git-pull.txt\n+++ b/Documentation/git-pull.txt\n@@ -127,8 +127,12 @@ 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+See `pull.mode`, `branch.<name>.pullmode` in linkgit:git-config[1] if you want\n+to make `git pull` always use `--merge`.\n \n Options related to fetching\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~\ndiff --git a/git-pull.sh b/git-pull.sh\nindex 3dfd856..26e4e55 100755\n--- a/git-pull.sh\n+++ b/git-pull.sh\n@@ -151,8 +151,12 @@ do\n \t-r|--r|--re|--reb|--reba|--rebas|--rebase)\n \t\tmode=rebase\n \t\t;;\n+\t-m|--m|--me|--mer|--merg|--merge)\n+\t\tmode=merge\n+\t\t;;\n \t--no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)\n-\t\tmode=\n+\t\tmode=merge\n+\t\twarn \"$(gettext \"--no-rebase is deprecated, please use --merge instead\")\"\n \t\t;;\n \t--recurse-submodules)\n \t\trecurse_submodules=--recurse-submodules\n-- \n1.9.2+fc1.3.gade8541\n"},{"id":"240166","messageId":"1398770226-9686-6-git-send-email-felipe.contreras@gmail.com","threadId":"36539","inReplyTo":"1398770226-9686-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v5 5/6] pull: add merge-ff-only option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2014-04-29T11:17:05Z","receivedAt":"2014-04-29T11:17:05Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"It is very typical for Git newcomers to inadvertently create merges and\nworst; inadvertently pushing them. This is one of the reasons many\nexperienced users prefer to avoid 'git pull', and recommend newcomers to\navoid it as well.\n\nTo avoid these problems and keep 'git pull' useful, it has been\nsuggested that 'git pull' barfs by default if the merge is\nnon-fast-forward, which unfortunately would break backwards\ncompatibility.\n\nThis patch leaves everything in place to enable this new mode, but it\nonly gets enabled if the user specifically configures it; pull.mode =\nmerge-ff-only.\n\nLater on this mode can be enabled by default (e.g. in v2.0).\n\nFor the full discussion you can read:\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/225146/focus=225305\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n Documentation/config.txt |  7 +++++--\n git-pull.sh              | 15 ++++++++++++++-\n t/t5520-pull.sh          | 36 ++++++++++++++++++++++++++++++++++++\n 3 files changed, 55 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 5978d35..4ebd3b5 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1884,8 +1884,11 @@ pretty.<name>::\n pull.mode::\n \tWhen \"git pull\" is run, this determines if it would either merge or\n \trebase the fetched branch. The possible values are 'merge',\n-\t'rebase', and 'rebase-preserve'. See \"branch.<name>.pullmode\" for doing\n-\tthis in a non branch-specific manner.\n+\t'rebase', 'merge-ff-only,' and 'rebase-preserve'.\n+\tIf 'merge-ff-only' is specified, the merge will only succeed if it's\n+\tfast-forward.\n+\tSee \"branch.<name>.pullmode\" for doing this in a non branch-specific\n+\tmanner.\n +\n \tWhen 'rebase-preserve', also pass `--preserve-merges` along to\n \t'git rebase' so that locally committed merge commits will not be\ndiff --git a/git-pull.sh b/git-pull.sh\nindex 26e4e55..946cbbe 100755\n--- a/git-pull.sh\n+++ b/git-pull.sh\n@@ -57,7 +57,7 @@ then\n \tmode=$(git config pull.mode)\n fi\n case \"$mode\" in\n-merge|rebase|'')\n+merge|rebase|merge-ff-only|'')\n \t;;\n rebase-preserve)\n \tmode=\"rebase\"\n@@ -83,6 +83,7 @@ then\n \t\twarn \"$(gettext \"Please use pull.mode and branch.<name>.pullmode instead.\")\"\n \tfi\n fi\n+test -z \"$mode\" && mode=merge\n dry_run=\n while :\n do\n@@ -318,6 +319,18 @@ case \"$merge_head\" in\n \t\tdie \"$(gettext \"Cannot rebase onto multiple branches\")\"\n \tfi\n \t;;\n+*)\n+\t# check if a non-fast-foward merge would be needed\n+\tmerge_head=${merge_head% }\n+\tif test \"$mode\" = merge-ff-only -a -z \"$no_ff$ff_only${squash#--no-squash}\" &&\n+\t\ttest -n \"$orig_head\" &&\n+\t\t! git merge-base --is-ancestor \"$orig_head\" \"$merge_head\" &&\n+\t\t! git merge-base --is-ancestor \"$merge_head\" \"$orig_head\"\n+\tthen\n+\t\tdie \"$(gettext \"The pull was not fast-forward, please either merge or rebase.\n+If unsure, run 'git pull --merge'.\")\"\n+\tfi\n+\t;;\n esac\n \n # Pulling into unborn branch: a shorthand for branching off\ndiff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\nindex 01ad17a..2e2b476 100755\n--- a/t/t5520-pull.sh\n+++ b/t/t5520-pull.sh\n@@ -365,4 +365,40 @@ test_expect_success 'git pull --rebase against local branch' '\n \ttest file = \"$(cat file2)\"\n '\n \n+test_expect_success 'git pull fast-forward' '\n+\ttest_when_finished \"git checkout master && git branch -D other test\" &&\n+\ttest_config pull.mode merge-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' '\n+\ttest_when_finished \"git checkout master && git branch -D other test\" &&\n+\ttest_config pull.mode merge-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_success 'git pull non-fast-forward (merge)' '\n+\ttest_when_finished \"git checkout master && git branch -D other test\" &&\n+\ttest_config pull.mode merge-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 --merge\n+'\n+\n test_done\n-- \n1.9.2+fc1.3.gade8541\n"},{"id":"240167","messageId":"1398770226-9686-7-git-send-email-felipe.contreras@gmail.com","threadId":"36539","inReplyTo":"1398770226-9686-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v5 6/6] pull: only allow ff merges by default","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2014-04-29T11:17:06Z","receivedAt":"2014-04-29T11:17:06Z","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 Documentation/git-pull.txt   | 18 ++++++++++++++++++\n git-pull.sh                  |  2 +-\n t/t4013-diff-various.sh      |  2 +-\n t/t5500-fetch-pack.sh        |  2 +-\n t/t5524-pull-msg.sh          |  2 +-\n t/t5700-clone-reference.sh   |  4 ++--\n t/t6022-merge-rename.sh      | 20 ++++++++++----------\n t/t6026-merge-attr.sh        |  2 +-\n t/t6029-merge-subtree.sh     |  6 +++---\n t/t6037-merge-ours-theirs.sh | 10 +++++-----\n 10 files changed, 43 insertions(+), 25 deletions(-)\n\ndiff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\nindex 767bca3..ca8e951 100644\n--- a/Documentation/git-pull.txt\n+++ b/Documentation/git-pull.txt\n@@ -23,6 +23,7 @@ More precisely, 'git pull' runs 'git fetch' with the given\n parameters and calls 'git merge' to merge the retrieved branch\n heads into the current branch.\n With `--rebase`, it runs 'git rebase' instead of 'git merge'.\n+With `--merge`, it forces the merge, even if it's non-fast forward.\n \n <repository> should be the name of a remote repository as\n passed to linkgit:git-fetch[1].  <refspec> can name an\n@@ -41,11 +42,28 @@ Assume the following history exists and the current branch is\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 origin/master\n+\t /\n     D---E---F---G master\n \t^\n \torigin/master in your repository\n ------------\n \n+By default `git pull` will fail on these situations, however, most likely\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 until its current commit (`C`) on top of `master` and record the\ndiff --git a/git-pull.sh b/git-pull.sh\nindex 946cbbe..8cf8f68 100755\n--- a/git-pull.sh\n+++ b/git-pull.sh\n@@ -83,7 +83,7 @@ then\n \t\twarn \"$(gettext \"Please use pull.mode and branch.<name>.pullmode instead.\")\"\n \tfi\n fi\n-test -z \"$mode\" && mode=merge\n+test -z \"$mode\" && mode=merge-ff-only\n dry_run=\n while :\n do\ndiff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh\nindex e77c09c..1840767 100755\n--- a/t/t4013-diff-various.sh\n+++ b/t/t4013-diff-various.sh\n@@ -64,7 +64,7 @@ test_expect_success setup '\n \texport GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&\n \n \tgit checkout master &&\n-\tgit pull -s ours . side &&\n+\tgit pull --merge -s ours . side &&\n \n \tGIT_AUTHOR_DATE=\"2006-06-26 00:05:00 +0000\" &&\n \tGIT_COMMITTER_DATE=\"2006-06-26 00:05:00 +0000\" &&\ndiff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh\nindex 5b2b1c2..f735cfe 100755\n--- a/t/t5500-fetch-pack.sh\n+++ b/t/t5500-fetch-pack.sh\n@@ -259,7 +259,7 @@ test_expect_success 'clone shallow object count' '\n test_expect_success 'pull in shallow repo with missing merge base' '\n \t(\n \t\tcd shallow &&\n-\t\ttest_must_fail git pull --depth 4 .. A\n+\t\ttest_must_fail git pull --merge --depth 4 .. A\n \t)\n '\n \ndiff --git a/t/t5524-pull-msg.sh b/t/t5524-pull-msg.sh\nindex 8cccecc..ec9f413 100755\n--- a/t/t5524-pull-msg.sh\n+++ b/t/t5524-pull-msg.sh\n@@ -25,7 +25,7 @@ test_expect_success setup '\n test_expect_success pull '\n (\n \tcd cloned &&\n-\tgit pull --log &&\n+\tgit pull --merge --log &&\n \tgit log -2 &&\n \tgit cat-file commit HEAD >result &&\n \tgrep Dollar result\ndiff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh\nindex 6537911..306badf 100755\n--- a/t/t5700-clone-reference.sh\n+++ b/t/t5700-clone-reference.sh\n@@ -94,7 +94,7 @@ cd \"$base_dir\"\n \n test_expect_success 'pulling changes from origin' \\\n 'cd C &&\n-git pull origin'\n+git pull --merge origin'\n \n cd \"$base_dir\"\n \n@@ -109,7 +109,7 @@ cd \"$base_dir\"\n \n test_expect_success 'pulling changes from origin' \\\n 'cd D &&\n-git pull origin'\n+git pull --merge origin'\n \n cd \"$base_dir\"\n \ndiff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh\nindex a89dfbe..f63300f 100755\n--- a/t/t6022-merge-rename.sh\n+++ b/t/t6022-merge-rename.sh\n@@ -100,7 +100,7 @@ git checkout master'\n test_expect_success 'pull renaming branch into unrenaming one' \\\n '\n \tgit show-branch &&\n-\ttest_expect_code 1 git pull . white &&\n+\ttest_expect_code 1 git pull --merge . white &&\n \tgit ls-files -s &&\n \tgit ls-files -u B >b.stages &&\n \ttest_line_count = 3 b.stages &&\n@@ -118,7 +118,7 @@ test_expect_success 'pull renaming branch into another renaming one' \\\n \trm -f B &&\n \tgit reset --hard &&\n \tgit checkout red &&\n-\ttest_expect_code 1 git pull . white &&\n+\ttest_expect_code 1 git pull --merge . white &&\n \tgit ls-files -u B >b.stages &&\n \ttest_line_count = 3 b.stages &&\n \tgit ls-files -s N >n.stages &&\n@@ -134,7 +134,7 @@ test_expect_success 'pull unrenaming branch into renaming one' \\\n '\n \tgit reset --hard &&\n \tgit show-branch &&\n-\ttest_expect_code 1 git pull . master &&\n+\ttest_expect_code 1 git pull --merge . master &&\n \tgit ls-files -u B >b.stages &&\n \ttest_line_count = 3 b.stages &&\n \tgit ls-files -s N >n.stages &&\n@@ -150,7 +150,7 @@ test_expect_success 'pull conflicting renames' \\\n '\n \tgit reset --hard &&\n \tgit show-branch &&\n-\ttest_expect_code 1 git pull . blue &&\n+\ttest_expect_code 1 git pull --merge . blue &&\n \tgit ls-files -u A >a.stages &&\n \ttest_line_count = 1 a.stages &&\n \tgit ls-files -u B >b.stages &&\n@@ -170,7 +170,7 @@ test_expect_success 'interference with untracked working tree file' '\n \tgit reset --hard &&\n \tgit show-branch &&\n \techo >A this file should not matter &&\n-\ttest_expect_code 1 git pull . white &&\n+\ttest_expect_code 1 git pull --merge . white &&\n \ttest_path_is_file A\n '\n \n@@ -180,7 +180,7 @@ test_expect_success 'interference with untracked working tree file' '\n \tgit show-branch &&\n \trm -f A &&\n \techo >A this file should not matter &&\n-\ttest_expect_code 1 git pull . red &&\n+\ttest_expect_code 1 git pull --merge . red &&\n \ttest_path_is_file A\n '\n \n@@ -190,7 +190,7 @@ test_expect_success 'interference with untracked working tree file' '\n \tgit checkout -f master &&\n \tgit tag -f anchor &&\n \tgit show-branch &&\n-\tgit pull . yellow &&\n+\tgit pull --merge . yellow &&\n \ttest_path_is_missing M &&\n \tgit reset --hard anchor\n '\n@@ -203,7 +203,7 @@ test_expect_success 'updated working tree file should prevent the merge' '\n \tgit show-branch &&\n \techo >>M one line addition &&\n \tcat M >M.saved &&\n-\ttest_expect_code 128 git pull . yellow &&\n+\ttest_expect_code 128 git pull --merge . yellow &&\n \ttest_cmp M M.saved &&\n \trm -f M.saved\n '\n@@ -217,7 +217,7 @@ test_expect_success 'updated working tree file should prevent the merge' '\n \techo >>M one line addition &&\n \tcat M >M.saved &&\n \tgit update-index M &&\n-\ttest_expect_code 128 git pull . yellow &&\n+\ttest_expect_code 128 git pull --merge . yellow &&\n \ttest_cmp M M.saved &&\n \trm -f M.saved\n '\n@@ -229,7 +229,7 @@ test_expect_success 'interference with untracked working tree file' '\n \tgit tag -f anchor &&\n \tgit show-branch &&\n \techo >M this file should not matter &&\n-\tgit pull . master &&\n+\tgit pull --merge . master &&\n \ttest_path_is_file M &&\n \t! {\n \t\tgit ls-files -s |\ndiff --git a/t/t6026-merge-attr.sh b/t/t6026-merge-attr.sh\nindex 5e43997..5428f19 100755\n--- a/t/t6026-merge-attr.sh\n+++ b/t/t6026-merge-attr.sh\n@@ -172,7 +172,7 @@ test_expect_success 'up-to-date merge without common ancestor' '\n \ttest_tick &&\n \t(\n \t\tcd repo1 &&\n-\t\tgit pull ../repo2 master\n+\t\tgit pull --merge ../repo2 master\n \t)\n '\n \ndiff --git a/t/t6029-merge-subtree.sh b/t/t6029-merge-subtree.sh\nindex 73fc240..0e626d1 100755\n--- a/t/t6029-merge-subtree.sh\n+++ b/t/t6029-merge-subtree.sh\n@@ -69,7 +69,7 @@ test_expect_success 'merge update' '\n \tgit checkout -b master2 &&\n \tgit commit -m \"update git-gui\" &&\n \tcd ../git &&\n-\tgit pull -s subtree gui master2 &&\n+\tgit pull --merge -s subtree gui master2 &&\n \tgit ls-files -s >actual &&\n \t(\n \t\techo \"100644 $o3 0\tgit-gui/git-gui.sh\"\n@@ -98,7 +98,7 @@ test_expect_success 'initial ambiguous subtree' '\n test_expect_success 'merge using explicit' '\n \tcd ../git &&\n \tgit reset --hard master2 &&\n-\tgit pull -Xsubtree=git-gui gui master2 &&\n+\tgit pull --merge -Xsubtree=git-gui gui master2 &&\n \tgit ls-files -s >actual &&\n \t(\n \t\techo \"100644 $o3 0\tgit-gui/git-gui.sh\"\n@@ -111,7 +111,7 @@ test_expect_success 'merge using explicit' '\n test_expect_success 'merge2 using explicit' '\n \tcd ../git &&\n \tgit reset --hard master2 &&\n-\tgit pull -Xsubtree=git-gui2 gui master2 &&\n+\tgit pull --merge -Xsubtree=git-gui2 gui master2 &&\n \tgit ls-files -s >actual &&\n \t(\n \t\techo \"100644 $o1 0\tgit-gui/git-gui.sh\"\ndiff --git a/t/t6037-merge-ours-theirs.sh b/t/t6037-merge-ours-theirs.sh\nindex 3889eca..8e67d2a 100755\n--- a/t/t6037-merge-ours-theirs.sh\n+++ b/t/t6037-merge-ours-theirs.sh\n@@ -66,11 +66,11 @@ test_expect_success 'binary file with -Xours/-Xtheirs' '\n '\n \n test_expect_success 'pull passes -X to underlying merge' '\n-\tgit reset --hard master && git pull -s recursive -Xours . side &&\n-\tgit reset --hard master && git pull -s recursive -X ours . side &&\n-\tgit reset --hard master && git pull -s recursive -Xtheirs . side &&\n-\tgit reset --hard master && git pull -s recursive -X theirs . side &&\n-\tgit reset --hard master && test_must_fail git pull -s recursive -X bork . side\n+\tgit reset --hard master && git pull -m -s recursive -Xours . side &&\n+\tgit reset --hard master && git pull -m -s recursive -X ours . side &&\n+\tgit reset --hard master && git pull -m -s recursive -Xtheirs . side &&\n+\tgit reset --hard master && git pull -m -s recursive -X theirs . side &&\n+\tgit reset --hard master && test_must_fail git pull -m -s recursive -X bork . side\n '\n \n test_done\n-- \n1.9.2+fc1.3.gade8541\n"},{"id":"240171","messageId":"1398774271999-7609129.post@n2.nabble.com","threadId":"36539","inReplyTo":"1398770226-9686-2-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v5 1/6] pull: rename pull.rename to pull.mode","fromName":"Marat Radchenko","fromEmail":"marat@slonopotamus.org","sentAt":"2014-04-29T12:24:32Z","receivedAt":"2014-04-29T12:24:32Z","isPatch":true,"sender":{"key":"marat@slonopotamus.org","avatar":"https://avatars.githubusercontent.com/u/92637?v=4"},"body":"Felipe Contreras wrote\n> [PATCH v5 1/6] pull: rename pull.rename to pull.mode\n\ns/pull.rename/pull.rebase/\n\n\n\n--\nView this message in context: http://git.661346.n2.nabble.com/PATCH-v5-0-6-Reject-non-ff-pulls-by-default-tp7609118p7609129.html\nSent from the git mailing list archive at Nabble.com.\n"},{"id":"240178","messageId":"535fa9fddcd12_6d5dff2f075@nysa.notmuch","threadId":"36539","inReplyTo":"1398774271999-7609129.post@n2.nabble.com","subject":"Re: [PATCH v5 1/6] pull: rename pull.rename to pull.mode","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2014-04-29T13:32:45Z","receivedAt":"2014-04-29T13:32:45Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Marat Radchenko wrote:\n> Felipe Contreras wrote\n> > [PATCH v5 1/6] pull: rename pull.rename to pull.mode\n> \n> s/pull.rename/pull.rebase/\n\nRight. Will fix.\n\n-- \nFelipe Contreras\n"},{"id":"240208","messageId":"5324ACC54F034438BBAFDB15A9D716D5@PhilipOakley","threadId":"36539","inReplyTo":"1398770226-9686-2-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v5 1/6] pull: rename pull.rename to pull.mode","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":"2014-04-29T21:54:41Z","receivedAt":"2014-04-29T21:54:41Z","isPatch":true,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Felipe Contreras\" <felipe.contreras@gmail.com>\n> Also 'branch.<name>.rebase' to 'branch.<name>.pullmode'.\n\nSorry I haven't commented earlier. Because the 0/6 explanation isn't a\ncommit, a few extra words would be useful to capture what the 0/6 cover\nletter said to start the patch series cleanly/clearly e.g. start with\n\n    Begin the \"Reject non-ff pulls by default\" process by creating new\n    config variables which will allow extra options, to replace the old \npull\n    configuration options.\n\nI didn't immediately grasp why the 'replacement' was happening, rather\nthan it being a creation and a deprecation.\n\n>\n> This way 'pull.mode' can be set to 'merge', and the default can be\n> something else.\n>\n> The old configurations still work, but get deprecated.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n> Documentation/config.txt   | 34 +++++++++++++++++-----------------\n> Documentation/git-pull.txt |  2 +-\n> branch.c                   |  4 ++--\n> builtin/remote.c           | 14 ++++++++++++--\n> git-pull.sh                | 39\n> +++++++++++++++++++++++++++++++++++++--\n> t/t3200-branch.sh          | 40\n> ++++++++++++++++++++--------------------\n> t/t5601-clone.sh           |  4 ++--\n> 7 files changed, 91 insertions(+), 46 deletions(-)\n>\n> diff --git a/Documentation/config.txt b/Documentation/config.txt\n> index c26a7c8..5978d35 100644\n> --- a/Documentation/config.txt\n> +++ b/Documentation/config.txt\n> @@ -708,7 +708,7 @@ branch.autosetupmerge::\n> branch.autosetuprebase::\n>  When a new branch is created with 'git branch' or 'git checkout'\n>  that tracks another branch, this variable tells Git to set\n> - up pull to rebase instead of merge (see \"branch.<name>.rebase\").\n> + up pull to rebase instead of merge (see \"branch.<name>.pullmode\").\n>  When `never`, rebase is never automatically set to true.\n>  When `local`, rebase is set to true for tracked branches of\n>  other local branches.\n> @@ -764,15 +764,15 @@ branch.<name>.mergeoptions::\n>  option values containing whitespace characters are currently not\n>  supported.\n>\n> -branch.<name>.rebase::\n> - When true, rebase the branch <name> on top of the fetched branch,\n> - instead of merging the default branch from the default remote when\n> - \"git pull\" is run. See \"pull.rebase\" for doing this in a non\n> - branch-specific manner.\n> +branch.<name>.pullmode::\n> + When \"git pull\" is run, this determines if it would either merge or\n> + rebase the fetched branch. The possible values are 'merge',\n> + 'rebase', and 'rebase-preserve'. See \"pull.mode\" for doing this in a\n> + non branch-specific manner.\n\nI'd think it useful to add that:\n    branch.<name>.rebase is deprecated.\ngiven the large amount of internet cruft about this older config\nvariable name\n\n> +\n> - When preserve, also pass `--preserve-merges` along to 'git rebase'\n> - so that locally committed merge commits will not be flattened\n> - by running 'git pull'.\n> + When 'rebase-preserve', also pass `--preserve-merges` along to\n> + 'git rebase' so that locally committed merge commits will not be\n> + flattened by running 'git pull'.\n> +\n> *NOTE*: this is a possibly dangerous operation; do *not* use\n> it unless you understand the implications (see linkgit:git-rebase[1]\n> @@ -1881,15 +1881,15 @@ pretty.<name>::\n>  Note that an alias with the same name as a built-in format\n>  will be silently ignored.\n>\n> -pull.rebase::\n> - When true, rebase branches on top of the fetched branch, instead\n> - of merging the default branch from the default remote when \"git\n> - pull\" is run. See \"branch.<name>.rebase\" for setting this on a\n> - per-branch basis.\n> +pull.mode::\n> + When \"git pull\" is run, this determines if it would either merge or\n> + rebase the fetched branch. The possible values are 'merge',\n> + 'rebase', and 'rebase-preserve'. See \"branch.<name>.pullmode\" for\n> doing\n> + this in a non branch-specific manner.\n\nAdd?:\n    pull.rebase is deprecated.\n\n> +\n> - When preserve, also pass `--preserve-merges` along to 'git rebase'\n> - so that locally committed merge commits will not be flattened\n> - by running 'git pull'.\n> + When 'rebase-preserve', also pass `--preserve-merges` along to\n> + 'git rebase' so that locally committed merge commits will not be\n> + flattened by running 'git pull'.\n> +\n> *NOTE*: this is a possibly dangerous operation; do *not* use\n> it unless you understand the implications (see linkgit:git-rebase[1]\n> diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\n> index 200eb22..9a91b9f 100644\n> --- a/Documentation/git-pull.txt\n> +++ b/Documentation/git-pull.txt\n> @@ -117,7 +117,7 @@ locally created merge commits will not be\n> flattened.\n> +\n> When false, merge the current branch into the upstream branch.\n> +\n> -See `pull.rebase`, `branch.<name>.rebase` and\n> `branch.autosetuprebase` in\n> +See `pull.mode`, `branch.<name>.pullmode` and\n> `branch.autosetuprebase` in\n> linkgit:git-config[1] if you want to make `git pull` always use\n> `--rebase` instead of merging.\n> +\n> diff --git a/branch.c b/branch.c\n> index 723a36b..63ce671 100644\n> --- a/branch.c\n> +++ b/branch.c\n> @@ -71,8 +71,8 @@ void install_branch_config(int flag, const char\n> *local, const char *origin, cons\n>\n>  if (rebasing) {\n>  strbuf_reset(&key);\n> - strbuf_addf(&key, \"branch.%s.rebase\", local);\n> - git_config_set(key.buf, \"true\");\n> + strbuf_addf(&key, \"branch.%s.pullmode\", local);\n> + git_config_set(key.buf, \"rebase\");\n>  }\n>  strbuf_release(&key);\n>\n> diff --git a/builtin/remote.c b/builtin/remote.c\n> index b3ab4cf..46d3c4d 100644\n> --- a/builtin/remote.c\n> +++ b/builtin/remote.c\n> @@ -264,7 +264,7 @@ static int config_read_branches(const char *key,\n> const char *value, void *cb)\n>  char *name;\n>  struct string_list_item *item;\n>  struct branch_info *info;\n> - enum { REMOTE, MERGE, REBASE } type;\n> + enum { REMOTE, MERGE, REBASE, PULLMODE } type;\n>\n>  key += 7;\n>  if (ends_with(key, \".remote\")) {\n> @@ -276,6 +276,9 @@ static int config_read_branches(const char *key,\n> const char *value, void *cb)\n>  } else if (ends_with(key, \".rebase\")) {\n>  name = xstrndup(key, strlen(key) - 7);\n>  type = REBASE;\n> + } else if (ends_with(key, \".pullmode\")) {\n> + name = xstrndup(key, strlen(key) - 9);\n> + type = PULLMODE;\n>  } else\n>  return 0;\n>\n> @@ -299,12 +302,19 @@ static int config_read_branches(const char *key,\n> const char *value, void *cb)\n>  space = strchr(value, ' ');\n>  }\n>  string_list_append(&info->merge, xstrdup(value));\n> - } else {\n> + } else if (type == REBASE) {\n>  int v = git_config_maybe_bool(orig_key, value);\n>  if (v >= 0)\n>  info->rebase = v;\n>  else if (!strcmp(value, \"preserve\"))\n>  info->rebase = 1;\n> + } else {\n> + if (!strcmp(value, \"rebase\"))\n> + info->rebase = 1;\n> + else if (!strcmp(value, \"merge\"))\n> + info->rebase = 0;\n> + else if (!strcmp(value, \"rebase-preserve\"))\n> + info->rebase = 1;\n>  }\n>  }\n>  return 0;\n> diff --git a/git-pull.sh b/git-pull.sh\n> index 0a5aa2c..d4e25f1 100755\n> --- a/git-pull.sh\n> +++ b/git-pull.sh\n> @@ -15,6 +15,10 @@ require_work_tree_exists\n> cd_to_toplevel\n>\n>\n> +warn () {\n> + printf >&2 '%s\\n' \"$*\"\n> +}\n> +\n> die_conflict () {\n>     git diff-index --cached --name-status -r --ignore-submodules\n> HEAD --\n>     if [ $(git config --bool --get advice.resolveConflict || echo\n> true) = \"true\" ]; then\n> @@ -47,10 +51,41 @@ log_arg= verbosity= progress= recurse_submodules=\n> verify_signatures=\n> merge_args= edit= rebase_args=\n> curr_branch=$(git symbolic-ref -q HEAD)\n> curr_branch_short=\"${curr_branch#refs/heads/}\"\n> -rebase=$(bool_or_string_config branch.$curr_branch_short.rebase)\n> +mode=$(git config branch.${curr_branch_short}.pullmode)\n> +if test -z \"$mode\"\n> +then\n> + mode=$(git config pull.mode)\n> +fi\n> +case \"$mode\" in\n> +merge)\n> + rebase=\"false\"\n> + ;;\n> +rebase)\n> + rebase=\"true\"\n> + ;;\n> +rebase-preserve)\n> + rebase=\"preserve\"\n> + ;;\n> +'')\n> + ;;\n> +*)\n> + echo \"Invalid value for 'mode'\"\n> + usage\n> + exit 1\n> + ;;\n> +esac\n> if test -z \"$rebase\"\n> then\n> - rebase=$(bool_or_string_config pull.rebase)\n> + rebase=$(bool_or_string_config branch.$curr_branch_short.rebase)\n> + if test -z \"$rebase\"\n> + then\n> + rebase=$(bool_or_string_config pull.rebase)\n> + fi\n> + if test -n \"$rebase\"\n> + then\n> + warn \"$(gettext \"The configurations pull.rebase and\n> branch.<name>.rebase are deprecated.\")\"\n> + warn \"$(gettext \"Please use pull.mode and branch.<name>.pullmode\n> instead.\")\"\n> + fi\n> fi\n> dry_run=\n> while :\n> diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh\n> index fcdb867..b79aa75 100755\n> --- a/t/t3200-branch.sh\n> +++ b/t/t3200-branch.sh\n> @@ -559,7 +559,7 @@ test_expect_success 'autosetuprebase local on a\n> tracked local branch' '\n>  git branch --track myr1 mybase &&\n>  test \"$(git config branch.myr1.remote)\" = . &&\n>  test \"$(git config branch.myr1.merge)\" = refs/heads/mybase &&\n> - test \"$(git config branch.myr1.rebase)\" = true\n> + test \"$(git config branch.myr1.pullmode)\" = rebase\n> '\n>\n> test_expect_success 'autosetuprebase always on a tracked local branch'\n> '\n> @@ -571,7 +571,7 @@ test_expect_success 'autosetuprebase always on a\n> tracked local branch' '\n>  git branch --track myr2 mybase &&\n>  test \"$(git config branch.myr2.remote)\" = . &&\n>  test \"$(git config branch.myr2.merge)\" = refs/heads/mybase &&\n> - test \"$(git config branch.myr2.rebase)\" = true\n> + test \"$(git config branch.myr2.pullmode)\" = rebase\n> '\n>\n> test_expect_success 'autosetuprebase remote on a tracked local branch'\n> '\n> @@ -583,7 +583,7 @@ test_expect_success 'autosetuprebase remote on a\n> tracked local branch' '\n>  git branch --track myr3 mybase2 &&\n>  test \"$(git config branch.myr3.remote)\" = . &&\n>  test \"$(git config branch.myr3.merge)\" = refs/heads/mybase2 &&\n> - ! test \"$(git config branch.myr3.rebase)\" = true\n> + ! test \"$(git config branch.myr3.pullmode)\" = rebase\n> '\n>\n> test_expect_success 'autosetuprebase never on a tracked local branch'\n> '\n> @@ -595,7 +595,7 @@ test_expect_success 'autosetuprebase never on a\n> tracked local branch' '\n>  git branch --track myr4 mybase2 &&\n>  test \"$(git config branch.myr4.remote)\" = . &&\n>  test \"$(git config branch.myr4.merge)\" = refs/heads/mybase2 &&\n> - ! test \"$(git config branch.myr4.rebase)\" = true\n> + ! test \"$(git config branch.myr4.pullmode)\" = rebase\n> '\n>\n> test_expect_success 'autosetuprebase local on a tracked remote branch'\n> '\n> @@ -606,7 +606,7 @@ test_expect_success 'autosetuprebase local on a\n> tracked remote branch' '\n>  git branch --track myr5 local/master &&\n>  test \"$(git config branch.myr5.remote)\" = local &&\n>  test \"$(git config branch.myr5.merge)\" = refs/heads/master &&\n> - ! test \"$(git config branch.myr5.rebase)\" = true\n> + ! test \"$(git config branch.myr5.pullmode)\" = rebase\n> '\n>\n> test_expect_success 'autosetuprebase never on a tracked remote branch'\n> '\n> @@ -617,7 +617,7 @@ test_expect_success 'autosetuprebase never on a\n> tracked remote branch' '\n>  git branch --track myr6 local/master &&\n>  test \"$(git config branch.myr6.remote)\" = local &&\n>  test \"$(git config branch.myr6.merge)\" = refs/heads/master &&\n> - ! test \"$(git config branch.myr6.rebase)\" = true\n> + ! test \"$(git config branch.myr6.pullmode)\" = rebase\n> '\n>\n> test_expect_success 'autosetuprebase remote on a tracked remote\n> branch' '\n> @@ -628,7 +628,7 @@ test_expect_success 'autosetuprebase remote on a\n> tracked remote branch' '\n>  git branch --track myr7 local/master &&\n>  test \"$(git config branch.myr7.remote)\" = local &&\n>  test \"$(git config branch.myr7.merge)\" = refs/heads/master &&\n> - test \"$(git config branch.myr7.rebase)\" = true\n> + test \"$(git config branch.myr7.pullmode)\" = rebase\n> '\n>\n> test_expect_success 'autosetuprebase always on a tracked remote\n> branch' '\n> @@ -639,7 +639,7 @@ test_expect_success 'autosetuprebase always on a\n> tracked remote branch' '\n>  git branch --track myr8 local/master &&\n>  test \"$(git config branch.myr8.remote)\" = local &&\n>  test \"$(git config branch.myr8.merge)\" = refs/heads/master &&\n> - test \"$(git config branch.myr8.rebase)\" = true\n> + test \"$(git config branch.myr8.pullmode)\" = rebase\n> '\n>\n> test_expect_success 'autosetuprebase unconfigured on a tracked remote\n> branch' '\n> @@ -650,7 +650,7 @@ test_expect_success 'autosetuprebase unconfigured\n> on a tracked remote branch' '\n>  git branch --track myr9 local/master &&\n>  test \"$(git config branch.myr9.remote)\" = local &&\n>  test \"$(git config branch.myr9.merge)\" = refs/heads/master &&\n> - test \"z$(git config branch.myr9.rebase)\" = z\n> + test \"z$(git config branch.myr9.pullmode)\" = z\n> '\n>\n> test_expect_success 'autosetuprebase unconfigured on a tracked local\n> branch' '\n> @@ -661,7 +661,7 @@ test_expect_success 'autosetuprebase unconfigured\n> on a tracked local branch' '\n>  git branch --track myr10 mybase2 &&\n>  test \"$(git config branch.myr10.remote)\" = . &&\n>  test \"$(git config branch.myr10.merge)\" = refs/heads/mybase2 &&\n> - test \"z$(git config branch.myr10.rebase)\" = z\n> + test \"z$(git config branch.myr10.pullmode)\" = z\n> '\n>\n> test_expect_success 'autosetuprebase unconfigured on untracked local\n> branch' '\n> @@ -671,7 +671,7 @@ test_expect_success 'autosetuprebase unconfigured\n> on untracked local branch' '\n>  git branch --no-track myr11 mybase2 &&\n>  test \"z$(git config branch.myr11.remote)\" = z &&\n>  test \"z$(git config branch.myr11.merge)\" = z &&\n> - test \"z$(git config branch.myr11.rebase)\" = z\n> + test \"z$(git config branch.myr11.pullmode)\" = z\n> '\n>\n> test_expect_success 'autosetuprebase unconfigured on untracked remote\n> branch' '\n> @@ -681,7 +681,7 @@ test_expect_success 'autosetuprebase unconfigured\n> on untracked remote branch' '\n>  git branch --no-track myr12 local/master &&\n>  test \"z$(git config branch.myr12.remote)\" = z &&\n>  test \"z$(git config branch.myr12.merge)\" = z &&\n> - test \"z$(git config branch.myr12.rebase)\" = z\n> + test \"z$(git config branch.myr12.pullmode)\" = z\n> '\n>\n> test_expect_success 'autosetuprebase never on an untracked local\n> branch' '\n> @@ -692,7 +692,7 @@ test_expect_success 'autosetuprebase never on an\n> untracked local branch' '\n>  git branch --no-track myr13 mybase2 &&\n>  test \"z$(git config branch.myr13.remote)\" = z &&\n>  test \"z$(git config branch.myr13.merge)\" = z &&\n> - test \"z$(git config branch.myr13.rebase)\" = z\n> + test \"z$(git config branch.myr13.pullmode)\" = z\n> '\n>\n> test_expect_success 'autosetuprebase local on an untracked local\n> branch' '\n> @@ -703,7 +703,7 @@ test_expect_success 'autosetuprebase local on an\n> untracked local branch' '\n>  git branch --no-track myr14 mybase2 &&\n>  test \"z$(git config branch.myr14.remote)\" = z &&\n>  test \"z$(git config branch.myr14.merge)\" = z &&\n> - test \"z$(git config branch.myr14.rebase)\" = z\n> + test \"z$(git config branch.myr14.pullmode)\" = z\n> '\n>\n> test_expect_success 'autosetuprebase remote on an untracked local\n> branch' '\n> @@ -714,7 +714,7 @@ test_expect_success 'autosetuprebase remote on an\n> untracked local branch' '\n>  git branch --no-track myr15 mybase2 &&\n>  test \"z$(git config branch.myr15.remote)\" = z &&\n>  test \"z$(git config branch.myr15.merge)\" = z &&\n> - test \"z$(git config branch.myr15.rebase)\" = z\n> + test \"z$(git config branch.myr15.pullmode)\" = z\n> '\n>\n> test_expect_success 'autosetuprebase always on an untracked local\n> branch' '\n> @@ -725,7 +725,7 @@ test_expect_success 'autosetuprebase always on an\n> untracked local branch' '\n>  git branch --no-track myr16 mybase2 &&\n>  test \"z$(git config branch.myr16.remote)\" = z &&\n>  test \"z$(git config branch.myr16.merge)\" = z &&\n> - test \"z$(git config branch.myr16.rebase)\" = z\n> + test \"z$(git config branch.myr16.pullmode)\" = z\n> '\n>\n> test_expect_success 'autosetuprebase never on an untracked remote\n> branch' '\n> @@ -736,7 +736,7 @@ test_expect_success 'autosetuprebase never on an\n> untracked remote branch' '\n>  git branch --no-track myr17 local/master &&\n>  test \"z$(git config branch.myr17.remote)\" = z &&\n>  test \"z$(git config branch.myr17.merge)\" = z &&\n> - test \"z$(git config branch.myr17.rebase)\" = z\n> + test \"z$(git config branch.myr17.pullmode)\" = z\n> '\n>\n> test_expect_success 'autosetuprebase local on an untracked remote\n> branch' '\n> @@ -747,7 +747,7 @@ test_expect_success 'autosetuprebase local on an\n> untracked remote branch' '\n>  git branch --no-track myr18 local/master &&\n>  test \"z$(git config branch.myr18.remote)\" = z &&\n>  test \"z$(git config branch.myr18.merge)\" = z &&\n> - test \"z$(git config branch.myr18.rebase)\" = z\n> + test \"z$(git config branch.myr18.pullmode)\" = z\n> '\n>\n> test_expect_success 'autosetuprebase remote on an untracked remote\n> branch' '\n> @@ -758,7 +758,7 @@ test_expect_success 'autosetuprebase remote on an\n> untracked remote branch' '\n>  git branch --no-track myr19 local/master &&\n>  test \"z$(git config branch.myr19.remote)\" = z &&\n>  test \"z$(git config branch.myr19.merge)\" = z &&\n> - test \"z$(git config branch.myr19.rebase)\" = z\n> + test \"z$(git config branch.myr19.pullmode)\" = z\n> '\n>\n> test_expect_success 'autosetuprebase always on an untracked remote\n> branch' '\n> @@ -769,7 +769,7 @@ test_expect_success 'autosetuprebase always on an\n> untracked remote branch' '\n>  git branch --no-track myr20 local/master &&\n>  test \"z$(git config branch.myr20.remote)\" = z &&\n>  test \"z$(git config branch.myr20.merge)\" = z &&\n> - test \"z$(git config branch.myr20.rebase)\" = z\n> + test \"z$(git config branch.myr20.pullmode)\" = z\n> '\n>\n> test_expect_success 'autosetuprebase always on detached HEAD' '\n> diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh\n> index 5e67035..0e91b67 100755\n> --- a/t/t5601-clone.sh\n> +++ b/t/t5601-clone.sh\n> @@ -191,8 +191,8 @@ test_expect_success 'clone respects global\n> branch.autosetuprebase' '\n>  rm -fr dst &&\n>  git clone src dst &&\n>  cd dst &&\n> - actual=\"z$(git config branch.master.rebase)\" &&\n> - test ztrue = $actual\n> + actual=\"$(git config branch.master.pullmode)\" &&\n> + test \"$actual\" = rebase\n>  )\n> '\n>\n> -- \n> 1.9.2+fc1.3.gade8541\n>\n>\n"},{"id":"240219","messageId":"53602210aff0c_10a211e3308d@nysa.notmuch","threadId":"36539","inReplyTo":"5324ACC54F034438BBAFDB15A9D716D5@PhilipOakley","subject":"Re: [PATCH v5 1/6] pull: rename pull.rename to pull.mode","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2014-04-29T22:05:04Z","receivedAt":"2014-04-29T22:05:04Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Philip Oakley wrote:\n> From: \"Felipe Contreras\" <felipe.contreras@gmail.com>\n> > Also 'branch.<name>.rebase' to 'branch.<name>.pullmode'.\n> \n> Sorry I haven't commented earlier. Because the 0/6 explanation isn't a\n> commit, a few extra words would be useful to capture what the 0/6 cover\n> letter said to start the patch series cleanly/clearly e.g. start with\n> \n>     Begin the \"Reject non-ff pulls by default\" process by creating new\n>     config variables which will allow extra options, to replace the old \n> pull\n>     configuration options.\n> \n> I didn't immediately grasp why the 'replacement' was happening, rather\n> than it being a creation and a deprecation.\n\nHow about this:\n\n> > This way 'pull.mode' can be set to 'merge', and the default can be\n> > something else.\n\nThis will allow us to eventually add a 'merge-ff-only' option, and\neventually set it as default to solve the problem of not rejecting\nnon-ff pulls by default.\n\n> > The old configurations still work, but get deprecated.\n> >\n> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n\n> > --- a/Documentation/config.txt\n> > +++ b/Documentation/config.txt\n\n> > @@ -764,15 +764,15 @@ branch.<name>.mergeoptions::\n> >  option values containing whitespace characters are currently not\n> >  supported.\n> >\n> > -branch.<name>.rebase::\n> > - When true, rebase the branch <name> on top of the fetched branch,\n> > - instead of merging the default branch from the default remote when\n> > - \"git pull\" is run. See \"pull.rebase\" for doing this in a non\n> > - branch-specific manner.\n> > +branch.<name>.pullmode::\n> > + When \"git pull\" is run, this determines if it would either merge or\n> > + rebase the fetched branch. The possible values are 'merge',\n> > + 'rebase', and 'rebase-preserve'. See \"pull.mode\" for doing this in a\n> > + non branch-specific manner.\n> \n> I'd think it useful to add that:\n>     branch.<name>.rebase is deprecated.\n> given the large amount of internet cruft about this older config\n> variable name\n\nI don't recall deprecated configurations in the documentation, but I\ndon't see a problem adding that either.\n\n-- \nFelipe Contreras\n"},{"id":"240255","messageId":"7B859CB604CE45AEA1DE2C9A9EF6C2B9@PhilipOakley","threadId":"36539","inReplyTo":"53602210aff0c_10a211e3308d@nysa.notmuch","subject":"Re: [PATCH v5 1/6] pull: rename pull.rename to pull.mode","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":"2014-04-29T23:00:03Z","receivedAt":"2014-04-29T23:00:03Z","isPatch":true,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Felipe Contreras\" <felipe.contreras@gmail.com>\n> Philip Oakley wrote:\n>> From: \"Felipe Contreras\" <felipe.contreras@gmail.com>\n>> > Also 'branch.<name>.rebase' to 'branch.<name>.pullmode'.\n>>\n>> Sorry I haven't commented earlier. Because the 0/6 explanation isn't \n>> a\n>> commit, a few extra words would be useful to capture what the 0/6 \n>> cover\n>> letter said to start the patch series cleanly/clearly e.g. start with\n>>\n>>     Begin the \"Reject non-ff pulls by default\" process by creating \n>> new\n>>     config variables which will allow extra options, to replace the \n>> old\n>> pull\n>>     configuration options.\n>>\n>> I didn't immediately grasp why the 'replacement' was happening, \n>> rather\n>> than it being a creation and a deprecation.\n>\n> How about this:\n>\n>> > This way 'pull.mode' can be set to 'merge', and the default can be\n>> > something else.\n\nMy initial problem was the word sequence order which, in the original, \nstarted with the 'replace' statement, which tripped me up. So I was \nlooking for some preparatory wording to set the scene and avoid the \ntrip.\n(I'm assuming you were noting that you already had the subsequent \"This \nway 'pull.mode'..\" statement, unfortunately I'd already tripped up by \nthen in the original, hence the suggestions for the scene setting)\n\n>\n> This will allow us to eventually add a 'merge-ff-only' option, and\n> eventually set it as default to solve the problem of not rejecting\n> non-ff pulls by default.\n>\n>> > The old configurations still work, but get deprecated.\n>> >\n>> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n>\n>> > --- a/Documentation/config.txt\n>> > +++ b/Documentation/config.txt\n>\n>> > @@ -764,15 +764,15 @@ branch.<name>.mergeoptions::\n>> >  option values containing whitespace characters are currently not\n>> >  supported.\n>> >\n>> > -branch.<name>.rebase::\n>> > - When true, rebase the branch <name> on top of the fetched branch,\n>> > - instead of merging the default branch from the default remote \n>> > when\n>> > - \"git pull\" is run. See \"pull.rebase\" for doing this in a non\n>> > - branch-specific manner.\n>> > +branch.<name>.pullmode::\n>> > + When \"git pull\" is run, this determines if it would either merge \n>> > or\n>> > + rebase the fetched branch. The possible values are 'merge',\n>> > + 'rebase', and 'rebase-preserve'. See \"pull.mode\" for doing this \n>> > in a\n>> > + non branch-specific manner.\n>>\n>> I'd think it useful to add that:\n>>     branch.<name>.rebase is deprecated.\n>> given the large amount of internet cruft about this older config\n>> variable name\n>\n> I don't recall deprecated configurations in the documentation, but I\n> don't see a problem adding that either.\n\nI'm sure that Junio will be able to form an opinion, which could go \neither way. On the one hand we try to avoid endless deprecation notices \nthat then never get removed. On the other, we have the internet advice \nto set those old variables, so its worth associating them with their \nnewer replacement with the warning. It'll be some else's judgment call \nat the end of the day.\n\n>\n> -- \n> Felipe Contreras\n>\n--\nPhilip \n"},{"id":"240340","messageId":"xmqqr44eg0s0.fsf@gitster.dls.corp.google.com","threadId":"36539","inReplyTo":"1398770226-9686-1-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v5 0/6] Reject non-ff pulls by default","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-04-30T17:55:27Z","receivedAt":"2014-04-30T17:55:27Z","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> These are the steps needed to achieve this:\n\nThe overall progression (this comment is only about the design, not\nthe implementation) looks almost sensible, but I may have missed\nsome issues because the presentation was done in reverse.\n\nIn the following comment, I'll flip the presentation order to better\nshow natural progression of what the users will see.\n\n> 1) Rename pull.rename to pull.mode and\n>    branch.<name>.rebase to branch.<name>.pullmode\n>\n> This way the configurations and options remain consistent:\n>\n>   git pull --merge\n>   pull.mode = merge\n>   branch.<name>.pullmode = merge\n>\n>   git pull --rebase\n>   pull.mode = rebase\n>   branch.<name>.pullmode = rebase\n>\n>   git pull --rebase=preserve\n>   pull.mode = rebase-preserve\n>   branch.<name>.pullmode = rebase-preserve\n>\n>   git pull\n>   pull.mode = merge-ff-only\n>   branch.<name>.pullmode = merge-ff-only\n\nUntil the \"--merge\" option is added, \"pull.mode = merge\" cannot be\nthe same as \"git pull --merge\".  I think you either need to squash\nthese two steps into one, or flip the order of them.\n\n> 2) Add --merge option\n>\n> Since we have a message that says \"If unsure, run 'git pull --merge'\", which is\n> more friendly than 'git pull --no-rebase', we should add this option, and\n> deprecate --no-rebase.\n\nObviously s/have a/will have a/, but the intention is good.\n\n> However, the documentation would become confusing if --merge is configured in\n> pull.rebase, instead, we want something like this:\n>\n>   See `pull.mode`, `branch.<name>.pullmode` in linkgit:git-config[1] if you want\n>   to make `git pull` always use `--merge`.\n\nIt gets unclear to me how the transition is planned around here.  Is\nthis a correct paraphrasing of these four steps?\n\n    - Add pull.mode (and its branch-specific friend) and \"pull\n      --merge\" so that people can set the former to \"merge\" or train\n      their fingers to type the latter to keep doing the\n      fetch-and-merge (your steps 1 and 2)\n\n    - Add ff-only to pull.mode (your step 3)\n\n    - With the endgame of \"out of box Git without any configuration\n      refuses 'git pull' (without --merge/--rebase) that does not\n      fast forward\" in mind, start warning \"In the future you will\n      have to either set pull.mode (and/or its friends) or type\n      \"pull --merge\" (or \"pull --rebase\") when the endgame version\n      of 'git pull' would fail with the error message, but still do\n      as was asked to do as before.  At this step, existing users\n      can set pull.mode to \"merge\" or \"rebase\" or whatever to\n      squelch the warning.\n\n    - Flip the default.  By the time this happens, thanks to the\n      previous step to warn beforehand, nobody needs to see the\n      warning. (your step 4)\n\nIf that is the rough outline, I think it is sensible.\n\n> 3) Add merge-ff-only config\n>\n> This option would trigger a check inside `git pull` itself, and error out with\n> the aforementioned message if it's not possible to do a fast-forward merge.\n>\n> However, this option conflicts with --rebase, and --no-rebase. Solution below.\n\nAm I reading you correctly that setting \"pull.mode = ff-only\" will\nrequire you to explicitly say \"git pull --merge/--rebase\"?  If that\nis the case, I think the step makes sense.\n\n> 4) Only allow fast-forward merges by default\n>\n> We could pass --ff-only to `git merge`, however, if we do that we'll get an error like this:\n>\n>   Not possible to fast-forward, aborting.\n>\n> This is not friendly; we want an error that is user-friendly:\n>\n>   The pull was not fast-forward, please either merge or rebase.\n>   If unsure, run 'git pull --merge'.\n>\n> When we do this we want to give the users the option to go back to the previous\n> behavior, so a new configuration is needed.\n"},{"id":"240348","messageId":"53614470489f9_f9b15012ecbc@nysa.notmuch","threadId":"36539","inReplyTo":"xmqqr44eg0s0.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v5 0/6] Reject non-ff pulls by default","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2014-04-30T18:44:00Z","receivedAt":"2014-04-30T18:44:00Z","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> > These are the steps needed to achieve this:\n> \n> The overall progression (this comment is only about the design, not\n> the implementation) looks almost sensible, but I may have missed\n> some issues because the presentation was done in reverse.\n> \n> In the following comment, I'll flip the presentation order to better\n> show natural progression of what the users will see.\n> \n> > 1) Rename pull.rename to pull.mode and\n> >    branch.<name>.rebase to branch.<name>.pullmode\n> >\n> > This way the configurations and options remain consistent:\n> >\n> >   git pull --merge\n> >   pull.mode = merge\n> >   branch.<name>.pullmode = merge\n> >\n> >   git pull --rebase\n> >   pull.mode = rebase\n> >   branch.<name>.pullmode = rebase\n> >\n> >   git pull --rebase=preserve\n> >   pull.mode = rebase-preserve\n> >   branch.<name>.pullmode = rebase-preserve\n> >\n> >   git pull\n> >   pull.mode = merge-ff-only\n> >   branch.<name>.pullmode = merge-ff-only\n> \n> Until the \"--merge\" option is added, \"pull.mode = merge\" cannot be\n> the same as \"git pull --merge\".  I think you either need to squash\n> these two steps into one, or flip the order of them.\n\nYeah, but the documentation of --merge should mention `pull.mode` and\n`branch.<name>.pullmode`. If I do --merge first I would have to mention\npull.rebase and branch.<name>.rebase, which is weird.\n\nI think it's more sensible to do the less visible changes first.\n\n> > 2) Add --merge option\n> >\n> > Since we have a message that says \"If unsure, run 'git pull --merge'\", which is\n> > more friendly than 'git pull --no-rebase', we should add this option, and\n> > deprecate --no-rebase.\n> \n> Obviously s/have a/will have a/, but the intention is good.\n> \n> > However, the documentation would become confusing if --merge is configured in\n> > pull.rebase, instead, we want something like this:\n> >\n> >   See `pull.mode`, `branch.<name>.pullmode` in linkgit:git-config[1] if you want\n> >   to make `git pull` always use `--merge`.\n> \n> It gets unclear to me how the transition is planned around here.  Is\n> this a correct paraphrasing of these four steps?\n> \n>     - Add pull.mode (and its branch-specific friend) and \"pull\n>       --merge\" so that people can set the former to \"merge\" or train\n>       their fingers to type the latter to keep doing the\n>       fetch-and-merge (your steps 1 and 2)\n> \n>     - Add ff-only to pull.mode (your step 3)\n\nCorrect.\n\n>     - With the endgame of \"out of box Git without any configuration\n>       refuses 'git pull' (without --merge/--rebase) that does not\n>       fast forward\" in mind, start warning \"In the future you will\n>       have to either set pull.mode (and/or its friends) or type\n>       \"pull --merge\" (or \"pull --rebase\") when the endgame version\n>       of 'git pull' would fail with the error message, but still do\n>       as was asked to do as before.  At this step, existing users\n>       can set pull.mode to \"merge\" or \"rebase\" or whatever to\n>       squelch the warning.\n> \n>     - Flip the default.  By the time this happens, thanks to the\n>       previous step to warn beforehand, nobody needs to see the\n>       warning. (your step 4)\n\nThis is what my last version of the series did[1]. However, my plan was\nto land this in 1.x so users could see the warning, and then flip the\nswitch on 2.0.\n\nThis plan, however, fell off the cliff.\n\n> If that is the rough outline, I think it is sensible.\n> \n> > 3) Add merge-ff-only config\n> >\n> > This option would trigger a check inside `git pull` itself, and error out with\n> > the aforementioned message if it's not possible to do a fast-forward merge.\n> >\n> > However, this option conflicts with --rebase, and --no-rebase. Solution below.\n> \n> Am I reading you correctly that setting \"pull.mode = ff-only\" will\n> require you to explicitly say \"git pull --merge/--rebase\"?  If that\n> is the case, I think the step makes sense.\n\npull.mode = merge-ff-only\n\n[1] http://article.gmane.org/gmane.comp.version-control.git/235951\n\n-- \nFelipe Contreras\n"},{"id":"240350","messageId":"xmqqy4ymeihb.fsf@gitster.dls.corp.google.com","threadId":"36539","inReplyTo":"53614470489f9_f9b15012ecbc@nysa.notmuch","subject":"Re: [PATCH v5 0/6] Reject non-ff pulls by default","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-04-30T19:16:00Z","receivedAt":"2014-04-30T19:16:00Z","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>>     - With the endgame of \"out of box Git without any configuration\n>>       refuses 'git pull' (without --merge/--rebase) that does not\n>>       fast forward\" in mind, start warning \"In the future you will\n>>       have to either set pull.mode (and/or its friends) or type\n>>       \"pull --merge\" (or \"pull --rebase\") when the endgame version\n>>       of 'git pull' would fail with the error message, but still do\n>>       as was asked to do as before.  At this step, existing users\n>>       can set pull.mode to \"merge\" or \"rebase\" or whatever to\n>>       squelch the warning.\n>> \n>>     - Flip the default.  By the time this happens, thanks to the\n>>       previous step to warn beforehand, nobody needs to see the\n>>       warning. (your step 4)\n>\n> This is what my last version of the series did[1]. However, my plan was\n> to land this in 1.x so users could see the warning, and then flip the\n> switch on 2.0.\n>\n> This plan, however, fell off the cliff.\n\nYeah, I see that $gmane/234488 explains why the second step in the\nprevious one stopped.  I guess it was in expecting a reroll state,\nwaiting for that other topic (I do not remember offhand) to\ngraduate.\n\nI see nothing touching the affected codepaths now, so this time\naround we may have a better chance, perhaps?\n"},{"id":"240352","messageId":"53614d8c23d6_2aa5fa32f06@nysa.notmuch","threadId":"36539","inReplyTo":"xmqqy4ymeihb.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v5 0/6] Reject non-ff pulls by default","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2014-04-30T19:22:52Z","receivedAt":"2014-04-30T19:22:52Z","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> >>     - With the endgame of \"out of box Git without any configuration\n> >>       refuses 'git pull' (without --merge/--rebase) that does not\n> >>       fast forward\" in mind, start warning \"In the future you will\n> >>       have to either set pull.mode (and/or its friends) or type\n> >>       \"pull --merge\" (or \"pull --rebase\") when the endgame version\n> >>       of 'git pull' would fail with the error message, but still do\n> >>       as was asked to do as before.  At this step, existing users\n> >>       can set pull.mode to \"merge\" or \"rebase\" or whatever to\n> >>       squelch the warning.\n> >> \n> >>     - Flip the default.  By the time this happens, thanks to the\n> >>       previous step to warn beforehand, nobody needs to see the\n> >>       warning. (your step 4)\n> >\n> > This is what my last version of the series did[1]. However, my plan was\n> > to land this in 1.x so users could see the warning, and then flip the\n> > switch on 2.0.\n> >\n> > This plan, however, fell off the cliff.\n> \n> Yeah, I see that $gmane/234488 explains why the second step in the\n> previous one stopped.  I guess it was in expecting a reroll state,\n> waiting for that other topic (I do not remember offhand) to\n> graduate.\n> \n> I see nothing touching the affected codepaths now, so this time\n> around we may have a better chance, perhaps?\n\nA chance of what? Do you want me to reroll to include the future\nbackwards-incompatible change warning? Should I include the patch that\nturns the switch?\n\n-- \nFelipe Contreras\n"},{"id":"240351","messageId":"xmqqtx9aehws.fsf@gitster.dls.corp.google.com","threadId":"36539","inReplyTo":"53614470489f9_f9b15012ecbc@nysa.notmuch","subject":"Re: [PATCH v5 0/6] Reject non-ff pulls by default","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-04-30T19:28:19Z","receivedAt":"2014-04-30T19:28:19Z","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> Junio C Hamano wrote:\n> ...\n>> Until the \"--merge\" option is added, \"pull.mode = merge\" cannot be\n>> the same as \"git pull --merge\".  I think you either need to squash\n>> these two steps into one, or flip the order of them.\n>\n> Yeah, but the documentation of --merge should mention `pull.mode` and\n> `branch.<name>.pullmode`. If I do --merge first I would have to mention\n> pull.rebase and branch.<name>.rebase, which is weird.\n\nAnd the point of your step (1) to introduce pull.mode is to fix the\nweirdness, so in that sense, it makes even more sense to do the\n\"--merge\" first and then pull.mode the second.\n\nIf you first add --merge with an awkward documentation in the first\nstep and then correct that awkwardness in the second step that adds\npull.mode (oh, by the way, we need to pay attention to pull.rename\nas a fallback at least for a while), that would show a clear\njustification why pull.mode is a good idea.\n\n> I think it's more sensible to do the less visible changes first.\n\nThe people who discover pull.mode and set it to \"merge\" will be\ngreeted with an error with that step.\n\nSo it appears that squashing these two (and possibly also the\naddition of merge-ff-only) into a single step would be the only\nalternative, if you want to avoid the \"introduce something that\nshows the awkwardness of the situation and immediately fix it\"\napproach.\n"},{"id":"240357","messageId":"xmqqppjyegsw.fsf@gitster.dls.corp.google.com","threadId":"36539","inReplyTo":"53614d8c23d6_2aa5fa32f06@nysa.notmuch","subject":"Re: [PATCH v5 0/6] Reject non-ff pulls by default","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-04-30T19:52:15Z","receivedAt":"2014-04-30T19:52: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> Junio C Hamano wrote:\n>> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>> ...\n>> > This plan, however, fell off the cliff.\n>> \n>> Yeah, I see that $gmane/234488 explains why the second step in the\n>> previous one stopped.  I guess it was in expecting a reroll state,\n>> waiting for that other topic (I do not remember offhand) to\n>> graduate.\n>> \n>> I see nothing touching the affected codepaths now, so this time\n>> around we may have a better chance, perhaps?\n>\n> A chance of what?\n\nA chance not to have the plan \"fell off the cliff\".\n\n> Do you want me to reroll to include the future\n> backwards-incompatible change warning?\n\nYes, as I said in the other thread ($gmane/247758), if you do not\nhave that step yet (I haven't looked at the implementation while\ndiscussing the design in this thread and looking at patches in other\ntopics) I'd strongly recommend adding one.\n\n> Should I include the patch that turns the switch?\n\nSorry, but you lost me here.  Turns what switch to what value?\n"},{"id":"240368","messageId":"53615C73.20409@bbn.com","threadId":"36539","inReplyTo":"1398770226-9686-2-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v5 1/6] pull: rename pull.rename to pull.mode","fromName":"Richard Hansen","fromEmail":"rhansen@bbn.com","sentAt":"2014-04-30T20:26:27Z","receivedAt":"2014-04-30T20:26:27Z","isPatch":true,"sender":{"key":"rhansen@rhansen.org","avatar":null},"body":"On 2014-04-29 07:17, Felipe Contreras wrote:\n> Also 'branch.<name>.rebase' to 'branch.<name>.pullmode'.\n> \n> This way 'pull.mode' can be set to 'merge', and the default can be\n> something else.\n> \n> The old configurations still work, but get deprecated.\n\nShould users be warned if both pull.rebase and pull.mode are set?  (Also\nif both branch.<name>.rebase and branch.<name>.pullmode are set.)\n\nHmm, thinking about it more, I think I prefer it to *not* warn if both\nare set (as is currently coded).  If the user set *mode then presumably\nthey've read the documentation and know that *mode is the right way to\nconfigure the behavior, so a warning would only serve to badger them\ninto cleaning up their config file.  And it would annoy users that keep\ntheir ~/.gitconfig in a dotfiles repo shared between machines with\ndifferent versions of Git.\n\nI prefer a deprecation note in the documentation as Philip suggests, but\nI'm OK without one too.\n\n-Richard\n\n\n> \n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  Documentation/config.txt   | 34 +++++++++++++++++-----------------\n>  Documentation/git-pull.txt |  2 +-\n>  branch.c                   |  4 ++--\n>  builtin/remote.c           | 14 ++++++++++++--\n>  git-pull.sh                | 39 +++++++++++++++++++++++++++++++++++++--\n>  t/t3200-branch.sh          | 40 ++++++++++++++++++++--------------------\n>  t/t5601-clone.sh           |  4 ++--\n>  7 files changed, 91 insertions(+), 46 deletions(-)\n> \n> diff --git a/Documentation/config.txt b/Documentation/config.txt\n> index c26a7c8..5978d35 100644\n> --- a/Documentation/config.txt\n> +++ b/Documentation/config.txt\n> @@ -708,7 +708,7 @@ branch.autosetupmerge::\n>  branch.autosetuprebase::\n>  \tWhen a new branch is created with 'git branch' or 'git checkout'\n>  \tthat tracks another branch, this variable tells Git to set\n> -\tup pull to rebase instead of merge (see \"branch.<name>.rebase\").\n> +\tup pull to rebase instead of merge (see \"branch.<name>.pullmode\").\n>  \tWhen `never`, rebase is never automatically set to true.\n>  \tWhen `local`, rebase is set to true for tracked branches of\n>  \tother local branches.\n> @@ -764,15 +764,15 @@ branch.<name>.mergeoptions::\n>  \toption values containing whitespace characters are currently not\n>  \tsupported.\n>  \n> -branch.<name>.rebase::\n> -\tWhen true, rebase the branch <name> on top of the fetched branch,\n> -\tinstead of merging the default branch from the default remote when\n> -\t\"git pull\" is run. See \"pull.rebase\" for doing this in a non\n> -\tbranch-specific manner.\n> +branch.<name>.pullmode::\n> +\tWhen \"git pull\" is run, this determines if it would either merge or\n> +\trebase the fetched branch. The possible values are 'merge',\n> +\t'rebase', and 'rebase-preserve'. See \"pull.mode\" for doing this in a\n> +\tnon branch-specific manner.\n>  +\n> -\tWhen preserve, also pass `--preserve-merges` along to 'git rebase'\n> -\tso that locally committed merge commits will not be flattened\n> -\tby running 'git pull'.\n> +\tWhen 'rebase-preserve', also pass `--preserve-merges` along to\n> +\t'git rebase' so that locally committed merge commits will not be\n> +\tflattened by running 'git pull'.\n>  +\n>  *NOTE*: this is a possibly dangerous operation; do *not* use\n>  it unless you understand the implications (see linkgit:git-rebase[1]\n> @@ -1881,15 +1881,15 @@ pretty.<name>::\n>  \tNote that an alias with the same name as a built-in format\n>  \twill be silently ignored.\n>  \n> -pull.rebase::\n> -\tWhen true, rebase branches on top of the fetched branch, instead\n> -\tof merging the default branch from the default remote when \"git\n> -\tpull\" is run. See \"branch.<name>.rebase\" for setting this on a\n> -\tper-branch basis.\n> +pull.mode::\n> +\tWhen \"git pull\" is run, this determines if it would either merge or\n> +\trebase the fetched branch. The possible values are 'merge',\n> +\t'rebase', and 'rebase-preserve'. See \"branch.<name>.pullmode\" for doing\n> +\tthis in a non branch-specific manner.\n>  +\n> -\tWhen preserve, also pass `--preserve-merges` along to 'git rebase'\n> -\tso that locally committed merge commits will not be flattened\n> -\tby running 'git pull'.\n> +\tWhen 'rebase-preserve', also pass `--preserve-merges` along to\n> +\t'git rebase' so that locally committed merge commits will not be\n> +\tflattened by running 'git pull'.\n>  +\n>  *NOTE*: this is a possibly dangerous operation; do *not* use\n>  it unless you understand the implications (see linkgit:git-rebase[1]\n> diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\n> index 200eb22..9a91b9f 100644\n> --- a/Documentation/git-pull.txt\n> +++ b/Documentation/git-pull.txt\n> @@ -117,7 +117,7 @@ locally created merge commits will not be flattened.\n>  +\n>  When false, merge the current branch into the upstream branch.\n>  +\n> -See `pull.rebase`, `branch.<name>.rebase` and `branch.autosetuprebase` in\n> +See `pull.mode`, `branch.<name>.pullmode` and `branch.autosetuprebase` in\n>  linkgit:git-config[1] if you want to make `git pull` always use\n>  `--rebase` instead of merging.\n>  +\n> diff --git a/branch.c b/branch.c\n> index 723a36b..63ce671 100644\n> --- a/branch.c\n> +++ b/branch.c\n> @@ -71,8 +71,8 @@ void install_branch_config(int flag, const char *local, const char *origin, cons\n>  \n>  \tif (rebasing) {\n>  \t\tstrbuf_reset(&key);\n> -\t\tstrbuf_addf(&key, \"branch.%s.rebase\", local);\n> -\t\tgit_config_set(key.buf, \"true\");\n> +\t\tstrbuf_addf(&key, \"branch.%s.pullmode\", local);\n> +\t\tgit_config_set(key.buf, \"rebase\");\n>  \t}\n>  \tstrbuf_release(&key);\n>  \n> diff --git a/builtin/remote.c b/builtin/remote.c\n> index b3ab4cf..46d3c4d 100644\n> --- a/builtin/remote.c\n> +++ b/builtin/remote.c\n> @@ -264,7 +264,7 @@ static int config_read_branches(const char *key, const char *value, void *cb)\n>  \t\tchar *name;\n>  \t\tstruct string_list_item *item;\n>  \t\tstruct branch_info *info;\n> -\t\tenum { REMOTE, MERGE, REBASE } type;\n> +\t\tenum { REMOTE, MERGE, REBASE, PULLMODE } type;\n>  \n>  \t\tkey += 7;\n>  \t\tif (ends_with(key, \".remote\")) {\n> @@ -276,6 +276,9 @@ static int config_read_branches(const char *key, const char *value, void *cb)\n>  \t\t} else if (ends_with(key, \".rebase\")) {\n>  \t\t\tname = xstrndup(key, strlen(key) - 7);\n>  \t\t\ttype = REBASE;\n> +\t\t} else if (ends_with(key, \".pullmode\")) {\n> +\t\t\tname = xstrndup(key, strlen(key) - 9);\n> +\t\t\ttype = PULLMODE;\n>  \t\t} else\n>  \t\t\treturn 0;\n>  \n> @@ -299,12 +302,19 @@ static int config_read_branches(const char *key, const char *value, void *cb)\n>  \t\t\t\tspace = strchr(value, ' ');\n>  \t\t\t}\n>  \t\t\tstring_list_append(&info->merge, xstrdup(value));\n> -\t\t} else {\n> +\t\t} else if (type == REBASE) {\n>  \t\t\tint v = git_config_maybe_bool(orig_key, value);\n>  \t\t\tif (v >= 0)\n>  \t\t\t\tinfo->rebase = v;\n>  \t\t\telse if (!strcmp(value, \"preserve\"))\n>  \t\t\t\tinfo->rebase = 1;\n> +\t\t} else {\n> +\t\t\tif (!strcmp(value, \"rebase\"))\n> +\t\t\t\tinfo->rebase = 1;\n> +\t\t\telse if (!strcmp(value, \"merge\"))\n> +\t\t\t\tinfo->rebase = 0;\n> +\t\t\telse if (!strcmp(value, \"rebase-preserve\"))\n> +\t\t\t\tinfo->rebase = 1;\n>  \t\t}\n>  \t}\n>  \treturn 0;\n> diff --git a/git-pull.sh b/git-pull.sh\n> index 0a5aa2c..d4e25f1 100755\n> --- a/git-pull.sh\n> +++ b/git-pull.sh\n> @@ -15,6 +15,10 @@ require_work_tree_exists\n>  cd_to_toplevel\n>  \n>  \n> +warn () {\n> +\tprintf >&2 '%s\\n' \"$*\"\n> +}\n> +\n>  die_conflict () {\n>      git diff-index --cached --name-status -r --ignore-submodules HEAD --\n>      if [ $(git config --bool --get advice.resolveConflict || echo true) = \"true\" ]; then\n> @@ -47,10 +51,41 @@ log_arg= verbosity= progress= recurse_submodules= verify_signatures=\n>  merge_args= edit= rebase_args=\n>  curr_branch=$(git symbolic-ref -q HEAD)\n>  curr_branch_short=\"${curr_branch#refs/heads/}\"\n> -rebase=$(bool_or_string_config branch.$curr_branch_short.rebase)\n> +mode=$(git config branch.${curr_branch_short}.pullmode)\n> +if test -z \"$mode\"\n> +then\n> +\tmode=$(git config pull.mode)\n> +fi\n> +case \"$mode\" in\n> +merge)\n> +\trebase=\"false\"\n> +\t;;\n> +rebase)\n> +\trebase=\"true\"\n> +\t;;\n> +rebase-preserve)\n> +\trebase=\"preserve\"\n> +\t;;\n> +'')\n> +\t;;\n> +*)\n> +\techo \"Invalid value for 'mode'\"\n> +\tusage\n> +\texit 1\n> +\t;;\n> +esac\n>  if test -z \"$rebase\"\n>  then\n> -\trebase=$(bool_or_string_config pull.rebase)\n> +\trebase=$(bool_or_string_config branch.$curr_branch_short.rebase)\n> +\tif test -z \"$rebase\"\n> +\tthen\n> +\t\trebase=$(bool_or_string_config pull.rebase)\n> +\tfi\n> +\tif test -n \"$rebase\"\n> +\tthen\n> +\t\twarn \"$(gettext \"The configurations pull.rebase and branch.<name>.rebase are deprecated.\")\"\n> +\t\twarn \"$(gettext \"Please use pull.mode and branch.<name>.pullmode instead.\")\"\n> +\tfi\n>  fi\n>  dry_run=\n>  while :\n> diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh\n> index fcdb867..b79aa75 100755\n> --- a/t/t3200-branch.sh\n> +++ b/t/t3200-branch.sh\n> @@ -559,7 +559,7 @@ test_expect_success 'autosetuprebase local on a tracked local branch' '\n>  \tgit branch --track myr1 mybase &&\n>  \ttest \"$(git config branch.myr1.remote)\" = . &&\n>  \ttest \"$(git config branch.myr1.merge)\" = refs/heads/mybase &&\n> -\ttest \"$(git config branch.myr1.rebase)\" = true\n> +\ttest \"$(git config branch.myr1.pullmode)\" = rebase\n>  '\n>  \n>  test_expect_success 'autosetuprebase always on a tracked local branch' '\n> @@ -571,7 +571,7 @@ test_expect_success 'autosetuprebase always on a tracked local branch' '\n>  \tgit branch --track myr2 mybase &&\n>  \ttest \"$(git config branch.myr2.remote)\" = . &&\n>  \ttest \"$(git config branch.myr2.merge)\" = refs/heads/mybase &&\n> -\ttest \"$(git config branch.myr2.rebase)\" = true\n> +\ttest \"$(git config branch.myr2.pullmode)\" = rebase\n>  '\n>  \n>  test_expect_success 'autosetuprebase remote on a tracked local branch' '\n> @@ -583,7 +583,7 @@ test_expect_success 'autosetuprebase remote on a tracked local branch' '\n>  \tgit branch --track myr3 mybase2 &&\n>  \ttest \"$(git config branch.myr3.remote)\" = . &&\n>  \ttest \"$(git config branch.myr3.merge)\" = refs/heads/mybase2 &&\n> -\t! test \"$(git config branch.myr3.rebase)\" = true\n> +\t! test \"$(git config branch.myr3.pullmode)\" = rebase\n>  '\n>  \n>  test_expect_success 'autosetuprebase never on a tracked local branch' '\n> @@ -595,7 +595,7 @@ test_expect_success 'autosetuprebase never on a tracked local branch' '\n>  \tgit branch --track myr4 mybase2 &&\n>  \ttest \"$(git config branch.myr4.remote)\" = . &&\n>  \ttest \"$(git config branch.myr4.merge)\" = refs/heads/mybase2 &&\n> -\t! test \"$(git config branch.myr4.rebase)\" = true\n> +\t! test \"$(git config branch.myr4.pullmode)\" = rebase\n>  '\n>  \n>  test_expect_success 'autosetuprebase local on a tracked remote branch' '\n> @@ -606,7 +606,7 @@ test_expect_success 'autosetuprebase local on a tracked remote branch' '\n>  \tgit branch --track myr5 local/master &&\n>  \ttest \"$(git config branch.myr5.remote)\" = local &&\n>  \ttest \"$(git config branch.myr5.merge)\" = refs/heads/master &&\n> -\t! test \"$(git config branch.myr5.rebase)\" = true\n> +\t! test \"$(git config branch.myr5.pullmode)\" = rebase\n>  '\n>  \n>  test_expect_success 'autosetuprebase never on a tracked remote branch' '\n> @@ -617,7 +617,7 @@ test_expect_success 'autosetuprebase never on a tracked remote branch' '\n>  \tgit branch --track myr6 local/master &&\n>  \ttest \"$(git config branch.myr6.remote)\" = local &&\n>  \ttest \"$(git config branch.myr6.merge)\" = refs/heads/master &&\n> -\t! test \"$(git config branch.myr6.rebase)\" = true\n> +\t! test \"$(git config branch.myr6.pullmode)\" = rebase\n>  '\n>  \n>  test_expect_success 'autosetuprebase remote on a tracked remote branch' '\n> @@ -628,7 +628,7 @@ test_expect_success 'autosetuprebase remote on a tracked remote branch' '\n>  \tgit branch --track myr7 local/master &&\n>  \ttest \"$(git config branch.myr7.remote)\" = local &&\n>  \ttest \"$(git config branch.myr7.merge)\" = refs/heads/master &&\n> -\ttest \"$(git config branch.myr7.rebase)\" = true\n> +\ttest \"$(git config branch.myr7.pullmode)\" = rebase\n>  '\n>  \n>  test_expect_success 'autosetuprebase always on a tracked remote branch' '\n> @@ -639,7 +639,7 @@ test_expect_success 'autosetuprebase always on a tracked remote branch' '\n>  \tgit branch --track myr8 local/master &&\n>  \ttest \"$(git config branch.myr8.remote)\" = local &&\n>  \ttest \"$(git config branch.myr8.merge)\" = refs/heads/master &&\n> -\ttest \"$(git config branch.myr8.rebase)\" = true\n> +\ttest \"$(git config branch.myr8.pullmode)\" = rebase\n>  '\n>  \n>  test_expect_success 'autosetuprebase unconfigured on a tracked remote branch' '\n> @@ -650,7 +650,7 @@ test_expect_success 'autosetuprebase unconfigured on a tracked remote branch' '\n>  \tgit branch --track myr9 local/master &&\n>  \ttest \"$(git config branch.myr9.remote)\" = local &&\n>  \ttest \"$(git config branch.myr9.merge)\" = refs/heads/master &&\n> -\ttest \"z$(git config branch.myr9.rebase)\" = z\n> +\ttest \"z$(git config branch.myr9.pullmode)\" = z\n>  '\n>  \n>  test_expect_success 'autosetuprebase unconfigured on a tracked local branch' '\n> @@ -661,7 +661,7 @@ test_expect_success 'autosetuprebase unconfigured on a tracked local branch' '\n>  \tgit branch --track myr10 mybase2 &&\n>  \ttest \"$(git config branch.myr10.remote)\" = . &&\n>  \ttest \"$(git config branch.myr10.merge)\" = refs/heads/mybase2 &&\n> -\ttest \"z$(git config branch.myr10.rebase)\" = z\n> +\ttest \"z$(git config branch.myr10.pullmode)\" = z\n>  '\n>  \n>  test_expect_success 'autosetuprebase unconfigured on untracked local branch' '\n> @@ -671,7 +671,7 @@ test_expect_success 'autosetuprebase unconfigured on untracked local branch' '\n>  \tgit branch --no-track myr11 mybase2 &&\n>  \ttest \"z$(git config branch.myr11.remote)\" = z &&\n>  \ttest \"z$(git config branch.myr11.merge)\" = z &&\n> -\ttest \"z$(git config branch.myr11.rebase)\" = z\n> +\ttest \"z$(git config branch.myr11.pullmode)\" = z\n>  '\n>  \n>  test_expect_success 'autosetuprebase unconfigured on untracked remote branch' '\n> @@ -681,7 +681,7 @@ test_expect_success 'autosetuprebase unconfigured on untracked remote branch' '\n>  \tgit branch --no-track myr12 local/master &&\n>  \ttest \"z$(git config branch.myr12.remote)\" = z &&\n>  \ttest \"z$(git config branch.myr12.merge)\" = z &&\n> -\ttest \"z$(git config branch.myr12.rebase)\" = z\n> +\ttest \"z$(git config branch.myr12.pullmode)\" = z\n>  '\n>  \n>  test_expect_success 'autosetuprebase never on an untracked local branch' '\n> @@ -692,7 +692,7 @@ test_expect_success 'autosetuprebase never on an untracked local branch' '\n>  \tgit branch --no-track myr13 mybase2 &&\n>  \ttest \"z$(git config branch.myr13.remote)\" = z &&\n>  \ttest \"z$(git config branch.myr13.merge)\" = z &&\n> -\ttest \"z$(git config branch.myr13.rebase)\" = z\n> +\ttest \"z$(git config branch.myr13.pullmode)\" = z\n>  '\n>  \n>  test_expect_success 'autosetuprebase local on an untracked local branch' '\n> @@ -703,7 +703,7 @@ test_expect_success 'autosetuprebase local on an untracked local branch' '\n>  \tgit branch --no-track myr14 mybase2 &&\n>  \ttest \"z$(git config branch.myr14.remote)\" = z &&\n>  \ttest \"z$(git config branch.myr14.merge)\" = z &&\n> -\ttest \"z$(git config branch.myr14.rebase)\" = z\n> +\ttest \"z$(git config branch.myr14.pullmode)\" = z\n>  '\n>  \n>  test_expect_success 'autosetuprebase remote on an untracked local branch' '\n> @@ -714,7 +714,7 @@ test_expect_success 'autosetuprebase remote on an untracked local branch' '\n>  \tgit branch --no-track myr15 mybase2 &&\n>  \ttest \"z$(git config branch.myr15.remote)\" = z &&\n>  \ttest \"z$(git config branch.myr15.merge)\" = z &&\n> -\ttest \"z$(git config branch.myr15.rebase)\" = z\n> +\ttest \"z$(git config branch.myr15.pullmode)\" = z\n>  '\n>  \n>  test_expect_success 'autosetuprebase always on an untracked local branch' '\n> @@ -725,7 +725,7 @@ test_expect_success 'autosetuprebase always on an untracked local branch' '\n>  \tgit branch --no-track myr16 mybase2 &&\n>  \ttest \"z$(git config branch.myr16.remote)\" = z &&\n>  \ttest \"z$(git config branch.myr16.merge)\" = z &&\n> -\ttest \"z$(git config branch.myr16.rebase)\" = z\n> +\ttest \"z$(git config branch.myr16.pullmode)\" = z\n>  '\n>  \n>  test_expect_success 'autosetuprebase never on an untracked remote branch' '\n> @@ -736,7 +736,7 @@ test_expect_success 'autosetuprebase never on an untracked remote branch' '\n>  \tgit branch --no-track myr17 local/master &&\n>  \ttest \"z$(git config branch.myr17.remote)\" = z &&\n>  \ttest \"z$(git config branch.myr17.merge)\" = z &&\n> -\ttest \"z$(git config branch.myr17.rebase)\" = z\n> +\ttest \"z$(git config branch.myr17.pullmode)\" = z\n>  '\n>  \n>  test_expect_success 'autosetuprebase local on an untracked remote branch' '\n> @@ -747,7 +747,7 @@ test_expect_success 'autosetuprebase local on an untracked remote branch' '\n>  \tgit branch --no-track myr18 local/master &&\n>  \ttest \"z$(git config branch.myr18.remote)\" = z &&\n>  \ttest \"z$(git config branch.myr18.merge)\" = z &&\n> -\ttest \"z$(git config branch.myr18.rebase)\" = z\n> +\ttest \"z$(git config branch.myr18.pullmode)\" = z\n>  '\n>  \n>  test_expect_success 'autosetuprebase remote on an untracked remote branch' '\n> @@ -758,7 +758,7 @@ test_expect_success 'autosetuprebase remote on an untracked remote branch' '\n>  \tgit branch --no-track myr19 local/master &&\n>  \ttest \"z$(git config branch.myr19.remote)\" = z &&\n>  \ttest \"z$(git config branch.myr19.merge)\" = z &&\n> -\ttest \"z$(git config branch.myr19.rebase)\" = z\n> +\ttest \"z$(git config branch.myr19.pullmode)\" = z\n>  '\n>  \n>  test_expect_success 'autosetuprebase always on an untracked remote branch' '\n> @@ -769,7 +769,7 @@ test_expect_success 'autosetuprebase always on an untracked remote branch' '\n>  \tgit branch --no-track myr20 local/master &&\n>  \ttest \"z$(git config branch.myr20.remote)\" = z &&\n>  \ttest \"z$(git config branch.myr20.merge)\" = z &&\n> -\ttest \"z$(git config branch.myr20.rebase)\" = z\n> +\ttest \"z$(git config branch.myr20.pullmode)\" = z\n>  '\n>  \n>  test_expect_success 'autosetuprebase always on detached HEAD' '\n> diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh\n> index 5e67035..0e91b67 100755\n> --- a/t/t5601-clone.sh\n> +++ b/t/t5601-clone.sh\n> @@ -191,8 +191,8 @@ test_expect_success 'clone respects global branch.autosetuprebase' '\n>  \t\trm -fr dst &&\n>  \t\tgit clone src dst &&\n>  \t\tcd dst &&\n> -\t\tactual=\"z$(git config branch.master.rebase)\" &&\n> -\t\ttest ztrue = $actual\n> +\t\tactual=\"$(git config branch.master.pullmode)\" &&\n> +\t\ttest \"$actual\" = rebase\n>  \t)\n>  '\n>  \n> \n"}]}