aboutsummaryrefslogtreecommitdiffstats
path: root/builtin/submodule--helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/submodule--helper.c')
-rw-r--r--builtin/submodule--helper.c117
1 files changed, 94 insertions, 23 deletions
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index f1218a1995..dc89488a7d 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1,9 +1,10 @@
+#define USE_THE_REPOSITORY_VARIABLE
#include "builtin.h"
#include "abspath.h"
#include "environment.h"
#include "gettext.h"
#include "hex.h"
-#include "repository.h"
+
#include "config.h"
#include "parse-options.h"
#include "quote.h"
@@ -363,9 +364,13 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
if (!info->quiet)
printf(_("Entering '%s'\n"), displaypath);
- if (info->argv[0] && run_command(&cp))
- die(_("run_command returned non-zero status for %s\n."),
- displaypath);
+ if (info->argv[0]) {
+ if (run_command(&cp))
+ die(_("run_command returned non-zero status for %s\n."),
+ displaypath);
+ } else {
+ child_process_clear(&cp);
+ }
if (info->recursive) {
struct child_process cpr = CHILD_PROCESS_INIT;
@@ -608,6 +613,7 @@ static void print_status(unsigned int flags, char state, const char *path,
}
static int handle_submodule_head_ref(const char *refname UNUSED,
+ const char *referent UNUSED,
const struct object_id *oid,
int flags UNUSED,
void *cb_data)
@@ -671,7 +677,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
setup_revisions(diff_files_args.nr, diff_files_args.v, &rev, &opt);
run_diff_files(&rev, 0);
- if (!diff_result_code(&rev.diffopt)) {
+ if (!diff_result_code(&rev)) {
print_status(flags, ' ', path, ce_oid,
displaypath);
} else if (!(flags & OPT_CACHED)) {
@@ -694,6 +700,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
if (flags & OPT_RECURSIVE) {
struct child_process cpr = CHILD_PROCESS_INIT;
+ int res;
cpr.git_cmd = 1;
cpr.dir = path;
@@ -709,7 +716,10 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
if (flags & OPT_QUIET)
strvec_push(&cpr.args, "--quiet");
- if (run_command(&cpr))
+ res = run_command(&cpr);
+ if (res == SIGPIPE + 128)
+ raise(SIGPIPE);
+ else if (res)
die(_("failed to recurse into submodule '%s'"), path);
}
@@ -916,7 +926,7 @@ static void generate_submodule_summary(struct summary_cb *info,
} else {
/* for a submodule removal (mode:0000000), don't warn */
if (p->mod_dst)
- warning(_("unexpected mode %o\n"), p->mod_dst);
+ warning(_("unexpected mode %o"), p->mod_dst);
}
}
@@ -1455,7 +1465,7 @@ static void deinit_submodule(const char *path, const char *prefix,
* remove the whole section so we have a clean state when
* the user later decides to init this submodule again
*/
- git_config_rename_section_in_file(NULL, sub_key, NULL);
+ repo_config_rename_section_in_file(the_repository, NULL, sub_key, NULL);
if (!(flags & OPT_QUIET))
printf(_("Submodule '%s' (%s) unregistered for path '%s'\n"),
sub->name, sub->url, displaypath);
@@ -1530,8 +1540,9 @@ struct module_clone_data {
const char *path;
const char *name;
const char *url;
- const char *depth;
+ int depth;
struct list_objects_filter_options *filter_options;
+ enum ref_storage_format ref_storage_format;
unsigned int quiet: 1;
unsigned int progress: 1;
unsigned int dissociate: 1;
@@ -1540,6 +1551,7 @@ struct module_clone_data {
};
#define MODULE_CLONE_DATA_INIT { \
.single_branch = -1, \
+ .ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN, \
}
struct submodule_alternate_setup {
@@ -1614,6 +1626,8 @@ static int add_possible_reference_from_superproject(
; /* nothing */
}
}
+
+ strbuf_release(&err);
strbuf_release(&sb);
}
@@ -1706,7 +1720,7 @@ static int clone_submodule(const struct module_clone_data *clone_data,
exit(128);
if (!is_absolute_path(clone_data->path))
- clone_data_path = to_free = xstrfmt("%s/%s", get_git_work_tree(),
+ clone_data_path = to_free = xstrfmt("%s/%s", repo_get_work_tree(the_repository),
clone_data->path);
if (validate_submodule_git_dir(sm_gitdir, clone_data->name) < 0)
@@ -1729,8 +1743,8 @@ static int clone_submodule(const struct module_clone_data *clone_data,
strvec_push(&cp.args, "--quiet");
if (clone_data->progress)
strvec_push(&cp.args, "--progress");
- if (clone_data->depth && *(clone_data->depth))
- strvec_pushl(&cp.args, "--depth", clone_data->depth, NULL);
+ if (clone_data->depth > 0)
+ strvec_pushf(&cp.args, "--depth=%d", clone_data->depth);
if (reference->nr) {
struct string_list_item *item;
@@ -1738,6 +1752,9 @@ static int clone_submodule(const struct module_clone_data *clone_data,
strvec_pushl(&cp.args, "--reference",
item->string, NULL);
}
+ if (clone_data->ref_storage_format != REF_STORAGE_FORMAT_UNKNOWN)
+ strvec_pushf(&cp.args, "--ref-format=%s",
+ ref_storage_format_to_name(clone_data->ref_storage_format));
if (clone_data->dissociate)
strvec_push(&cp.args, "--dissociate");
if (sm_gitdir && *sm_gitdir)
@@ -1832,6 +1849,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 *ref_storage_format = NULL;
struct option module_clone_options[] = {
OPT_STRING(0, "prefix", &clone_data.prefix,
@@ -1849,10 +1867,11 @@ static int module_clone(int argc, const char **argv, const char *prefix)
OPT_STRING_LIST(0, "reference", &reference,
N_("repo"),
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_("use --reference only while cloning")),
- OPT_STRING(0, "depth", &clone_data.depth,
- N_("string"),
+ OPT_INTEGER(0, "depth", &clone_data.depth,
N_("depth for shallow clones")),
OPT__QUIET(&quiet, "suppress output for cloning a submodule"),
OPT_BOOL(0, "progress", &progress,
@@ -1875,6 +1894,11 @@ static int module_clone(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, module_clone_options,
git_submodule_helper_usage, 0);
+ if (ref_storage_format) {
+ clone_data.ref_storage_format = ref_storage_format_by_name(ref_storage_format);
+ if (clone_data.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
+ die(_("unknown ref storage format '%s'"), ref_storage_format);
+ }
clone_data.dissociate = !!dissociate;
clone_data.quiet = !!quiet;
clone_data.progress = !!progress;
@@ -1974,6 +1998,7 @@ struct update_data {
struct submodule_update_strategy update_strategy;
struct list_objects_filter_options *filter_options;
struct module_list list;
+ enum ref_storage_format ref_storage_format;
int depth;
int max_jobs;
int single_branch;
@@ -1997,6 +2022,7 @@ struct update_data {
#define UPDATE_DATA_INIT { \
.update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \
.list = MODULE_LIST_INIT, \
+ .ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN, \
.recommend_shallow = -1, \
.references = STRING_LIST_INIT_DUP, \
.single_branch = -1, \
@@ -2006,6 +2032,7 @@ struct update_data {
static void update_data_release(struct update_data *ud)
{
free(ud->displaypath);
+ submodule_update_strategy_release(&ud->update_strategy);
module_list_release(&ud->list);
}
@@ -2132,6 +2159,9 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
expand_list_objects_filter_spec(suc->update_data->filter_options));
if (suc->update_data->require_init)
strvec_push(&child->args, "--require-init");
+ if (suc->update_data->ref_storage_format != REF_STORAGE_FORMAT_UNKNOWN)
+ strvec_pushf(&child->args, "--ref-format=%s",
+ ref_storage_format_to_name(suc->update_data->ref_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);
@@ -2269,6 +2299,7 @@ static int is_tip_reachable(const char *path, const struct object_id *oid)
struct child_process cp = CHILD_PROCESS_INIT;
struct strbuf rev = STRBUF_INIT;
char *hex = oid_to_hex(oid);
+ int reachable;
cp.git_cmd = 1;
cp.dir = path;
@@ -2278,9 +2309,12 @@ static int is_tip_reachable(const char *path, const struct object_id *oid)
prepare_submodule_repo_env(&cp.env);
if (capture_command(&cp, &rev, GIT_MAX_HEXSZ + 1) || rev.len)
- return 0;
+ reachable = 0;
+ else
+ reachable = 1;
- return 1;
+ strbuf_release(&rev);
+ return reachable;
}
static int fetch_in_submodule(const char *module_path, int depth, int quiet,
@@ -2562,6 +2596,9 @@ static void update_data_to_args(const struct update_data *update_data,
for_each_string_list_item(item, &update_data->references)
strvec_pushl(args, "--reference", item->string, NULL);
}
+ if (update_data->ref_storage_format != REF_STORAGE_FORMAT_UNKNOWN)
+ strvec_pushf(args, "--ref-format=%s",
+ ref_storage_format_to_name(update_data->ref_storage_format));
if (update_data->filter_options && update_data->filter_options->choice)
strvec_pushf(args, "--filter=%s",
expand_list_objects_filter_spec(
@@ -2616,15 +2653,20 @@ static int update_submodule(struct update_data *update_data)
if (!update_data->nofetch) {
if (fetch_in_submodule(update_data->sm_path, update_data->depth,
- 0, NULL))
+ 0, NULL)) {
+ free(remote_ref);
return die_message(_("Unable to fetch in submodule path '%s'"),
update_data->sm_path);
+ }
}
if (repo_resolve_gitlink_ref(the_repository, update_data->sm_path,
- remote_ref, &update_data->oid))
- return die_message(_("Unable to find %s revision in submodule path '%s'"),
- remote_ref, update_data->sm_path);
+ remote_ref, &update_data->oid)) {
+ ret = die_message(_("Unable to find %s revision in submodule path '%s'"),
+ remote_ref, update_data->sm_path);
+ free(remote_ref);
+ return ret;
+ }
free(remote_ref);
}
@@ -2737,6 +2779,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 *ref_storage_format = NULL;
int ret;
struct option module_update_options[] = {
OPT__SUPER_PREFIX(&opt.super_prefix),
@@ -2760,6 +2803,8 @@ static int module_update(int argc, const char **argv, const char *prefix)
SM_UPDATE_REBASE),
OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"),
N_("reference repository")),
+ OPT_STRING(0, "ref-format", &ref_storage_format, N_("format"),
+ N_("specify the reference format to use")),
OPT_BOOL(0, "dissociate", &opt.dissociate,
N_("use --reference only while cloning")),
OPT_INTEGER(0, "depth", &opt.depth,
@@ -2803,6 +2848,12 @@ static int module_update(int argc, const char **argv, const char *prefix)
module_update_options);
}
+ if (ref_storage_format) {
+ opt.ref_storage_format = ref_storage_format_by_name(ref_storage_format);
+ if (opt.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
+ die(_("unknown ref storage format '%s'"), ref_storage_format);
+ }
+
opt.filter_options = &filter_options;
opt.prefix = prefix;
@@ -2924,7 +2975,9 @@ static int push_check(int argc, const char **argv, const char *prefix UNUSED)
rs->src);
}
}
+
refspec_clear(&refspec);
+ free_refs(local_refs);
}
free(head);
@@ -3098,13 +3151,17 @@ struct add_data {
const char *sm_name;
const char *repo;
const char *realrepo;
+ enum ref_storage_format ref_storage_format;
int depth;
unsigned int force: 1;
unsigned int quiet: 1;
unsigned int progress: 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)
{
@@ -3198,9 +3255,10 @@ 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.dissociate = add_data->dissociate;
if (add_data->depth >= 0)
- clone_data.depth = xstrfmt("%d", add_data->depth);
+ clone_data.depth = add_data->depth;
if (clone_submodule(&clone_data, &reference))
goto cleanup;
@@ -3223,6 +3281,7 @@ static int add_submodule(const struct add_data *add_data)
die(_("unable to checkout submodule '%s'"), add_data->sm_path);
}
ret = 0;
+
cleanup:
string_list_clear(&reference, 1);
return ret;
@@ -3362,6 +3421,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 *ref_storage_format = NULL;
char *to_free = NULL;
struct option options[] = {
OPT_STRING('b', "branch", &add_data.branch, N_("branch"),
@@ -3372,6 +3432,8 @@ static int module_add(int argc, const char **argv, const char *prefix)
OPT_BOOL(0, "progress", &progress, N_("force cloning progress")),
OPT_STRING(0, "reference", &add_data.reference_path, N_("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_STRING(0, "name", &add_data.sm_name, N_("name"),
N_("sets the submodule's name to the given string "
@@ -3398,6 +3460,12 @@ static int module_add(int argc, const char **argv, const char *prefix)
if (argc == 0 || argc > 2)
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];
if (argc == 1)
add_data.sm_path = git_url_basename(add_data.repo, 0, 0);
@@ -3479,7 +3547,10 @@ cleanup:
return ret;
}
-int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
+int cmd_submodule__helper(int argc,
+ const char **argv,
+ const char *prefix,
+ struct repository *repo UNUSED)
{
parse_opt_subcommand_fn *fn = NULL;
const char *const usage[] = {