diff options
Diffstat (limited to 'builtin/submodule--helper.c')
| -rw-r--r-- | builtin/submodule--helper.c | 150 |
1 files changed, 119 insertions, 31 deletions
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 673810d2c0..19e5878381 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; @@ -394,7 +399,8 @@ cleanup: free(displaypath); } -static int module_foreach(int argc, const char **argv, const char *prefix) +static int module_foreach(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct foreach_cb info = FOREACH_CB_INIT; struct pathspec pathspec = { 0 }; @@ -539,7 +545,8 @@ static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data info->flags); } -static int module_init(int argc, const char **argv, const char *prefix) +static int module_init(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct init_cb info = INIT_CB_INIT; struct pathspec pathspec = { 0 }; @@ -608,6 +615,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 +679,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 +702,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 +718,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); } @@ -728,7 +740,8 @@ static void status_submodule_cb(const struct cache_entry *list_item, info->prefix, info->super_prefix, info->flags); } -static int module_status(int argc, const char **argv, const char *prefix) +static int module_status(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct status_cb info = STATUS_CB_INIT; struct pathspec pathspec = { 0 }; @@ -916,7 +929,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); } } @@ -1153,7 +1166,8 @@ cleanup: return ret; } -static int module_summary(int argc, const char **argv, const char *prefix) +static int module_summary(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct summary_cb info = SUMMARY_CB_INIT; int cached = 0; @@ -1329,7 +1343,8 @@ static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data info->flags); } -static int module_sync(int argc, const char **argv, const char *prefix) +static int module_sync(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct sync_cb info = SYNC_CB_INIT; struct pathspec pathspec = { 0 }; @@ -1455,7 +1470,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); @@ -1475,7 +1490,8 @@ static void deinit_submodule_cb(const struct cache_entry *list_item, deinit_submodule(list_item->name, info->prefix, info->flags); } -static int module_deinit(int argc, const char **argv, const char *prefix) +static int module_deinit(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct deinit_cb info = DEINIT_CB_INIT; struct pathspec pathspec = { 0 }; @@ -1532,6 +1548,7 @@ struct module_clone_data { const char *url; 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 +1557,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 +1632,8 @@ static int add_possible_reference_from_superproject( ; /* nothing */ } } + + strbuf_release(&err); strbuf_release(&sb); } @@ -1706,7 +1726,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) @@ -1738,6 +1758,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) @@ -1825,13 +1848,15 @@ static int clone_submodule(const struct module_clone_data *clone_data, return 0; } -static int module_clone(int argc, const char **argv, const char *prefix) +static int module_clone(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int dissociate = 0, quiet = 0, progress = 0, require_init = 0; struct module_clone_data clone_data = MODULE_CLONE_DATA_INIT; 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,6 +1874,8 @@ 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_INTEGER(0, "depth", &clone_data.depth, @@ -1874,6 +1901,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; @@ -1973,6 +2005,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; @@ -1996,6 +2029,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, \ @@ -2005,6 +2039,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); } @@ -2131,6 +2166,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); @@ -2302,7 +2340,14 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, strvec_pushf(&cp.args, "--depth=%d", depth); if (oid) { char *hex = oid_to_hex(oid); - char *remote = get_default_remote(); + char *remote; + int code; + + code = get_default_remote_submodule(module_path, &remote); + if (code) { + child_process_clear(&cp); + return code; + } strvec_pushl(&cp.args, remote, hex, NULL); free(remote); @@ -2565,6 +2610,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( @@ -2619,15 +2667,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); } @@ -2733,13 +2786,15 @@ cleanup: return ret; } -static int module_update(int argc, const char **argv, const char *prefix) +static int module_update(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct pathspec pathspec = { 0 }; struct pathspec pathspec2 = { 0 }; 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), @@ -2763,6 +2818,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, @@ -2806,6 +2863,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; @@ -2856,7 +2919,8 @@ cleanup: return ret; } -static int push_check(int argc, const char **argv, const char *prefix UNUSED) +static int push_check(int argc, const char **argv, const char *prefix UNUSED, + struct repository *repo UNUSED) { struct remote *remote; const char *superproject_head; @@ -2927,14 +2991,17 @@ static int push_check(int argc, const char **argv, const char *prefix UNUSED) rs->src); } } + refspec_clear(&refspec); + free_refs(local_refs); } free(head); return 0; } -static int absorb_git_dirs(int argc, const char **argv, const char *prefix) +static int absorb_git_dirs(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int i; struct pathspec pathspec = { 0 }; @@ -2967,7 +3034,8 @@ cleanup: return ret; } -static int module_set_url(int argc, const char **argv, const char *prefix) +static int module_set_url(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int quiet = 0, ret; const char *newurl; @@ -3006,7 +3074,8 @@ static int module_set_url(int argc, const char **argv, const char *prefix) return !!ret; } -static int module_set_branch(int argc, const char **argv, const char *prefix) +static int module_set_branch(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int opt_default = 0, ret; const char *opt_branch = NULL; @@ -3056,7 +3125,8 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) return !!ret; } -static int module_create_branch(int argc, const char **argv, const char *prefix) +static int module_create_branch(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { enum branch_track track; int quiet = 0, force = 0, reflog = 0, dry_run = 0; @@ -3101,13 +3171,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) { @@ -3201,6 +3275,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.dissociate = add_data->dissociate; if (add_data->depth >= 0) clone_data.depth = add_data->depth; @@ -3362,10 +3437,12 @@ static void die_on_repo_without_commits(const char *path) strbuf_release(&sb); } -static int module_add(int argc, const char **argv, const char *prefix) +static int module_add(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { 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"), @@ -3376,6 +3453,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 " @@ -3402,6 +3481,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); @@ -3483,7 +3568,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) { parse_opt_subcommand_fn *fn = NULL; const char *const usage[] = { @@ -3509,5 +3597,5 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix) }; argc = parse_options(argc, argv, prefix, options, usage, 0); - return fn(argc, argv, prefix); + return fn(argc, argv, prefix, repo); } |
