diff options
Diffstat (limited to 'builtin')
-rw-r--r-- | builtin/bisect--helper.c | 229 | ||||
-rw-r--r-- | builtin/for-each-repo.c | 5 | ||||
-rw-r--r-- | builtin/gc.c | 45 | ||||
-rw-r--r-- | builtin/notes.c | 2 | ||||
-rw-r--r-- | builtin/prune.c | 4 | ||||
-rw-r--r-- | builtin/push.c | 12 | ||||
-rw-r--r-- | builtin/rebase.c | 27 | ||||
-rw-r--r-- | builtin/receive-pack.c | 10 | ||||
-rw-r--r-- | builtin/rev-list.c | 1 | ||||
-rw-r--r-- | builtin/rev-parse.c | 18 | ||||
-rw-r--r-- | builtin/rm.c | 3 | ||||
-rw-r--r-- | builtin/submodule--helper.c | 146 |
12 files changed, 262 insertions, 240 deletions
diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c index 1d2ce8a0e1..6e41cbdb2d 100644 --- a/builtin/bisect--helper.c +++ b/builtin/bisect--helper.c @@ -1279,115 +1279,144 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc) return res; } +static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNUSED) +{ + if (argc > 1) + return error(_("--bisect-reset requires either no argument or a commit")); + return bisect_reset(argc ? argv[0] : NULL); +} + +static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNUSED) +{ + int res; + struct bisect_terms terms = { 0 }; + + if (argc > 1) + return error(_("--bisect-terms requires 0 or 1 argument")); + res = bisect_terms(&terms, argc == 1 ? argv[0] : NULL); + free_terms(&terms); + return res; +} + +static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNUSED) +{ + int res; + struct bisect_terms terms = { 0 }; + + set_terms(&terms, "bad", "good"); + res = bisect_start(&terms, argv, argc); + free_terms(&terms); + return res; +} + +static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *prefix) +{ + int res; + struct bisect_terms terms = { 0 }; + + if (argc) + return error(_("--bisect-next requires 0 arguments")); + get_terms(&terms); + res = bisect_next(&terms, prefix); + free_terms(&terms); + return res; +} + +static int cmd_bisect__state(int argc, const char **argv, const char *prefix UNUSED) +{ + int res; + struct bisect_terms terms = { 0 }; + + set_terms(&terms, "bad", "good"); + get_terms(&terms); + res = bisect_state(&terms, argv, argc); + free_terms(&terms); + return res; +} + +static int cmd_bisect__log(int argc, const char **argv UNUSED, const char *prefix UNUSED) +{ + if (argc) + return error(_("--bisect-log requires 0 arguments")); + return bisect_log(); +} + +static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UNUSED) +{ + int res; + struct bisect_terms terms = { 0 }; + + if (argc != 1) + return error(_("no logfile given")); + set_terms(&terms, "bad", "good"); + res = bisect_replay(&terms, argv[0]); + free_terms(&terms); + return res; +} + +static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUSED) +{ + int res; + struct bisect_terms terms = { 0 }; + + set_terms(&terms, "bad", "good"); + get_terms(&terms); + res = bisect_skip(&terms, argv, argc); + free_terms(&terms); + return res; +} + +static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix UNUSED) +{ + int res; + struct bisect_terms terms = { 0 }; + + get_terms(&terms); + res = bisect_visualize(&terms, argv, argc); + free_terms(&terms); + return res; +} + +static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSED) +{ + int res; + struct bisect_terms terms = { 0 }; + + if (!argc) + return error(_("bisect run failed: no command provided.")); + get_terms(&terms); + res = bisect_run(&terms, argv, argc); + free_terms(&terms); + return res; +} + int cmd_bisect__helper(int argc, const char **argv, const char *prefix) { - enum { - BISECT_RESET = 1, - BISECT_NEXT_CHECK, - BISECT_TERMS, - BISECT_START, - BISECT_AUTOSTART, - BISECT_NEXT, - BISECT_STATE, - BISECT_LOG, - BISECT_REPLAY, - BISECT_SKIP, - BISECT_VISUALIZE, - BISECT_RUN, - } cmdmode = 0; - int res = 0, nolog = 0; + int res = 0; + parse_opt_subcommand_fn *fn = NULL; struct option options[] = { - OPT_CMDMODE(0, "bisect-reset", &cmdmode, - N_("reset the bisection state"), BISECT_RESET), - OPT_CMDMODE(0, "bisect-next-check", &cmdmode, - N_("check whether bad or good terms exist"), BISECT_NEXT_CHECK), - OPT_CMDMODE(0, "bisect-terms", &cmdmode, - N_("print out the bisect terms"), BISECT_TERMS), - OPT_CMDMODE(0, "bisect-start", &cmdmode, - N_("start the bisect session"), BISECT_START), - OPT_CMDMODE(0, "bisect-next", &cmdmode, - N_("find the next bisection commit"), BISECT_NEXT), - OPT_CMDMODE(0, "bisect-state", &cmdmode, - N_("mark the state of ref (or refs)"), BISECT_STATE), - OPT_CMDMODE(0, "bisect-log", &cmdmode, - N_("list the bisection steps so far"), BISECT_LOG), - OPT_CMDMODE(0, "bisect-replay", &cmdmode, - N_("replay the bisection process from the given file"), BISECT_REPLAY), - OPT_CMDMODE(0, "bisect-skip", &cmdmode, - N_("skip some commits for checkout"), BISECT_SKIP), - OPT_CMDMODE(0, "bisect-visualize", &cmdmode, - N_("visualize the bisection"), BISECT_VISUALIZE), - OPT_CMDMODE(0, "bisect-run", &cmdmode, - N_("use <cmd>... to automatically bisect"), BISECT_RUN), - OPT_BOOL(0, "no-log", &nolog, - N_("no log for BISECT_WRITE")), + OPT_SUBCOMMAND("reset", &fn, cmd_bisect__reset), + OPT_SUBCOMMAND("terms", &fn, cmd_bisect__terms), + OPT_SUBCOMMAND("start", &fn, cmd_bisect__start), + OPT_SUBCOMMAND("next", &fn, cmd_bisect__next), + OPT_SUBCOMMAND("state", &fn, cmd_bisect__state), + OPT_SUBCOMMAND("log", &fn, cmd_bisect__log), + OPT_SUBCOMMAND("replay", &fn, cmd_bisect__replay), + OPT_SUBCOMMAND("skip", &fn, cmd_bisect__skip), + OPT_SUBCOMMAND("visualize", &fn, cmd_bisect__visualize), + OPT_SUBCOMMAND("view", &fn, cmd_bisect__visualize), + OPT_SUBCOMMAND("run", &fn, cmd_bisect__run), OPT_END() }; - struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL }; - argc = parse_options(argc, argv, prefix, options, - git_bisect_helper_usage, - PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_UNKNOWN_OPT); + git_bisect_helper_usage, 0); - if (!cmdmode) + if (!fn) usage_with_options(git_bisect_helper_usage, options); + argc--; + argv++; - switch (cmdmode) { - case BISECT_RESET: - if (argc > 1) - return error(_("--bisect-reset requires either no argument or a commit")); - res = bisect_reset(argc ? argv[0] : NULL); - break; - case BISECT_TERMS: - if (argc > 1) - return error(_("--bisect-terms requires 0 or 1 argument")); - res = bisect_terms(&terms, argc == 1 ? argv[0] : NULL); - break; - case BISECT_START: - set_terms(&terms, "bad", "good"); - res = bisect_start(&terms, argv, argc); - break; - case BISECT_NEXT: - if (argc) - return error(_("--bisect-next requires 0 arguments")); - get_terms(&terms); - res = bisect_next(&terms, prefix); - break; - case BISECT_STATE: - set_terms(&terms, "bad", "good"); - get_terms(&terms); - res = bisect_state(&terms, argv, argc); - break; - case BISECT_LOG: - if (argc) - return error(_("--bisect-log requires 0 arguments")); - res = bisect_log(); - break; - case BISECT_REPLAY: - if (argc != 1) - return error(_("no logfile given")); - set_terms(&terms, "bad", "good"); - res = bisect_replay(&terms, argv[0]); - break; - case BISECT_SKIP: - set_terms(&terms, "bad", "good"); - get_terms(&terms); - res = bisect_skip(&terms, argv, argc); - break; - case BISECT_VISUALIZE: - get_terms(&terms); - res = bisect_visualize(&terms, argv, argc); - break; - case BISECT_RUN: - if (!argc) - return error(_("bisect run failed: no command provided.")); - get_terms(&terms); - res = bisect_run(&terms, argv, argc); - break; - default: - BUG("unknown subcommand %d", cmdmode); - } - free_terms(&terms); + res = fn(argc, argv, prefix); /* * Handle early success diff --git a/builtin/for-each-repo.c b/builtin/for-each-repo.c index d45d873f57..6aeac37148 100644 --- a/builtin/for-each-repo.c +++ b/builtin/for-each-repo.c @@ -14,13 +14,16 @@ static int run_command_on_repo(const char *path, int argc, const char ** argv) { int i; struct child_process child = CHILD_PROCESS_INIT; + char *abspath = interpolate_path(path, 0); child.git_cmd = 1; - strvec_pushl(&child.args, "-C", path, NULL); + strvec_pushl(&child.args, "-C", abspath, NULL); for (i = 0; i < argc; i++) strvec_push(&child.args, argv[i]); + free(abspath); + return run_command(&child); } diff --git a/builtin/gc.c b/builtin/gc.c index 6b08dcf3c5..02455fdcd7 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -1480,13 +1480,15 @@ static char *get_maintpath(void) } static char const * const builtin_maintenance_register_usage[] = { - "git maintenance register", + "git maintenance register [--config-file <path>]", NULL }; static int maintenance_register(int argc, const char **argv, const char *prefix) { + char *config_file = NULL; struct option options[] = { + OPT_STRING(0, "config-file", &config_file, N_("file"), N_("use given config file")), OPT_END(), }; int found = 0; @@ -1523,12 +1525,16 @@ static int maintenance_register(int argc, const char **argv, const char *prefix) if (!found) { int rc; - char *user_config, *xdg_config; - git_global_config(&user_config, &xdg_config); - if (!user_config) - die(_("$HOME not set")); + char *user_config = NULL, *xdg_config = NULL; + + if (!config_file) { + git_global_config(&user_config, &xdg_config); + config_file = user_config; + if (!user_config) + die(_("$HOME not set")); + } rc = git_config_set_multivar_in_file_gently( - user_config, "maintenance.repo", maintpath, + config_file, "maintenance.repo", maintpath, CONFIG_REGEX_NONE, 0); free(user_config); free(xdg_config); @@ -1543,14 +1549,16 @@ static int maintenance_register(int argc, const char **argv, const char *prefix) } static char const * const builtin_maintenance_unregister_usage[] = { - "git maintenance unregister [--force]", + "git maintenance unregister [--config-file <path>] [--force]", NULL }; static int maintenance_unregister(int argc, const char **argv, const char *prefix) { int force = 0; + char *config_file = NULL; struct option options[] = { + OPT_STRING(0, "config-file", &config_file, N_("file"), N_("use given config file")), OPT__FORCE(&force, N_("return success even if repository was not registered"), PARSE_OPT_NOCOMPLETE), @@ -1561,6 +1569,7 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi int found = 0; struct string_list_item *item; const struct string_list *list; + struct config_set cs = { { 0 } }; argc = parse_options(argc, argv, prefix, options, builtin_maintenance_unregister_usage, 0); @@ -1568,7 +1577,13 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi usage_with_options(builtin_maintenance_unregister_usage, options); - list = git_config_get_value_multi(key); + if (config_file) { + git_configset_init(&cs); + git_configset_add_file(&cs, config_file); + list = git_configset_get_value_multi(&cs, key); + } else { + list = git_config_get_value_multi(key); + } if (list) { for_each_string_list_item(item, list) { if (!strcmp(maintpath, item->string)) { @@ -1580,12 +1595,15 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi if (found) { int rc; - char *user_config, *xdg_config; - git_global_config(&user_config, &xdg_config); - if (!user_config) - die(_("$HOME not set")); + char *user_config = NULL, *xdg_config = NULL; + if (!config_file) { + git_global_config(&user_config, &xdg_config); + config_file = user_config; + if (!user_config) + die(_("$HOME not set")); + } rc = git_config_set_multivar_in_file_gently( - user_config, key, NULL, maintpath, + config_file, key, NULL, maintpath, CONFIG_FLAGS_MULTI_REPLACE | CONFIG_FLAGS_FIXED_VALUE); free(user_config); free(xdg_config); @@ -1598,6 +1616,7 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi die(_("repository '%s' is not registered"), maintpath); } + git_configset_clear(&cs); free(maintpath); return 0; } diff --git a/builtin/notes.c b/builtin/notes.c index be51f69225..80d9dfd25c 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -181,7 +181,7 @@ static void prepare_note_data(const struct object_id *object, struct note_data * strbuf_addch(&buf, '\n'); strbuf_add_commented_lines(&buf, "\n", strlen("\n")); strbuf_add_commented_lines(&buf, _(note_template), strlen(_(note_template))); - strbuf_addch(&buf, '\n'); + strbuf_add_commented_lines(&buf, "\n", strlen("\n")); write_or_die(fd, buf.buf, buf.len); write_commented_object(fd, object); diff --git a/builtin/prune.c b/builtin/prune.c index df376b2ed1..2719220108 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -127,7 +127,9 @@ static void remove_temporary_files(const char *path) dir = opendir(path); if (!dir) { - fprintf(stderr, "Unable to open directory %s\n", path); + if (errno != ENOENT) + fprintf(stderr, "Unable to open directory %s: %s\n", + path, strerror(errno)); return; } while ((de = readdir(dir)) != NULL) diff --git a/builtin/push.c b/builtin/push.c index f0329c62a2..60ac8017e5 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -466,8 +466,16 @@ static int option_parse_recurse_submodules(const struct option *opt, if (unset) *recurse_submodules = RECURSE_SUBMODULES_OFF; - else - *recurse_submodules = parse_push_recurse_submodules_arg(opt->long_name, arg); + else { + if (!strcmp(arg, "only-is-on-demand")) { + if (*recurse_submodules == RECURSE_SUBMODULES_ONLY) { + warning(_("recursing into submodule with push.recurseSubmodules=only; using on-demand instead")); + *recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND; + } + } else { + *recurse_submodules = parse_push_recurse_submodules_arg(opt->long_name, arg); + } + } return 0; } diff --git a/builtin/rebase.c b/builtin/rebase.c index 1384008fe0..b22768ca5b 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -30,8 +30,6 @@ #include "reset.h" #include "hook.h" -#define DEFAULT_REFLOG_ACTION "rebase" - static char const * const builtin_rebase_usage[] = { N_("git rebase [-i] [options] [--exec <cmd>] " "[--onto <newbase> | --keep-base] [<upstream> [<branch>]]"), @@ -106,6 +104,7 @@ struct rebase_options { } flags; struct strvec git_am_opts; enum action action; + char *reflog_action; int signoff; int allow_rerere_autoupdate; int keep_empty; @@ -159,6 +158,7 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts) opts->committer_date_is_author_date; replay.ignore_date = opts->ignore_date; replay.gpg_sign = xstrdup_or_null(opts->gpg_sign_opt); + replay.reflog_action = xstrdup(opts->reflog_action); if (opts->strategy) replay.strategy = xstrdup_or_null(opts->strategy); else if (!replay.strategy && replay.default_strategy) { @@ -585,10 +585,10 @@ static int move_to_original_branch(struct rebase_options *opts) BUG("move_to_original_branch without onto"); strbuf_addf(&branch_reflog, "%s (finish): %s onto %s", - getenv(GIT_REFLOG_ACTION_ENVIRONMENT), + opts->reflog_action, opts->head_name, oid_to_hex(&opts->onto->object.oid)); strbuf_addf(&head_reflog, "%s (finish): returning to %s", - getenv(GIT_REFLOG_ACTION_ENVIRONMENT), opts->head_name); + opts->reflog_action, opts->head_name); ropts.branch = opts->head_name; ropts.flags = RESET_HEAD_REFS_ONLY; ropts.branch_msg = branch_reflog.buf; @@ -618,7 +618,7 @@ static int run_am(struct rebase_options *opts) am.git_cmd = 1; strvec_push(&am.args, "am"); strvec_pushf(&am.env, GIT_REFLOG_ACTION_ENVIRONMENT "=%s (pick)", - getenv(GIT_REFLOG_ACTION_ENVIRONMENT)); + opts->reflog_action); if (opts->action == ACTION_CONTINUE) { strvec_push(&am.args, "--resolved"); strvec_pushf(&am.args, "--resolvemsg=%s", resolvemsg); @@ -685,7 +685,7 @@ static int run_am(struct rebase_options *opts) ropts.oid = &opts->orig_head->object.oid; ropts.branch = opts->head_name; - ropts.default_reflog_action = DEFAULT_REFLOG_ACTION; + ropts.default_reflog_action = opts->reflog_action; reset_head(the_repository, &ropts); error(_("\ngit encountered an error while preparing the " "patches to replay\n" @@ -834,8 +834,7 @@ static int checkout_up_to_date(struct rebase_options *options) int ret = 0; strbuf_addf(&buf, "%s: checkout %s", - getenv(GIT_REFLOG_ACTION_ENVIRONMENT), - options->switch_to); + options->reflog_action, options->switch_to); ropts.oid = &options->orig_head->object.oid; ropts.branch = options->head_name; ropts.flags = RESET_HEAD_RUN_POST_CHECKOUT_HOOK; @@ -1243,7 +1242,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (options.action != ACTION_NONE && !in_progress) die(_("No rebase in progress?")); - setenv(GIT_REFLOG_ACTION_ENVIRONMENT, "rebase", 0); if (options.action == ACTION_EDIT_TODO && !is_merge(&options)) die(_("The --edit-todo action can only be used during " @@ -1258,6 +1256,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) trace2_cmd_mode(action_names[options.action]); } + options.reflog_action = getenv(GIT_REFLOG_ACTION_ENVIRONMENT); + options.reflog_action = + xstrdup(options.reflog_action ? options.reflog_action : "rebase"); + switch (options.action) { case ACTION_CONTINUE: { struct object_id head; @@ -1310,7 +1312,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) exit(1); strbuf_addf(&head_msg, "%s (abort): returning to %s", - getenv(GIT_REFLOG_ACTION_ENVIRONMENT), + options.reflog_action, options.head_name ? options.head_name : oid_to_hex(&options.orig_head->object.oid)); ropts.oid = &options.orig_head->object.oid; @@ -1786,13 +1788,13 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) "it...\n")); strbuf_addf(&msg, "%s (start): checkout %s", - getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name); + options.reflog_action, options.onto_name); ropts.oid = &options.onto->object.oid; ropts.orig_head = &options.orig_head->object.oid, ropts.flags = RESET_HEAD_DETACH | RESET_ORIG_HEAD | RESET_HEAD_RUN_POST_CHECKOUT_HOOK; ropts.head_msg = msg.buf; - ropts.default_reflog_action = DEFAULT_REFLOG_ACTION; + ropts.default_reflog_action = options.reflog_action; if (reset_head(the_repository, &ropts)) die(_("Could not detach HEAD")); strbuf_release(&msg); @@ -1824,6 +1826,7 @@ run_rebase: cleanup: strbuf_release(&buf); strbuf_release(&revisions); + free(options.reflog_action); free(options.head_name); free(options.gpg_sign_opt); free(options.cmd); diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 44bcea3a5b..a90af30363 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -80,6 +80,7 @@ static struct object_id push_cert_oid; static struct signature_check sigcheck; static const char *push_cert_nonce; static const char *cert_nonce_seed; +static struct string_list hidden_refs = STRING_LIST_INIT_DUP; static const char *NONCE_UNSOLICITED = "UNSOLICITED"; static const char *NONCE_BAD = "BAD"; @@ -130,7 +131,7 @@ static enum deny_action parse_deny_action(const char *var, const char *value) static int receive_pack_config(const char *var, const char *value, void *cb) { - int status = parse_hide_refs_config(var, value, "receive"); + int status = parse_hide_refs_config(var, value, "receive", &hidden_refs); if (status) return status; @@ -296,7 +297,7 @@ static int show_ref_cb(const char *path_full, const struct object_id *oid, struct oidset *seen = data; const char *path = strip_namespace(path_full); - if (ref_is_hidden(path, path_full)) + if (ref_is_hidden(path, path_full, &hidden_refs)) return 0; /* @@ -1794,7 +1795,7 @@ static void reject_updates_to_hidden(struct command *commands) strbuf_setlen(&refname_full, prefix_len); strbuf_addstr(&refname_full, cmd->ref_name); - if (!ref_is_hidden(cmd->ref_name, refname_full.buf)) + if (!ref_is_hidden(cmd->ref_name, refname_full.buf, &hidden_refs)) continue; if (is_null_oid(&cmd->new_oid)) cmd->error_string = "deny deleting a hidden ref"; @@ -1928,6 +1929,8 @@ static void execute_commands(struct command *commands, opt.err_fd = err_fd; opt.progress = err_fd && !quiet; opt.env = tmp_objdir_env(tmp_objdir); + opt.exclude_hidden_refs_section = "receive"; + if (check_connected(iterate_receive_command_list, &data, &opt)) set_connectivity_errors(commands, si); @@ -2591,6 +2594,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix) packet_flush(1); oid_array_clear(&shallow); oid_array_clear(&ref); + string_list_clear(&hidden_refs, 0); free((void *)push_cert_nonce); return 0; } diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 3acd93f71e..d42db0b0cc 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -38,6 +38,7 @@ static const char rev_list_usage[] = " --tags\n" " --remotes\n" " --stdin\n" +" --exclude-hidden=[receive|uploadpack]\n" " --quiet\n" " ordering output:\n" " --topo-order\n" diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index d4c81352a6..1c344d74a7 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -39,7 +39,7 @@ static int abbrev_ref_strict; static int output_sq; static int stuck_long; -static struct string_list *ref_excludes; +static struct ref_exclusions ref_excludes = REF_EXCLUSIONS_INIT; /* * Some arguments are relevant "revision" arguments, @@ -198,7 +198,7 @@ static int show_default(void) static int show_reference(const char *refname, const struct object_id *oid, int flag UNUSED, void *cb_data UNUSED) { - if (ref_excluded(ref_excludes, refname)) + if (ref_excluded(&ref_excludes, refname)) return 0; show_rev(NORMAL, oid, refname); return 0; @@ -585,7 +585,7 @@ static void handle_ref_opt(const char *pattern, const char *prefix) for_each_glob_ref_in(show_reference, pattern, prefix, NULL); else for_each_ref_in(prefix, show_reference, NULL); - clear_ref_exclusion(&ref_excludes); + clear_ref_exclusions(&ref_excludes); } enum format_type { @@ -863,7 +863,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) } if (!strcmp(arg, "--all")) { for_each_ref(show_reference, NULL); - clear_ref_exclusion(&ref_excludes); + clear_ref_exclusions(&ref_excludes); continue; } if (skip_prefix(arg, "--disambiguate=", &arg)) { @@ -876,10 +876,14 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) continue; } if (opt_with_value(arg, "--branches", &arg)) { + if (ref_excludes.hidden_refs_configured) + return error(_("--exclude-hidden cannot be used together with --branches")); handle_ref_opt(arg, "refs/heads/"); continue; } if (opt_with_value(arg, "--tags", &arg)) { + if (ref_excludes.hidden_refs_configured) + return error(_("--exclude-hidden cannot be used together with --tags")); handle_ref_opt(arg, "refs/tags/"); continue; } @@ -888,6 +892,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) continue; } if (opt_with_value(arg, "--remotes", &arg)) { + if (ref_excludes.hidden_refs_configured) + return error(_("--exclude-hidden cannot be used together with --remotes")); handle_ref_opt(arg, "refs/remotes/"); continue; } @@ -895,6 +901,10 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) add_ref_exclusion(&ref_excludes, arg); continue; } + if (skip_prefix(arg, "--exclude-hidden=", &arg)) { + exclude_hidden_refs(&ref_excludes, arg); + continue; + } if (!strcmp(arg, "--show-toplevel")) { const char *work_tree = get_git_work_tree(); if (work_tree) diff --git a/builtin/rm.c b/builtin/rm.c index 40b7990de1..d4989d4d86 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -86,8 +86,7 @@ static void submodules_absorb_gitdir_if_needed(void) continue; if (!submodule_uses_gitfile(name)) - absorb_git_dir_into_superproject(name, - ABSORB_GITDIR_RECURSE_SUBMODULES); + absorb_git_dir_into_superproject(name); } } diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index ebe86e6817..05f2c9bc98 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -616,6 +616,9 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, int diff_files_result; struct strbuf buf = STRBUF_INIT; const char *git_dir; + struct setup_revision_opt opt = { + .free_removed_argv_elements = 1, + }; if (!submodule_from_path(the_repository, null_oid(), path)) die(_("no submodule mapping found in .gitmodules for path '%s'"), @@ -649,9 +652,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, repo_init_revisions(the_repository, &rev, NULL); rev.abbrev = 0; - diff_files_args.nr = setup_revisions(diff_files_args.nr, - diff_files_args.v, - &rev, NULL); + setup_revisions(diff_files_args.nr, diff_files_args.v, &rev, &opt); diff_files_result = run_diff_files(&rev, 0); if (!diff_result_code(&rev.diffopt, diff_files_result)) { @@ -1378,8 +1379,7 @@ static void deinit_submodule(const char *path, const char *prefix, ".git file by using absorbgitdirs."), displaypath); - absorb_git_dir_into_superproject(path, - ABSORB_GITDIR_RECURSE_SUBMODULES); + absorb_git_dir_into_superproject(path); } @@ -2643,9 +2643,6 @@ static int module_update(int argc, const char **argv, const char *prefix) N_("traverse submodules recursively")), OPT_BOOL('N', "no-fetch", &opt.nofetch, N_("don't fetch new objects from the remote site")), - OPT_STRING(0, "prefix", &opt.prefix, - N_("path"), - N_("path into the working tree")), OPT_SET_INT(0, "checkout", &opt.update_default, N_("use the 'checkout' update strategy (default)"), SM_UPDATE_CHECKOUT), @@ -2701,6 +2698,7 @@ static int module_update(int argc, const char **argv, const char *prefix) } opt.filter_options = &filter_options; + opt.prefix = prefix; if (opt.update_default) opt.update_strategy.type = opt.update_default; @@ -2830,13 +2828,7 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix) int i; struct pathspec pathspec = { 0 }; struct module_list list = MODULE_LIST_INIT; - unsigned flags = ABSORB_GITDIR_RECURSE_SUBMODULES; struct option embed_gitdir_options[] = { - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_BIT(0, "--recursive", &flags, N_("recurse into submodules"), - ABSORB_GITDIR_RECURSE_SUBMODULES), OPT_END() }; const char *const git_submodule_helper_usage[] = { @@ -2852,7 +2844,7 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix) goto cleanup; for (i = 0; i < list.nr; i++) - absorb_git_dir_into_superproject(list.entries[i]->name, flags); + absorb_git_dir_into_superproject(list.entries[i]->name); ret = 0; cleanup: @@ -2861,51 +2853,6 @@ cleanup: return ret; } -static int module_config(int argc, const char **argv, const char *prefix) -{ - enum { - CHECK_WRITEABLE = 1, - DO_UNSET = 2 - } command = 0; - struct option module_config_options[] = { - OPT_CMDMODE(0, "check-writeable", &command, - N_("check if it is safe to write to the .gitmodules file"), - CHECK_WRITEABLE), - OPT_CMDMODE(0, "unset", &command, - N_("unset the config in the .gitmodules file"), - DO_UNSET), - OPT_END() - }; - const char *const git_submodule_helper_usage[] = { - N_("git submodule--helper config <name> [<value>]"), - N_("git submodule--helper config --unset <name>"), - "git submodule--helper config --check-writeable", - NULL - }; - - argc = parse_options(argc, argv, prefix, module_config_options, - git_submodule_helper_usage, PARSE_OPT_KEEP_ARGV0); - - if (argc == 1 && command == CHECK_WRITEABLE) - return is_writing_gitmodules_ok() ? 0 : -1; - - /* Equivalent to ACTION_GET in builtin/config.c */ - if (argc == 2 && command != DO_UNSET) - return print_config_from_gitmodules(the_repository, argv[1]); - - /* Equivalent to ACTION_SET in builtin/config.c */ - if (argc == 3 || (argc == 2 && command == DO_UNSET)) { - const char *value = (argc == 3) ? argv[2] : NULL; - - if (!is_writing_gitmodules_ok()) - die(_("please make sure that the .gitmodules file is in the working tree")); - - return config_set_in_gitmodules_file_gently(argv[1], value); - } - - usage_with_options(git_submodule_helper_usage, module_config_options); -} - static int module_set_url(int argc, const char **argv, const char *prefix) { int quiet = 0; @@ -3404,48 +3351,45 @@ cleanup: return ret; } -#define SUPPORT_SUPER_PREFIX (1<<0) - -struct cmd_struct { - const char *cmd; - int (*fn)(int, const char **, const char *); - unsigned option; -}; - -static struct cmd_struct commands[] = { - {"clone", module_clone, SUPPORT_SUPER_PREFIX}, - {"add", module_add, 0}, - {"update", module_update, SUPPORT_SUPER_PREFIX}, - {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, - {"init", module_init, 0}, - {"status", module_status, SUPPORT_SUPER_PREFIX}, - {"sync", module_sync, SUPPORT_SUPER_PREFIX}, - {"deinit", module_deinit, 0}, - {"summary", module_summary, 0}, - {"push-check", push_check, 0}, - {"absorbgitdirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX}, - {"config", module_config, 0}, - {"set-url", module_set_url, 0}, - {"set-branch", module_set_branch, 0}, - {"create-branch", module_create_branch, 0}, -}; - int cmd_submodule__helper(int argc, const char **argv, const char *prefix) { - int i; - if (argc < 2 || !strcmp(argv[1], "-h")) - usage("git submodule--helper <command>"); - - for (i = 0; i < ARRAY_SIZE(commands); i++) { - if (!strcmp(argv[1], commands[i].cmd)) { - if (get_super_prefix() && - !(commands[i].option & SUPPORT_SUPER_PREFIX)) - die(_("%s doesn't support --super-prefix"), - commands[i].cmd); - return commands[i].fn(argc - 1, argv + 1, prefix); - } - } + const char *cmd = argv[0]; + const char *subcmd; + parse_opt_subcommand_fn *fn = NULL; + const char *const usage[] = { + N_("git submodule--helper <command>"), + NULL + }; + struct option options[] = { + OPT_SUBCOMMAND("clone", &fn, module_clone), + OPT_SUBCOMMAND("add", &fn, module_add), + OPT_SUBCOMMAND("update", &fn, module_update), + OPT_SUBCOMMAND("foreach", &fn, module_foreach), + OPT_SUBCOMMAND("init", &fn, module_init), + OPT_SUBCOMMAND("status", &fn, module_status), + OPT_SUBCOMMAND("sync", &fn, module_sync), + OPT_SUBCOMMAND("deinit", &fn, module_deinit), + OPT_SUBCOMMAND("summary", &fn, module_summary), + OPT_SUBCOMMAND("push-check", &fn, push_check), + OPT_SUBCOMMAND("absorbgitdirs", &fn, absorb_git_dirs), + OPT_SUBCOMMAND("set-url", &fn, module_set_url), + OPT_SUBCOMMAND("set-branch", &fn, module_set_branch), + OPT_SUBCOMMAND("create-branch", &fn, module_create_branch), + OPT_END() + }; + argc = parse_options(argc, argv, prefix, options, usage, 0); + subcmd = argv[0]; + + if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") && + strcmp(subcmd, "foreach") && strcmp(subcmd, "status") && + strcmp(subcmd, "sync") && strcmp(subcmd, "absorbgitdirs") && + get_super_prefix()) + /* + * xstrfmt() rather than "%s %s" to keep the translated + * string identical to git.c's. + */ + die(_("%s doesn't support --super-prefix"), + xstrfmt("'%s %s'", cmd, subcmd)); - die(_("'%s' is not a valid submodule--helper " - "subcommand"), argv[1]); + return fn(argc, argv, prefix); } |