{"thread":{"id":"30994","subject":"[PATCH 3/6] Teach \"git remote\" about remote.default.","startedAt":"2012-07-11T15:33:55Z","lastAt":"2012-07-13T20:29:10Z","messageCount":17,"participants":["marcnarc@xiplink.com","Junio C Hamano","Marc Branchaud"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"194911","messageId":"1342020841-24368-1-git-send-email-marcnarc@xiplink.com","threadId":"30994","inReplyTo":null,"subject":"[PATCH v2 0/6] Default remote","fromName":"","fromEmail":"marcnarc@xiplink.com","sentAt":"2012-07-11T15:33:55Z","receivedAt":"2012-07-11T15:33:55Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"Incorporated feedback on the first version of this series[1], and also added\ndocumentation updates.\n\nNote that the documentation changes include 4 minor grammatical fixes (verb\ntenses, added a \"the\" in a couple fo places).  \n\nI also added Phil's \"git push\" scenario to patch #2's message, rather than\nputting it in the documentation as I'd planned.  Explaining the behavior\nchange in the commit message felt more natural.\n\nThe specific differences from v1 are:\n\nPatch #1 (Rename remote.c's default_remote_name static variables.):\n  * Expanded the commit message to explain the choice of\n    \"effective_remote_name\".\n\nPatch #2 (Teach remote.c about the remote.default configuration setting.):\n  * Added documentation updates.\n  * Commit message now describes change in default \"git push\" behavior.\n  * Moved new remote_get_default_name() and remote_count() functions\n    to patch #3.\n\nPatch #3 (Teach \"git remote\" about remote.default.):\n  * (Was patch #4 in v1 of this series.)\n  * Documented changes to \"git remote\".\n  * The remote_get_default_name() and remote_count() functions are\n    now added to remote.[ch] here, with proper declarations.\n  * Added a test to ensure that renaming the \"origin\" remote still\n    properly sets remote.default in repos created with an older\n    version of git.\n\nPatch #4 (Teach clone to set remote.default.):\n  * (Was patch #3 in v1 of this series.)\n  * Commit message now justifies changes to \"git clone\".\n\nPatches 5 & 6 are unchanged.\n\n\t\tM.\n\n[1] http://thread.gmane.org/gmane.comp.version-control.git/201065\n\nMarc Branchaud (6):\n      Rename remote.c's default_remote_name static variables.\n      Teach remote.c about the remote.default configuration setting.\n      Teach \"git remote\" about remote.default.\n      Teach clone to set remote.default.\n      Test that plain \"git fetch\" uses remote.default when on a detached HEAD.\n      Teach get_default_remote to respect remote.default.\n\n Documentation/config.txt           |  8 ++++\n Documentation/git-pull.txt         |  6 ++-\n Documentation/git-push.txt         |  8 +++-\n Documentation/git-remote.txt       | 32 ++++++++++++++--\n Documentation/pull-fetch-param.txt |  6 +++\n builtin/clone.c                    |  2 +\n builtin/remote.c                   | 29 +++++++++++++++\n git-parse-remote.sh                |  5 +--\n remote.c                           | 34 +++++++++++++----\n remote.h                           |  2 +\n t/t5505-remote.sh                  | 76 ++++++++++++++++++++++++++++++++++++++\n t/t5510-fetch.sh                   | 17 +++++++++\n t/t5512-ls-remote.sh               |  8 +++-\n t/t5528-push-default.sh            |  4 +-\n t/t5601-clone.sh                   | 10 +++++\n t/t5702-clone-options.sh           |  7 +++-\n t/t7400-submodule-basic.sh         | 21 +++++++++++\n 17 files changed, 253 insertions(+), 22 deletions(-)\n"},{"id":"194915","messageId":"1342020841-24368-2-git-send-email-marcnarc@xiplink.com","threadId":"30994","inReplyTo":"1342020841-24368-1-git-send-email-marcnarc@xiplink.com","subject":"[PATCH 1/6] Rename remote.c's default_remote_name static variables.","fromName":"","fromEmail":"marcnarc@xiplink.com","sentAt":"2012-07-11T15:33:56Z","receivedAt":"2012-07-11T15:33:56Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"From: Marc Branchaud <marcnarc@xiplink.com>\n\nThis prepares the code to handle a true remote.default configuration value.\n\nRename two variables:\n  default_remote_name          --> effective_remote_name\n  explicit_default_remote_name --> explicit_effective_remote_name\n\neffective_remote_name is the remote name that is currently \"in effect\".\nThis is the currently checked-out branch's remote (in which case\nexplicit_effective_remote_name=1), or \"origin\" if the branch has no remote\n(or the working tree is a detached HEAD).\n\nThe next commit re-introduces default_remote_name with its new semantics.\n\nSigned-off-by: Marc Branchaud <marcnarc@xiplink.com>\n---\n remote.c | 16 ++++++++--------\n 1 file changed, 8 insertions(+), 8 deletions(-)\n\ndiff --git a/remote.c b/remote.c\nindex 6833538..6f371e0 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -47,8 +47,8 @@ static int branches_alloc;\n static int branches_nr;\n \n static struct branch *current_branch;\n-static const char *default_remote_name;\n-static int explicit_default_remote_name;\n+static const char *effective_remote_name;\n+static int explicit_effective_remote_name;\n \n static struct rewrites rewrites;\n static struct rewrites rewrites_push;\n@@ -360,8 +360,8 @@ static int handle_config(const char *key, const char *value, void *cb)\n \t\t\t\treturn config_error_nonbool(key);\n \t\t\tbranch->remote_name = xstrdup(value);\n \t\t\tif (branch == current_branch) {\n-\t\t\t\tdefault_remote_name = branch->remote_name;\n-\t\t\t\texplicit_default_remote_name = 1;\n+\t\t\t\teffective_remote_name = branch->remote_name;\n+\t\t\t\texplicit_effective_remote_name = 1;\n \t\t\t}\n \t\t} else if (!strcmp(subkey, \".merge\")) {\n \t\t\tif (!value)\n@@ -481,9 +481,9 @@ static void read_config(void)\n \tunsigned char sha1[20];\n \tconst char *head_ref;\n \tint flag;\n-\tif (default_remote_name) /* did this already */\n+\tif (effective_remote_name) /* did this already */\n \t\treturn;\n-\tdefault_remote_name = xstrdup(\"origin\");\n+\teffective_remote_name = xstrdup(\"origin\");\n \tcurrent_branch = NULL;\n \thead_ref = resolve_ref_unsafe(\"HEAD\", sha1, 0, &flag);\n \tif (head_ref && (flag & REF_ISSYMREF) &&\n@@ -680,8 +680,8 @@ struct remote *remote_get(const char *name)\n \tif (name)\n \t\tname_given = 1;\n \telse {\n-\t\tname = default_remote_name;\n-\t\tname_given = explicit_default_remote_name;\n+\t\tname = effective_remote_name;\n+\t\tname_given = explicit_effective_remote_name;\n \t}\n \n \tret = make_remote(name, 0);\n-- \n1.7.11.1\n"},{"id":"194916","messageId":"1342020841-24368-3-git-send-email-marcnarc@xiplink.com","threadId":"30994","inReplyTo":"1342020841-24368-1-git-send-email-marcnarc@xiplink.com","subject":"[PATCH 2/6] Teach remote.c about the remote.default configuration setting.","fromName":"","fromEmail":"marcnarc@xiplink.com","sentAt":"2012-07-11T15:33:57Z","receivedAt":"2012-07-11T15:33:57Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"From: Marc Branchaud <marcnarc@xiplink.com>\n\nThe code now has a default_remote_name and an effective_remote_name:\n\n - default_remote_name is set by remote.default in the config, or is \"origin\"\n   if remote.default doesn't exist (\"origin\" was the fallback value before\n   this change).\n\n - effective_remote_name is the name of the remote tracked by the current\n   branch, or is default_remote_name if the current branch doesn't have a\n   remote.\n\nThis has a minor side effect on the default behavior of \"git push\".  Consider\nthe following sequence of commands:\n\n      git config remote.default foo                 # Set default remote\n      git checkout somelocalbranch                  # Does not track a remote\n      git remote add origin ssh://example.com/repo  # Add a new \"origin\"\n      git push\n\nPrior to this change, the above \"git push\" would attempt to push to the new\n\"origin\" repository at ssh://example.com/repo.  Now instead that \"git push\"\nwill attempt to push to the repository named \"foo\".\n\nSigned-off-by: Marc Branchaud <marcnarc@xiplink.com>\n---\n Documentation/config.txt           |  8 ++++++++\n Documentation/git-pull.txt         |  6 +++++-\n Documentation/git-push.txt         |  8 +++++++-\n Documentation/pull-fetch-param.txt |  6 ++++++\n remote.c                           | 14 +++++++++++---\n 5 files changed, 37 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 915cb5a..7869e1b 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1856,6 +1856,14 @@ remote.<name>.vcs::\n \tSetting this to a value <vcs> will cause git to interact with\n \tthe remote with the git-remote-<vcs> helper.\n \n+remote.default::\n+\tThis value is the <name> of a remote.  When Git needs to automatically\n+\tchoose a remote to use, it first tries the 'branch.<branchname>.remote'\n+\tvalue of the currently checked-out branch.  If the currently checked-out\n+\tbranch has no remote, Git uses the remote named by 'remote.default', or\n+\tthe remote named \"origin\" if no value is set (even if there is no\n+\tactual remote named \"origin\").\n+\n remotes.<group>::\n \tThe list of remotes which are fetched by \"git remote update\n \t<group>\".  See linkgit:git-remote[1].\ndiff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\nindex defb544..2610253 100644\n--- a/Documentation/git-pull.txt\n+++ b/Documentation/git-pull.txt\n@@ -33,7 +33,11 @@ but usually it is the name of a branch in the remote repository.\n \n Default values for <repository> and <branch> are read from the\n \"remote\" and \"merge\" configuration for the current branch\n-as set by linkgit:git-branch[1] `--track`.\n+as set by linkgit:git-branch[1] `--track`.  If the current branch\n+has no remote configured, the default for <repository> is read\n+from the \"remote.default\" configuration variable.  If that variable\n+is not set, the default <repository> is \"origin\" even if there is no\n+actual remote named \"origin\".\n \n Assume the following history exists and the current branch is\n \"`master`\":\ndiff --git a/Documentation/git-push.txt b/Documentation/git-push.txt\nindex cb97cc1..fc17d39 100644\n--- a/Documentation/git-push.txt\n+++ b/Documentation/git-push.txt\n@@ -27,10 +27,16 @@ documentation for linkgit:git-receive-pack[1].\n OPTIONS[[OPTIONS]]\n ------------------\n <repository>::\n-\tThe \"remote\" repository that is destination of a push\n+\tThe \"remote\" repository that is the destination of the push\n \toperation.  This parameter can be either a URL\n \t(see the section <<URLS,GIT URLS>> below) or the name\n \tof a remote (see the section <<REMOTES,REMOTES>> below).\n+\tIf this parameter is omitted, git tries to use the remote\n+\tassociated with the currently checked-out branch.  If there\n+\tis no remote associated with the current branch, git uses\n+\tthe remote named by the \"remote.default\" configuration variable.\n+\tIf \"remote.default\" is not set, git uses the name \"origin\" even\n+\tif there is no actual remote named \"origin\".\n \n <refspec>...::\n \tThe format of a <refspec> parameter is an optional plus\ndiff --git a/Documentation/pull-fetch-param.txt b/Documentation/pull-fetch-param.txt\nindex 94a9d32..696f1fb 100644\n--- a/Documentation/pull-fetch-param.txt\n+++ b/Documentation/pull-fetch-param.txt\n@@ -3,6 +3,12 @@\n \tor pull operation.  This parameter can be either a URL\n \t(see the section <<URLS,GIT URLS>> below) or the name\n \tof a remote (see the section <<REMOTES,REMOTES>> below).\n+\tIf this parameter is omitted, git tries to use the remote\n+\tassociated with the currently checked-out branch.  If there\n+\tis no remote associated with the current branch, git uses\n+\tthe remote named by the \"remote.default\" configuration variable.\n+\tIf \"remote.default\" is not set, git uses the name \"origin\" even\n+\tif there is no actual remote named \"origin\".\n \n ifndef::git-pull[]\n <group>::\ndiff --git a/remote.c b/remote.c\nindex 6f371e0..2ebdbbd 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -47,6 +47,7 @@ static int branches_alloc;\n static int branches_nr;\n \n static struct branch *current_branch;\n+static const char *default_remote_name;\n static const char *effective_remote_name;\n static int explicit_effective_remote_name;\n \n@@ -397,8 +398,12 @@ static int handle_config(const char *key, const char *value, void *cb)\n \t\treturn 0;\n \t}\n \tsubkey = strrchr(name, '.');\n-\tif (!subkey)\n+\tif (!subkey) {\n+\t\t/* Look for remote.default */\n+\t\tif (!strcmp(name, \"default\"))\n+\t\t\tdefault_remote_name = xstrdup(value);\n \t\treturn 0;\n+\t}\n \tremote = make_remote(name, subkey - name);\n \tremote->origin = REMOTE_CONFIG;\n \tif (!strcmp(subkey, \".mirror\"))\n@@ -481,9 +486,8 @@ static void read_config(void)\n \tunsigned char sha1[20];\n \tconst char *head_ref;\n \tint flag;\n-\tif (effective_remote_name) /* did this already */\n+\tif (default_remote_name) /* did this already */\n \t\treturn;\n-\teffective_remote_name = xstrdup(\"origin\");\n \tcurrent_branch = NULL;\n \thead_ref = resolve_ref_unsafe(\"HEAD\", sha1, 0, &flag);\n \tif (head_ref && (flag & REF_ISSYMREF) &&\n@@ -492,6 +496,10 @@ static void read_config(void)\n \t\t\tmake_branch(head_ref + strlen(\"refs/heads/\"), 0);\n \t}\n \tgit_config(handle_config, NULL);\n+\tif (!default_remote_name)\n+\t\tdefault_remote_name = \"origin\";\n+\tif (!effective_remote_name)\n+\t\teffective_remote_name = default_remote_name;\n \talias_all_urls();\n }\n \n-- \n1.7.11.1\n"},{"id":"194910","messageId":"1342020841-24368-4-git-send-email-marcnarc@xiplink.com","threadId":"30994","inReplyTo":"1342020841-24368-1-git-send-email-marcnarc@xiplink.com","subject":"[PATCH 3/6] Teach \"git remote\" about remote.default.","fromName":"","fromEmail":"marcnarc@xiplink.com","sentAt":"2012-07-11T15:33:58Z","receivedAt":"2012-07-11T15:33:58Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"From: Marc Branchaud <marcnarc@xiplink.com>\n\nThe \"rename\" and \"rm\" commands now handle the case where the remote being\nchanged is the default remote.\n\nIf the \"add\" command is used to add the repo's first remote, that remote\nbecomes the default remote.\n\nAlso introduce a \"default\" sub-command to get or set the default remote:\n\n - \"git remote default\" (with no parameter) displays the current default remote.\n\n - \"git remote default <remo>\" checks if <remo> is a configured remote and if\n   so changes remote.default to <remo>.\n\nThese changes needed a couple of new helper functions in remote.c:\n - remote_get_default_name() returns default_remote_name.\n - remote_count() returns the number of remotes.\n\n(The test in t5528 had to be changed because now with push.default=matching\na plain \"git push\" succeeds with \"Everything up-to-date\".  It used to\nfail with \"No configured push destination\".)\n\nSigned-off-by: Marc Branchaud <marcnarc@xiplink.com>\n---\n Documentation/git-remote.txt | 32 ++++++++++++++++---\n builtin/remote.c             | 29 +++++++++++++++++\n remote.c                     | 12 +++++++\n remote.h                     |  2 ++\n t/t5505-remote.sh            | 76 ++++++++++++++++++++++++++++++++++++++++++++\n t/t5512-ls-remote.sh         |  8 ++++-\n t/t5528-push-default.sh      |  4 +--\n 7 files changed, 156 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt\nindex a308f4c..f4de21d 100644\n--- a/Documentation/git-remote.txt\n+++ b/Documentation/git-remote.txt\n@@ -11,6 +11,7 @@ SYNOPSIS\n [verse]\n 'git remote' [-v | --verbose]\n 'git remote add' [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <name> <url>\n+'git remote default' [<name>]\n 'git remote rename' <old> <new>\n 'git remote rm' <name>\n 'git remote set-head' <name> (-a | -d | <branch>)\n@@ -75,20 +76,43 @@ because a fetch would overwrite any local commits.\n +\n When a push mirror is created with `--mirror=push`, then `git push`\n will always behave as if `--mirror` was passed.\n++\n+When the first remote is added to a repository, it becomes the repository's\n+default remote.\n+\n+'default'::\n+\n+Displays or sets the name of the repository's default remote.  When git needs\n+to automatically choose a remote to use, it first tries to use the remote\n+associated with the currently checked-out branch.  If the currently\n+checked-out branch has no remote, git uses the repository's default remote.\n+If the repository has no default remote, git tries to use a remote named\n+\"origin\" even if there is no actual remote named \"origin\".  (In other words,\n+the default value for the default remote name is \"origin\".)\n++\n+With no <name> parameter, displays the current default remote name.\n++\n+With the <name> parameter, sets the repository's default remote to <name>.\n \n 'rename'::\n \n-Rename the remote named <old> to <new>. All remote-tracking branches and\n+Renames the remote named <old> to <new>. All remote-tracking branches and\n configuration settings for the remote are updated.\n +\n In case <old> and <new> are the same, and <old> is a file under\n `$GIT_DIR/remotes` or `$GIT_DIR/branches`, the remote is converted to\n the configuration file format.\n++\n+If <old> was the repository's default remote name, the default remote name\n+changes to <new>.\n \n 'rm'::\n \n-Remove the remote named <name>. All remote-tracking branches and\n-configuration settings for the remote are removed.\n+Removes the remote named <name>. All remote-tracking branches and\n+configuration settings for the remote are removed.  If the remote was\n+the repository's default remote, then the repository's default remote\n+name is changed to \"origin\".  Use 'git remote default <name>' to set\n+the repository's default remote name.\n \n 'set-head'::\n \n@@ -160,7 +184,7 @@ actually prune them.\n \n 'update'::\n \n-Fetch updates for a named set of remotes in the repository as defined by\n+Fetches updates for a named set of remotes in the repository as defined by\n remotes.<group>.  If a named group is not specified on the command line,\n the configuration parameter remotes.default will be used; if\n remotes.default is not defined, all remotes which do not have the\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 920262d..1fb272c 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -12,6 +12,7 @@ static const char * const builtin_remote_usage[] = {\n \t\"git remote add [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <name> <url>\",\n \t\"git remote rename <old> <new>\",\n \t\"git remote rm <name>\",\n+\t\"git remote default [<name>]\",\n \t\"git remote set-head <name> (-a | -d | <branch>)\",\n \t\"git remote [-v | --verbose] show [-n] <name>\",\n \t\"git remote prune [-n | --dry-run] <name>\",\n@@ -198,6 +199,9 @@ static int add(int argc, const char **argv)\n \tif (!valid_fetch_refspec(buf2.buf))\n \t\tdie(_(\"'%s' is not a valid remote name\"), name);\n \n+\tif (remote_count() == 1) /* remote_get() adds a remote if it's new */\n+\t\tgit_config_set(\"remote.default\", name);\n+\n \tstrbuf_addf(&buf, \"remote.%s.url\", name);\n \tif (git_config_set(buf.buf, url))\n \t\treturn 1;\n@@ -656,6 +660,10 @@ static int mv(int argc, const char **argv)\n \t\treturn error(_(\"Could not rename config section '%s' to '%s'\"),\n \t\t\t\tbuf.buf, buf2.buf);\n \n+\tif (!strcmp(oldremote->name, remote_get_default_name())) {\n+\t\tgit_config_set(\"remote.default\", newremote->name);\n+\t}\n+\n \tstrbuf_reset(&buf);\n \tstrbuf_addf(&buf, \"remote.%s.fetch\", rename.new);\n \tif (git_config_set_multivar(buf.buf, NULL, NULL, 1))\n@@ -798,6 +806,10 @@ static int rm(int argc, const char **argv)\n \tif (git_config_rename_section(buf.buf, NULL) < 1)\n \t\treturn error(_(\"Could not remove config section '%s'\"), buf.buf);\n \n+\tif (!strcmp(remote->name, remote_get_default_name())) {\n+\t\tgit_config_set(\"remote.default\", NULL);\n+\t}\n+\n \tread_branches();\n \tfor (i = 0; i < branch_list.nr; i++) {\n \t\tstruct string_list_item *item = branch_list.items + i;\n@@ -845,6 +857,21 @@ static int rm(int argc, const char **argv)\n \treturn result;\n }\n \n+static int deflt(int argc, const char **argv)\n+{\n+\tif (argc < 2)\n+\t\tprintf_ln(\"%s\", remote_get_default_name());\n+\telse {\n+\t\tconst char *name = argv[1];\n+\t\tif (remote_is_configured(name)) {\n+\t\t\tgit_config_set(\"remote.default\", name);\n+\t\t\tprintf_ln(_(\"Default remote set to '%s'.\"), name);\n+\t\t} else\n+\t\t\treturn error(_(\"No remote named '%s'.\"), name);\n+\t}\n+\treturn 0;\n+}\n+\n static void clear_push_info(void *util, const char *string)\n {\n \tstruct push_info *info = util;\n@@ -1582,6 +1609,8 @@ int cmd_remote(int argc, const char **argv, const char *prefix)\n \t\tresult = mv(argc, argv);\n \telse if (!strcmp(argv[0], \"rm\"))\n \t\tresult = rm(argc, argv);\n+\telse if (!strcmp(argv[0], \"default\"))\n+\t\tresult = deflt(argc, argv);\n \telse if (!strcmp(argv[0], \"set-head\"))\n \t\tresult = set_head(argc, argv);\n \telse if (!strcmp(argv[0], \"set-branches\"))\ndiff --git a/remote.c b/remote.c\nindex 2ebdbbd..8d9e8a8 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -679,6 +679,18 @@ static int valid_remote_nick(const char *name)\n \treturn !strchr(name, '/'); /* no slash */\n }\n \n+const char *remote_get_default_name(void)\n+{\n+\tread_config();\n+\treturn default_remote_name;\n+}\n+\n+int remote_count(void)\n+{\n+\tread_config();\n+\treturn remotes_nr;\n+}\n+\n struct remote *remote_get(const char *name)\n {\n \tstruct remote *ret;\ndiff --git a/remote.h b/remote.h\nindex 251d8fd..c8c54e8 100644\n--- a/remote.h\n+++ b/remote.h\n@@ -52,6 +52,8 @@ struct remote {\n \n struct remote *remote_get(const char *name);\n int remote_is_configured(const char *name);\n+const char *remote_get_default_name(void);\n+int remote_count(void);\n \n typedef int each_remote_fn(struct remote *remote, void *priv);\n int for_each_remote(each_remote_fn fn, void *priv);\ndiff --git a/t/t5505-remote.sh b/t/t5505-remote.sh\nindex e8af615..0027a82 100755\n--- a/t/t5505-remote.sh\n+++ b/t/t5505-remote.sh\n@@ -77,6 +77,15 @@ test_expect_success 'add another remote' '\n )\n '\n \n+test_expect_success 'add first remote sets default' '\n+(\n+\ttest_create_repo default-first-remote &&\n+\tcd default-first-remote &&\n+\tgit remote add first /path/to/first &&\n+\ttest \"$(git config --get remote.default)\" = first\n+)\n+'\n+\n test_expect_success 'remote forces tracking branches' '\n (\n \tcd test &&\n@@ -107,6 +116,16 @@ test_expect_success 'remove remote' '\n )\n '\n \n+test_expect_success 'remove default remote' '\n+(\n+\tgit clone one no-default\n+\tcd no-default &&\n+\ttest \"$(git config --get remote.default)\" = origin   # Sanity check\n+\tgit remote rm origin &&\n+\ttest_must_fail git config --get remote.default\n+)\n+'\n+\n test_expect_success 'remove remote protects local branches' '\n (\n \tcd test &&\n@@ -662,6 +681,28 @@ test_expect_success 'rename a remote with name prefix of other remote' '\n \n '\n \n+test_expect_success 'rename the default remote' '\n+\tgit clone one default-rename &&\n+\t(cd default-rename &&\n+\t\ttest \"$(git config --get remote.default)\" = origin   # Sanity?\n+\t\tgit remote rename origin tyrion\n+\t\ttest \"$(git config --get remote.default)\" = tyrion\n+\t)\n+\n+'\n+\n+# This test ensures that repos created wth an older version of git and that\n+# have a remote named \"origin\" get remote.default updated properly.\n+test_expect_success 'rename the \"origin\" remote if remote.default is not set' '\n+\tgit clone one default-oldschool &&\n+\t(cd default-oldschool &&\n+\t\tgit config --unset remote.default\n+\t\tgit remote rename origin stark\n+\t\ttest \"$(git config --get remote.default)\" = stark\n+\t)\n+'\n+\n+\n cat > remotes_origin << EOF\n URL: $(pwd)/one\n Push: refs/heads/master:refs/heads/upstream\n@@ -997,4 +1038,39 @@ test_expect_success 'remote set-url --delete baz' '\n \tcmp expect actual\n '\n \n+test_expect_success 'remote default' '\n+(\n+\tgit clone -o up one default\n+\tcd default &&\n+\ttest \"$(git remote default)\" = up\n+)\n+'\n+\n+test_expect_success 'remote default (none)' '\n+(\n+\ttest_create_repo default-none &&\n+\tcd default-none &&\n+\ttest \"$(git remote default)\" = origin\n+)\n+'\n+\n+test_expect_success 'remote default set' '\n+(\n+\ttest_create_repo default-set &&\n+\tcd default-set &&\n+\tgit remote add A /foo-A &&\n+\tgit remote add B /foo-A &&\n+\tgit remote default B &&\n+\ttest \"$(git remote default)\" = B\n+)\n+'\n+\n+test_expect_success 'remote default bad' '\n+(\n+\tgit clone one default-bad &&\n+\tcd default-bad &&\n+\ttest_must_fail git remote default NonExistant\n+)\n+'\n+\n test_done\ndiff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh\nindex 6764d51..853b045 100755\n--- a/t/t5512-ls-remote.sh\n+++ b/t/t5512-ls-remote.sh\n@@ -40,7 +40,13 @@ test_expect_success 'ls-remote self' '\n '\n \n test_expect_success 'dies when no remote specified and no default remotes found' '\n-\ttest_must_fail git ls-remote\n+\ttest_create_repo no-remotes &&\n+\t(\n+\t\tcd no-remotes &&\n+\t\ttest_must_fail git ls-remote &&\n+\t\ttest_config remote.default blop &&\n+\t\ttest_must_fail git ls-remote\n+\t)\n '\n \n test_expect_success 'use \"origin\" when no remote specified' '\ndiff --git a/t/t5528-push-default.sh b/t/t5528-push-default.sh\nindex 4736da8..6a08998 100755\n--- a/t/t5528-push-default.sh\n+++ b/t/t5528-push-default.sh\n@@ -71,10 +71,10 @@ test_expect_success '\"upstream\" does not push when remotes do not match' '\n \ttest_must_fail git push parent2\n '\n \n-test_expect_success 'push from/to new branch with upstream, matching and simple' '\n+test_expect_success 'push from/to new remoteless branch with upstream, matching and simple' '\n \tgit checkout -b new-branch &&\n \ttest_push_failure simple &&\n-\ttest_push_failure matching &&\n+\ttest_push_success matching master &&\n \ttest_push_failure upstream\n '\n \n-- \n1.7.11.1\n"},{"id":"194912","messageId":"1342020841-24368-5-git-send-email-marcnarc@xiplink.com","threadId":"30994","inReplyTo":"1342020841-24368-1-git-send-email-marcnarc@xiplink.com","subject":"[PATCH 4/6] Teach clone to set remote.default.","fromName":"","fromEmail":"marcnarc@xiplink.com","sentAt":"2012-07-11T15:33:59Z","receivedAt":"2012-07-11T15:33:59Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"From: Marc Branchaud <marcnarc@xiplink.com>\n\nThis makes git-clone consistent with the remote.default support implemented in\ngit-remote.  Specifically, since \"git remote add\" sets remote.default if\nit's adding the first remote to the repository, when clone itself adds the\nfirst remote it should do the same.\n\nThis also makes \"git clone -o\" work without a special case in the code (so\n\"git clone /some/repo\" and \"git clone -o origin /some/repo\" produce the same\nresult).\n\nSigned-off-by: Marc Branchaud <marcnarc@xiplink.com>\n---\n builtin/clone.c          |  2 ++\n t/t5601-clone.sh         | 10 ++++++++++\n t/t5702-clone-options.sh |  7 +++++--\n 3 files changed, 17 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex a4d8d25..b198456 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -770,6 +770,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tgit_config_set(key.buf, repo);\n \tstrbuf_reset(&key);\n \n+\tgit_config_set(\"remote.default\", option_origin);\n+\n \tif (option_reference.nr)\n \t\tsetup_reference();\n \ndiff --git a/t/t5601-clone.sh b/t/t5601-clone.sh\nindex 67869b4..046610d 100755\n--- a/t/t5601-clone.sh\n+++ b/t/t5601-clone.sh\n@@ -57,6 +57,16 @@ test_expect_success 'clone checks out files' '\n \n '\n \n+test_expect_success 'clone sets remote.default' '\n+\n+\trm -fr dst &&\n+\tgit clone src dst &&\n+\t(\n+\t\tcd dst &&\n+\t\ttest \"$(git config --get remote.default)\" = origin\n+\t)\n+'\n+\n test_expect_success 'clone respects GIT_WORK_TREE' '\n \n \tGIT_WORK_TREE=worktree git clone src bare &&\ndiff --git a/t/t5702-clone-options.sh b/t/t5702-clone-options.sh\nindex 02cb024..9e573dd 100755\n--- a/t/t5702-clone-options.sh\n+++ b/t/t5702-clone-options.sh\n@@ -15,8 +15,11 @@ test_expect_success 'setup' '\n test_expect_success 'clone -o' '\n \n \tgit clone -o foo parent clone-o &&\n-\t(cd clone-o && git rev-parse --verify refs/remotes/foo/master)\n-\n+\t(\n+\t\tcd clone-o &&\n+\t\tgit rev-parse --verify refs/remotes/foo/master &&\n+\t\ttest \"$(git config --get remote.default)\" = foo\n+\t)\n '\n \n test_expect_success 'redirected clone' '\n-- \n1.7.11.1\n"},{"id":"194913","messageId":"1342020841-24368-6-git-send-email-marcnarc@xiplink.com","threadId":"30994","inReplyTo":"1342020841-24368-1-git-send-email-marcnarc@xiplink.com","subject":"[PATCH 5/6] Test that plain \"git fetch\" uses remote.default when on a detached HEAD.","fromName":"","fromEmail":"marcnarc@xiplink.com","sentAt":"2012-07-11T15:34:00Z","receivedAt":"2012-07-11T15:34:00Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"From: Marc Branchaud <marcnarc@xiplink.com>\n\nSigned-off-by: Marc Branchaud <marcnarc@xiplink.com>\n---\n t/t5510-fetch.sh | 17 +++++++++++++++++\n 1 file changed, 17 insertions(+)\n\ndiff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh\nindex d7a19a1..8ecd996 100755\n--- a/t/t5510-fetch.sh\n+++ b/t/t5510-fetch.sh\n@@ -69,6 +69,23 @@ test_expect_success \"fetch test\" '\n \ttest \"z$mine\" = \"z$his\"\n '\n \n+test_expect_success \"fetch test detached HEAD uses default remote\" '\n+\tcd \"$D\" &&\n+\tgit clone -o foo . default-remote &&\n+\tgit checkout -b detached &&\n+\ttest_commit update1 &&\n+\t(\n+\t\tcd default-remote &&\n+\t\tgit checkout HEAD@{0} &&\n+\t\tgit fetch &&\n+\t\ttest -f .git/refs/remotes/foo/detached &&\n+\t\tmine=`git rev-parse refs/remotes/foo/detached` &&\n+\t\this=`cd .. && git rev-parse refs/heads/detached` &&\n+\t\ttest \"z$mine\" = \"z$his\"\n+\t) &&\n+\tgit checkout master\n+'\n+\n test_expect_success \"fetch test for-merge\" '\n \tcd \"$D\" &&\n \tcd three &&\n-- \n1.7.11.1\n"},{"id":"194914","messageId":"1342020841-24368-7-git-send-email-marcnarc@xiplink.com","threadId":"30994","inReplyTo":"1342020841-24368-1-git-send-email-marcnarc@xiplink.com","subject":"[PATCH 6/6] Teach get_default_remote to respect remote.default.","fromName":"","fromEmail":"marcnarc@xiplink.com","sentAt":"2012-07-11T15:34:01Z","receivedAt":"2012-07-11T15:34:01Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"From: Marc Branchaud <marcnarc@xiplink.com>\n\nUse \"git remote default\" instead of replicating its logic.\n\nThe unit test checks a relative-path submodule because the submodule code\nis (almost) the only thing that uses get_default_remote.\n\nSigned-off-by: Marc Branchaud <marcnarc@xiplink.com>\n---\n git-parse-remote.sh        |  5 +----\n t/t7400-submodule-basic.sh | 21 +++++++++++++++++++++\n 2 files changed, 22 insertions(+), 4 deletions(-)\n\ndiff --git a/git-parse-remote.sh b/git-parse-remote.sh\nindex 484b2e6..49257f0 100644\n--- a/git-parse-remote.sh\n+++ b/git-parse-remote.sh\n@@ -5,10 +5,7 @@\n GIT_DIR=$(git rev-parse -q --git-dir) || :;\n \n get_default_remote () {\n-\tcurr_branch=$(git symbolic-ref -q HEAD)\n-\tcurr_branch=\"${curr_branch#refs/heads/}\"\n-\torigin=$(git config --get \"branch.$curr_branch.remote\")\n-\techo ${origin:-origin}\n+\techo $(git remote default)\n }\n \n get_remote_merge_branch () {\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 81827e6..2ac2ffc 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -507,6 +507,27 @@ test_expect_success 'relative path works with user@host:path' '\n \t)\n '\n \n+test_expect_success 'realtive path works when superproject on detached HEAD' '\n+\t(\n+\t\ttest_create_repo detach &&\n+\t\tcd detach &&\n+\t\ttest_create_repo sub &&\n+\t\t(\n+\t\t\tcd sub &&\n+\t\t\ttest_commit foo\n+\t\t) &&\n+\t\tgit add sub &&\n+\t\tgit commit -m \"added sub\" &&\n+\t\trm -rf sub &&\n+\t\tgit checkout HEAD@{0} &&\n+\t\tgit config -f .gitmodules submodule.sub.path sub &&\n+\t\tgit config -f .gitmodules submodule.sub.url ../subrepo &&\n+\t\tgit remote add awkward /path/to/awkward\n+\t\tgit submodule init sub &&\n+\t\ttest \"$(git config submodule.sub.url)\" = /path/to/subrepo\n+\t)\n+'\n+\n test_expect_success 'moving the superproject does not break submodules' '\n \t(\n \t\tcd addtest &&\n-- \n1.7.11.1\n"},{"id":"194925","messageId":"7vy5mqduuc.fsf@alter.siamese.dyndns.org","threadId":"30994","inReplyTo":"1342020841-24368-1-git-send-email-marcnarc@xiplink.com","subject":"Re: [PATCH v2 0/6] Default remote","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-07-11T18:19:07Z","receivedAt":"2012-07-11T18:19:07Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"marcnarc@xiplink.com writes:\n\n> Incorporated feedback on the first version of this series[1], and also added\n> documentation updates.\n>\n> Note that the documentation changes include 4 minor grammatical fixes (verb\n> tenses, added a \"the\" in a couple fo places).  \n> ...\n> Patches 5 & 6 are unchanged.\n\nVery nicely written summary that describes incremental changes.\n"},{"id":"194926","messageId":"7vr4siduq3.fsf@alter.siamese.dyndns.org","threadId":"30994","inReplyTo":"1342020841-24368-3-git-send-email-marcnarc@xiplink.com","subject":"Re: [PATCH 2/6] Teach remote.c about the remote.default configuration setting.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-07-11T18:21:40Z","receivedAt":"2012-07-11T18:21:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"marcnarc@xiplink.com writes:\n\n> From: Marc Branchaud <marcnarc@xiplink.com>\n>\n> The code now has a default_remote_name and an effective_remote_name:\n>\n>  - default_remote_name is set by remote.default in the config, or is \"origin\"\n>    if remote.default doesn't exist (\"origin\" was the fallback value before\n>    this change).\n>\n>  - effective_remote_name is the name of the remote tracked by the current\n>    branch, or is default_remote_name if the current branch doesn't have a\n>    remote.\n>\n> This has a minor side effect on the default behavior of \"git push\".  Consider\n> the following sequence of commands:\n>\n>       git config remote.default foo                 # Set default remote\n>       git checkout somelocalbranch                  # Does not track a remote\n>       git remote add origin ssh://example.com/repo  # Add a new \"origin\"\n>       git push\n>\n> Prior to this change, the above \"git push\" would attempt to push to the new\n> \"origin\" repository at ssh://example.com/repo.  Now instead that \"git push\"\n> will attempt to push to the repository named \"foo\".\n\nHrm, is this a _minor_ side effect?\n\nIsn't that a natural and direct consequence of \"now you can set\nremote.default configuration to name the remote you want to use in\nplace of traditional 'origin'\" feature?  I think changing the\nbehaviour of \"git push\" in such a way is the point (may not be the\nonly but one of the important points) of this series.\n\n> diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt\n> index cb97cc1..fc17d39 100644\n> --- a/Documentation/git-push.txt\n> +++ b/Documentation/git-push.txt\n> @@ -27,10 +27,16 @@ documentation for linkgit:git-receive-pack[1].\n>  OPTIONS[[OPTIONS]]\n>  ------------------\n>  <repository>::\n> -\tThe \"remote\" repository that is destination of a push\n> +\tThe \"remote\" repository that is the destination of the push\n>  \toperation.  This parameter can be either a URL\n>  \t(see the section <<URLS,GIT URLS>> below) or the name\n>  \tof a remote (see the section <<REMOTES,REMOTES>> below).\n> +\tIf this parameter is omitted, git tries to use the remote\n> +\tassociated with the currently checked-out branch.  If there\n> +\tis no remote associated with the current branch, git uses\n> +\tthe remote named by the \"remote.default\" configuration variable.\n> +\tIf \"remote.default\" is not set, git uses the name \"origin\" even\n> +\tif there is no actual remote named \"origin\".\n\nThis comment applies to other changes to the documentation in this\npatch I didn't quote, but I think the phrasing 'even if there is no\nacutual remote named \"origin\"' needs to be rethought, because \"we\nuse it even if there is no such remote determined with this logic\"\napplies equally to branch.$name.remote, remote.default or built-in\ndefault value of remote.default which happens to be \"origin\".\n\n> diff --git a/remote.c b/remote.c\n> index 6f371e0..2ebdbbd 100644\n> --- a/remote.c\n> +++ b/remote.c\n> @@ -47,6 +47,7 @@ static int branches_alloc;\n>  static int branches_nr;\n>  \n>  static struct branch *current_branch;\n> +static const char *default_remote_name;\n>  static const char *effective_remote_name;\n\nComing from UNIX background, \"effective\" gives me an impression that\nit is contrasted with \"real\" (i.e. there is \"real remote\" for the\nbranch, but during this particular invocation it is overridden and\n\"effective remote\" is used instead).  Perhaps it is just me.\n\nSomething along the line of remote-name-to-use, use-remote, might\nsound more natural.\n"},{"id":"194927","messageId":"7vk3yaduh1.fsf@alter.siamese.dyndns.org","threadId":"30994","inReplyTo":"1342020841-24368-4-git-send-email-marcnarc@xiplink.com","subject":"Re: [PATCH 3/6] Teach \"git remote\" about remote.default.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-07-11T18:27:06Z","receivedAt":"2012-07-11T18:27:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"marcnarc@xiplink.com writes:\n\n> From: Marc Branchaud <marcnarc@xiplink.com>\n>\n> The \"rename\" and \"rm\" commands now handle the case where the remote being\n> changed is the default remote.\n\n\"handle the case\" is way underspecified.\n\nUntil I peeked the patch, I couldn't tell if you were now allowing\n\"git remote rm\" that does not say which remote to remove the remote\nnamed via remote.default by default, and had to wonder if you made\n\"git remote rename frotz\" without any other argument mean \"git\nremote rename <remote.default> frotz\" or the other way around.\n\n        The \"rename\" and \"rm\" commands adjusts the value of the\n        remote.default variable when they make the current default\n        remote disappear.\n\n> If the \"add\" command is used to add the repo's first remote, that remote\n> becomes the default remote.\n\nProbably sensible, but I could easily imagine existing users to be\nsurprised, harmed and complain, especially now those who want this\nbehaviour already have a separate \"remote default\" command to set it\nthemselves.\n\n> Also introduce a \"default\" sub-command to get or set the default remote:\n>\n>  - \"git remote default\" (with no parameter) displays the current default remote.\n>\n>  - \"git remote default <remo>\" checks if <remo> is a configured remote and if\n>    so changes remote.default to <remo>.\n\nAvoid cute and not-widely-used abbreviation; in other words s/<remo>/<remote>/.\n\n> These changes needed a couple of new helper functions in remote.c:\n>  - remote_get_default_name() returns default_remote_name.\n>  - remote_count() returns the number of remotes.\n>\n> (The test in t5528 had to be changed because now with push.default=matching\n> a plain \"git push\" succeeds with \"Everything up-to-date\".  It used to\n> fail with \"No configured push destination\".)\n\nI would like to see people think, when their \"new feature\" breaks\nexisting tests and needs adjustments, like this:\n\n    Even test scripts gets upset with this unexpected behaviour\n    change---real users may also be hurt the same way.  Should we\n    really need to do this change?  What can we do to help them?\n\nEven though I said \"Probably sensible\", I would prefer the \"first\nremote automatically replaces 'origin'\" feature not to be part of\nthis patch.  It is something we can queue separately on top as a\nseparate feature.\n\nI personally think in the long run it is probably the right thing to\ndo, but at the same time, I do not think it is something we want to\nthrow at the users as a flag-day event without transition planning.\n\n> +'default'::\n> +\n> +Displays or sets the name of the repository's default remote.  When git needs\n> +to automatically choose a remote to use, it first tries to use the remote\n> +associated with the currently checked-out branch.  If the currently\n> +checked-out branch has no remote, git uses the repository's default remote.\n> +If the repository has no default remote, git tries to use a remote named\n> +\"origin\" even if there is no actual remote named \"origin\".  (In other words,\n> +the default value for the default remote name is \"origin\".)\n\nAfter saying something long-winded and convoluted that you think it\nneeds \"In other words,\" appended, try to re-read the sentence\nwithout the long-winded part (and \"In other words,\").  I often find\nthat the long description is unnecessary after doing so myself.\n\nI wonder if it makes the result easier to read if you consolidated\nall the duplicated explanations of what the \"default remote\" is/does\nin this patch and previous patches to a single place (perhaps\nglossary) and refer to it from these places, e.g.\n\n\tdefault::\n\n        \tDisplay or sets the name of the default remote for\n\t        the repository.  See \"default remote\" in\n\t        linkgit:gitglossary[7].\n\n>  'rename'::\n>  \n> -Rename the remote named <old> to <new>. All remote-tracking branches and\n> +Renames the remote named <old> to <new>. All remote-tracking branches and\n\nWhy change the mood from imperative (which I thought was the norm\nfor these command descriptions) to third-person-present?\n\n>  configuration settings for the remote are updated.\n>  +\n>  In case <old> and <new> are the same, and <old> is a file under\n>  `$GIT_DIR/remotes` or `$GIT_DIR/branches`, the remote is converted to\n>  the configuration file format.\n> ++\n> +If <old> was the repository's default remote name, the default remote name\n> +changes to <new>.\n\nThis is unrelated to your patch, but I wonder what should happen to\nthis repository:\n\n\tgit config branch.foo.remote origin\n        git remote rename origin upstream\n\nShould branch.foo.remote be updated, and if so how (either set to\nupstream or configuration removed)?\n\n>  'rm'::\n>  \n> -Remove the remote named <name>. All remote-tracking branches and\n> -configuration settings for the remote are removed.\n> +Removes the remote named <name>. All remote-tracking branches and\n\nWhy change the mood from imperative (which I thought was the norm\nfor these command descriptions) to third-person-present?\n\n> +configuration settings for the remote are removed.  If the remote was\n> +the repository's default remote, then the repository's default remote\n> +name is changed to \"origin\".  Use 'git remote default <name>' to set\n> +the repository's default remote name.\n\nI think your patch actually removes remote.default (which I think is\ngood), and describing it as \"changes default remot to 'origin'\" like\nyou did above is perfectly good.\n\n> diff --git a/builtin/remote.c b/builtin/remote.c\n> index 920262d..1fb272c 100644\n> --- a/builtin/remote.c\n> +++ b/builtin/remote.c\n> @@ -12,6 +12,7 @@ static const char * const builtin_remote_usage[] = {\n>  \t\"git remote add [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <name> <url>\",\n>  \t\"git remote rename <old> <new>\",\n>  \t\"git remote rm <name>\",\n> +\t\"git remote default [<name>]\",\n>  \t\"git remote set-head <name> (-a | -d | <branch>)\",\n>  \t\"git remote [-v | --verbose] show [-n] <name>\",\n>  \t\"git remote prune [-n | --dry-run] <name>\",\n> @@ -198,6 +199,9 @@ static int add(int argc, const char **argv)\n>  \tif (!valid_fetch_refspec(buf2.buf))\n>  \t\tdie(_(\"'%s' is not a valid remote name\"), name);\n>  \n> +\tif (remote_count() == 1) /* remote_get() adds a remote if it's new */\n> +\t\tgit_config_set(\"remote.default\", name);\n> +\n>  \tstrbuf_addf(&buf, \"remote.%s.url\", name);\n>  \tif (git_config_set(buf.buf, url))\n>  \t\treturn 1;\n> @@ -656,6 +660,10 @@ static int mv(int argc, const char **argv)\n>  \t\treturn error(_(\"Could not rename config section '%s' to '%s'\"),\n>  \t\t\t\tbuf.buf, buf2.buf);\n>  \n> +\tif (!strcmp(oldremote->name, remote_get_default_name())) {\n> +\t\tgit_config_set(\"remote.default\", newremote->name);\n> +\t}\n> +\n>  \tstrbuf_reset(&buf);\n>  \tstrbuf_addf(&buf, \"remote.%s.fetch\", rename.new);\n>  \tif (git_config_set_multivar(buf.buf, NULL, NULL, 1))\n> @@ -798,6 +806,10 @@ static int rm(int argc, const char **argv)\n>  \tif (git_config_rename_section(buf.buf, NULL) < 1)\n>  \t\treturn error(_(\"Could not remove config section '%s'\"), buf.buf);\n>  \n> +\tif (!strcmp(remote->name, remote_get_default_name())) {\n> +\t\tgit_config_set(\"remote.default\", NULL);\n> +\t}\n> +\n>  \tread_branches();\n>  \tfor (i = 0; i < branch_list.nr; i++) {\n>  \t\tstruct string_list_item *item = branch_list.items + i;\n> @@ -845,6 +857,21 @@ static int rm(int argc, const char **argv)\n>  \treturn result;\n>  }\n>  \n> +static int deflt(int argc, const char **argv)\n\nPerhaps it is a good time to update the naming convention of\nfunctions that implement subcommands (e.g. cmd_default())?\n\n> +{\n> +\tif (argc < 2)\n> +\t\tprintf_ln(\"%s\", remote_get_default_name());\n\nGood.  If somebody anal cares about the vanilla hardcoded default\n'origin' and 'remote.default' having 'origin' as a configured value,\nhe should be using \"git config\" to ask the difference.  Users of\n\"remote default\" interface should not have to care.\n\n> +\telse {\n> +\t\tconst char *name = argv[1];\n> +\t\tif (remote_is_configured(name)) {\n> +\t\t\tgit_config_set(\"remote.default\", name);\n> +\t\t\tprintf_ln(_(\"Default remote set to '%s'.\"), name);\n> +\t\t} else\n> +\t\t\treturn error(_(\"No remote named '%s'.\"), name);\n> +\t}\n\nI am not sure if this is a good idea.  Shouldn't \"git remote default\nfrotz\" followed by \"git remote add frotz\" work?  I'd prefer to see\nthis demoted to a warning, perhaps like this:\n\n\tif (!remote_is_configured(name))\n\t\twarning(_(\"No remote named '%s' defined yet.\"),\n\t\tname);\n\tgit_confg_set(\"remote.default\", name);\n\nwithout the noisy report of \"I did what you told me to do\".\n"},{"id":"194932","messageId":"4FFDE4EB.3060100@xiplink.com","threadId":"30994","inReplyTo":"7vr4siduq3.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/6] Teach remote.c about the remote.default configuration setting.","fromName":"Marc Branchaud","fromEmail":"marcnarc@xiplink.com","sentAt":"2012-07-11T20:41:15Z","receivedAt":"2012-07-11T20:41:15Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"On 12-07-11 02:21 PM, Junio C Hamano wrote:\n> marcnarc@xiplink.com writes:\n> \n>> From: Marc Branchaud <marcnarc@xiplink.com>\n>>\n>> The code now has a default_remote_name and an effective_remote_name:\n>>\n>>  - default_remote_name is set by remote.default in the config, or is \"origin\"\n>>    if remote.default doesn't exist (\"origin\" was the fallback value before\n>>    this change).\n>>\n>>  - effective_remote_name is the name of the remote tracked by the current\n>>    branch, or is default_remote_name if the current branch doesn't have a\n>>    remote.\n>>\n>> This has a minor side effect on the default behavior of \"git push\".  Consider\n>> the following sequence of commands:\n>>\n>>       git config remote.default foo                 # Set default remote\n>>       git checkout somelocalbranch                  # Does not track a remote\n>>       git remote add origin ssh://example.com/repo  # Add a new \"origin\"\n>>       git push\n>>\n>> Prior to this change, the above \"git push\" would attempt to push to the new\n>> \"origin\" repository at ssh://example.com/repo.  Now instead that \"git push\"\n>> will attempt to push to the repository named \"foo\".\n> \n> Hrm, is this a _minor_ side effect?\n\nWell, I thought so...  :)\n\nIt's minor because of what you say:\n\n> Isn't that a natural and direct consequence of \"now you can set\n> remote.default configuration to name the remote you want to use in\n> place of traditional 'origin'\" feature?  I think changing the\n> behaviour of \"git push\" in such a way is the point (may not be the\n> only but one of the important points) of this series.\n\nI agree.  Phil Hord pointed out the change in behaviour and felt the commit\nmessage should explain it.\n\nShould I just remove \"minor\"?\n\n>> diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt\n>> index cb97cc1..fc17d39 100644\n>> --- a/Documentation/git-push.txt\n>> +++ b/Documentation/git-push.txt\n>> @@ -27,10 +27,16 @@ documentation for linkgit:git-receive-pack[1].\n>>  OPTIONS[[OPTIONS]]\n>>  ------------------\n>>  <repository>::\n>> -\tThe \"remote\" repository that is destination of a push\n>> +\tThe \"remote\" repository that is the destination of the push\n>>  \toperation.  This parameter can be either a URL\n>>  \t(see the section <<URLS,GIT URLS>> below) or the name\n>>  \tof a remote (see the section <<REMOTES,REMOTES>> below).\n>> +\tIf this parameter is omitted, git tries to use the remote\n>> +\tassociated with the currently checked-out branch.  If there\n>> +\tis no remote associated with the current branch, git uses\n>> +\tthe remote named by the \"remote.default\" configuration variable.\n>> +\tIf \"remote.default\" is not set, git uses the name \"origin\" even\n>> +\tif there is no actual remote named \"origin\".\n> \n> This comment applies to other changes to the documentation in this\n> patch I didn't quote, but I think the phrasing 'even if there is no\n> acutual remote named \"origin\"' needs to be rethought, because \"we\n> use it even if there is no such remote determined with this logic\"\n> applies equally to branch.$name.remote, remote.default or built-in\n> default value of remote.default which happens to be \"origin\".\n\nI'm sorry, but I'm having trouble understanding what you mean.  I don't see\nhow the \"because ...\" part of your sentence suggests what aspect needs\nrephrasing.\n\n(BTW, I'm under the impression that when git sets branch.$name.remote it\ndoesn't ever have to fall back to the default remote name.  That is, commands\nthat set the value always have the user explicitly, though perhaps\nindirectly, specifying the remote.  Did I miss something?)\n\n>> diff --git a/remote.c b/remote.c\n>> index 6f371e0..2ebdbbd 100644\n>> --- a/remote.c\n>> +++ b/remote.c\n>> @@ -47,6 +47,7 @@ static int branches_alloc;\n>>  static int branches_nr;\n>>  \n>>  static struct branch *current_branch;\n>> +static const char *default_remote_name;\n>>  static const char *effective_remote_name;\n> \n> Coming from UNIX background, \"effective\" gives me an impression that\n> it is contrasted with \"real\" (i.e. there is \"real remote\" for the\n> branch, but during this particular invocation it is overridden and\n> \"effective remote\" is used instead).  Perhaps it is just me.\n\nI did have something like that in mind when I chose \"effective\":  There's a\ndefault remote name that's normally used, but in the certain circumstances\nit's overridden.  Perhaps \"effective_default_remote_name\" would be better,\nthough that's getting to be a mouthful (plus it would mean having an\n\"explicit_effective_default_remote_name\", which IMHO is a bit much).\n\n> Something along the line of remote-name-to-use, use-remote, might\n> sound more natural.\n\ncurrent_remote_name?\n\n\t\tM.\n"},{"id":"194933","messageId":"4FFDE4ED.8020502@xiplink.com","threadId":"30994","inReplyTo":"7vk3yaduh1.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 3/6] Teach \"git remote\" about remote.default.","fromName":"Marc Branchaud","fromEmail":"marcnarc@xiplink.com","sentAt":"2012-07-11T20:41:17Z","receivedAt":"2012-07-11T20:41:17Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"On 12-07-11 02:27 PM, Junio C Hamano wrote:\n> marcnarc@xiplink.com writes:\n> \n>> From: Marc Branchaud <marcnarc@xiplink.com>\n>>\n>> The \"rename\" and \"rm\" commands now handle the case where the remote being\n>> changed is the default remote.\n> \n> \"handle the case\" is way underspecified.\n> \n> Until I peeked the patch, I couldn't tell if you were now allowing\n> \"git remote rm\" that does not say which remote to remove the remote\n> named via remote.default by default, and had to wonder if you made\n> \"git remote rename frotz\" without any other argument mean \"git\n> remote rename <remote.default> frotz\" or the other way around.\n> \n>         The \"rename\" and \"rm\" commands adjusts the value of the\n>         remote.default variable when they make the current default\n>         remote disappear.\n\nI'll use that.\n\n>> If the \"add\" command is used to add the repo's first remote, that remote\n>> becomes the default remote.\n> \n> Probably sensible, but I could easily imagine existing users to be\n> surprised, harmed and complain, especially now those who want this\n> behaviour already have a separate \"remote default\" command to set it\n> themselves.\n\nAs you suggest below, it makes more sense to put the\nfirst-remote-is-the-default change in a separate patch.  I'll combine it with\nthe git-clone change in patch #4.\n\n>> Also introduce a \"default\" sub-command to get or set the default remote:\n>>\n>>  - \"git remote default\" (with no parameter) displays the current default remote.\n>>\n>>  - \"git remote default <remo>\" checks if <remo> is a configured remote and if\n>>    so changes remote.default to <remo>.\n> \n> Avoid cute and not-widely-used abbreviation; in other words s/<remo>/<remote>/.\n\nOK.\n\n>> These changes needed a couple of new helper functions in remote.c:\n>>  - remote_get_default_name() returns default_remote_name.\n>>  - remote_count() returns the number of remotes.\n>>\n>> (The test in t5528 had to be changed because now with push.default=matching\n>> a plain \"git push\" succeeds with \"Everything up-to-date\".  It used to\n>> fail with \"No configured push destination\".)\n> \n> I would like to see people think, when their \"new feature\" breaks\n> existing tests and needs adjustments, like this:\n> \n>     Even test scripts gets upset with this unexpected behaviour\n>     change---real users may also be hurt the same way.  Should we\n>     really need to do this change?  What can we do to help them?\n\nI did not think the change was that important, because the fact that the\ncommand failed looked like a bug to me (ie. just because I used \"-o foo\" when\nI cloned shouldn't make \"git push\" with push.default=matching fail).  So it\nfeels to me like the patch is just making things work the way they should\nhave in the first place.\n\n> Even though I said \"Probably sensible\", I would prefer the \"first\n> remote automatically replaces 'origin'\" feature not to be part of\n> this patch.  It is something we can queue separately on top as a\n> separate feature.\n\nAgreed.\n\nHowever, this push.default=matching change isn't caused by the \"first remote\nautomatically replaces 'origin'\" stuff.  It's a direct result of having\nremote.default set.\n\n> I personally think in the long run it is probably the right thing to\n> do, but at the same time, I do not think it is something we want to\n> throw at the users as a flag-day event without transition planning.\n\nFair enough.\n\nWhat about a warning displayed if \"remote.default\" is not set?  Something like:\n\n\tThis repository does not have an explicitly configured default\n\tremote.  Selecting \"origin\" as the default remote repository.\n\tTo suppress this warning, or if you wish to have a different\n\tdefault remote repository, run \"git remote default <name>\".\n\tIn git X.Y, the default remote will be automatically configured\n\tas the first remote added to the repository.\n\n>> +'default'::\n>> +\n>> +Displays or sets the name of the repository's default remote.  When git needs\n>> +to automatically choose a remote to use, it first tries to use the remote\n>> +associated with the currently checked-out branch.  If the currently\n>> +checked-out branch has no remote, git uses the repository's default remote.\n>> +If the repository has no default remote, git tries to use a remote named\n>> +\"origin\" even if there is no actual remote named \"origin\".  (In other words,\n>> +the default value for the default remote name is \"origin\".)\n> \n> After saying something long-winded and convoluted that you think it\n> needs \"In other words,\" appended, try to re-read the sentence\n> without the long-winded part (and \"In other words,\").  I often find\n> that the long description is unnecessary after doing so myself.\n\nI'll take another crack at it.\n\n> I wonder if it makes the result easier to read if you consolidated\n> all the duplicated explanations of what the \"default remote\" is/does\n> in this patch and previous patches to a single place (perhaps\n> glossary) and refer to it from these places, e.g.\n> \n> \tdefault::\n> \n>         \tDisplay or sets the name of the default remote for\n> \t        the repository.  See \"default remote\" in\n> \t        linkgit:gitglossary[7].\n\nGood idea!\n\n>>  'rename'::\n>>  \n>> -Rename the remote named <old> to <new>. All remote-tracking branches and\n>> +Renames the remote named <old> to <new>. All remote-tracking branches and\n> \n> Why change the mood from imperative (which I thought was the norm\n> for these command descriptions) to third-person-present?\n\nThis was to make the file consistent -- some parts were already in\nthird-person-present.  I simply chose the wrong tense -- will change it to\nall-imperative.\n\n>>  configuration settings for the remote are updated.\n>>  +\n>>  In case <old> and <new> are the same, and <old> is a file under\n>>  `$GIT_DIR/remotes` or `$GIT_DIR/branches`, the remote is converted to\n>>  the configuration file format.\n>> ++\n>> +If <old> was the repository's default remote name, the default remote name\n>> +changes to <new>.\n> \n> This is unrelated to your patch, but I wonder what should happen to\n> this repository:\n> \n> \tgit config branch.foo.remote origin\n>         git remote rename origin upstream\n> \n> Should branch.foo.remote be updated, and if so how (either set to\n> upstream or configuration removed)?\n\nI believe it should be updated, and that it should be set to \"upstream\".\n\nAn lo!  This is exactly what git already does...  :)\n\n>>  'rm'::\n>>  \n>> -Remove the remote named <name>. All remote-tracking branches and\n>> -configuration settings for the remote are removed.\n>> +Removes the remote named <name>. All remote-tracking branches and\n> \n> Why change the mood from imperative (which I thought was the norm\n> for these command descriptions) to third-person-present?\n> \n>> +configuration settings for the remote are removed.  If the remote was\n>> +the repository's default remote, then the repository's default remote\n>> +name is changed to \"origin\".  Use 'git remote default <name>' to set\n>> +the repository's default remote name.\n> \n> I think your patch actually removes remote.default (which I think is\n> good), and describing it as \"changes default remot to 'origin'\" like\n> you did above is perfectly good.\n> \n>> diff --git a/builtin/remote.c b/builtin/remote.c\n>> index 920262d..1fb272c 100644\n>> --- a/builtin/remote.c\n>> +++ b/builtin/remote.c\n>> @@ -12,6 +12,7 @@ static const char * const builtin_remote_usage[] = {\n>>  \t\"git remote add [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <name> <url>\",\n>>  \t\"git remote rename <old> <new>\",\n>>  \t\"git remote rm <name>\",\n>> +\t\"git remote default [<name>]\",\n>>  \t\"git remote set-head <name> (-a | -d | <branch>)\",\n>>  \t\"git remote [-v | --verbose] show [-n] <name>\",\n>>  \t\"git remote prune [-n | --dry-run] <name>\",\n>> @@ -198,6 +199,9 @@ static int add(int argc, const char **argv)\n>>  \tif (!valid_fetch_refspec(buf2.buf))\n>>  \t\tdie(_(\"'%s' is not a valid remote name\"), name);\n>>  \n>> +\tif (remote_count() == 1) /* remote_get() adds a remote if it's new */\n>> +\t\tgit_config_set(\"remote.default\", name);\n>> +\n>>  \tstrbuf_addf(&buf, \"remote.%s.url\", name);\n>>  \tif (git_config_set(buf.buf, url))\n>>  \t\treturn 1;\n>> @@ -656,6 +660,10 @@ static int mv(int argc, const char **argv)\n>>  \t\treturn error(_(\"Could not rename config section '%s' to '%s'\"),\n>>  \t\t\t\tbuf.buf, buf2.buf);\n>>  \n>> +\tif (!strcmp(oldremote->name, remote_get_default_name())) {\n>> +\t\tgit_config_set(\"remote.default\", newremote->name);\n>> +\t}\n>> +\n>>  \tstrbuf_reset(&buf);\n>>  \tstrbuf_addf(&buf, \"remote.%s.fetch\", rename.new);\n>>  \tif (git_config_set_multivar(buf.buf, NULL, NULL, 1))\n>> @@ -798,6 +806,10 @@ static int rm(int argc, const char **argv)\n>>  \tif (git_config_rename_section(buf.buf, NULL) < 1)\n>>  \t\treturn error(_(\"Could not remove config section '%s'\"), buf.buf);\n>>  \n>> +\tif (!strcmp(remote->name, remote_get_default_name())) {\n>> +\t\tgit_config_set(\"remote.default\", NULL);\n>> +\t}\n>> +\n>>  \tread_branches();\n>>  \tfor (i = 0; i < branch_list.nr; i++) {\n>>  \t\tstruct string_list_item *item = branch_list.items + i;\n>> @@ -845,6 +857,21 @@ static int rm(int argc, const char **argv)\n>>  \treturn result;\n>>  }\n>>  \n>> +static int deflt(int argc, const char **argv)\n> \n> Perhaps it is a good time to update the naming convention of\n> functions that implement subcommands (e.g. cmd_default())?\n\nI struggled with the naming here, so I agree.  I thought of using _default().\n\nSince the \"cmd_\" prefix is already used for the main commands, perhaps\nanother prefix for subcommands?  Maybe \"sub_\"?  Some of the shell-based\ncommands use the main command itself as a prefix (e.g. bisect_start()).\nDoing that here would mean \"remote_default()\" etc.  Any preference?\n\n>> +{\n>> +\tif (argc < 2)\n>> +\t\tprintf_ln(\"%s\", remote_get_default_name());\n> \n> Good.  If somebody anal cares about the vanilla hardcoded default\n> 'origin' and 'remote.default' having 'origin' as a configured value,\n> he should be using \"git config\" to ask the difference.  Users of\n> \"remote default\" interface should not have to care.\n> \n>> +\telse {\n>> +\t\tconst char *name = argv[1];\n>> +\t\tif (remote_is_configured(name)) {\n>> +\t\t\tgit_config_set(\"remote.default\", name);\n>> +\t\t\tprintf_ln(_(\"Default remote set to '%s'.\"), name);\n>> +\t\t} else\n>> +\t\t\treturn error(_(\"No remote named '%s'.\"), name);\n>> +\t}\n> \n> I am not sure if this is a good idea.  Shouldn't \"git remote default\n> frotz\" followed by \"git remote add frotz\" work?\n\nTo me it feels wrong to allow the user to set the default remote to something\nthat doesn't actually exist.  It's like trying to add a non-existent file.\nAnd what if the user forgets the second step?\n\nIt seems saner for a command to fail if it knows a change it's about to make\nwill cause problems.\n\n> I'd prefer to see\n> this demoted to a warning, perhaps like this:\n> \n> \tif (!remote_is_configured(name))\n> \t\twarning(_(\"No remote named '%s' defined yet.\"),\n> \t\tname);\n> \tgit_confg_set(\"remote.default\", name);\n\nThe warning helps, but it still feels wrong.\n\nPlus the wording doesn't make it clear that the configuration was changed\nanyway.  (Yes, it says \"warning\" and all, but as a user I can't be sure.)  If\nwe were to use a warning, it should be \"Set the default remote to '%s' even\nthough no remote with that name exists.\"\n\n> without the noisy report of \"I did what you told me to do\".\n\nI'll drop the noise.\n\n\t\tM.\n"},{"id":"194936","messageId":"7vd342dku3.fsf@alter.siamese.dyndns.org","threadId":"30994","inReplyTo":"4FFDE4ED.8020502@xiplink.com","subject":"Re: [PATCH 3/6] Teach \"git remote\" about remote.default.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-07-11T21:55:16Z","receivedAt":"2012-07-11T21:55:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Marc Branchaud <marcnarc@xiplink.com> writes:\n\n> What about a warning displayed if \"remote.default\" is not set?  Something like:\n>\n> \tThis repository does not have an explicitly configured default\n> \tremote.  Selecting \"origin\" as the default remote repository.\n> \tTo suppress this warning, or if you wish to have a different\n> \tdefault remote repository, run \"git remote default <name>\".\n> \tIn git X.Y, the default remote will be automatically configured\n> \tas the first remote added to the repository.\n\nWhen do you plan to issue the above message?  Any time we default to\n'origin' without remote.default?  \n\nI do not see a value to it---if the user has been happily using\n'origin' as the default remote, there is no reason to give such a\nnoise.  We will keep defaulting to 'origin' even in the version of\nGit with this series in it.\n\nA warning is necessary if we plan to _later_ add the \"first remote\ncreated either by 'git clone' or 'git remote add' is automatically\nset as the value for remote.default configuration\" feature, and the\nplace to do so is \"git clone\" and \"git remote add\" that creates the\nfirst remote for the repository.  If the name of the remote created\nby them is 'origin', then there is no need for warning, but if the\nuser called that first remote with a name that is _not_ 'origin',\nlater versions of Git will change the behaviour.\n\nI can see a transition plan that goes like this:\n\nStep 0.  With this series but without the \"first one becomes default\"\n\n    $ git init\n    $ git remote add upstream git://over.there.xz/git.git/\n    hint: You may want to run \"git remote default upstream\" now so that\n    hint: a lazy 'git push' and 'git fetch' defaults to this 'upstream'\n    hint: repository, instead of 'origin' (which you do not yet have).\n\n    $ git config --global advice.settingDefaultRemote false\n    $ git remote rm upstream\n    $ git remote add upstream git://over.there.xz/git.git/\n    ... nothing, as the user declined the advice ...\n\nStep 1.  \"First one becomes default\" as an opt-in feature\n\n    $ git config --global --unset advice.settingDefaultRemote\n    $ git init\n    $ git remote add upstream git://over.there.xz/git.git/\n    hint: You may want to run \"git remote default upstream\" now so that\n    hint: a lazy 'git push' and 'git fetch' defaults to this 'upstream'\n    hint: repository, instead of 'origin' (which you do not yet have).\n    hint: \"git config --global remote.firstRemoteBecomesDefault true\" can be\n    hint: used to make the first remote added to the repository the default\n    hint: remote automatically.\n    $ git remote default\n    origin\n\n    $ git config --global remote.firstRemoteBecomesDefault true\n    $ git remote rm upstream\n    $ git remote add upstream git://over.there.xz/git.git/\n    ... nothing; user already knows about remote.firstRemoteBecomesDefault\n    $ git remote default\n    upstream\n\nStep 2.  Start warning the default change for \"First one becomes default\"\n\n    $ git config --global --unset advice.settingDefaultRemote\n    $ git config --global --unset remote.firstRemoteBecomesDefault\n    $ git init\n    $ git remote add upstream git://over.there.xz/git.git/\n    hint: You may want to run \"git remote default upstream\" now so that\n    hint: a lazy 'git push' and 'git fetch' defaults to this 'upstream'\n    hint: repository, instead of 'origin' (which you do not yet have).\n    hint: \"git config --global remote.firstRemoteBecomesDefault true\" can be\n    hint: used to make the first remote added to the repository the default\n    hint: remote automatically.\n    hint:\n    hint: In future versions of Git, this will happen automatically.\n    hint: If you do not want the first remote to become default, run\n    hint: \"git config --global remote.firstRemoteBecomesDefault false\" now.\n\nStep 3. \"First one becomes default\" is now default\n\n    $ git config --global --unset advice.settingDefaultRemote\n    $ git config --global --unset remote.firstRemoteBecomesDefault\n    $ git init\n    $ git remote add upstream git://over.there.xz/git.git/\n    warning: Made 'upstream' the default remote for this repository.\n    $ git remote default\n    upstream\n\n    $ git remote rm upstream\n    $ git config --global remote.firstRemoteBecomesDefault true\n    $ git init\n    $ git remote add upstream git://over.there.xz/git.git/\n    ... nothing; the user explicitly told us what to do\n    $ git remote default\n    upstream\n\n    $ git remote rm upstream\n    $ git config --global remote.firstRemoteBecomesDefault false\n    $ git init\n    $ git remote add upstream git://over.there.xz/git.git/\n    ... nothing; the user explicitly told us what to do\n    $ git remote default\n    origin\n\n> Since the \"cmd_\" prefix is already used for the main commands, perhaps\n> another prefix for subcommands?  Maybe \"sub_\"?  Some of the shell-based\n> commands use the main command itself as a prefix (e.g. bisect_start()).\n> Doing that here would mean \"remote_default()\" etc.  Any preference?\n\nNo strong preference for file-scope-statics.\n\n>>> +{\n>>> +\tif (argc < 2)\n>>> +\t\tprintf_ln(\"%s\", remote_get_default_name());\n>> \n>> Good.  If somebody anal cares about the vanilla hardcoded default\n>> 'origin' and 'remote.default' having 'origin' as a configured value,\n>> he should be using \"git config\" to ask the difference.  Users of\n>> \"remote default\" interface should not have to care.\n>> \n>>> +\telse {\n>>> +\t\tconst char *name = argv[1];\n>>> +\t\tif (remote_is_configured(name)) {\n>>> +\t\t\tgit_config_set(\"remote.default\", name);\n>>> +\t\t\tprintf_ln(_(\"Default remote set to '%s'.\"), name);\n>>> +\t\t} else\n>>> +\t\t\treturn error(_(\"No remote named '%s'.\"), name);\n>>> +\t}\n>> \n>> I am not sure if this is a good idea.  Shouldn't \"git remote default\n>> frotz\" followed by \"git remote add frotz\" work?\n>\n> To me it feels wrong to allow the user to set the default remote to something\n> that doesn't actually exist.  It's like trying to add a non-existent file.\n\nEvery few weeks, I do this:\n\n\tln -f -s Documentation/RelNotes/$new_version.txt RelNotes\n        edit Documentation/RelNotes/$new_version.txt\n\n> And what if the user forgets the second step?\n\nThat is why we warn on an unusual order.  A lazy \"git push\" will\nfail and that would be sufficient clue.\n\nAnd another reason for the warning (with \"you do not yet have\") is\nto prevent this:\n\n\tgit remote add frotz git://over.there.xz/git.git\n        git remote default frozt\n\n> It seems saner for a command to fail if it knows a change it's about to make\n> will cause problems.\n\nThe point is that you do *NOT* know it will cause problems.  People\nwho want to do things in an unusual order *know* what they are doing\na lot better than you do.  Don't get in their way.\n"},{"id":"194937","messageId":"7v8veqdkfd.fsf@alter.siamese.dyndns.org","threadId":"30994","inReplyTo":"4FFDE4EB.3060100@xiplink.com","subject":"Re: [PATCH 2/6] Teach remote.c about the remote.default configuration setting.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-07-11T22:04:06Z","receivedAt":"2012-07-11T22:04:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Marc Branchaud <marcnarc@xiplink.com> writes:\n\n> On 12-07-11 02:21 PM, Junio C Hamano wrote:\n>> marcnarc@xiplink.com writes:\n>> \n>>> From: Marc Branchaud <marcnarc@xiplink.com>\n>>>\n>>> The code now has a default_remote_name and an effective_remote_name:\n>>>\n>>>  - default_remote_name is set by remote.default in the config, or is \"origin\"\n>>>    if remote.default doesn't exist (\"origin\" was the fallback value before\n>>>    this change).\n>>>\n>>>  - effective_remote_name is the name of the remote tracked by the current\n>>>    branch, or is default_remote_name if the current branch doesn't have a\n>>>    remote.\n>>>\n>>> This has a minor side effect on the default behavior of \"git push\"....\n>> \n>> Hrm, is this a _minor_ side effect?\n>\n> Well, I thought so...  :)\n>\n> It's minor because of what you say:\n>\n>> Isn't that a natural and direct consequence of \"now you can set\n>> remote.default configuration to name the remote you want to use in\n>> place of traditional 'origin'\" feature?  I think changing the\n>> behaviour of \"git push\" in such a way is the point (may not be the\n>> only but one of the important points) of this series.\n>\n> I agree.  Phil Hord pointed out the change in behaviour and felt the commit\n> message should explain it.\n>\n> Should I just remove \"minor\"?\n\nIs it even a _side effect_?  Isn't this one of the primary points of\nthe series?  I do not think this patch makes sense if we did not\nwant that change to happen.\n\nOr am I missing something?\n\n>>> diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt\n>>> index cb97cc1..fc17d39 100644\n>>> --- a/Documentation/git-push.txt\n>>> +++ b/Documentation/git-push.txt\n>>> @@ -27,10 +27,16 @@ documentation for linkgit:git-receive-pack[1].\n>>>  OPTIONS[[OPTIONS]]\n>>>  ------------------\n>>>  <repository>::\n>>> -\tThe \"remote\" repository that is destination of a push\n>>> +\tThe \"remote\" repository that is the destination of the push\n>>>  \toperation.  This parameter can be either a URL\n>>>  \t(see the section <<URLS,GIT URLS>> below) or the name\n>>>  \tof a remote (see the section <<REMOTES,REMOTES>> below).\n>>> +\tIf this parameter is omitted, git tries to use the remote\n>>> +\tassociated with the currently checked-out branch.  If there\n>>> +\tis no remote associated with the current branch, git uses\n>>> +\tthe remote named by the \"remote.default\" configuration variable.\n>>> +\tIf \"remote.default\" is not set, git uses the name \"origin\" even\n>>> +\tif there is no actual remote named \"origin\".\n>> \n>> This comment applies to other changes to the documentation in this\n>> patch I didn't quote, but I think the phrasing 'even if there is no\n>> acutual remote named \"origin\"' needs to be rethought, because \"we\n>> use it even if there is no such remote determined with this logic\"\n>> applies equally to branch.$name.remote, remote.default or built-in\n>> default value of remote.default which happens to be \"origin\".\n>\n> I'm sorry, but I'm having trouble understanding what you mean.  I don't see\n> how the \"because ...\" part of your sentence suggests what aspect needs\n> rephrasing.\n\nYou say the remote is taken from three places (branch.$name.remote,\nremote.default, or 'origin').\n\nImagine there is remote.origin.url at all.  If remote.default is set\nto 'origin', or branch.$name.remote for the current branch is set to\n'origin', the repository you will try to use is 'origin'.  And you\nwill fail the same way if you try to push there.  It does not matter\nif the hardcoded default gave you 'origin' or configuration variable\ngave it to you.  The name is used regardless, even if there is no\nactual remote under such name.\n\nSo \"If 'remote.default' is not set, git uses the name \"origin\" even\nif there is no actual remote\", while is not untrue, is misleading.\nEven if there is no actual remote 'origin', if 'remote.default' is\nset to 'origin', git will use that name, and will fail the same way.\n\nJust saying \"If 'remote.default' is not set, git uses 'origin'\" or\neven \"'remote.default', if unset, defaults to 'origin'\" would be\nsufficient.\n"},{"id":"195022","messageId":"500078E4.3000901@xiplink.com","threadId":"30994","inReplyTo":"7v8veqdkfd.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/6] Teach remote.c about the remote.default configuration setting.","fromName":"Marc Branchaud","fromEmail":"marcnarc@xiplink.com","sentAt":"2012-07-13T19:37:08Z","receivedAt":"2012-07-13T19:37:08Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"On 12-07-11 06:04 PM, Junio C Hamano wrote:\n> Marc Branchaud <marcnarc@xiplink.com> writes:\n> \n>> On 12-07-11 02:21 PM, Junio C Hamano wrote:\n>>> marcnarc@xiplink.com writes:\n>>>\n>>>> From: Marc Branchaud <marcnarc@xiplink.com>\n>>>>\n>>>> The code now has a default_remote_name and an effective_remote_name:\n>>>>\n>>>>  - default_remote_name is set by remote.default in the config, or is \"origin\"\n>>>>    if remote.default doesn't exist (\"origin\" was the fallback value before\n>>>>    this change).\n>>>>\n>>>>  - effective_remote_name is the name of the remote tracked by the current\n>>>>    branch, or is default_remote_name if the current branch doesn't have a\n>>>>    remote.\n>>>>\n>>>> This has a minor side effect on the default behavior of \"git push\"....\n>>>\n>>> Hrm, is this a _minor_ side effect?\n>>\n>> Well, I thought so...  :)\n>>\n>> It's minor because of what you say:\n>>\n>>> Isn't that a natural and direct consequence of \"now you can set\n>>> remote.default configuration to name the remote you want to use in\n>>> place of traditional 'origin'\" feature?  I think changing the\n>>> behaviour of \"git push\" in such a way is the point (may not be the\n>>> only but one of the important points) of this series.\n>>\n>> I agree.  Phil Hord pointed out the change in behaviour and felt the commit\n>> message should explain it.\n>>\n>> Should I just remove \"minor\"?\n> \n> Is it even a _side effect_?  Isn't this one of the primary points of\n> the series?  I do not think this patch makes sense if we did not\n> want that change to happen.\n> \n> Or am I missing something?\n\nNo, you're not -- I agree that this change in behaviour makes sense.  I\nsimply hadn't anticipated this effect when I first did the work.\n\nSo should the commit message simply say \"This changes the default behavior of\n'git push' ...\"?  Or are you suggesting the message needn't mention it at all?\n\n>>>> diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt\n>>>> index cb97cc1..fc17d39 100644\n>>>> --- a/Documentation/git-push.txt\n>>>> +++ b/Documentation/git-push.txt\n>>>> @@ -27,10 +27,16 @@ documentation for linkgit:git-receive-pack[1].\n>>>>  OPTIONS[[OPTIONS]]\n>>>>  ------------------\n>>>>  <repository>::\n>>>> -\tThe \"remote\" repository that is destination of a push\n>>>> +\tThe \"remote\" repository that is the destination of the push\n>>>>  \toperation.  This parameter can be either a URL\n>>>>  \t(see the section <<URLS,GIT URLS>> below) or the name\n>>>>  \tof a remote (see the section <<REMOTES,REMOTES>> below).\n>>>> +\tIf this parameter is omitted, git tries to use the remote\n>>>> +\tassociated with the currently checked-out branch.  If there\n>>>> +\tis no remote associated with the current branch, git uses\n>>>> +\tthe remote named by the \"remote.default\" configuration variable.\n>>>> +\tIf \"remote.default\" is not set, git uses the name \"origin\" even\n>>>> +\tif there is no actual remote named \"origin\".\n>>>\n>>> This comment applies to other changes to the documentation in this\n>>> patch I didn't quote, but I think the phrasing 'even if there is no\n>>> acutual remote named \"origin\"' needs to be rethought, because \"we\n>>> use it even if there is no such remote determined with this logic\"\n>>> applies equally to branch.$name.remote, remote.default or built-in\n>>> default value of remote.default which happens to be \"origin\".\n>>\n>> I'm sorry, but I'm having trouble understanding what you mean.  I don't see\n>> how the \"because ...\" part of your sentence suggests what aspect needs\n>> rephrasing.\n> \n> You say the remote is taken from three places (branch.$name.remote,\n> remote.default, or 'origin').\n> \n> Imagine there is remote.origin.url at all.  If remote.default is set\n> to 'origin', or branch.$name.remote for the current branch is set to\n> 'origin', the repository you will try to use is 'origin'.  And you\n> will fail the same way if you try to push there.  It does not matter\n> if the hardcoded default gave you 'origin' or configuration variable\n> gave it to you.  The name is used regardless, even if there is no\n> actual remote under such name.\n> \n> So \"If 'remote.default' is not set, git uses the name \"origin\" even\n> if there is no actual remote\", while is not untrue, is misleading.\n> Even if there is no actual remote 'origin', if 'remote.default' is\n> set to 'origin', git will use that name, and will fail the same way.\n> \n> Just saying \"If 'remote.default' is not set, git uses 'origin'\" or\n> even \"'remote.default', if unset, defaults to 'origin'\" would be\n> sufficient.\n\nThanks, I understand you now.\n\nI feel it's rather surprising that git defaults to \"origin\".  I think the\ndocs should explain that git in fact ignores whatever remotes are actually\nconfigured in the repository, that git only looks in specific places for a\nremote name.  That's what I was trying to convey with the \"even if\" clause.\n\nI'll try to rephrase.\n\n\t\tM.\n"},{"id":"195024","messageId":"50007CD8.3040802@xiplink.com","threadId":"30994","inReplyTo":"7vd342dku3.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 3/6] Teach \"git remote\" about remote.default.","fromName":"Marc Branchaud","fromEmail":"marcnarc@xiplink.com","sentAt":"2012-07-13T19:54:00Z","receivedAt":"2012-07-13T19:54:00Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"On 12-07-11 05:55 PM, Junio C Hamano wrote:\n> Marc Branchaud <marcnarc@xiplink.com> writes:\n> \n>> What about a warning displayed if \"remote.default\" is not set?  Something like:\n>>\n>> \tThis repository does not have an explicitly configured default\n>> \tremote.  Selecting \"origin\" as the default remote repository.\n>> \tTo suppress this warning, or if you wish to have a different\n>> \tdefault remote repository, run \"git remote default <name>\".\n>> \tIn git X.Y, the default remote will be automatically configured\n>> \tas the first remote added to the repository.\n> \n> When do you plan to issue the above message?  Any time we default to\n> 'origin' without remote.default?  \n> \n> I do not see a value to it---if the user has been happily using\n> 'origin' as the default remote, there is no reason to give such a\n> noise.  We will keep defaulting to 'origin' even in the version of\n> Git with this series in it.\n> \n> A warning is necessary if we plan to _later_ add the \"first remote\n> created either by 'git clone' or 'git remote add' is automatically\n> set as the value for remote.default configuration\" feature, and the\n> place to do so is \"git clone\" and \"git remote add\" that creates the\n> first remote for the repository.  If the name of the remote created\n> by them is 'origin', then there is no need for warning, but if the\n> user called that first remote with a name that is _not_ 'origin',\n> later versions of Git will change the behaviour.\n> \n> I can see a transition plan that goes like this:\n\nI like your plan -- thanks for working it out in such detail!\n\nI'll re-roll the series to work like your plan's Step 0, and I'll post a\nseparate RFC patch on top of it that initiates the transition, so folks can\ndiscuss it specifically.\n\n> Step 0.  With this series but without the \"first one becomes default\"\n> \n>     $ git init\n>     $ git remote add upstream git://over.there.xz/git.git/\n>     hint: You may want to run \"git remote default upstream\" now so that\n>     hint: a lazy 'git push' and 'git fetch' defaults to this 'upstream'\n>     hint: repository, instead of 'origin' (which you do not yet have).\n> \n>     $ git config --global advice.settingDefaultRemote false\n>     $ git remote rm upstream\n>     $ git remote add upstream git://over.there.xz/git.git/\n>     ... nothing, as the user declined the advice ...\n> \n> Step 1.  \"First one becomes default\" as an opt-in feature\n> \n>     $ git config --global --unset advice.settingDefaultRemote\n>     $ git init\n>     $ git remote add upstream git://over.there.xz/git.git/\n>     hint: You may want to run \"git remote default upstream\" now so that\n>     hint: a lazy 'git push' and 'git fetch' defaults to this 'upstream'\n>     hint: repository, instead of 'origin' (which you do not yet have).\n>     hint: \"git config --global remote.firstRemoteBecomesDefault true\" can be\n>     hint: used to make the first remote added to the repository the default\n>     hint: remote automatically.\n>     $ git remote default\n>     origin\n> \n>     $ git config --global remote.firstRemoteBecomesDefault true\n>     $ git remote rm upstream\n>     $ git remote add upstream git://over.there.xz/git.git/\n>     ... nothing; user already knows about remote.firstRemoteBecomesDefault\n>     $ git remote default\n>     upstream\n> \n> Step 2.  Start warning the default change for \"First one becomes default\"\n> \n>     $ git config --global --unset advice.settingDefaultRemote\n>     $ git config --global --unset remote.firstRemoteBecomesDefault\n>     $ git init\n>     $ git remote add upstream git://over.there.xz/git.git/\n>     hint: You may want to run \"git remote default upstream\" now so that\n>     hint: a lazy 'git push' and 'git fetch' defaults to this 'upstream'\n>     hint: repository, instead of 'origin' (which you do not yet have).\n>     hint: \"git config --global remote.firstRemoteBecomesDefault true\" can be\n>     hint: used to make the first remote added to the repository the default\n>     hint: remote automatically.\n>     hint:\n>     hint: In future versions of Git, this will happen automatically.\n>     hint: If you do not want the first remote to become default, run\n>     hint: \"git config --global remote.firstRemoteBecomesDefault false\" now.\n> \n> Step 3. \"First one becomes default\" is now default\n> \n>     $ git config --global --unset advice.settingDefaultRemote\n>     $ git config --global --unset remote.firstRemoteBecomesDefault\n>     $ git init\n>     $ git remote add upstream git://over.there.xz/git.git/\n>     warning: Made 'upstream' the default remote for this repository.\n>     $ git remote default\n>     upstream\n> \n>     $ git remote rm upstream\n>     $ git config --global remote.firstRemoteBecomesDefault true\n>     $ git init\n>     $ git remote add upstream git://over.there.xz/git.git/\n>     ... nothing; the user explicitly told us what to do\n>     $ git remote default\n>     upstream\n> \n>     $ git remote rm upstream\n>     $ git config --global remote.firstRemoteBecomesDefault false\n>     $ git init\n>     $ git remote add upstream git://over.there.xz/git.git/\n>     ... nothing; the user explicitly told us what to do\n>     $ git remote default\n>     origin\n> \n>> Since the \"cmd_\" prefix is already used for the main commands, perhaps\n>> another prefix for subcommands?  Maybe \"sub_\"?  Some of the shell-based\n>> commands use the main command itself as a prefix (e.g. bisect_start()).\n>> Doing that here would mean \"remote_default()\" etc.  Any preference?\n> \n> No strong preference for file-scope-statics.\n> \n>>>> +{\n>>>> +\tif (argc < 2)\n>>>> +\t\tprintf_ln(\"%s\", remote_get_default_name());\n>>>\n>>> Good.  If somebody anal cares about the vanilla hardcoded default\n>>> 'origin' and 'remote.default' having 'origin' as a configured value,\n>>> he should be using \"git config\" to ask the difference.  Users of\n>>> \"remote default\" interface should not have to care.\n>>>\n>>>> +\telse {\n>>>> +\t\tconst char *name = argv[1];\n>>>> +\t\tif (remote_is_configured(name)) {\n>>>> +\t\t\tgit_config_set(\"remote.default\", name);\n>>>> +\t\t\tprintf_ln(_(\"Default remote set to '%s'.\"), name);\n>>>> +\t\t} else\n>>>> +\t\t\treturn error(_(\"No remote named '%s'.\"), name);\n>>>> +\t}\n>>>\n>>> I am not sure if this is a good idea.  Shouldn't \"git remote default\n>>> frotz\" followed by \"git remote add frotz\" work?\n>>\n>> To me it feels wrong to allow the user to set the default remote to something\n>> that doesn't actually exist.  It's like trying to add a non-existent file.\n> \n> Every few weeks, I do this:\n> \n> \tln -f -s Documentation/RelNotes/$new_version.txt RelNotes\n>         edit Documentation/RelNotes/$new_version.txt\n> \n>> And what if the user forgets the second step?\n> \n> That is why we warn on an unusual order.  A lazy \"git push\" will\n> fail and that would be sufficient clue.\n> \n> And another reason for the warning (with \"you do not yet have\") is\n> to prevent this:\n> \n>         git remote add frotz git://over.there.xz/git.git\n>         git remote default frozt\n\nSee, to me an error in this case makes more sense.  But I feel I'm splitting\nhairs now, and I'm happy to go with the warning instead.\n\n>> It seems saner for a command to fail if it knows a change it's about to make\n>> will cause problems.\n> \n> The point is that you do *NOT* know it will cause problems.  People\n> who want to do things in an unusual order *know* what they are doing\n> a lot better than you do.  Don't get in their way.\n\nI'll aim to post a revised series next week.\n\n\t\tM.\n"},{"id":"195026","messageId":"7vehof8kx5.fsf@alter.siamese.dyndns.org","threadId":"30994","inReplyTo":"500078E4.3000901@xiplink.com","subject":"Re: [PATCH 2/6] Teach remote.c about the remote.default configuration setting.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-07-13T20:29:10Z","receivedAt":"2012-07-13T20:29:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Marc Branchaud <marcnarc@xiplink.com> writes:\n\n>> Is it even a _side effect_?  Isn't this one of the primary points of\n>> the series?  I do not think this patch makes sense if we did not\n>> want that change to happen.\n>> \n>> Or am I missing something?\n>\n> No, you're not -- I agree that this change in behaviour makes sense.  I\n> simply hadn't anticipated this effect when I first did the work.\n>\n> So should the commit message simply say \"This changes the default behavior of\n> 'git push' ...\"?  Or are you suggesting the message needn't mention it at all?\n\nIt is one of the more important behaviour changes we are making on\npurpose with this series; it deserves to be described in the log, I\nwould think.\n"}]}