* [PATCH 0/2] Persistent submodule pathspec specification @ 2016-05-21 0:28 Stefan Beller 2016-05-21 0:28 ` [PATCH 1/2] submodule update: add `--init-default-path` switch Stefan Beller 2016-05-21 0:28 ` [PATCH 2/2] clone: add --init-submodule=<pathspec> switch Stefan Beller 0 siblings, 2 replies; 5+ messages in thread From: Stefan Beller @ 2016-05-21 0:28 UTC (permalink / raw) To: gitster, Jens.Lehmann; +Cc: git, Stefan Beller This was part of the former series 'submodule groups'. However the labeling was ripped out and goes in its own series sb/pathspec-label. First we introduce a switch `--init-default-path` for `git submodule update` which will read the pathspec to initialize the submodules not from the command line but from `submodule.defaultUpdatePath`, which can be configured permanently. The second patch utilizes this by having `clone` set that config option and using that new option when calling to update the submodules. Thanks, Stefan Stefan Beller (2): submodule update: add `--init-default-path` switch clone: add --init-submodule=<pathspec> switch 6 files changed, 216 insertions(+), 14 deletions(-) Documentation/config.txt | 5 ++ Documentation/git-clone.txt | 25 +++++--- Documentation/git-submodule.txt | 11 +++- builtin/clone.c | 34 +++++++++- git-submodule.sh | 21 ++++++- t/t7400-submodule-basic.sh | 134 ++++++++++++++++++++++++++++++++++++++++ -- 2.8.3.396.g0eed146 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] submodule update: add `--init-default-path` switch 2016-05-21 0:28 [PATCH 0/2] Persistent submodule pathspec specification Stefan Beller @ 2016-05-21 0:28 ` Stefan Beller 2016-05-21 0:28 ` [PATCH 2/2] clone: add --init-submodule=<pathspec> switch Stefan Beller 1 sibling, 0 replies; 5+ messages in thread From: Stefan Beller @ 2016-05-21 0:28 UTC (permalink / raw) To: gitster, Jens.Lehmann; +Cc: git, Stefan Beller The new switch `--init-default-path` initializes the submodules which are configured in `submodule.defaultUpdatePath` instead of those given as command line arguments before updating. In the first implementation this is made incompatible with further command line arguments as it is unclear what the user means by git submodule update --init --init-default-path <paths> This new switch allows to record more complex patterns as it saves retyping them whenever you invoke update. Signed-off-by: Stefan Beller <sbeller@google.com> --- Documentation/config.txt | 5 ++++ Documentation/git-submodule.txt | 11 ++++++++- git-submodule.sh | 21 +++++++++++++--- t/t7400-submodule-basic.sh | 53 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 4 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index e4cd291..121b236 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -2786,6 +2786,11 @@ submodule.fetchJobs:: in parallel. A value of 0 will give some reasonable default. If unset, it defaults to 1. +submodule.defaultUpdatePath:: + Specifies a set of submodules to initialize when calling + `git submodule --init-default-group` by using the pathspec + syntax. + tag.forceSignAnnotated:: A boolean to specify whether annotated tags created should be GPG signed. If `--annotate` is specified on the command line, it takes diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 9226c43..000231e 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -14,7 +14,7 @@ SYNOPSIS 'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...] 'git submodule' [--quiet] init [--] [<path>...] 'git submodule' [--quiet] deinit [-f|--force] (--all|[--] <path>...) -'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch] +'git submodule' [--quiet] update [--init[-default-path]] [--remote] [-N|--no-fetch] [-f|--force] [--rebase|--merge] [--reference <repository>] [--depth <depth>] [--recursive] [--jobs <n>] [--] [<path>...] 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>] @@ -193,6 +193,10 @@ If the submodule is not yet initialized, and you just want to use the setting as stored in .gitmodules, you can automatically initialize the submodule with the `--init` option. +You can configure a set of submodules using pathspec syntax in +submodule.defaultUpdatePath you can use `--init-default-path` to initialize +those before updating. + If `--recursive` is specified, this command will recurse into the registered submodules, and update any nested submodules within. -- @@ -360,6 +364,11 @@ the submodule itself. Initialize all submodules for which "git submodule init" has not been called so far before updating. +--init-default-path:: + This option is only valid for the update command. + Initialize all submodules configured in "`submodule.defaultUpdatePath`" + that have not been updated before. + --name:: This option is only valid for the add command. It sets the submodule's name to the given string instead of defaulting to its path. The name diff --git a/git-submodule.sh b/git-submodule.sh index 5a4dec0..3d12145 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -9,7 +9,7 @@ USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <re or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...] or: $dashless [--quiet] init [--] [<path>...] or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...) - or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--reference <repository>] [--recursive] [--] [<path>...] + or: $dashless [--quiet] update [--init[-default-path]] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--reference <repository>] [--recursive] [--] [<path>...] or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...] or: $dashless [--quiet] foreach [--recursive] <command> or: $dashless [--quiet] sync [--recursive] [--] [<path>...]" @@ -528,7 +528,12 @@ cmd_update() GIT_QUIET=1 ;; -i|--init) - init=1 + test -z $init || test $init = by_args || die "$(gettext "Only one of --init or --init-default-path may be used.")" + init=by_args + ;; + --init-default-path) + test -z $init || test $init = by_config || die "$(gettext "Only one of --init or --init-default-path may be used.")" + init=by_config ;; --remote) remote=1 @@ -591,7 +596,17 @@ cmd_update() if test -n "$init" then - cmd_init "--" "$@" || return + if test "$init" = "by_config" + then + if test $# -gt 0 + then + die "$(gettext "path arguments are incompatible with --init-default-path")" + fi + cmd_init "--" $(git config --get-all submodule.defaultUpdatePath) || return + else + cmd_init "--" "$@" || return + fi + fi { diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 3570f7b..4173c72 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -1116,5 +1116,58 @@ test_expect_success 'submodule helper list is not confused by common prefixes' ' test_cmp expect actual ' +test_expect_success 'setup superproject with submodules' ' + mkdir sub1 && + ( + cd sub1 && + git init && + test_commit test + test_commit test2 + ) && + mkdir multisuper && + ( + cd multisuper && + git init && + git submodule add ../sub1 sub0 && + git submodule add ../sub1 sub1 && + git submodule add ../sub1 sub2 && + git submodule add ../sub1 sub3 && + git commit -m "add some submodules" + ) +' + +cat >expect <<-EOF +-sub0 + sub1 (test2) + sub2 (test2) + sub3 (test2) +EOF + +test_expect_success 'submodule update --init with a specification' ' + test_when_finished "rm -rf multisuper_clone" && + pwd=$(pwd) && + git clone file://"$pwd"/multisuper multisuper_clone && + ( + cd multisuper_clone && + git submodule update --init . ":(exclude)sub0" && + git submodule status |cut -c 1,43- >../actual + ) && + test_cmp expect actual +' + +test_expect_success 'submodule update --init-default-path' ' + test_when_finished "rm -rf multisuper_clone" && + pwd=$(pwd) && + git clone file://"$pwd"/multisuper multisuper_clone && + ( + cd multisuper_clone && + git config submodule.defaultUpdatePath "." && + git config --add submodule.defaultUpdatePath ":(exclude)sub0" && + git submodule update --init-default-path && + git submodule status |cut -c 1,43- >../actual && + test_must_fail git submodule update --init-default-path sub0 + ) && + test_cmp expect actual +' test_done -- 2.8.3.395.ga2acc22.dirty ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] clone: add --init-submodule=<pathspec> switch 2016-05-21 0:28 [PATCH 0/2] Persistent submodule pathspec specification Stefan Beller 2016-05-21 0:28 ` [PATCH 1/2] submodule update: add `--init-default-path` switch Stefan Beller @ 2016-05-21 0:28 ` Stefan Beller 1 sibling, 0 replies; 5+ messages in thread From: Stefan Beller @ 2016-05-21 0:28 UTC (permalink / raw) To: gitster, Jens.Lehmann; +Cc: git, Stefan Beller The new switch passes the pathspec to `git submodule update --init` which is called after the actual clone is done. Additionally this configures the submodule.defaultUpdatePath to be the given pathspec, such that any future invocation of `git submodule update --init-default-paths` will keep up with the pathspec. Signed-off-by: Stefan Beller <sbeller@google.com> --- Documentation/git-clone.txt | 25 +++++++++----- builtin/clone.c | 34 +++++++++++++++++-- t/t7400-submodule-basic.sh | 81 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 10 deletions(-) diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 1b15cd7..33e5894 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -14,8 +14,9 @@ SYNOPSIS [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>] [--dissociate] [--separate-git-dir <git dir>] [--depth <depth>] [--[no-]single-branch] - [--recursive | --recurse-submodules] [--[no-]shallow-submodules] - [--jobs <n>] [--] <repository> [<directory>] + [--recursive | --recurse-submodules] [--jobs <n>] + [--init-submodule <submodulespec>] [--] <repository> + [<directory>] DESCRIPTION ----------- @@ -207,12 +208,20 @@ objects from the source repository into a pack in the cloned repository. --recursive:: --recurse-submodules:: - After the clone is created, initialize all submodules within, - using their default settings. This is equivalent to running - `git submodule update --init --recursive` immediately after - the clone is finished. This option is ignored if the cloned - repository does not have a worktree/checkout (i.e. if any of - `--no-checkout`/`-n`, `--bare`, or `--mirror` is given) + After the clone is created, initialize and clone all submodules + within, using their default settings. This is equivalent to + running `git submodule update --recursive --init ` + immediately after the clone is finished. This option is ignored + if the cloned repository does not have a worktree/checkout (i.e. + if any of `--no-checkout`/`-n`, `--bare`, or `--mirror` is given) + +--init-submodule:: + After the clone is created, initialize and clone specified + submodules within, using their default settings. It is possible + to give multiple specifications by giving this argument multiple + times. This is equivalent to configure `submodule.defaultUpdateGroup` + and then running `git submodule update --init-default-path` + immediately after the clone is finished. --[no-]shallow-submodules:: All submodules which are cloned will be shallow with a depth of 1. diff --git a/builtin/clone.c b/builtin/clone.c index 5f867e6..56967f9 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -53,6 +53,16 @@ static struct string_list option_config; static struct string_list option_reference; static int option_dissociate; static int max_jobs = -1; +static struct string_list init_submodules; + +static int init_submodules_cb(const struct option *opt, const char *arg, int unset) +{ + if (unset) + return -1; + + string_list_append((struct string_list *)opt->value, arg); + return 0; +} static struct option builtin_clone_options[] = { OPT__VERBOSITY(&option_verbosity), @@ -103,6 +113,9 @@ static struct option builtin_clone_options[] = { TRANSPORT_FAMILY_IPV4), OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"), TRANSPORT_FAMILY_IPV6), + OPT_CALLBACK(0, "init-submodule", &init_submodules, N_("<pathspec>"), + N_("clone specific submodules. Pass ultiple times for complex pathspecs"), + init_submodules_cb), OPT_END() }; @@ -734,14 +747,22 @@ static int checkout(void) err |= run_hook_le(NULL, "post-checkout", sha1_to_hex(null_sha1), sha1_to_hex(sha1), "1", NULL); - if (!err && option_recursive) { + if (!err && (option_recursive || init_submodules.nr > 0)) { struct argv_array args = ARGV_ARRAY_INIT; - argv_array_pushl(&args, "submodule", "update", "--init", "--recursive", NULL); + argv_array_pushl(&args, "submodule", "update", NULL); + + if (init_submodules.nr > 0) + argv_array_pushf(&args, "--init-default-path"); + else + argv_array_pushf(&args, "--init"); if (option_shallow_submodules == 1 || (option_shallow_submodules == -1 && option_depth)) argv_array_push(&args, "--depth=1"); + if (option_recursive) + argv_array_pushf(&args, "--recursive"); + if (max_jobs != -1) argv_array_pushf(&args, "--jobs=%d", max_jobs); @@ -883,6 +904,15 @@ int cmd_clone(int argc, const char **argv, const char *prefix) option_no_checkout = 1; } + if (init_submodules.nr > 0) { + struct string_list_item *item; + struct strbuf sb = STRBUF_INIT; + for_each_string_list_item(item, &init_submodules) { + strbuf_addf(&sb, "submodule.defaultUpdatePath=%s", item->string); + string_list_append(&option_config, strbuf_detach(&sb, 0)); + } + } + if (!option_origin) option_origin = "origin"; diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 4173c72..af5d0ce 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -1170,4 +1170,85 @@ test_expect_success 'submodule update --init-default-path' ' test_cmp expect actual ' +cat <<EOF > expected + sub0 (test2) +-sub1 +-sub2 +-sub3 +EOF + +test_expect_success 'clone --init-submodule works' ' + test_when_finished "rm -rf multisuper_clone" && + git clone --recurse-submodules --init-submodule="sub0" multisuper multisuper_clone && + ( + cd multisuper_clone && + git submodule status |cut -c 1,43- >../actual + ) && + test_cmp actual expected +' + +cat <<EOF > expect +-sub0 + sub1 (test2) +-sub2 + sub3 (test2) +EOF +test_expect_success 'clone with multiple --init-submodule options' ' + test_when_finished "rm -rf multisuper_clone" && + git clone --recurse-submodules \ + --init-submodule="." \ + --init-submodule ":(exclude)sub0" \ + --init-submodule ":(exclude)sub2" \ + multisuper multisuper_clone && + ( + cd multisuper_clone && + git submodule status |cut -c1,43- >../actual + ) && + test_cmp expect actual +' + +cat <<EOF > expect +-sub0 + sub1 (test2) +-sub2 + sub3 (test2) +EOF + +cat <<EOF > expect2 +-sub0 + sub1 (test2) +-sub2 + sub3 (test2) +-sub4 + sub5 (test2) +EOF + +test_expect_success 'clone and subsequent updates correctly auto-initialize submodules' ' + test_when_finished "rm -rf multisuper_clone" && + git clone --recurse-submodules --init-submodule="." \ + --init-submodule ":(exclude)sub0" \ + --init-submodule ":(exclude)sub2" \ + --init-submodule ":(exclude)sub4" \ + multisuper multisuper_clone && + ( + cd multisuper_clone && + git submodule status |cut -c1,43- >../actual + ) && + test_cmp expect actual && + ( + cd multisuper && + git submodule add ../sub1 sub4 && + git submodule add ../sub1 sub5 && + git commit -m "add more submodules" + ) && + ( + cd multisuper_clone && + # obtain the new superproject + git pull && + git submodule update --init-default-path && + git submodule status |cut -c1,43- >../actual + ) && + test_cmp expect2 actual +' + test_done -- 2.8.3.395.ga2acc22.dirty ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCHv2 0/2] Persistent submodule pathspec specification @ 2016-05-24 2:24 Stefan Beller 2016-05-24 2:24 ` [PATCH 2/2] clone: add --init-submodule=<pathspec> switch Stefan Beller 0 siblings, 1 reply; 5+ messages in thread From: Stefan Beller @ 2016-05-24 2:24 UTC (permalink / raw) Cc: git, sunshine, gitster, pclouds, Stefan Beller Changes since v1: * fixed a broken && chain in a subshell for testing, as pointed out by Eric! This was part of the former series 'submodule groups'. However the labeling was ripped out and goes in its own series sb/pathspec-label. First we introduce a switch `--init-default-path` for `git submodule update` which will read the pathspec to initialize the submodules not from the command line but from `submodule.defaultUpdatePath`, which can be configured permanently. The second patch utilizes this by having `clone` set that config option and using that new option when calling to update the submodules. Thanks, Stefan Stefan Beller (2): submodule update: add `--init-default-path` switch clone: add --init-submodule=<pathspec> switch 6 files changed, 216 insertions(+), 14 deletions(-) Documentation/config.txt | 5 ++ Documentation/git-clone.txt | 25 +++++--- Documentation/git-submodule.txt | 11 +++- builtin/clone.c | 34 +++++++++- git-submodule.sh | 21 ++++++- t/t7400-submodule-basic.sh | 134 ++++++++++++++++++++++++++++++++++++++++ -- 2.8.3.396.g0eed146 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] clone: add --init-submodule=<pathspec> switch 2016-05-24 2:24 [PATCHv2 0/2] Persistent submodule pathspec specification Stefan Beller @ 2016-05-24 2:24 ` Stefan Beller 0 siblings, 0 replies; 5+ messages in thread From: Stefan Beller @ 2016-05-24 2:24 UTC (permalink / raw) Cc: git, sunshine, gitster, pclouds, Stefan Beller The new switch passes the pathspec to `git submodule update --init` which is called after the actual clone is done. Additionally this configures the submodule.defaultUpdatePath to be the given pathspec, such that any future invocation of `git submodule update --init-default-paths` will keep up with the pathspec. Signed-off-by: Stefan Beller <sbeller@google.com> --- Documentation/git-clone.txt | 25 +++++++++----- builtin/clone.c | 34 +++++++++++++++++-- t/t7400-submodule-basic.sh | 81 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 10 deletions(-) diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 1b15cd7..33e5894 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -14,8 +14,9 @@ SYNOPSIS [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>] [--dissociate] [--separate-git-dir <git dir>] [--depth <depth>] [--[no-]single-branch] - [--recursive | --recurse-submodules] [--[no-]shallow-submodules] - [--jobs <n>] [--] <repository> [<directory>] + [--recursive | --recurse-submodules] [--jobs <n>] + [--init-submodule <submodulespec>] [--] <repository> + [<directory>] DESCRIPTION ----------- @@ -207,12 +208,20 @@ objects from the source repository into a pack in the cloned repository. --recursive:: --recurse-submodules:: - After the clone is created, initialize all submodules within, - using their default settings. This is equivalent to running - `git submodule update --init --recursive` immediately after - the clone is finished. This option is ignored if the cloned - repository does not have a worktree/checkout (i.e. if any of - `--no-checkout`/`-n`, `--bare`, or `--mirror` is given) + After the clone is created, initialize and clone all submodules + within, using their default settings. This is equivalent to + running `git submodule update --recursive --init ` + immediately after the clone is finished. This option is ignored + if the cloned repository does not have a worktree/checkout (i.e. + if any of `--no-checkout`/`-n`, `--bare`, or `--mirror` is given) + +--init-submodule:: + After the clone is created, initialize and clone specified + submodules within, using their default settings. It is possible + to give multiple specifications by giving this argument multiple + times. This is equivalent to configure `submodule.defaultUpdateGroup` + and then running `git submodule update --init-default-path` + immediately after the clone is finished. --[no-]shallow-submodules:: All submodules which are cloned will be shallow with a depth of 1. diff --git a/builtin/clone.c b/builtin/clone.c index 5f867e6..56967f9 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -53,6 +53,16 @@ static struct string_list option_config; static struct string_list option_reference; static int option_dissociate; static int max_jobs = -1; +static struct string_list init_submodules; + +static int init_submodules_cb(const struct option *opt, const char *arg, int unset) +{ + if (unset) + return -1; + + string_list_append((struct string_list *)opt->value, arg); + return 0; +} static struct option builtin_clone_options[] = { OPT__VERBOSITY(&option_verbosity), @@ -103,6 +113,9 @@ static struct option builtin_clone_options[] = { TRANSPORT_FAMILY_IPV4), OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"), TRANSPORT_FAMILY_IPV6), + OPT_CALLBACK(0, "init-submodule", &init_submodules, N_("<pathspec>"), + N_("clone specific submodules. Pass ultiple times for complex pathspecs"), + init_submodules_cb), OPT_END() }; @@ -734,14 +747,22 @@ static int checkout(void) err |= run_hook_le(NULL, "post-checkout", sha1_to_hex(null_sha1), sha1_to_hex(sha1), "1", NULL); - if (!err && option_recursive) { + if (!err && (option_recursive || init_submodules.nr > 0)) { struct argv_array args = ARGV_ARRAY_INIT; - argv_array_pushl(&args, "submodule", "update", "--init", "--recursive", NULL); + argv_array_pushl(&args, "submodule", "update", NULL); + + if (init_submodules.nr > 0) + argv_array_pushf(&args, "--init-default-path"); + else + argv_array_pushf(&args, "--init"); if (option_shallow_submodules == 1 || (option_shallow_submodules == -1 && option_depth)) argv_array_push(&args, "--depth=1"); + if (option_recursive) + argv_array_pushf(&args, "--recursive"); + if (max_jobs != -1) argv_array_pushf(&args, "--jobs=%d", max_jobs); @@ -883,6 +904,15 @@ int cmd_clone(int argc, const char **argv, const char *prefix) option_no_checkout = 1; } + if (init_submodules.nr > 0) { + struct string_list_item *item; + struct strbuf sb = STRBUF_INIT; + for_each_string_list_item(item, &init_submodules) { + strbuf_addf(&sb, "submodule.defaultUpdatePath=%s", item->string); + string_list_append(&option_config, strbuf_detach(&sb, 0)); + } + } + if (!option_origin) option_origin = "origin"; diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 112d86a..a8d45cda 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -1170,4 +1170,85 @@ test_expect_success 'submodule update --init-default-path' ' test_cmp expect actual ' +cat <<EOF > expected + sub0 (test2) +-sub1 +-sub2 +-sub3 +EOF + +test_expect_success 'clone --init-submodule works' ' + test_when_finished "rm -rf multisuper_clone" && + git clone --recurse-submodules --init-submodule="sub0" multisuper multisuper_clone && + ( + cd multisuper_clone && + git submodule status |cut -c 1,43- >../actual + ) && + test_cmp actual expected +' + +cat <<EOF > expect +-sub0 + sub1 (test2) +-sub2 + sub3 (test2) +EOF +test_expect_success 'clone with multiple --init-submodule options' ' + test_when_finished "rm -rf multisuper_clone" && + git clone --recurse-submodules \ + --init-submodule="." \ + --init-submodule ":(exclude)sub0" \ + --init-submodule ":(exclude)sub2" \ + multisuper multisuper_clone && + ( + cd multisuper_clone && + git submodule status |cut -c1,43- >../actual + ) && + test_cmp expect actual +' + +cat <<EOF > expect +-sub0 + sub1 (test2) +-sub2 + sub3 (test2) +EOF + +cat <<EOF > expect2 +-sub0 + sub1 (test2) +-sub2 + sub3 (test2) +-sub4 + sub5 (test2) +EOF + +test_expect_success 'clone and subsequent updates correctly auto-initialize submodules' ' + test_when_finished "rm -rf multisuper_clone" && + git clone --recurse-submodules --init-submodule="." \ + --init-submodule ":(exclude)sub0" \ + --init-submodule ":(exclude)sub2" \ + --init-submodule ":(exclude)sub4" \ + multisuper multisuper_clone && + ( + cd multisuper_clone && + git submodule status |cut -c1,43- >../actual + ) && + test_cmp expect actual && + ( + cd multisuper && + git submodule add ../sub1 sub4 && + git submodule add ../sub1 sub5 && + git commit -m "add more submodules" + ) && + ( + cd multisuper_clone && + # obtain the new superproject + git pull && + git submodule update --init-default-path && + git submodule status |cut -c1,43- >../actual + ) && + test_cmp expect2 actual +' + test_done -- 2.8.3.397.g0b71a98 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCHv3 0/2] Persistent submodule pathspec specification @ 2016-05-26 20:47 Stefan Beller 2016-05-26 20:47 ` [PATCH 2/2] clone: add --init-submodule=<pathspec> switch Stefan Beller 0 siblings, 1 reply; 5+ messages in thread From: Stefan Beller @ 2016-05-26 20:47 UTC (permalink / raw) To: git; +Cc: sunshine, gitster, pclouds, ramsay, Stefan Beller Changes since v2: * I replaced one 0 by NULL as pointed out by Ramsay, and reformatted the line to stay within 80 characters: --- a/builtin/clone.c +++ b/builtin/clone.c @@ -908,8 +908,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix) struct string_list_item *item; struct strbuf sb = STRBUF_INIT; for_each_string_list_item(item, &init_submodules) { - strbuf_addf(&sb, "submodule.defaultUpdatePath=%s", item->string); - string_list_append(&option_config, strbuf_detach(&sb, 0)); + strbuf_addf(&sb, "submodule.defaultUpdatePath=%s", + item->string); + string_list_append(&option_config, + strbuf_detach(&sb, NULL)); } } Changes since v1: * fixed a broken && chain in a subshell for testing, as pointed out by Eric! This was part of the former series 'submodule groups'. However the labeling was ripped out and goes in its own series sb/pathspec-label. First we introduce a switch `--init-default-path` for `git submodule update` which will read the pathspec to initialize the submodules not from the command line but from `submodule.defaultUpdatePath`, which can be configured permanently. The second patch utilizes this by having `clone` set that config option and using that new option when calling to update the submodules. Thanks, Stefan Stefan Beller (2): submodule update: add `--init-default-path` switch clone: add --init-submodule=<pathspec> switch Documentation/config.txt | 5 ++ Documentation/git-clone.txt | 25 +++++--- Documentation/git-submodule.txt | 11 +++- builtin/clone.c | 36 ++++++++++- git-submodule.sh | 21 ++++++- t/t7400-submodule-basic.sh | 134 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 218 insertions(+), 14 deletions(-) -- 2.9.0.rc0.2.g145fc64 base-commit: 3a0f269e7c82aa3a87323cb7ae04ac5f129f036b ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] clone: add --init-submodule=<pathspec> switch 2016-05-26 20:47 [PATCHv3 0/2] Persistent submodule pathspec specification Stefan Beller @ 2016-05-26 20:47 ` Stefan Beller 0 siblings, 0 replies; 5+ messages in thread From: Stefan Beller @ 2016-05-26 20:47 UTC (permalink / raw) To: git; +Cc: sunshine, gitster, pclouds, ramsay, Stefan Beller The new switch passes the pathspec to `git submodule update --init` which is called after the actual clone is done. Additionally this configures the submodule.defaultUpdatePath to be the given pathspec, such that any future invocation of `git submodule update --init-default-paths` will keep up with the pathspec. Signed-off-by: Stefan Beller <sbeller@google.com> --- Documentation/git-clone.txt | 25 +++++++++----- builtin/clone.c | 36 ++++++++++++++++++-- t/t7400-submodule-basic.sh | 81 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 10 deletions(-) diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 1b15cd7..33e5894 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -14,8 +14,9 @@ SYNOPSIS [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>] [--dissociate] [--separate-git-dir <git dir>] [--depth <depth>] [--[no-]single-branch] - [--recursive | --recurse-submodules] [--[no-]shallow-submodules] - [--jobs <n>] [--] <repository> [<directory>] + [--recursive | --recurse-submodules] [--jobs <n>] + [--init-submodule <submodulespec>] [--] <repository> + [<directory>] DESCRIPTION ----------- @@ -207,12 +208,20 @@ objects from the source repository into a pack in the cloned repository. --recursive:: --recurse-submodules:: - After the clone is created, initialize all submodules within, - using their default settings. This is equivalent to running - `git submodule update --init --recursive` immediately after - the clone is finished. This option is ignored if the cloned - repository does not have a worktree/checkout (i.e. if any of - `--no-checkout`/`-n`, `--bare`, or `--mirror` is given) + After the clone is created, initialize and clone all submodules + within, using their default settings. This is equivalent to + running `git submodule update --recursive --init ` + immediately after the clone is finished. This option is ignored + if the cloned repository does not have a worktree/checkout (i.e. + if any of `--no-checkout`/`-n`, `--bare`, or `--mirror` is given) + +--init-submodule:: + After the clone is created, initialize and clone specified + submodules within, using their default settings. It is possible + to give multiple specifications by giving this argument multiple + times. This is equivalent to configure `submodule.defaultUpdateGroup` + and then running `git submodule update --init-default-path` + immediately after the clone is finished. --[no-]shallow-submodules:: All submodules which are cloned will be shallow with a depth of 1. diff --git a/builtin/clone.c b/builtin/clone.c index 5f867e6..668c1f4 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -53,6 +53,16 @@ static struct string_list option_config; static struct string_list option_reference; static int option_dissociate; static int max_jobs = -1; +static struct string_list init_submodules; + +static int init_submodules_cb(const struct option *opt, const char *arg, int unset) +{ + if (unset) + return -1; + + string_list_append((struct string_list *)opt->value, arg); + return 0; +} static struct option builtin_clone_options[] = { OPT__VERBOSITY(&option_verbosity), @@ -103,6 +113,9 @@ static struct option builtin_clone_options[] = { TRANSPORT_FAMILY_IPV4), OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"), TRANSPORT_FAMILY_IPV6), + OPT_CALLBACK(0, "init-submodule", &init_submodules, N_("<pathspec>"), + N_("clone specific submodules. Pass ultiple times for complex pathspecs"), + init_submodules_cb), OPT_END() }; @@ -734,14 +747,22 @@ static int checkout(void) err |= run_hook_le(NULL, "post-checkout", sha1_to_hex(null_sha1), sha1_to_hex(sha1), "1", NULL); - if (!err && option_recursive) { + if (!err && (option_recursive || init_submodules.nr > 0)) { struct argv_array args = ARGV_ARRAY_INIT; - argv_array_pushl(&args, "submodule", "update", "--init", "--recursive", NULL); + argv_array_pushl(&args, "submodule", "update", NULL); + + if (init_submodules.nr > 0) + argv_array_pushf(&args, "--init-default-path"); + else + argv_array_pushf(&args, "--init"); if (option_shallow_submodules == 1 || (option_shallow_submodules == -1 && option_depth)) argv_array_push(&args, "--depth=1"); + if (option_recursive) + argv_array_pushf(&args, "--recursive"); + if (max_jobs != -1) argv_array_pushf(&args, "--jobs=%d", max_jobs); @@ -883,6 +904,17 @@ int cmd_clone(int argc, const char **argv, const char *prefix) option_no_checkout = 1; } + if (init_submodules.nr > 0) { + struct string_list_item *item; + struct strbuf sb = STRBUF_INIT; + for_each_string_list_item(item, &init_submodules) { + strbuf_addf(&sb, "submodule.defaultUpdatePath=%s", + item->string); + string_list_append(&option_config, + strbuf_detach(&sb, NULL)); + } + } + if (!option_origin) option_origin = "origin"; diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 112d86a..a8d45cda 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -1170,4 +1170,85 @@ test_expect_success 'submodule update --init-default-path' ' test_cmp expect actual ' +cat <<EOF > expected + sub0 (test2) +-sub1 +-sub2 +-sub3 +EOF + +test_expect_success 'clone --init-submodule works' ' + test_when_finished "rm -rf multisuper_clone" && + git clone --recurse-submodules --init-submodule="sub0" multisuper multisuper_clone && + ( + cd multisuper_clone && + git submodule status |cut -c 1,43- >../actual + ) && + test_cmp actual expected +' + +cat <<EOF > expect +-sub0 + sub1 (test2) +-sub2 + sub3 (test2) +EOF +test_expect_success 'clone with multiple --init-submodule options' ' + test_when_finished "rm -rf multisuper_clone" && + git clone --recurse-submodules \ + --init-submodule="." \ + --init-submodule ":(exclude)sub0" \ + --init-submodule ":(exclude)sub2" \ + multisuper multisuper_clone && + ( + cd multisuper_clone && + git submodule status |cut -c1,43- >../actual + ) && + test_cmp expect actual +' + +cat <<EOF > expect +-sub0 + sub1 (test2) +-sub2 + sub3 (test2) +EOF + +cat <<EOF > expect2 +-sub0 + sub1 (test2) +-sub2 + sub3 (test2) +-sub4 + sub5 (test2) +EOF + +test_expect_success 'clone and subsequent updates correctly auto-initialize submodules' ' + test_when_finished "rm -rf multisuper_clone" && + git clone --recurse-submodules --init-submodule="." \ + --init-submodule ":(exclude)sub0" \ + --init-submodule ":(exclude)sub2" \ + --init-submodule ":(exclude)sub4" \ + multisuper multisuper_clone && + ( + cd multisuper_clone && + git submodule status |cut -c1,43- >../actual + ) && + test_cmp expect actual && + ( + cd multisuper && + git submodule add ../sub1 sub4 && + git submodule add ../sub1 sub5 && + git commit -m "add more submodules" + ) && + ( + cd multisuper_clone && + # obtain the new superproject + git pull && + git submodule update --init-default-path && + git submodule status |cut -c1,43- >../actual + ) && + test_cmp expect2 actual +' + test_done -- 2.9.0.rc0.2.g145fc64 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-05-26 20:47 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-05-21 0:28 [PATCH 0/2] Persistent submodule pathspec specification Stefan Beller 2016-05-21 0:28 ` [PATCH 1/2] submodule update: add `--init-default-path` switch Stefan Beller 2016-05-21 0:28 ` [PATCH 2/2] clone: add --init-submodule=<pathspec> switch Stefan Beller -- strict thread matches above, loose matches on Subject: below -- 2016-05-24 2:24 [PATCHv2 0/2] Persistent submodule pathspec specification Stefan Beller 2016-05-24 2:24 ` [PATCH 2/2] clone: add --init-submodule=<pathspec> switch Stefan Beller 2016-05-26 20:47 [PATCHv3 0/2] Persistent submodule pathspec specification Stefan Beller 2016-05-26 20:47 ` [PATCH 2/2] clone: add --init-submodule=<pathspec> switch Stefan Beller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).