builtin/submodule: allow "add" to use different ref storage format

Same as with "clone", users may want to add a submodule to a repository
with a non-default ref storage format. Wire up a new `--ref-format=`
option that works the same as for `git submodule clone`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Patrick Steinhardt
2024-08-08 09:35:47 +02:00
committed by Junio C Hamano
parent fb99dded31
commit c369fc46d0
4 changed files with 39 additions and 2 deletions

View File

@ -34,7 +34,7 @@ COMMANDS
With no arguments, shows the status of existing submodules. Several With no arguments, shows the status of existing submodules. Several
subcommands are available to perform operations on the submodules. subcommands are available to perform operations on the submodules.
add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--depth <depth>] [--] <repository> [<path>]:: add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--ref-format <format>] [--depth <depth>] [--] <repository> [<path>]::
Add the given repository as a submodule at the given path Add the given repository as a submodule at the given path
to the changeset to be committed next to the current to the changeset to be committed next to the current
project: the current project is termed the "superproject". project: the current project is termed the "superproject".
@ -71,6 +71,9 @@ submodule repositories will be kept together in the same relative
location, and only the superproject's URL needs to be provided. location, and only the superproject's URL needs to be provided.
git-submodule will correctly locate the submodule using the relative git-submodule will correctly locate the submodule using the relative
URL in `.gitmodules`. URL in `.gitmodules`.
+
If `--ref-format <format>` is specified, the ref storage format of newly
cloned submodules will be set accordingly.
status [--cached] [--recursive] [--] [<path>...]:: status [--cached] [--recursive] [--] [<path>...]::
Show the status of the submodules. This will print the SHA-1 of the Show the status of the submodules. This will print the SHA-1 of the

View File

@ -3128,13 +3128,17 @@ struct add_data {
const char *sm_name; const char *sm_name;
const char *repo; const char *repo;
const char *realrepo; const char *realrepo;
enum ref_storage_format ref_storage_format;
int depth; int depth;
unsigned int force: 1; unsigned int force: 1;
unsigned int quiet: 1; unsigned int quiet: 1;
unsigned int progress: 1; unsigned int progress: 1;
unsigned int dissociate: 1; unsigned int dissociate: 1;
}; };
#define ADD_DATA_INIT { .depth = -1 } #define ADD_DATA_INIT { \
.depth = -1, \
.ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN, \
}
static void append_fetch_remotes(struct strbuf *msg, const char *git_dir_path) static void append_fetch_remotes(struct strbuf *msg, const char *git_dir_path)
{ {
@ -3228,6 +3232,7 @@ static int add_submodule(const struct add_data *add_data)
string_list_append(&reference, p)->util = p; string_list_append(&reference, p)->util = p;
} }
clone_data.ref_storage_format = add_data->ref_storage_format;
clone_data.dissociate = add_data->dissociate; clone_data.dissociate = add_data->dissociate;
if (add_data->depth >= 0) if (add_data->depth >= 0)
clone_data.depth = xstrfmt("%d", add_data->depth); clone_data.depth = xstrfmt("%d", add_data->depth);
@ -3392,6 +3397,7 @@ static int module_add(int argc, const char **argv, const char *prefix)
{ {
int force = 0, quiet = 0, progress = 0, dissociate = 0; int force = 0, quiet = 0, progress = 0, dissociate = 0;
struct add_data add_data = ADD_DATA_INIT; struct add_data add_data = ADD_DATA_INIT;
const char *ref_storage_format = NULL;
char *to_free = NULL; char *to_free = NULL;
struct option options[] = { struct option options[] = {
OPT_STRING('b', "branch", &add_data.branch, N_("branch"), OPT_STRING('b', "branch", &add_data.branch, N_("branch"),
@ -3402,6 +3408,8 @@ static int module_add(int argc, const char **argv, const char *prefix)
OPT_BOOL(0, "progress", &progress, N_("force cloning progress")), OPT_BOOL(0, "progress", &progress, N_("force cloning progress")),
OPT_STRING(0, "reference", &add_data.reference_path, N_("repository"), OPT_STRING(0, "reference", &add_data.reference_path, N_("repository"),
N_("reference repository")), N_("reference repository")),
OPT_STRING(0, "ref-format", &ref_storage_format, N_("format"),
N_("specify the reference format to use")),
OPT_BOOL(0, "dissociate", &dissociate, N_("borrow the objects from reference repositories")), OPT_BOOL(0, "dissociate", &dissociate, N_("borrow the objects from reference repositories")),
OPT_STRING(0, "name", &add_data.sm_name, N_("name"), OPT_STRING(0, "name", &add_data.sm_name, N_("name"),
N_("sets the submodule's name to the given string " N_("sets the submodule's name to the given string "
@ -3428,6 +3436,12 @@ static int module_add(int argc, const char **argv, const char *prefix)
if (argc == 0 || argc > 2) if (argc == 0 || argc > 2)
usage_with_options(usage, options); usage_with_options(usage, options);
if (ref_storage_format) {
add_data.ref_storage_format = ref_storage_format_by_name(ref_storage_format);
if (add_data.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
die(_("unknown ref storage format '%s'"), ref_storage_format);
}
add_data.repo = argv[0]; add_data.repo = argv[0];
if (argc == 1) if (argc == 1)
add_data.sm_path = git_url_basename(add_data.repo, 0, 0); add_data.sm_path = git_url_basename(add_data.repo, 0, 0);

View File

@ -94,6 +94,14 @@ cmd_add()
--reference=*) --reference=*)
reference_path="${1#--reference=}" reference_path="${1#--reference=}"
;; ;;
--ref-format)
case "$2" in '') usage ;; esac
ref_format="--ref-format=$2"
shift
;;
--ref-format=*)
ref_format="$1"
;;
--dissociate) --dissociate)
dissociate=1 dissociate=1
;; ;;
@ -135,6 +143,7 @@ cmd_add()
${progress:+"--progress"} \ ${progress:+"--progress"} \
${branch:+--branch "$branch"} \ ${branch:+--branch "$branch"} \
${reference_path:+--reference "$reference_path"} \ ${reference_path:+--reference "$reference_path"} \
${ref_format:+"$ref_format"} \
${dissociate:+--dissociate} \ ${dissociate:+--dissociate} \
${custom_name:+--name "$custom_name"} \ ${custom_name:+--name "$custom_name"} \
${depth:+"$depth"} \ ${depth:+"$depth"} \

View File

@ -37,6 +37,17 @@ test_expect_success 'add existing repository with different ref storage format'
) )
' '
test_expect_success 'add submodules with different ref storage format' '
test_when_finished "rm -rf submodule upstream" &&
git init submodule &&
test_commit -C submodule submodule-initial &&
git init upstream &&
test_ref_format upstream "$GIT_DEFAULT_REF_FORMAT" &&
git -C upstream submodule add --ref-format="$OTHER_FORMAT" "file://$(pwd)/submodule" &&
test_ref_format upstream/submodule "$OTHER_FORMAT"
'
test_expect_success 'recursive clone propagates ref storage format' ' test_expect_success 'recursive clone propagates ref storage format' '
test_when_finished "rm -rf submodule upstream downstream" && test_when_finished "rm -rf submodule upstream downstream" &&