From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mike Crowe Subject: [PATCH] push: add recurseSubmodules config option Date: Mon, 16 Nov 2015 13:24:54 +0000 Message-ID: <1447680294-13395-1-git-send-email-mac@mcrowe.com> Cc: Mike Crowe To: git@vger.kernel.org X-From: git-owner@vger.kernel.org Mon Nov 16 14:42:16 2015 Return-path: Envelope-to: gcvg-git-2@plane.gmane.org Received: from vger.kernel.org ([209.132.180.67]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1ZyK16-0006hJ-QN for gcvg-git-2@plane.gmane.org; Mon, 16 Nov 2015 14:40:21 +0100 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752937AbbKPNkQ (ORCPT ); Mon, 16 Nov 2015 08:40:16 -0500 Received: from relay.appriver.com ([207.97.230.34]:57751 "EHLO relay.appriver.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751859AbbKPNkM (ORCPT ); Mon, 16 Nov 2015 08:40:12 -0500 X-Greylist: delayed 902 seconds by postgrey-1.27 at vger.kernel.org; Mon, 16 Nov 2015 08:40:12 EST Received: from [86.30.112.98] (HELO elite.brightsign) by relay.appriver.com (CommuniGate Pro SMTP 6.1.2) with ESMTP id 640748026; Mon, 16 Nov 2015 08:25:08 -0500 Received: from chuckie.brightsign ([172.30.1.25] helo=chuckie) by elite.brightsign with esmtp (Exim 4.84) (envelope-from ) id 1ZyJmL-0006pw-Sn; Mon, 16 Nov 2015 13:25:05 +0000 Received: from mac by chuckie with local (Exim 4.84) (envelope-from ) id 1ZyJmL-0003Uk-Rv; Mon, 16 Nov 2015 13:25:05 +0000 X-Mailer: git-send-email 2.1.4 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Archived-At: The --recurse-submodules command line parameter has existed for some time but it has no config file equivalent. Following the style of the corresponding parameter for git fetch, let's invent push.recurseSubmodules to provide a default for this parameter. This also requires the addition of --recurse-submodules=no to allow the configuration to be overridden on the command line when required. The most straightforward way to implement this appears to be to make push use code in submodule-config in a similar way to fetch. Signed-off-by: Mike Crowe --- Documentation/config.txt | 13 +++++ Documentation/git-push.txt | 4 +- builtin/push.c | 37 ++++++++----- submodule-config.c | 20 +++++++ submodule-config.h | 1 + submodule.h | 1 + t/t5531-deep-submodule-push.sh | 123 ++++++++++++++++++++++++++++++++++++++++- 7 files changed, 182 insertions(+), 17 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 391a0c3..0546da5 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -2226,6 +2226,19 @@ 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. 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. diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index 85a4d7d..fb0e9b7 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -257,7 +257,7 @@ 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:: +--recurse-submodules=check|on-demand|no:: 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 @@ -267,6 +267,8 @@ origin +master` to force a push to the `master` branch). See the 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' is used to override the push.recurseSubmodules + variable when no submodule recursion is required. --[no-]verify:: Toggle the pre-push hook (see linkgit:githooks[5]). The diff --git a/builtin/push.c b/builtin/push.c index 3bda430..dfced74 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -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[] = { @@ -20,7 +21,7 @@ static int thin = 1; static int deleterefs; static const char *receivepack; static int verbosity; -static int progress = -1; +static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT; static struct push_cas_option cas; @@ -452,22 +453,15 @@ 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)) + if (*recurse_submodules != RECURSE_SUBMODULES_DEFAULT) 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; - else - die("bad %s argument: %s", opt->long_name, arg); - } else - die("option %s needs an argument (check|on-demand)", - opt->long_name); + if (arg) + *recurse_submodules = parse_push_recurse_submodules_arg(opt->long_name, arg); + else + 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); @@ -532,6 +530,7 @@ int cmd_push(int argc, const char **argv, const char *prefix) int flags = 0; int tags = 0; int push_cert = -1; + int recurse_submodules_from_cmdline = RECURSE_SUBMODULES_DEFAULT; int rc; const char *repo = NULL; /* default repository */ struct option options[] = { @@ -549,7 +548,7 @@ int cmd_push(int argc, const char **argv, const char *prefix) 0, CAS_OPT_NAME, &cas, N_("refname>: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 on command line for gar/bage" && + git config push.recurseSubmodules on-demand && + git push ../pub.git master && + git config --unset push.recurseSubmodules && + # 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 fails if submodule commit not on remote using check from cmdline overriding 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 overridiing config junk" + ) && + ( + cd work && + git add gar/bage && + git commit -m "Recurse on command-line overriding config for gar/bage" && + git config push.recurseSubmodules on-demand && + test_must_fail git push --recurse-submodules=check ../pub.git master && + git config --unset push.recurseSubmodules && + # 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^ + ) +' + +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 config push.recurseSubmodules check && + git push --recurse-submodules=on-demand ../pub.git master && + git config --unset push.recurseSubmodules && + # 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 config push.recurseSubmodules check && + git push --recurse-submodules=no ../pub.git master && + git config --unset push.recurseSubmodules && + # 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^ + ) +' + test_expect_success 'push fails when commit on multiple branches if one branch has no remote' ' ( cd work/gar/bage && -- 2.1.4