{"thread":{"id":"18325","subject":"[PATCH v3 0/2] New config variable push.default","startedAt":"2009-03-16T15:42:50Z","lastAt":"2009-03-16T15:42:52Z","messageCount":3,"participants":["Finn Arne Gangstad"],"isPatch":true,"patchVersion":3,"patchTotal":2},"messages":[{"id":"108092","messageId":"1237218172-16565-1-git-send-email-finnag@pvv.org","threadId":"18325","inReplyTo":null,"subject":"[PATCH v3 0/2] New config variable push.default","fromName":"Finn Arne Gangstad","fromEmail":"finnag@pvv.org","sentAt":"2009-03-16T15:42:50Z","receivedAt":"2009-03-16T15:42:50Z","isPatch":true,"sender":{"key":"finnag@pvv.org","avatar":"https://gravatar.com/avatar/b421ddd58c3f0f93aa473e17b98bb8d53c221fef741746bc8cb59fae4ec6d95e?d=mp&s=160"},"body":"Add a new configuration variable push.default that decides what action\nto take if you do not give \"git push\" any refspecs, and no refspecs\nare implied by options (--all or --mirror), and no refspecs are\nconfigured for the current remote.\n\nSome minor rewording of error messages since last time, and split the\npatch into two. Patch 1 introduces the variable with all\nfunctionality, and patch 2 adds a warning if the default behavior is\ntrigged and push.default has not been configured.\n\nPossible configuration values are:\n\n- nothing: Do not push anything.\n\n- tracking: Push the current branch to the branch it is tracking.  In this\n  mode, push will always push to the same branch that pull would pull from.\n  This functionality does not exist today.\n\n- current: Push the current branch to a branch of the same name on the\n  current remote, create it if it does not exist.  Identical to \n  \"git push <remote> HEAD\", but you do not have to explicitly give the remote.\n\n- matching: The current behavior, push every branch to the current remote if\n  a branch with the same name already exists there.\n\n\nFinn Arne Gangstad (2):\n      New config push.default to decide default behavior for push\n      Display warning for default git push with no push.default config\n\n Documentation/RelNotes-1.6.3.txt |    7 +++\n Documentation/config.txt         |   18 +++++++++\n builtin-push.c                   |   76 +++++++++++++++++++++++++++++++++++--\n cache.h                          |    9 ++++\n config.c                         |   28 ++++++++++++++\n environment.c                    |    1 +\n 6 files changed, 134 insertions(+), 5 deletions(-)\n"},{"id":"108093","messageId":"1237218172-16565-2-git-send-email-finnag@pvv.org","threadId":"18325","inReplyTo":"1237218172-16565-1-git-send-email-finnag@pvv.org","subject":"[PATCH 1/2] New config push.default to decide default behavior for push","fromName":"Finn Arne Gangstad","fromEmail":"finnag@pvv.org","sentAt":"2009-03-16T15:42:51Z","receivedAt":"2009-03-16T15:42:51Z","isPatch":true,"sender":{"key":"finnag@pvv.org","avatar":"https://gravatar.com/avatar/b421ddd58c3f0f93aa473e17b98bb8d53c221fef741746bc8cb59fae4ec6d95e?d=mp&s=160"},"body":"When \"git push\" is not told what refspecs to push, it pushes all matching\nbranches to the current remote.  For some workflows this default is not\nuseful, and surprises new users.  Some have even found that this default\nbehaviour is too easy to trigger by accident with unwanted consequences.\n\nIntroduce a new configuration variable \"push.default\" that decides what\naction git push should take if no refspecs are given or implied by the\ncommand line arguments or the current remote configuration.\n\nPossible values are:\n\n  'nothing'  : Push nothing;\n  'matching' : Current default behaviour, push all branches that already\n               exist in the current remote;\n  'tracking' : Push the current branch to whatever it is tracking;\n  'current'  : Push the current branch to a branch of the same name,\n               i.e. HEAD.\n\nSigned-off-by: Finn Arne Gangstad <finnag@pvv.org>\n---\n Documentation/config.txt |   18 +++++++++++++++\n builtin-push.c           |   53 +++++++++++++++++++++++++++++++++++++++++----\n cache.h                  |    9 +++++++\n config.c                 |   28 ++++++++++++++++++++++++\n environment.c            |    1 +\n 5 files changed, 104 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 56bd781..1a27f60 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1170,6 +1170,24 @@ pull.octopus::\n pull.twohead::\n \tThe default merge strategy to use when pulling a single branch.\n \n+push.default::\n+\tDefines the action git push should take if no refspec is given\n+\ton the command line, no refspec is configured in the remote, and\n+\tno refspec is implied by any of the options given on the command\n+\tline.\n++\n+The term `current remote` means the remote configured for the current\n+branch, or `origin` if no remote is configured. `origin` is also used\n+if you are not on any branch. Possible values are:\n++\n+* `nothing` do not push anything.\n+* `matching` push all matching branches to the current remote.\n+  All branches having the same name in both ends are considered to be\n+  matching. This is the current default value.\n+* `tracking` push the current branch to the branch it is tracking.\n+* `current` push the current branch to a branch of the same name on the\n+  current remote.\n+\n rebase.stat::\n \tWhether to show a diffstat of what changed upstream since the last\n \trebase. False by default.\ndiff --git a/builtin-push.c b/builtin-push.c\nindex 122fdcf..45fe843 100644\n--- a/builtin-push.c\n+++ b/builtin-push.c\n@@ -48,6 +48,48 @@ static void set_refspecs(const char **refs, int nr)\n \t}\n }\n \n+static void setup_push_tracking(void)\n+{\n+\tstruct strbuf refspec = STRBUF_INIT;\n+\tstruct branch *branch = branch_get(NULL);\n+\tif (!branch)\n+\t\tdie(\"You are not currently on a branch.\");\n+\tif (!branch->merge_nr)\n+\t\tdie(\"The current branch %s is not tracking anything.\",\n+\t\t    branch->name);\n+\tif (branch->merge_nr != 1)\n+\t\tdie(\"The current branch %s is tracking multiple branches, \"\n+\t\t    \"refusing to push.\", branch->name);\n+\tstrbuf_addf(&refspec, \"%s:%s\", branch->name, branch->merge[0]->src);\n+\tadd_refspec(refspec.buf);\n+}\n+\n+static void setup_default_push_refspecs(void)\n+{\n+\tgit_config(git_default_config, NULL);\n+\tswitch (push_default) {\n+\tcase PUSH_DEFAULT_UNSPECIFIED:\n+\t\t/* fallthrough */\n+\n+\tcase PUSH_DEFAULT_MATCHING:\n+\t\tadd_refspec(\":\");\n+\t\tbreak;\n+\n+\tcase PUSH_DEFAULT_TRACKING:\n+\t\tsetup_push_tracking();\n+\t\tbreak;\n+\n+\tcase PUSH_DEFAULT_CURRENT:\n+\t\tadd_refspec(\"HEAD\");\n+\t\tbreak;\n+\n+\tcase PUSH_DEFAULT_NOTHING:\n+\t\tdie(\"You didn't specify any refspecs to push, and \"\n+\t\t    \"push.default is \\\"nothing\\\".\");\n+\t\tbreak;\n+\t}\n+}\n+\n static int do_push(const char *repo, int flags)\n {\n \tint i, errs;\n@@ -76,11 +118,12 @@ static int do_push(const char *repo, int flags)\n \t\treturn error(\"--all and --mirror are incompatible\");\n \t}\n \n-\tif (!refspec\n-\t\t&& !(flags & TRANSPORT_PUSH_ALL)\n-\t\t&& remote->push_refspec_nr) {\n-\t\trefspec = remote->push_refspec;\n-\t\trefspec_nr = remote->push_refspec_nr;\n+\tif (!refspec && !(flags & TRANSPORT_PUSH_ALL)) {\n+\t\tif (remote->push_refspec_nr) {\n+\t\t\trefspec = remote->push_refspec;\n+\t\t\trefspec_nr = remote->push_refspec_nr;\n+\t\t} else if (!(flags & TRANSPORT_PUSH_MIRROR))\n+\t\t\tsetup_default_push_refspecs();\n \t}\n \terrs = 0;\n \tfor (i = 0; i < remote->url_nr; i++) {\ndiff --git a/cache.h b/cache.h\nindex fdc4ada..93f00a4 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -541,8 +541,17 @@ enum rebase_setup_type {\n \tAUTOREBASE_ALWAYS,\n };\n \n+enum push_default_type {\n+\tPUSH_DEFAULT_UNSPECIFIED = -1,\n+\tPUSH_DEFAULT_NOTHING = 0,\n+\tPUSH_DEFAULT_MATCHING,\n+\tPUSH_DEFAULT_TRACKING,\n+\tPUSH_DEFAULT_CURRENT,\n+};\n+\n extern enum branch_track git_branch_track;\n extern enum rebase_setup_type autorebase;\n+extern enum push_default_type push_default;\n \n #define GIT_REPO_VERSION 0\n extern int repository_format_version;\ndiff --git a/config.c b/config.c\nindex 0c8c76f..28ac0fb 100644\n--- a/config.c\n+++ b/config.c\n@@ -565,6 +565,31 @@ static int git_default_branch_config(const char *var, const char *value)\n \treturn 0;\n }\n \n+static int git_default_push_config(const char *var, const char *value)\n+{\n+\tif (!strcmp(var, \"push.default\")) {\n+\t\tif (!value)\n+\t\t\treturn config_error_nonbool(var);\n+\t\telse if (!strcmp(value, \"nothing\"))\n+\t\t\tpush_default = PUSH_DEFAULT_NOTHING;\n+\t\telse if (!strcmp(value, \"matching\"))\n+\t\t\tpush_default = PUSH_DEFAULT_MATCHING;\n+\t\telse if (!strcmp(value, \"tracking\"))\n+\t\t\tpush_default = PUSH_DEFAULT_TRACKING;\n+\t\telse if (!strcmp(value, \"current\"))\n+\t\t\tpush_default = PUSH_DEFAULT_CURRENT;\n+\t\telse {\n+\t\t\terror(\"Malformed value for %s: %s\", var, value);\n+\t\t\treturn error(\"Must be one of nothing, matching, \"\n+\t\t\t\t     \"tracking or current.\");\n+\t\t}\t\t\n+\t\treturn 0;\n+\t}\n+\n+\t/* Add other config variables here and to Documentation/config.txt. */\n+\treturn 0;\n+}\n+\n static int git_default_mailmap_config(const char *var, const char *value)\n {\n \tif (!strcmp(var, \"mailmap.file\"))\n@@ -588,6 +613,9 @@ int git_default_config(const char *var, const char *value, void *dummy)\n \tif (!prefixcmp(var, \"branch.\"))\n \t\treturn git_default_branch_config(var, value);\n \n+\tif (!prefixcmp(var, \"push.\"))\n+\t\treturn git_default_push_config(var, value);\n+\n \tif (!prefixcmp(var, \"mailmap.\"))\n \t\treturn git_default_mailmap_config(var, value);\n \ndiff --git a/environment.c b/environment.c\nindex e278bce..4696885 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -42,6 +42,7 @@ enum safe_crlf safe_crlf = SAFE_CRLF_WARN;\n unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;\n enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;\n enum rebase_setup_type autorebase = AUTOREBASE_NEVER;\n+enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;\n \n /* Parallel index stat data preload? */\n int core_preload_index = 0;\n-- \n1.6.2.1.138.gc403b.dirty\n"},{"id":"108094","messageId":"1237218172-16565-3-git-send-email-finnag@pvv.org","threadId":"18325","inReplyTo":"1237218172-16565-1-git-send-email-finnag@pvv.org","subject":"[PATCH 2/2] Display warning for default git push with no push.default config","fromName":"Finn Arne Gangstad","fromEmail":"finnag@pvv.org","sentAt":"2009-03-16T15:42:52Z","receivedAt":"2009-03-16T15:42:52Z","isPatch":true,"sender":{"key":"finnag@pvv.org","avatar":"https://gravatar.com/avatar/b421ddd58c3f0f93aa473e17b98bb8d53c221fef741746bc8cb59fae4ec6d95e?d=mp&s=160"},"body":"If a git push without any refspecs is attempted, display a warning.\nThe current default behavior is to push all matching refspecs, which\nmay come as a surprise to new users, so the warning shows how\npush.default can be configured and what the possible values are.\n\nTraditionalists who wish to keep the current behaviour are also told\nhow to configure this once and never see the warning again.\n\nSigned-off-by: Finn Arne Gangstad <finnag@pvv.org>\n---\n Documentation/RelNotes-1.6.3.txt |    7 +++++++\n builtin-push.c                   |   23 +++++++++++++++++++++++\n 2 files changed, 30 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/RelNotes-1.6.3.txt b/Documentation/RelNotes-1.6.3.txt\nindex 679ad28..d961bc8 100644\n--- a/Documentation/RelNotes-1.6.3.txt\n+++ b/Documentation/RelNotes-1.6.3.txt\n@@ -22,6 +22,13 @@ branch pointed at by its HEAD, gets a large warning.  You can choose what\n should happen upon such a push by setting the configuration variable\n receive.denyDeleteCurrent in the receiving repository.\n \n+In a future release, the default of \"git push\" without further\n+arguments may be changed. Currently, it will push all matching\n+refspecs to the current remote.  A configuration variable push.default\n+has been introduced to select the default behaviour.  To ease the\n+transition, a big warning is issued if this is not configured and a\n+git push without arguments is attempted.\n+\n \n Updates since v1.6.2\n --------------------\ndiff --git a/builtin-push.c b/builtin-push.c\nindex 45fe843..c8e559f 100644\n--- a/builtin-push.c\n+++ b/builtin-push.c\n@@ -64,11 +64,34 @@ static void setup_push_tracking(void)\n \tadd_refspec(refspec.buf);\n }\n \n+static const char *warn_unconfigured_push_msg[] = {\n+\t\"You did not specify any refspecs to push, and the current remote\",\n+\t\"has not configured any push refspecs. The default action in this\",\n+\t\"case has been to push all matching refspecs, that is, all branches\",\n+\t\"that exist both locally and remotely will be updated.\",\n+\t\"This default may change in the future.\",\n+\t\"\",\n+\t\"You can specify what action you want to take in this case, and\",\n+\t\"avoid seeing this message again, by configuring 'push.default' to:\",\n+\t\"  'nothing'  : Do not push anythig\",\n+\t\"  'matching' : Push all matching branches (the current default)\",\n+\t\"  'tracking' : Push the current branch to whatever it is tracking\",\n+\t\"  'current'  : Push the current branch\"\n+};\n+\n+static void warn_unconfigured_push(void)\n+{\n+\tint i;\n+\tfor (i = 0; i < ARRAY_SIZE(warn_unconfigured_push_msg); i++)\n+\t\twarning(\"%s\", warn_unconfigured_push_msg[i]);\n+}\n+\n static void setup_default_push_refspecs(void)\n {\n \tgit_config(git_default_config, NULL);\n \tswitch (push_default) {\n \tcase PUSH_DEFAULT_UNSPECIFIED:\n+\t\twarn_unconfigured_push();\n \t\t/* fallthrough */\n \n \tcase PUSH_DEFAULT_MATCHING:\n-- \n1.6.2.1.138.gc403b.dirty\n"}]}