builtin/submodule: propagate "--object-storage-format="
The ref storage format passed to git-clone(1) propagates to recursively cloned submodules, and git-submodule(1)'s "add" and "update" subcommands accept `--ref-storage-format=` so that newly cloned submodules can be set up with a specific format. Teach git-submodule(1) to also propagate the object storage format. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
1 parent
176165d380
commit
87a55d790c
6 files changed
+185
-7
No files matched your search
@@ -34,7 +34,7 @@ COMMANDS
|
||||
With no arguments, shows the status of existing submodules. Several
|
||||
subcommands are available to perform operations on the submodules.
|
||||
|
||||
`add [-b <branch>] [-f | --force] [--name <name>] [--reference <repository>] [--ref-storage-format <format>] [--depth <depth>] [--] <repository> [<path>]`::
|
||||
`add [-b <branch>] [-f | --force] [--name <name>] [--reference <repository>] [--ref-storage-format <format>] [--object-storage-format <format>] [--depth <depth>] [--] <repository> [<path>]`::
|
||||
Add the given repository as a submodule at the given path
|
||||
to the changeset to be committed next to the current
|
||||
project: the current project is termed the "superproject".
|
||||
@@ -75,6 +75,9 @@ URL in `.gitmodules`.
|
||||
If `--ref-storage-format <format>` or its deprecated alias `--ref-format
|
||||
<format>` is specified, the ref storage format of the newly cloned submodules
|
||||
will be set accordingly.
|
||||
+
|
||||
If `--object-storage-format <format>` is specified, the object storage format
|
||||
of the newly cloned submodules will be set accordingly.
|
||||
|
||||
`status [--cached] [--recursive] [--] [<path>...]`::
|
||||
Show the status of the submodules. This will print the SHA-1 of the
|
||||
@@ -140,7 +143,7 @@ If you really want to remove a submodule from the repository and commit
|
||||
that use linkgit:git-rm[1] instead. See linkgit:gitsubmodules[7] for removal
|
||||
options.
|
||||
|
||||
`update [--init] [--remote] [-N | --no-fetch] [--[no-]recommend-shallow] [-f | --force] [--checkout | --rebase | --merge] [--reference=<repository>] [--ref-storage-format=<format>] [--depth=<depth>] [--recursive] [--jobs <n>] [--[no-]single-branch] [--filter=<filter-spec>] [--] [<path>...]`::
|
||||
`update [--init] [--remote] [-N | --no-fetch] [--[no-]recommend-shallow] [-f | --force] [--checkout | --rebase | --merge] [--reference=<repository>] [--ref-storage-format=<format>] [--object-storage-format=<format>] [--depth=<depth>] [--recursive] [--jobs <n>] [--[no-]single-branch] [--filter=<filter-spec>] [--] [<path>...]`::
|
||||
+
|
||||
--
|
||||
Update the registered submodules to match what the superproject
|
||||
@@ -193,6 +196,9 @@ If `--ref-storage-format <format>` or its deprecated alias `--ref-format
|
||||
<format>` is specified, the ref storage format of the newly cloned submodules
|
||||
will be set accordingly.
|
||||
|
||||
If `--object-storage-format <format>` is specified, the object storage format
|
||||
of the newly cloned submodules will be set accordingly.
|
||||
|
||||
If `--filter <filter-spec>` is specified, the given partial clone filter will be
|
||||
applied to the submodule. See linkgit:git-rev-list[1] for details on filter
|
||||
specifications.
|
||||
|
||||
+14
-5
@@ -681,7 +681,8 @@ static int git_sparse_checkout_init(const char *repo)
|
||||
static int checkout(int submodule_progress,
|
||||
struct list_objects_filter_options *filter_options,
|
||||
int filter_submodules,
|
||||
enum ref_storage_format ref_storage_format)
|
||||
enum ref_storage_format ref_storage_format,
|
||||
enum object_storage_format object_storage_format)
|
||||
{
|
||||
struct object_id oid;
|
||||
char *head;
|
||||
@@ -771,6 +772,10 @@ static int checkout(int submodule_progress,
|
||||
strvec_pushf(&cmd.args, "--ref-storage-format=%s",
|
||||
ref_storage_format_to_name(ref_storage_format));
|
||||
|
||||
if (object_storage_format != OBJECT_STORAGE_FORMAT_UNKNOWN)
|
||||
strvec_pushf(&cmd.args, "--object-storage-format=%s",
|
||||
object_storage_format_to_name(object_storage_format));
|
||||
|
||||
if (filter_submodules && filter_options->choice)
|
||||
strvec_pushf(&cmd.args, "--filter=%s",
|
||||
expand_list_objects_filter_spec(filter_options));
|
||||
@@ -936,6 +941,7 @@ int cmd_clone(int argc,
|
||||
int submodule_progress;
|
||||
int filter_submodules = 0;
|
||||
int hash_algo;
|
||||
enum object_storage_format object_storage_format = OBJECT_STORAGE_FORMAT_UNKNOWN;
|
||||
enum ref_storage_format ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN;
|
||||
const int do_not_override_repo_unix_permissions = -1;
|
||||
int option_reject_shallow = -1; /* unspecified */
|
||||
@@ -1081,9 +1087,11 @@ int cmd_clone(int argc,
|
||||
die(_("unknown ref storage format '%s'"), ref_storage_format_uri);
|
||||
}
|
||||
|
||||
if (object_storage_format_uri &&
|
||||
object_storage_format_by_uri(object_storage_format_uri, NULL) == OBJECT_STORAGE_FORMAT_UNKNOWN)
|
||||
die(_("unknown object storage format '%s'"), object_storage_format_uri);
|
||||
if (object_storage_format_uri) {
|
||||
object_storage_format = object_storage_format_by_uri(object_storage_format_uri, NULL);
|
||||
if (object_storage_format == OBJECT_STORAGE_FORMAT_UNKNOWN)
|
||||
die(_("unknown object storage format '%s'"), object_storage_format_uri);
|
||||
}
|
||||
|
||||
if (option_mirror) {
|
||||
option_bare = 1;
|
||||
@@ -1701,7 +1709,8 @@ int cmd_clone(int argc,
|
||||
err = checkout(submodule_progress,
|
||||
&filter_options,
|
||||
filter_submodules,
|
||||
ref_storage_format);
|
||||
ref_storage_format,
|
||||
object_storage_format);
|
||||
|
||||
list_objects_filter_release(&filter_options);
|
||||
|
||||
|
||||
@@ -1739,6 +1739,7 @@ struct module_clone_data {
|
||||
int depth;
|
||||
struct list_objects_filter_options *filter_options;
|
||||
enum ref_storage_format ref_storage_format;
|
||||
enum object_storage_format object_storage_format;
|
||||
unsigned int quiet: 1;
|
||||
unsigned int progress: 1;
|
||||
unsigned int dissociate: 1;
|
||||
@@ -1748,6 +1749,7 @@ struct module_clone_data {
|
||||
#define MODULE_CLONE_DATA_INIT { \
|
||||
.single_branch = -1, \
|
||||
.ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN, \
|
||||
.object_storage_format = OBJECT_STORAGE_FORMAT_UNKNOWN, \
|
||||
}
|
||||
|
||||
struct submodule_alternate_setup {
|
||||
@@ -1948,6 +1950,9 @@ static int clone_submodule(const struct module_clone_data *clone_data,
|
||||
if (clone_data->ref_storage_format != REF_STORAGE_FORMAT_UNKNOWN)
|
||||
strvec_pushf(&cp.args, "--ref-storage-format=%s",
|
||||
ref_storage_format_to_name(clone_data->ref_storage_format));
|
||||
if (clone_data->object_storage_format != OBJECT_STORAGE_FORMAT_UNKNOWN)
|
||||
strvec_pushf(&cp.args, "--object-storage-format=%s",
|
||||
object_storage_format_to_name(clone_data->object_storage_format));
|
||||
if (clone_data->dissociate)
|
||||
strvec_push(&cp.args, "--dissociate");
|
||||
if (sm_gitdir && *sm_gitdir)
|
||||
@@ -2044,6 +2049,7 @@ static int module_clone(int argc, const char **argv, const char *prefix,
|
||||
struct string_list reference = STRING_LIST_INIT_NODUP;
|
||||
struct list_objects_filter_options filter_options =
|
||||
LIST_OBJECTS_FILTER_INIT;
|
||||
const char *object_storage_format = NULL;
|
||||
const char *ref_storage_format = NULL;
|
||||
|
||||
struct option module_clone_options[] = {
|
||||
@@ -2065,6 +2071,8 @@ static int module_clone(int argc, const char **argv, const char *prefix,
|
||||
OPT_STRING(0, "ref-storage-format", &ref_storage_format, N_("format"),
|
||||
N_("specify the reference storage format to use")),
|
||||
OPT_ALIAS_F(0, "ref-format", "ref-storage-format", PARSE_OPT_HIDDEN),
|
||||
OPT_STRING(0, "object-storage-format", &object_storage_format, N_("format"),
|
||||
N_("specify the object storage format to use")),
|
||||
OPT_BOOL(0, "dissociate", &dissociate,
|
||||
N_("use --reference only while cloning")),
|
||||
OPT_INTEGER(0, "depth", &clone_data.depth,
|
||||
@@ -2095,6 +2103,13 @@ static int module_clone(int argc, const char **argv, const char *prefix,
|
||||
if (clone_data.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
|
||||
die(_("unknown ref storage format '%s'"), ref_storage_format);
|
||||
}
|
||||
|
||||
if (object_storage_format) {
|
||||
clone_data.object_storage_format = object_storage_format_by_name(object_storage_format);
|
||||
if (clone_data.object_storage_format == OBJECT_STORAGE_FORMAT_UNKNOWN)
|
||||
die(_("unknown object storage format '%s'"), object_storage_format);
|
||||
}
|
||||
|
||||
clone_data.dissociate = !!dissociate;
|
||||
clone_data.quiet = !!quiet;
|
||||
clone_data.progress = !!progress;
|
||||
@@ -2201,6 +2216,7 @@ struct update_data {
|
||||
struct submodule_update_strategy update_strategy;
|
||||
struct list_objects_filter_options *filter_options;
|
||||
struct module_list list;
|
||||
enum object_storage_format object_storage_format;
|
||||
enum ref_storage_format ref_storage_format;
|
||||
int depth;
|
||||
int max_jobs;
|
||||
@@ -2365,6 +2381,9 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
|
||||
if (suc->update_data->ref_storage_format != REF_STORAGE_FORMAT_UNKNOWN)
|
||||
strvec_pushf(&child->args, "--ref-storage-format=%s",
|
||||
ref_storage_format_to_name(suc->update_data->ref_storage_format));
|
||||
if (suc->update_data->object_storage_format != OBJECT_STORAGE_FORMAT_UNKNOWN)
|
||||
strvec_pushf(&child->args, "--object-storage-format=%s",
|
||||
object_storage_format_to_name(suc->update_data->object_storage_format));
|
||||
strvec_pushl(&child->args, "--path", sub->path, NULL);
|
||||
strvec_pushl(&child->args, "--name", sub->name, NULL);
|
||||
strvec_pushl(&child->args, "--url", url, NULL);
|
||||
@@ -2809,6 +2828,9 @@ static void update_data_to_args(const struct update_data *update_data,
|
||||
if (update_data->ref_storage_format != REF_STORAGE_FORMAT_UNKNOWN)
|
||||
strvec_pushf(args, "--ref-storage-format=%s",
|
||||
ref_storage_format_to_name(update_data->ref_storage_format));
|
||||
if (update_data->object_storage_format)
|
||||
strvec_pushf(args, "--object-storage-format=%s",
|
||||
object_storage_format_to_name(update_data->object_storage_format));
|
||||
if (update_data->filter_options && update_data->filter_options->choice)
|
||||
strvec_pushf(args, "--filter=%s",
|
||||
expand_list_objects_filter_spec(
|
||||
@@ -2992,6 +3014,7 @@ static int module_update(int argc, const char **argv, const char *prefix,
|
||||
struct update_data opt = UPDATE_DATA_INIT;
|
||||
struct list_objects_filter_options filter_options =
|
||||
LIST_OBJECTS_FILTER_INIT;
|
||||
const char *object_storage_format = NULL;
|
||||
const char *ref_storage_format = NULL;
|
||||
int ret;
|
||||
struct option module_update_options[] = {
|
||||
@@ -3019,6 +3042,8 @@ static int module_update(int argc, const char **argv, const char *prefix,
|
||||
OPT_STRING(0, "ref-storage-format", &ref_storage_format, N_("format"),
|
||||
N_("specify the reference storage format to use")),
|
||||
OPT_ALIAS_F(0, "ref-format", "ref-storage-format", PARSE_OPT_HIDDEN),
|
||||
OPT_STRING(0, "object-storage-format", &object_storage_format, N_("format"),
|
||||
N_("specify the object storage format to use")),
|
||||
OPT_BOOL(0, "dissociate", &opt.dissociate,
|
||||
N_("use --reference only while cloning")),
|
||||
OPT_INTEGER(0, "depth", &opt.depth,
|
||||
@@ -3067,6 +3092,11 @@ static int module_update(int argc, const char **argv, const char *prefix,
|
||||
if (opt.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
|
||||
die(_("unknown ref storage format '%s'"), ref_storage_format);
|
||||
}
|
||||
if (object_storage_format) {
|
||||
opt.object_storage_format = object_storage_format_by_name(object_storage_format);
|
||||
if (opt.object_storage_format == OBJECT_STORAGE_FORMAT_UNKNOWN)
|
||||
die(_("unknown object storage format '%s'"), object_storage_format);
|
||||
}
|
||||
|
||||
opt.filter_options = &filter_options;
|
||||
opt.prefix = prefix;
|
||||
@@ -3371,6 +3401,7 @@ struct add_data {
|
||||
const char *sm_name;
|
||||
const char *repo;
|
||||
const char *realrepo;
|
||||
enum object_storage_format object_storage_format;
|
||||
enum ref_storage_format ref_storage_format;
|
||||
int depth;
|
||||
unsigned int force: 1;
|
||||
@@ -3477,6 +3508,7 @@ static int add_submodule(const struct add_data *add_data)
|
||||
string_list_append(&reference, p)->util = p;
|
||||
}
|
||||
clone_data.ref_storage_format = add_data->ref_storage_format;
|
||||
clone_data.object_storage_format = add_data->object_storage_format;
|
||||
clone_data.dissociate = add_data->dissociate;
|
||||
if (add_data->depth >= 0)
|
||||
clone_data.depth = add_data->depth;
|
||||
@@ -3652,6 +3684,7 @@ static int module_add(int argc, const char **argv, const char *prefix,
|
||||
{
|
||||
int force = 0, quiet = 0, progress = 0, dissociate = 0;
|
||||
struct add_data add_data = ADD_DATA_INIT;
|
||||
const char *object_storage_format = NULL;
|
||||
const char *ref_storage_format = NULL;
|
||||
char *to_free = NULL;
|
||||
const struct submodule *existing;
|
||||
@@ -3669,6 +3702,8 @@ static int module_add(int argc, const char **argv, const char *prefix,
|
||||
OPT_STRING(0, "ref-storage-format", &ref_storage_format, N_("format"),
|
||||
N_("specify the reference storage format to use")),
|
||||
OPT_ALIAS_F(0, "ref-format", "ref-storage-format", PARSE_OPT_HIDDEN),
|
||||
OPT_STRING(0, "object-storage-format", &object_storage_format, N_("format"),
|
||||
N_("specify the object storage format to use")),
|
||||
OPT_BOOL(0, "dissociate", &dissociate, N_("borrow the objects from reference repositories")),
|
||||
OPT_STRING(0, "name", &add_data.sm_name, N_("name"),
|
||||
N_("sets the submodule's name to the given string "
|
||||
@@ -3700,6 +3735,11 @@ static int module_add(int argc, const char **argv, const char *prefix,
|
||||
if (add_data.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
|
||||
die(_("unknown ref storage format '%s'"), ref_storage_format);
|
||||
}
|
||||
if (object_storage_format) {
|
||||
add_data.object_storage_format = object_storage_format_by_name(object_storage_format);
|
||||
if (add_data.object_storage_format == OBJECT_STORAGE_FORMAT_UNKNOWN)
|
||||
die(_("unknown object storage format '%s'"), object_storage_format);
|
||||
}
|
||||
|
||||
add_data.repo = argv[0];
|
||||
if (argc == 1)
|
||||
|
||||
@@ -103,6 +103,14 @@ cmd_add()
|
||||
--ref-format=*|--ref-storage-format=*)
|
||||
ref_storage_format="$1"
|
||||
;;
|
||||
--object-storage-format)
|
||||
case "$2" in '') usage ;; esac
|
||||
object_storage_format="--object-storage-format=$2"
|
||||
shift
|
||||
;;
|
||||
--object-storage-format=*)
|
||||
object_storage_format="$1"
|
||||
;;
|
||||
--dissociate)
|
||||
dissociate=$1
|
||||
;;
|
||||
@@ -148,6 +156,7 @@ cmd_add()
|
||||
${branch:+"$branch"} \
|
||||
${reference:+"$reference"} \
|
||||
${ref_storage_format:+"$ref_storage_format"} \
|
||||
${object_storage_format:+"$object_storage_format"} \
|
||||
$dissociate \
|
||||
${name:+"$name"} \
|
||||
${depth:+"$depth"} \
|
||||
@@ -310,6 +319,14 @@ cmd_update()
|
||||
--ref-format=*|--ref-storage-format=*)
|
||||
ref_storage_format="$1"
|
||||
;;
|
||||
--object-storage-format)
|
||||
case "$2" in '') usage ;; esac
|
||||
object_storage_format="--object-storage-format=$2"
|
||||
shift
|
||||
;;
|
||||
--object-storage-format=*)
|
||||
object_storage_format="$1"
|
||||
;;
|
||||
--reference)
|
||||
case "$2" in '') usage ;; esac
|
||||
reference="--reference=$2"
|
||||
@@ -386,6 +403,7 @@ cmd_update()
|
||||
$merge \
|
||||
$checkout \
|
||||
${ref_storage_format:+"$ref_storage_format"} \
|
||||
${object_storage_format:+"$object_storage_format"} \
|
||||
${reference:+"$reference"} \
|
||||
$dissociate \
|
||||
${depth:+"$depth"} \
|
||||
|
||||
@@ -926,6 +926,7 @@ integration_tests = [
|
||||
't7424-submodule-mixed-ref-formats.sh',
|
||||
't7425-submodule-gitdir-path-extension.sh',
|
||||
't7426-submodule-get-default-remote.sh',
|
||||
't7427-submodule-object-storage-format.sh',
|
||||
't7450-bad-git-dotfiles.sh',
|
||||
't7500-commit-template-squash-signoff.sh',
|
||||
't7501-commit-basic-functionality.sh',
|
||||
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='submodules handle the object storage format'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_object_storage_format () {
|
||||
echo "$2" >expect &&
|
||||
git -C "$1" rev-parse --show-object-storage-format >actual &&
|
||||
test_cmp expect actual
|
||||
}
|
||||
|
||||
test_expect_success 'setup' '
|
||||
git config set --global protocol.file.allow always
|
||||
'
|
||||
|
||||
test_expect_success 'add existing repository with different object storage format' '
|
||||
test_when_finished "rm -rf parent" &&
|
||||
|
||||
git init parent &&
|
||||
(
|
||||
cd parent &&
|
||||
test_commit parent &&
|
||||
git init --object-storage-format=files://objs submodule &&
|
||||
test_commit -C submodule submodule &&
|
||||
git submodule add ./submodule &&
|
||||
test_object_storage_format submodule files://objs
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'add submodules with explicit files storage format' '
|
||||
test_when_finished "rm -rf submodule upstream" &&
|
||||
|
||||
git init submodule &&
|
||||
test_commit -C submodule submodule-initial &&
|
||||
git init upstream &&
|
||||
test_object_storage_format upstream files &&
|
||||
git -C upstream submodule add --object-storage-format=files "file://$(pwd)/submodule" &&
|
||||
test_object_storage_format upstream/submodule files
|
||||
'
|
||||
|
||||
test_expect_success 'add submodules with garbage object storage format' '
|
||||
test_when_finished "rm -rf submodule upstream" &&
|
||||
|
||||
git init submodule &&
|
||||
test_commit -C submodule submodule-initial &&
|
||||
git init upstream &&
|
||||
cat >expect <<-EOF &&
|
||||
fatal: unknown object storage format ${SQ}garbage${SQ}
|
||||
EOF
|
||||
test_must_fail git -C upstream submodule add --object-storage-format=garbage "file://$(pwd)/submodule" 2>err &&
|
||||
test_cmp expect err
|
||||
'
|
||||
|
||||
test_expect_success 'add submodules with object storage payload is rejected' '
|
||||
test_when_finished "rm -rf submodule upstream" &&
|
||||
|
||||
git init submodule &&
|
||||
test_commit -C submodule submodule-initial &&
|
||||
git init upstream &&
|
||||
cat >expect <<-EOF &&
|
||||
fatal: unknown object storage format ${SQ}files://objs${SQ}
|
||||
EOF
|
||||
test_must_fail git -C upstream submodule add --object-storage-format=files://objs "file://$(pwd)/submodule" 2>err &&
|
||||
test_cmp expect err
|
||||
'
|
||||
|
||||
test_expect_success 'recursive clone propagates object storage format' '
|
||||
test_when_finished "rm -rf submodule upstream downstream" &&
|
||||
|
||||
git init submodule &&
|
||||
test_commit -C submodule submodule-initial &&
|
||||
git init upstream &&
|
||||
git -C upstream submodule add "file://$(pwd)/submodule" &&
|
||||
git -C upstream commit -am "add submodule" &&
|
||||
|
||||
test_object_storage_format upstream files &&
|
||||
test_object_storage_format upstream/submodule files &&
|
||||
|
||||
git clone --object-storage-format=files://objs --recurse-submodules \
|
||||
upstream downstream &&
|
||||
test_object_storage_format downstream files://objs &&
|
||||
test_object_storage_format downstream/submodule files &&
|
||||
test_path_is_dir downstream/.git/objs/pack &&
|
||||
test_path_is_dir downstream/.git/modules/submodule/objects/pack
|
||||
'
|
||||
|
||||
test_expect_success 'clone submodules with explicit object storage format' '
|
||||
test_when_finished "rm -rf submodule upstream downstream" &&
|
||||
|
||||
git init submodule &&
|
||||
test_commit -C submodule submodule-initial &&
|
||||
git init upstream &&
|
||||
git -C upstream submodule add "file://$(pwd)/submodule" &&
|
||||
git -C upstream commit -m "upstream submodule" &&
|
||||
|
||||
git clone --no-recurse-submodules "file://$(pwd)/upstream" downstream &&
|
||||
test_object_storage_format downstream files &&
|
||||
git -C downstream submodule update --init --object-storage-format=files &&
|
||||
test_object_storage_format downstream/submodule files &&
|
||||
test_path_is_dir downstream/.git/modules/submodule/objects/pack
|
||||
'
|
||||
|
||||
test_done
|
||||
Reference in new issue
Block a user