When we have a another clone of a superproject, we may want to
mirror the submodules using alternates. Introduce an option
`--super-reference` that let's a user point to another superproject,
which is assumed to have the same structure as the one they are
running the "submodule update" command from and has all submodules
checked out to borrow the submodule objects from within the other
superprojects git directory.

Signed-off-by: Stefan Beller <sbel...@google.com>
---
 Documentation/git-submodule.txt |  8 +++++++-
 builtin/submodule--helper.c     | 14 +++++++++++++-
 git-submodule.sh                | 10 ++++++++++
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index bf3bb37..6f2f873 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -16,7 +16,7 @@ SYNOPSIS
 'git submodule' [--quiet] deinit [-f|--force] (--all|[--] <path>...)
 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch]
              [--[no-]recommend-shallow] [-f|--force] [--rebase|--merge]
-             [--reference <repository>] [--depth <depth>] [--recursive]
+             [--[super-]reference <repository>] [--depth <depth>] [--recursive]
              [--jobs <n>] [--] [<path>...]
 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]
              [commit] [--] [<path>...]
@@ -370,6 +370,12 @@ the submodule itself.
        This option is only valid for add and update commands.  These
        commands sometimes need to clone a remote repository. In this case,
        this option will be passed to the linkgit:git-clone[1] command.
+
+--super-reference <superproject repository>::
+       This option is only valid for the update command. When update needs
+       to clone a repository, a reference will be passed to the clone command
+       that points at the submodule path inside the reference superproject.
+
 +
 *NOTE*: Do *not* use this option unless you have read the note
 for linkgit:git-clone[1]'s `--reference` and `--shared` options carefully.
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index b7710a7..ea6b27c 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -584,6 +584,7 @@ struct submodule_update_clone {
        int quiet;
        int recommend_shallow;
        struct string_list references;
+       struct string_list super_references;
        const char *depth;
        const char *recursive_prefix;
        const char *prefix;
@@ -600,7 +601,7 @@ struct submodule_update_clone {
 };
 #define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
        SUBMODULE_UPDATE_STRATEGY_INIT, 0, -1, STRING_LIST_INIT_DUP, \
-       NULL, NULL, NULL, \
+       STRING_LIST_INIT_DUP, NULL, NULL, NULL, \
        STRING_LIST_INIT_DUP, 0, NULL, 0, 0}
 
 
@@ -715,6 +716,15 @@ static int prepare_to_clone_next_submodule(const struct 
cache_entry *ce,
                for_each_string_list_item(item, &suc->references)
                        argv_array_pushl(&child->args, "--reference", 
item->string, NULL);
        }
+       if (suc->super_references.nr) {
+               struct string_list_item *item;
+               for_each_string_list_item(item, &suc->super_references) {
+                       strbuf_reset(&sb);
+                       argv_array_pushf(&child->args, "--reference=%s/%s",
+                                        relative_path(item->string, 
suc->prefix, &sb),
+                                        sub->path);
+               }
+       }
        if (suc->depth)
                argv_array_push(&child->args, suc->depth);
 
@@ -835,6 +845,8 @@ static int update_clone(int argc, const char **argv, const 
char *prefix)
                           N_("rebase, merge, checkout or none")),
                OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"),
                           N_("reference repository")),
+               OPT_STRING_LIST(0, "super-reference", &suc.super_references, 
N_("repo"),
+                          N_("superproject of a reference repository")),
                OPT_STRING(0, "depth", &suc.depth, "<depth>",
                           N_("Create a shallow clone truncated to the "
                              "specified number of revisions")),
diff --git a/git-submodule.sh b/git-submodule.sh
index 3b412f5..17f4ace 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -34,6 +34,7 @@ command=
 branch=
 force=
 reference=
+superreference=
 cached=
 recursive=
 init=
@@ -520,6 +521,14 @@ cmd_update()
                --reference=*)
                        reference="$1"
                        ;;
+               --super-reference)
+                       case "$2" in '') usage ;; esac
+                       superreference="--super-reference=$2"
+                       shift
+                       ;;
+               --super-reference=*)
+                       superreference="$1"
+                       ;;
                -m|--merge)
                        update="merge"
                        ;;
@@ -576,6 +585,7 @@ cmd_update()
                ${prefix:+--recursive-prefix "$prefix"} \
                ${update:+--update "$update"} \
                ${reference:+"$reference"} \
+               ${superreference:+"$superreference"} \
                ${depth:+--depth "$depth"} \
                ${recommend_shallow:+"$recommend_shallow"} \
                ${jobs:+$jobs} \
-- 
2.9.2.572.g9d9644e.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to