Skip to content

Commit 2545c08

Browse files
committed
Merge branch 'fg/push-default'
* fg/push-default: builtin-push.c: Fix typo: "anythig" -> "anything" Display warning for default git push with no push.default config New config push.default to decide default behavior for push Conflicts: Documentation/config.txt
2 parents 0b3035f + b2655cd commit 2545c08

File tree

6 files changed

+134
-5
lines changed

6 files changed

+134
-5
lines changed

Documentation/RelNotes-1.6.3.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ branch pointed at by its HEAD, gets a large warning. You can choose what
2222
should happen upon such a push by setting the configuration variable
2323
receive.denyDeleteCurrent in the receiving repository.
2424

25+
In a future release, the default of "git push" without further
26+
arguments might be changed. Currently, it will push all matching
27+
refspecs to the current remote. A configuration variable push.default
28+
has been introduced to select the default behaviour. To ease the
29+
transition, a big warning is issued if this is not configured and a
30+
git push without arguments is attempted.
31+
2532

2633
Updates since v1.6.2
2734
--------------------

Documentation/config.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,24 @@ pull.octopus::
11941194
pull.twohead::
11951195
The default merge strategy to use when pulling a single branch.
11961196

1197+
push.default::
1198+
Defines the action git push should take if no refspec is given
1199+
on the command line, no refspec is configured in the remote, and
1200+
no refspec is implied by any of the options given on the command
1201+
line.
1202+
+
1203+
The term `current remote` means the remote configured for the current
1204+
branch, or `origin` if no remote is configured. `origin` is also used
1205+
if you are not on any branch. Possible values are:
1206+
+
1207+
* `nothing` do not push anything.
1208+
* `matching` push all matching branches to the current remote.
1209+
All branches having the same name in both ends are considered to be
1210+
matching. This is the current default value.
1211+
* `tracking` push the current branch to the branch it is tracking.
1212+
* `current` push the current branch to a branch of the same name on the
1213+
current remote.
1214+
11971215
rebase.stat::
11981216
Whether to show a diffstat of what changed upstream since the last
11991217
rebase. False by default.

builtin-push.c

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,71 @@ static void set_refspecs(const char **refs, int nr)
4848
}
4949
}
5050

51+
static void setup_push_tracking(void)
52+
{
53+
struct strbuf refspec = STRBUF_INIT;
54+
struct branch *branch = branch_get(NULL);
55+
if (!branch)
56+
die("You are not currently on a branch.");
57+
if (!branch->merge_nr)
58+
die("The current branch %s is not tracking anything.",
59+
branch->name);
60+
if (branch->merge_nr != 1)
61+
die("The current branch %s is tracking multiple branches, "
62+
"refusing to push.", branch->name);
63+
strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src);
64+
add_refspec(refspec.buf);
65+
}
66+
67+
static const char *warn_unconfigured_push_msg[] = {
68+
"You did not specify any refspecs to push, and the current remote",
69+
"has not configured any push refspecs. The default action in this",
70+
"case is to push all matching refspecs, that is, all branches",
71+
"that exist both locally and remotely will be updated. This may",
72+
"not necessarily be what you want to happen.",
73+
"",
74+
"You can specify what action you want to take in this case, and",
75+
"avoid seeing this message again, by configuring 'push.default' to:",
76+
" 'nothing' : Do not push anything",
77+
" 'matching' : Push all matching branches (default)",
78+
" 'tracking' : Push the current branch to whatever it is tracking",
79+
" 'current' : Push the current branch"
80+
};
81+
82+
static void warn_unconfigured_push(void)
83+
{
84+
int i;
85+
for (i = 0; i < ARRAY_SIZE(warn_unconfigured_push_msg); i++)
86+
warning("%s", warn_unconfigured_push_msg[i]);
87+
}
88+
89+
static void setup_default_push_refspecs(void)
90+
{
91+
git_config(git_default_config, NULL);
92+
switch (push_default) {
93+
case PUSH_DEFAULT_UNSPECIFIED:
94+
warn_unconfigured_push();
95+
/* fallthrough */
96+
97+
case PUSH_DEFAULT_MATCHING:
98+
add_refspec(":");
99+
break;
100+
101+
case PUSH_DEFAULT_TRACKING:
102+
setup_push_tracking();
103+
break;
104+
105+
case PUSH_DEFAULT_CURRENT:
106+
add_refspec("HEAD");
107+
break;
108+
109+
case PUSH_DEFAULT_NOTHING:
110+
die("You didn't specify any refspecs to push, and "
111+
"push.default is \"nothing\".");
112+
break;
113+
}
114+
}
115+
51116
static int do_push(const char *repo, int flags)
52117
{
53118
int i, errs;
@@ -79,11 +144,12 @@ static int do_push(const char *repo, int flags)
79144
return error("--all and --mirror are incompatible");
80145
}
81146

82-
if (!refspec
83-
&& !(flags & TRANSPORT_PUSH_ALL)
84-
&& remote->push_refspec_nr) {
85-
refspec = remote->push_refspec;
86-
refspec_nr = remote->push_refspec_nr;
147+
if (!refspec && !(flags & TRANSPORT_PUSH_ALL)) {
148+
if (remote->push_refspec_nr) {
149+
refspec = remote->push_refspec;
150+
refspec_nr = remote->push_refspec_nr;
151+
} else if (!(flags & TRANSPORT_PUSH_MIRROR))
152+
setup_default_push_refspecs();
87153
}
88154
errs = 0;
89155
for (i = 0; i < remote->url_nr; i++) {

cache.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,8 +542,17 @@ enum rebase_setup_type {
542542
AUTOREBASE_ALWAYS,
543543
};
544544

545+
enum push_default_type {
546+
PUSH_DEFAULT_UNSPECIFIED = -1,
547+
PUSH_DEFAULT_NOTHING = 0,
548+
PUSH_DEFAULT_MATCHING,
549+
PUSH_DEFAULT_TRACKING,
550+
PUSH_DEFAULT_CURRENT,
551+
};
552+
545553
extern enum branch_track git_branch_track;
546554
extern enum rebase_setup_type autorebase;
555+
extern enum push_default_type push_default;
547556

548557
#define GIT_REPO_VERSION 0
549558
extern int repository_format_version;

config.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,31 @@ static int git_default_branch_config(const char *var, const char *value)
565565
return 0;
566566
}
567567

568+
static int git_default_push_config(const char *var, const char *value)
569+
{
570+
if (!strcmp(var, "push.default")) {
571+
if (!value)
572+
return config_error_nonbool(var);
573+
else if (!strcmp(value, "nothing"))
574+
push_default = PUSH_DEFAULT_NOTHING;
575+
else if (!strcmp(value, "matching"))
576+
push_default = PUSH_DEFAULT_MATCHING;
577+
else if (!strcmp(value, "tracking"))
578+
push_default = PUSH_DEFAULT_TRACKING;
579+
else if (!strcmp(value, "current"))
580+
push_default = PUSH_DEFAULT_CURRENT;
581+
else {
582+
error("Malformed value for %s: %s", var, value);
583+
return error("Must be one of nothing, matching, "
584+
"tracking or current.");
585+
}
586+
return 0;
587+
}
588+
589+
/* Add other config variables here and to Documentation/config.txt. */
590+
return 0;
591+
}
592+
568593
static int git_default_mailmap_config(const char *var, const char *value)
569594
{
570595
if (!strcmp(var, "mailmap.file"))
@@ -588,6 +613,9 @@ int git_default_config(const char *var, const char *value, void *dummy)
588613
if (!prefixcmp(var, "branch."))
589614
return git_default_branch_config(var, value);
590615

616+
if (!prefixcmp(var, "push."))
617+
return git_default_push_config(var, value);
618+
591619
if (!prefixcmp(var, "mailmap."))
592620
return git_default_mailmap_config(var, value);
593621

environment.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
4242
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
4343
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
4444
enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
45+
enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
4546

4647
/* Parallel index stat data preload? */
4748
int core_preload_index = 0;

0 commit comments

Comments
 (0)