From 521537476fe99b97bfcdf1b8f0c579061af5fd3e Mon Sep 17 00:00:00 2001 From: Finn Arne Gangstad Date: Mon, 16 Mar 2009 16:42:51 +0100 Subject: New config push.default to decide default behavior for push When "git push" is not told what refspecs to push, it pushes all matching branches to the current remote. For some workflows this default is not useful, and surprises new users. Some have even found that this default behaviour is too easy to trigger by accident with unwanted consequences. Introduce a new configuration variable "push.default" that decides what action git push should take if no refspecs are given or implied by the command line arguments or the current remote configuration. Possible values are: 'nothing' : Push nothing; 'matching' : Current default behaviour, push all branches that already exist in the current remote; 'tracking' : Push the current branch to whatever it is tracking; 'current' : Push the current branch to a branch of the same name, i.e. HEAD. Signed-off-by: Finn Arne Gangstad Signed-off-by: Junio C Hamano --- builtin-push.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) (limited to 'builtin-push.c') diff --git a/builtin-push.c b/builtin-push.c index 122fdcfbdc..45fe843b20 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -48,6 +48,48 @@ static void set_refspecs(const char **refs, int nr) } } +static void setup_push_tracking(void) +{ + struct strbuf refspec = STRBUF_INIT; + struct branch *branch = branch_get(NULL); + if (!branch) + die("You are not currently on a branch."); + if (!branch->merge_nr) + die("The current branch %s is not tracking anything.", + branch->name); + if (branch->merge_nr != 1) + die("The current branch %s is tracking multiple branches, " + "refusing to push.", branch->name); + strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src); + add_refspec(refspec.buf); +} + +static void setup_default_push_refspecs(void) +{ + git_config(git_default_config, NULL); + switch (push_default) { + case PUSH_DEFAULT_UNSPECIFIED: + /* fallthrough */ + + case PUSH_DEFAULT_MATCHING: + add_refspec(":"); + break; + + case PUSH_DEFAULT_TRACKING: + setup_push_tracking(); + break; + + case PUSH_DEFAULT_CURRENT: + add_refspec("HEAD"); + break; + + case PUSH_DEFAULT_NOTHING: + die("You didn't specify any refspecs to push, and " + "push.default is \"nothing\"."); + break; + } +} + static int do_push(const char *repo, int flags) { int i, errs; @@ -76,11 +118,12 @@ static int do_push(const char *repo, int flags) return error("--all and --mirror are incompatible"); } - if (!refspec - && !(flags & TRANSPORT_PUSH_ALL) - && remote->push_refspec_nr) { - refspec = remote->push_refspec; - refspec_nr = remote->push_refspec_nr; + if (!refspec && !(flags & TRANSPORT_PUSH_ALL)) { + if (remote->push_refspec_nr) { + refspec = remote->push_refspec; + refspec_nr = remote->push_refspec_nr; + } else if (!(flags & TRANSPORT_PUSH_MIRROR)) + setup_default_push_refspecs(); } errs = 0; for (i = 0; i < remote->url_nr; i++) { -- cgit v1.2.1 From 665d3e8f057b90d7b43d70db75b9ac5506bd204d Mon Sep 17 00:00:00 2001 From: Finn Arne Gangstad Date: Mon, 16 Mar 2009 16:42:52 +0100 Subject: Display warning for default git push with no push.default config If a git push without any refspecs is attempted, display a warning. The current default behavior is to push all matching refspecs, which may come as a surprise to new users, so the warning shows how push.default can be configured and what the possible values are. Traditionalists who wish to keep the current behaviour are also told how to configure this once and never see the warning again. Signed-off-by: Finn Arne Gangstad Signed-off-by: Junio C Hamano --- builtin-push.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'builtin-push.c') diff --git a/builtin-push.c b/builtin-push.c index 45fe843b20..8f4fa5b09e 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -64,11 +64,34 @@ static void setup_push_tracking(void) add_refspec(refspec.buf); } +static const char *warn_unconfigured_push_msg[] = { + "You did not specify any refspecs to push, and the current remote", + "has not configured any push refspecs. The default action in this", + "case is to push all matching refspecs, that is, all branches", + "that exist both locally and remotely will be updated. This may", + "not necessarily be what you want to happen.", + "", + "You can specify what action you want to take in this case, and", + "avoid seeing this message again, by configuring 'push.default' to:", + " 'nothing' : Do not push anythig", + " 'matching' : Push all matching branches (default)", + " 'tracking' : Push the current branch to whatever it is tracking", + " 'current' : Push the current branch" +}; + +static void warn_unconfigured_push(void) +{ + int i; + for (i = 0; i < ARRAY_SIZE(warn_unconfigured_push_msg); i++) + warning("%s", warn_unconfigured_push_msg[i]); +} + static void setup_default_push_refspecs(void) { git_config(git_default_config, NULL); switch (push_default) { case PUSH_DEFAULT_UNSPECIFIED: + warn_unconfigured_push(); /* fallthrough */ case PUSH_DEFAULT_MATCHING: -- cgit v1.2.1 From b2655cdae953d619d488b69b7d49e4204e5682dc Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Wed, 25 Mar 2009 13:14:03 -0700 Subject: builtin-push.c: Fix typo: "anythig" -> "anything" Signed-off-by: Kevin Ballard Signed-off-by: Junio C Hamano --- builtin-push.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin-push.c') diff --git a/builtin-push.c b/builtin-push.c index 8f4fa5b09e..bbf019850e 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -73,7 +73,7 @@ static const char *warn_unconfigured_push_msg[] = { "", "You can specify what action you want to take in this case, and", "avoid seeing this message again, by configuring 'push.default' to:", - " 'nothing' : Do not push anythig", + " 'nothing' : Do not push anything", " 'matching' : Push all matching branches (default)", " 'tracking' : Push the current branch to whatever it is tracking", " 'current' : Push the current branch" -- cgit v1.2.1