diff options
author | Finn Arne Gangstad <finnag@pvv.org> | 2009-03-16 16:42:51 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2009-03-17 14:50:21 -0700 |
commit | 521537476fe99b97bfcdf1b8f0c579061af5fd3e (patch) | |
tree | 54e9b9349d7ba1197de646dfaf7154968ee2470b /builtin-push.c | |
parent | archive: use parseopt for local-only options (diff) | |
download | tgif-521537476fe99b97bfcdf1b8f0c579061af5fd3e.tar.xz |
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 <finnag@pvv.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-push.c')
-rw-r--r-- | builtin-push.c | 53 |
1 files changed, 48 insertions, 5 deletions
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++) { |