mirror of
https://github.com/git/git
synced 2024-08-24 18:26:02 +00:00
Merge branch 'mc/push-recurse-submodules-config'
Add new config to avoid typing "--recurse-submodules" on each push. * mc/push-recurse-submodules-config: push: follow the "last one wins" convention for --recurse-submodules push: test that --recurse-submodules on command line overrides config push: add recurseSubmodules config option
This commit is contained in:
commit
5d35d72fc3
|
@ -2229,6 +2229,20 @@ push.gpgSign::
|
|||
override a value from a lower-priority config file. An explicit
|
||||
command-line flag always overrides this config option.
|
||||
|
||||
push.recurseSubmodules::
|
||||
Make sure all submodule commits used by the revisions to be pushed
|
||||
are available on a remote-tracking branch. If the value is 'check'
|
||||
then Git will verify that all submodule commits that changed in the
|
||||
revisions to be pushed are available on at least one remote of the
|
||||
submodule. If any commits are missing, the push will be aborted and
|
||||
exit with non-zero status. If the value is 'on-demand' then all
|
||||
submodules that changed in the revisions to be pushed will be
|
||||
pushed. If on-demand was not able to push all necessary revisions
|
||||
it will also be aborted and exit with non-zero status. If the value
|
||||
is 'no' then default behavior of ignoring submodules when pushing
|
||||
is retained. You may override this configuration at time of push by
|
||||
specifying '--recurse-submodules=check|on-demand|no'.
|
||||
|
||||
rebase.stat::
|
||||
Whether to show a diffstat of what changed upstream since the last
|
||||
rebase. False by default.
|
||||
|
|
|
@ -257,16 +257,20 @@ origin +master` to force a push to the `master` branch). See the
|
|||
is specified. This flag forces progress status even if the
|
||||
standard error stream is not directed to a terminal.
|
||||
|
||||
--recurse-submodules=check|on-demand::
|
||||
Make sure all submodule commits used by the revisions to be
|
||||
pushed are available on a remote-tracking branch. If 'check' is
|
||||
used Git will verify that all submodule commits that changed in
|
||||
the revisions to be pushed are available on at least one remote
|
||||
of the submodule. If any commits are missing the push will be
|
||||
aborted and exit with non-zero status. If 'on-demand' is used
|
||||
all submodules that changed in the revisions to be pushed will
|
||||
be pushed. If on-demand was not able to push all necessary
|
||||
revisions it will also be aborted and exit with non-zero status.
|
||||
--no-recurse-submodules::
|
||||
--recurse-submodules=check|on-demand|no::
|
||||
May be used to make sure all submodule commits used by the
|
||||
revisions to be pushed are available on a remote-tracking branch.
|
||||
If 'check' is used Git will verify that all submodule commits that
|
||||
changed in the revisions to be pushed are available on at least one
|
||||
remote of the submodule. If any commits are missing the push will
|
||||
be aborted and exit with non-zero status. If 'on-demand' is used
|
||||
all submodules that changed in the revisions to be pushed will be
|
||||
pushed. If on-demand was not able to push all necessary revisions
|
||||
it will also be aborted and exit with non-zero status. A value of
|
||||
'no' or using '--no-recurse-submodules' can be used to override the
|
||||
push.recurseSubmodules configuration variable when no submodule
|
||||
recursion is required.
|
||||
|
||||
--[no-]verify::
|
||||
Toggle the pre-push hook (see linkgit:githooks[5]). The
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "transport.h"
|
||||
#include "parse-options.h"
|
||||
#include "submodule.h"
|
||||
#include "submodule-config.h"
|
||||
#include "send-pack.h"
|
||||
|
||||
static const char * const push_usage[] = {
|
||||
|
@ -21,6 +22,7 @@ static int deleterefs;
|
|||
static const char *receivepack;
|
||||
static int verbosity;
|
||||
static int progress = -1;
|
||||
static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
|
||||
|
||||
static struct push_cas_option cas;
|
||||
|
||||
|
@ -452,22 +454,14 @@ static int do_push(const char *repo, int flags)
|
|||
static int option_parse_recurse_submodules(const struct option *opt,
|
||||
const char *arg, int unset)
|
||||
{
|
||||
int *flags = opt->value;
|
||||
int *recurse_submodules = opt->value;
|
||||
|
||||
if (*flags & (TRANSPORT_RECURSE_SUBMODULES_CHECK |
|
||||
TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND))
|
||||
die("%s can only be used once.", opt->long_name);
|
||||
|
||||
if (arg) {
|
||||
if (!strcmp(arg, "check"))
|
||||
*flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
|
||||
else if (!strcmp(arg, "on-demand"))
|
||||
*flags |= TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND;
|
||||
if (unset)
|
||||
*recurse_submodules = RECURSE_SUBMODULES_OFF;
|
||||
else if (arg)
|
||||
*recurse_submodules = parse_push_recurse_submodules_arg(opt->long_name, arg);
|
||||
else
|
||||
die("bad %s argument: %s", opt->long_name, arg);
|
||||
} else
|
||||
die("option %s needs an argument (check|on-demand)",
|
||||
opt->long_name);
|
||||
die("%s missing parameter", opt->long_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -522,6 +516,10 @@ static int git_push_config(const char *k, const char *v, void *cb)
|
|||
return error("Invalid value for '%s'", k);
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(k, "push.recursesubmodules")) {
|
||||
const char *value;
|
||||
if (!git_config_get_value("push.recursesubmodules", &value))
|
||||
recurse_submodules = parse_push_recurse_submodules_arg(k, value);
|
||||
}
|
||||
|
||||
return git_default_config(k, v, NULL);
|
||||
|
@ -549,7 +547,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
|
|||
0, CAS_OPT_NAME, &cas, N_("refname>:<expect"),
|
||||
N_("require old value of ref to be at this value"),
|
||||
PARSE_OPT_OPTARG, parseopt_push_cas_option },
|
||||
{ OPTION_CALLBACK, 0, "recurse-submodules", &flags, "check|on-demand",
|
||||
{ OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules, N_("check|on-demand|no"),
|
||||
N_("control recursive pushing of submodules"),
|
||||
PARSE_OPT_OPTARG, option_parse_recurse_submodules },
|
||||
OPT_BOOL( 0 , "thin", &thin, N_("use thin pack")),
|
||||
|
@ -580,6 +578,11 @@ int cmd_push(int argc, const char **argv, const char *prefix)
|
|||
if (deleterefs && argc < 2)
|
||||
die(_("--delete doesn't make sense without any refs"));
|
||||
|
||||
if (recurse_submodules == RECURSE_SUBMODULES_CHECK)
|
||||
flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
|
||||
else if (recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)
|
||||
flags |= TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND;
|
||||
|
||||
if (tags)
|
||||
add_refspec("refs/tags/*");
|
||||
|
||||
|
|
|
@ -228,6 +228,35 @@ int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg)
|
|||
return parse_fetch_recurse(opt, arg, 1);
|
||||
}
|
||||
|
||||
static int parse_push_recurse(const char *opt, const char *arg,
|
||||
int die_on_error)
|
||||
{
|
||||
switch (git_config_maybe_bool(opt, arg)) {
|
||||
case 1:
|
||||
/* There's no simple "on" value when pushing */
|
||||
if (die_on_error)
|
||||
die("bad %s argument: %s", opt, arg);
|
||||
else
|
||||
return RECURSE_SUBMODULES_ERROR;
|
||||
case 0:
|
||||
return RECURSE_SUBMODULES_OFF;
|
||||
default:
|
||||
if (!strcmp(arg, "on-demand"))
|
||||
return RECURSE_SUBMODULES_ON_DEMAND;
|
||||
else if (!strcmp(arg, "check"))
|
||||
return RECURSE_SUBMODULES_CHECK;
|
||||
else if (die_on_error)
|
||||
die("bad %s argument: %s", opt, arg);
|
||||
else
|
||||
return RECURSE_SUBMODULES_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int parse_push_recurse_submodules_arg(const char *opt, const char *arg)
|
||||
{
|
||||
return parse_push_recurse(opt, arg, 1);
|
||||
}
|
||||
|
||||
static void warn_multiple_config(const unsigned char *commit_sha1,
|
||||
const char *name, const char *option)
|
||||
{
|
||||
|
|
|
@ -19,6 +19,7 @@ struct submodule {
|
|||
};
|
||||
|
||||
int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg);
|
||||
int parse_push_recurse_submodules_arg(const char *opt, const char *arg);
|
||||
int parse_submodule_config_option(const char *var, const char *value);
|
||||
const struct submodule *submodule_from_name(const unsigned char *commit_sha1,
|
||||
const char *name);
|
||||
|
|
|
@ -5,6 +5,7 @@ struct diff_options;
|
|||
struct argv_array;
|
||||
|
||||
enum {
|
||||
RECURSE_SUBMODULES_CHECK = -4,
|
||||
RECURSE_SUBMODULES_ERROR = -3,
|
||||
RECURSE_SUBMODULES_NONE = -2,
|
||||
RECURSE_SUBMODULES_ON_DEMAND = -1,
|
||||
|
|
|
@ -64,7 +64,12 @@ test_expect_success 'push fails if submodule commit not on remote' '
|
|||
cd work &&
|
||||
git add gar/bage &&
|
||||
git commit -m "Third commit for gar/bage" &&
|
||||
test_must_fail git push --recurse-submodules=check ../pub.git master
|
||||
# the push should fail with --recurse-submodules=check
|
||||
# on the command line...
|
||||
test_must_fail git push --recurse-submodules=check ../pub.git master &&
|
||||
|
||||
# ...or if specified in the configuration..
|
||||
test_must_fail git -c push.recurseSubmodules=check push ../pub.git master
|
||||
)
|
||||
'
|
||||
|
||||
|
@ -79,6 +84,216 @@ test_expect_success 'push succeeds after commit was pushed to remote' '
|
|||
)
|
||||
'
|
||||
|
||||
test_expect_success 'push succeeds if submodule commit not on remote but using on-demand on command line' '
|
||||
(
|
||||
cd work/gar/bage &&
|
||||
>recurse-on-demand-on-command-line &&
|
||||
git add recurse-on-demand-on-command-line &&
|
||||
git commit -m "Recurse on-demand on command line junk"
|
||||
) &&
|
||||
(
|
||||
cd work &&
|
||||
git add gar/bage &&
|
||||
git commit -m "Recurse on-demand on command line for gar/bage" &&
|
||||
git push --recurse-submodules=on-demand ../pub.git master &&
|
||||
# Check that the supermodule commit got there
|
||||
git fetch ../pub.git &&
|
||||
git diff --quiet FETCH_HEAD master &&
|
||||
# Check that the submodule commit got there too
|
||||
cd gar/bage &&
|
||||
git diff --quiet origin/master master
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'push succeeds if submodule commit not on remote but using on-demand from config' '
|
||||
(
|
||||
cd work/gar/bage &&
|
||||
>recurse-on-demand-from-config &&
|
||||
git add recurse-on-demand-from-config &&
|
||||
git commit -m "Recurse on-demand from config junk"
|
||||
) &&
|
||||
(
|
||||
cd work &&
|
||||
git add gar/bage &&
|
||||
git commit -m "Recurse on-demand from config for gar/bage" &&
|
||||
git -c push.recurseSubmodules=on-demand push ../pub.git master &&
|
||||
# Check that the supermodule commit got there
|
||||
git fetch ../pub.git &&
|
||||
git diff --quiet FETCH_HEAD master &&
|
||||
# Check that the submodule commit got there too
|
||||
cd gar/bage &&
|
||||
git diff --quiet origin/master master
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'push recurse-submodules on command line overrides config' '
|
||||
(
|
||||
cd work/gar/bage &&
|
||||
>recurse-check-on-command-line-overriding-config &&
|
||||
git add recurse-check-on-command-line-overriding-config &&
|
||||
git commit -m "Recurse on command-line overriding config junk"
|
||||
) &&
|
||||
(
|
||||
cd work &&
|
||||
git add gar/bage &&
|
||||
git commit -m "Recurse on command-line overriding config for gar/bage" &&
|
||||
|
||||
# Ensure that we can override on-demand in the config
|
||||
# to just check submodules
|
||||
test_must_fail git -c push.recurseSubmodules=on-demand push --recurse-submodules=check ../pub.git master &&
|
||||
# Check that the supermodule commit did not get there
|
||||
git fetch ../pub.git &&
|
||||
git diff --quiet FETCH_HEAD master^ &&
|
||||
# Check that the submodule commit did not get there
|
||||
(cd gar/bage && git diff --quiet origin/master master^) &&
|
||||
|
||||
# Ensure that we can override check in the config to
|
||||
# disable submodule recursion entirely
|
||||
(cd gar/bage && git diff --quiet origin/master master^) &&
|
||||
git -c push.recurseSubmodules=on-demand push --recurse-submodules=no ../pub.git master &&
|
||||
git fetch ../pub.git &&
|
||||
git diff --quiet FETCH_HEAD master &&
|
||||
(cd gar/bage && git diff --quiet origin/master master^) &&
|
||||
|
||||
# Ensure that we can override check in the config to
|
||||
# disable submodule recursion entirely (alternative form)
|
||||
git -c push.recurseSubmodules=on-demand push --no-recurse-submodules ../pub.git master &&
|
||||
git fetch ../pub.git &&
|
||||
git diff --quiet FETCH_HEAD master &&
|
||||
(cd gar/bage && git diff --quiet origin/master master^) &&
|
||||
|
||||
# Ensure that we can override check in the config to
|
||||
# push the submodule too
|
||||
git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git master &&
|
||||
git fetch ../pub.git &&
|
||||
git diff --quiet FETCH_HEAD master &&
|
||||
(cd gar/bage && git diff --quiet origin/master master)
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'push recurse-submodules last one wins on command line' '
|
||||
(
|
||||
cd work/gar/bage &&
|
||||
>recurse-check-on-command-line-overriding-earlier-command-line &&
|
||||
git add recurse-check-on-command-line-overriding-earlier-command-line &&
|
||||
git commit -m "Recurse on command-line overridiing earlier command-line junk"
|
||||
) &&
|
||||
(
|
||||
cd work &&
|
||||
git add gar/bage &&
|
||||
git commit -m "Recurse on command-line overriding earlier command-line for gar/bage" &&
|
||||
|
||||
# should result in "check"
|
||||
test_must_fail git push --recurse-submodules=on-demand --recurse-submodules=check ../pub.git master &&
|
||||
# Check that the supermodule commit did not get there
|
||||
git fetch ../pub.git &&
|
||||
git diff --quiet FETCH_HEAD master^ &&
|
||||
# Check that the submodule commit did not get there
|
||||
(cd gar/bage && git diff --quiet origin/master master^) &&
|
||||
|
||||
# should result in "no"
|
||||
git push --recurse-submodules=on-demand --recurse-submodules=no ../pub.git master &&
|
||||
# Check that the supermodule commit did get there
|
||||
git fetch ../pub.git &&
|
||||
git diff --quiet FETCH_HEAD master &&
|
||||
# Check that the submodule commit did not get there
|
||||
(cd gar/bage && git diff --quiet origin/master master^) &&
|
||||
|
||||
# should result in "no"
|
||||
git push --recurse-submodules=on-demand --no-recurse-submodules ../pub.git master &&
|
||||
# Check that the submodule commit did not get there
|
||||
(cd gar/bage && git diff --quiet origin/master master^) &&
|
||||
|
||||
# But the options in the other order should push the submodule
|
||||
git push --recurse-submodules=check --recurse-submodules=on-demand ../pub.git master &&
|
||||
# Check that the submodule commit did get there
|
||||
git fetch ../pub.git &&
|
||||
(cd gar/bage && git diff --quiet origin/master master)
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'push succeeds if submodule commit not on remote using on-demand from cmdline overriding config' '
|
||||
(
|
||||
cd work/gar/bage &&
|
||||
>recurse-on-demand-on-command-line-overriding-config &&
|
||||
git add recurse-on-demand-on-command-line-overriding-config &&
|
||||
git commit -m "Recurse on-demand on command-line overriding config junk"
|
||||
) &&
|
||||
(
|
||||
cd work &&
|
||||
git add gar/bage &&
|
||||
git commit -m "Recurse on-demand on command-line overriding config for gar/bage" &&
|
||||
git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git master &&
|
||||
# Check that the supermodule commit got there
|
||||
git fetch ../pub.git &&
|
||||
git diff --quiet FETCH_HEAD master &&
|
||||
# Check that the submodule commit got there
|
||||
cd gar/bage &&
|
||||
git diff --quiet origin/master master
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline overriding config' '
|
||||
(
|
||||
cd work/gar/bage &&
|
||||
>recurse-disable-on-command-line-overriding-config &&
|
||||
git add recurse-disable-on-command-line-overriding-config &&
|
||||
git commit -m "Recurse disable on command-line overriding config junk"
|
||||
) &&
|
||||
(
|
||||
cd work &&
|
||||
git add gar/bage &&
|
||||
git commit -m "Recurse disable on command-line overriding config for gar/bage" &&
|
||||
git -c push.recurseSubmodules=check push --recurse-submodules=no ../pub.git master &&
|
||||
# Check that the supermodule commit got there
|
||||
git fetch ../pub.git &&
|
||||
git diff --quiet FETCH_HEAD master &&
|
||||
# But that the submodule commit did not
|
||||
( cd gar/bage && git diff --quiet origin/master master^ ) &&
|
||||
# Now push it to avoid confusing future tests
|
||||
git push --recurse-submodules=on-demand ../pub.git master
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline (alternative form) overriding config' '
|
||||
(
|
||||
cd work/gar/bage &&
|
||||
>recurse-disable-on-command-line-alt-overriding-config &&
|
||||
git add recurse-disable-on-command-line-alt-overriding-config &&
|
||||
git commit -m "Recurse disable on command-line alternative overriding config junk"
|
||||
) &&
|
||||
(
|
||||
cd work &&
|
||||
git add gar/bage &&
|
||||
git commit -m "Recurse disable on command-line alternative overriding config for gar/bage" &&
|
||||
git -c push.recurseSubmodules=check push --no-recurse-submodules ../pub.git master &&
|
||||
# Check that the supermodule commit got there
|
||||
git fetch ../pub.git &&
|
||||
git diff --quiet FETCH_HEAD master &&
|
||||
# But that the submodule commit did not
|
||||
( cd gar/bage && git diff --quiet origin/master master^ ) &&
|
||||
# Now push it to avoid confusing future tests
|
||||
git push --recurse-submodules=on-demand ../pub.git master
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'push fails if recurse submodules option passed as yes' '
|
||||
(
|
||||
cd work/gar/bage &&
|
||||
>recurse-push-fails-if-recurse-submodules-passed-as-yes &&
|
||||
git add recurse-push-fails-if-recurse-submodules-passed-as-yes &&
|
||||
git commit -m "Recurse push fails if recurse submodules option passed as yes"
|
||||
) &&
|
||||
(
|
||||
cd work &&
|
||||
git add gar/bage &&
|
||||
git commit -m "Recurse push fails if recurse submodules option passed as yes for gar/bage" &&
|
||||
test_must_fail git push --recurse-submodules=yes ../pub.git master &&
|
||||
test_must_fail git -c push.recurseSubmodules=yes push ../pub.git master &&
|
||||
git push --recurse-submodules=on-demand ../pub.git master
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'push fails when commit on multiple branches if one branch has no remote' '
|
||||
(
|
||||
cd work/gar/bage &&
|
||||
|
|
Loading…
Reference in a new issue