summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2011-12-18 21:38:29 -0800
committerJunio C Hamano <gitster@pobox.com>2011-12-18 21:38:56 -0800
commitd8a3581b55e27c071e22a540620cf8a42291af87 (patch)
tree16c29a066773f5231ddb9dab61a7998ee0a5ac19
parent26e94af0ba2f35438bab4a88caa4a16f5e056bac (diff)
downloadgit-jc/advise-push-default.tar.gz
push: hint to use push.default=upstream when appropriatejc/advise-push-default
If you push into a shared repository that others push to, and you have local branches in your repository that matches the remote side but do not keep them up-to-date, then 'matching refs' is not an appropriate default for you. Detect when push failed due to non-fast-forward _and_ we did matching refs by default (i.e. if the user explicitly said ':' from the command line, or had push.default set to 'matching', then we do not want to advise), and give a hint to tell the user that the user may want to set 'push.default' configuration variable to 'upstream', if the remote repository receives pushes from other places. Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--Documentation/config.txt6
-rw-r--r--advice.c2
-rw-r--r--advice.h1
-rw-r--r--builtin/push.c25
-rw-r--r--cache.h3
-rw-r--r--environment.c2
6 files changed, 37 insertions, 2 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt
index f22d926777..681811095c 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -141,6 +141,12 @@ advice.*::
Advice shown when you used linkgit:git-checkout[1] to
move to the detach HEAD state, to instruct how to create
a local branch after the fact.
+ pushUseUpstream::
+ Advice to set 'push.default' to 'upstream' when you ran
+ linkgit:git-push[1] and pushed 'matching refs' by default
+ (i.e. you did not have any explicit refspec on the command
+ line, and no 'push.default' configuration was set) and it
+ resulted in a non-fast-forward error.
--
core.fileMode::
diff --git a/advice.c b/advice.c
index e02e632df3..9b56709d2c 100644
--- a/advice.c
+++ b/advice.c
@@ -6,6 +6,7 @@ int advice_commit_before_merge = 1;
int advice_resolve_conflict = 1;
int advice_implicit_identity = 1;
int advice_detached_head = 1;
+int advice_push_use_upstream = 1;
static struct {
const char *name;
@@ -17,6 +18,7 @@ static struct {
{ "resolveconflict", &advice_resolve_conflict },
{ "implicitidentity", &advice_implicit_identity },
{ "detachedhead", &advice_detached_head },
+ { "pushuseupstream", &advice_push_use_upstream },
};
void advise(const char *advice, ...)
diff --git a/advice.h b/advice.h
index e5d0af782b..6bb89cdce0 100644
--- a/advice.h
+++ b/advice.h
@@ -9,6 +9,7 @@ extern int advice_commit_before_merge;
extern int advice_resolve_conflict;
extern int advice_implicit_identity;
extern int advice_detached_head;
+extern int advice_push_use_upstream;
int git_default_advice_config(const char *var, const char *value);
void advise(const char *advice, ...);
diff --git a/builtin/push.c b/builtin/push.c
index 35cce532f2..5f8c7f4917 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -9,6 +9,7 @@
#include "transport.h"
#include "parse-options.h"
#include "submodule.h"
+#include "advice.h"
static const char * const push_usage[] = {
"git push [<options>] [<repository> [<refspec>...]]",
@@ -24,6 +25,7 @@ static int progress;
static const char **refspec;
static int refspec_nr;
static int refspec_alloc;
+static int default_matching_used;
static void add_refspec(const char *ref)
{
@@ -95,6 +97,9 @@ static void setup_default_push_refspecs(struct remote *remote)
{
switch (push_default) {
default:
+ case PUSH_DEFAULT_UNSPECIFIED:
+ default_matching_used = 1;
+ /* fallthru */
case PUSH_DEFAULT_MATCHING:
add_refspec(":");
break;
@@ -114,6 +119,23 @@ static void setup_default_push_refspecs(struct remote *remote)
}
}
+static const char *message_advice_use_upstream[] = {
+ "If you are pushing into a repository that receives pushes from",
+ "repositories other than the current repository, you may want to",
+ "set 'push.default' configuration variable to 'upstream' to avoid",
+ "pushing branches you haven't worked on that others have updated.",
+};
+
+static void advise_use_upstream(void)
+{
+ int i;
+
+ if (!advice_push_use_upstream)
+ return;
+ for (i = 0; i < ARRAY_SIZE(message_advice_use_upstream); i++)
+ advise(message_advice_use_upstream[i]);
+}
+
static int push_with_options(struct transport *transport, int flags)
{
int err;
@@ -136,6 +158,9 @@ static int push_with_options(struct transport *transport, int flags)
err |= transport_disconnect(transport);
+ if (nonfastforward && default_matching_used)
+ advise_use_upstream();
+
if (!err)
return 0;
diff --git a/cache.h b/cache.h
index 2e6ad3604e..d5351fa566 100644
--- a/cache.h
+++ b/cache.h
@@ -623,7 +623,8 @@ enum push_default_type {
PUSH_DEFAULT_NOTHING = 0,
PUSH_DEFAULT_MATCHING,
PUSH_DEFAULT_UPSTREAM,
- PUSH_DEFAULT_CURRENT
+ PUSH_DEFAULT_CURRENT,
+ PUSH_DEFAULT_UNSPECIFIED
};
extern enum branch_track git_branch_track;
diff --git a/environment.c b/environment.c
index 0bee6a7a88..e5fb862a9b 100644
--- a/environment.c
+++ b/environment.c
@@ -51,7 +51,7 @@ enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
-enum push_default_type push_default = PUSH_DEFAULT_MATCHING;
+enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
#ifndef OBJECT_CREATION_MODE
#define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS
#endif