diff options
Diffstat (limited to 'builtin')
35 files changed, 375 insertions, 240 deletions
diff --git a/builtin/add.c b/builtin/add.c index 76277df326..0c60402267 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -88,7 +88,7 @@ static int fix_unmerged_status(struct diff_filepair *p, } static void update_callback(struct diff_queue_struct *q, - struct diff_options *opt, void *cbdata) + struct diff_options *opt UNUSED, void *cbdata) { int i; struct update_callback_data *data = cbdata; @@ -695,6 +695,6 @@ finish: die(_("Unable to write new index file")); dir_clear(&dir); - UNLEAK(pathspec); + clear_pathspec(&pathspec); return exit_status; } diff --git a/builtin/am.c b/builtin/am.c index 30c9b3a9cd..82a41cbfc4 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -117,6 +117,7 @@ struct am_state { /* various operating modes and command line options */ int interactive; + int no_verify; int threeway; int quiet; int signoff; /* enum signoff_type */ @@ -472,10 +473,12 @@ static void am_destroy(const struct am_state *state) */ static int run_applypatch_msg_hook(struct am_state *state) { - int ret; + int ret = 0; assert(state->msg); - ret = run_hooks_l("applypatch-msg", am_path(state, "final-commit"), NULL); + + if (!state->no_verify) + ret = run_hooks_l("applypatch-msg", am_path(state, "final-commit"), NULL); if (!ret) { FREE_AND_NULL(state->msg); @@ -1476,6 +1479,7 @@ static int run_apply(const struct am_state *state, const char *index_file) int res, opts_left; int force_apply = 0; int options = 0; + const char **apply_argv; if (init_apply_state(&apply_state, the_repository, NULL)) BUG("init_apply_state() failed"); @@ -1483,7 +1487,14 @@ static int run_apply(const struct am_state *state, const char *index_file) strvec_push(&apply_opts, "apply"); strvec_pushv(&apply_opts, state->git_apply_opts.v); - opts_left = apply_parse_options(apply_opts.nr, apply_opts.v, + /* + * Build a copy that apply_parse_options() can rearrange. + * apply_opts.v keeps referencing the allocated strings for + * strvec_clear() to release. + */ + DUP_ARRAY(apply_argv, apply_opts.v, apply_opts.nr); + + opts_left = apply_parse_options(apply_opts.nr, apply_argv, &apply_state, &force_apply, &options, NULL); @@ -1513,6 +1524,7 @@ static int run_apply(const struct am_state *state, const char *index_file) strvec_clear(&apply_paths); strvec_clear(&apply_opts); clear_apply_state(&apply_state); + free(apply_argv); if (res) return res; @@ -1640,7 +1652,7 @@ static void do_commit(const struct am_state *state) const char *reflog_msg, *author, *committer = NULL; struct strbuf sb = STRBUF_INIT; - if (run_hooks("pre-applypatch")) + if (!state->no_verify && run_hooks("pre-applypatch")) exit(1); if (write_cache_as_tree(&tree, 0, NULL)) @@ -2330,6 +2342,8 @@ int cmd_am(int argc, const char **argv, const char *prefix) struct option options[] = { OPT_BOOL('i', "interactive", &state.interactive, N_("run interactively")), + OPT_BOOL('n', "no-verify", &state.no_verify, + N_("bypass pre-applypatch and applypatch-msg hooks")), OPT_HIDDEN_BOOL('b', "binary", &binary, N_("historical option -- no-op")), OPT_BOOL('3', "3way", &state.threeway, diff --git a/builtin/bisect--helper.c b/builtin/bisect.c index 6e41cbdb2d..cc9483e851 100644 --- a/builtin/bisect--helper.c +++ b/builtin/bisect.c @@ -20,18 +20,40 @@ static GIT_PATH_FUNC(git_path_bisect_names, "BISECT_NAMES") static GIT_PATH_FUNC(git_path_bisect_first_parent, "BISECT_FIRST_PARENT") static GIT_PATH_FUNC(git_path_bisect_run, "BISECT_RUN") -static const char * const git_bisect_helper_usage[] = { - N_("git bisect--helper --bisect-reset [<commit>]"), - "git bisect--helper --bisect-terms [--term-good | --term-old | --term-bad | --term-new]", - N_("git bisect--helper --bisect-start [--term-{new,bad}=<term> --term-{old,good}=<term>]" - " [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<paths>...]"), - "git bisect--helper --bisect-next", - N_("git bisect--helper --bisect-state (bad|new) [<rev>]"), - N_("git bisect--helper --bisect-state (good|old) [<rev>...]"), - N_("git bisect--helper --bisect-replay <filename>"), - N_("git bisect--helper --bisect-skip [(<rev>|<range>)...]"), - "git bisect--helper --bisect-visualize", - N_("git bisect--helper --bisect-run <cmd>..."), +#define BUILTIN_GIT_BISECT_START_USAGE \ + N_("git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>]" \ + " [--no-checkout] [--first-parent] [<bad> [<good>...]] [--]" \ + " [<pathspec>...]") +#define BUILTIN_GIT_BISECT_STATE_USAGE \ + N_("git bisect (good|bad) [<rev>...]") +#define BUILTIN_GIT_BISECT_TERMS_USAGE \ + "git bisect terms [--term-good | --term-bad]" +#define BUILTIN_GIT_BISECT_SKIP_USAGE \ + N_("git bisect skip [(<rev>|<range>)...]") +#define BUILTIN_GIT_BISECT_NEXT_USAGE \ + "git bisect next" +#define BUILTIN_GIT_BISECT_RESET_USAGE \ + N_("git bisect reset [<commit>]") +#define BUILTIN_GIT_BISECT_VISUALIZE_USAGE \ + "git bisect visualize" +#define BUILTIN_GIT_BISECT_REPLAY_USAGE \ + N_("git bisect replay <logfile>") +#define BUILTIN_GIT_BISECT_LOG_USAGE \ + "git bisect log" +#define BUILTIN_GIT_BISECT_RUN_USAGE \ + N_("git bisect run <cmd>...") + +static const char * const git_bisect_usage[] = { + BUILTIN_GIT_BISECT_START_USAGE, + BUILTIN_GIT_BISECT_STATE_USAGE, + BUILTIN_GIT_BISECT_TERMS_USAGE, + BUILTIN_GIT_BISECT_SKIP_USAGE, + BUILTIN_GIT_BISECT_NEXT_USAGE, + BUILTIN_GIT_BISECT_RESET_USAGE, + BUILTIN_GIT_BISECT_VISUALIZE_USAGE, + BUILTIN_GIT_BISECT_REPLAY_USAGE, + BUILTIN_GIT_BISECT_LOG_USAGE, + BUILTIN_GIT_BISECT_RUN_USAGE, NULL }; @@ -1191,13 +1213,13 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc) if (bisect_next_check(terms, NULL)) return BISECT_FAILED; - if (argc) - sq_quote_argv(&command, argv); - else { + if (!argc) { error(_("bisect run failed: no command provided.")); return BISECT_FAILED; } + sq_quote_argv(&command, argv); + strbuf_ltrim(&command); while (1) { res = do_bisect_run(command.buf); @@ -1211,8 +1233,8 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc) if (is_first_run && (res == 126 || res == 127)) { int rc = verify_good(terms, command.buf); is_first_run = 0; - if (rc < 0) { - error(_("unable to verify '%s' on good" + if (rc < 0 || 128 <= rc) { + error(_("unable to verify %s on good" " revision"), command.buf); res = BISECT_FAILED; break; @@ -1227,7 +1249,7 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc) if (res < 0 || 128 <= res) { error(_("bisect run failed: exit code %d from" - " '%s' is < 0 or >= 128"), res, command.buf); + " %s is < 0 or >= 128"), res, command.buf); break; } @@ -1261,14 +1283,14 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc) if (res == BISECT_ONLY_SKIPPED_LEFT) error(_("bisect run cannot continue any more")); else if (res == BISECT_INTERNAL_SUCCESS_MERGE_BASE) { - printf(_("bisect run success")); + puts(_("bisect run success")); res = BISECT_OK; } else if (res == BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND) { - printf(_("bisect found first bad commit")); + puts(_("bisect found first bad commit")); res = BISECT_OK; } else if (res) { - error(_("bisect run failed: 'git bisect--helper --bisect-state" - " %s' exited with error code %d"), new_state, res); + error(_("bisect run failed: 'bisect-state %s'" + " exited with error code %d"), new_state, res); } else { continue; } @@ -1282,7 +1304,8 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc) 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 error(_("'%s' requires either no argument or a commit"), + "git bisect reset"); return bisect_reset(argc ? argv[0] : NULL); } @@ -1292,7 +1315,8 @@ static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNU struct bisect_terms terms = { 0 }; if (argc > 1) - return error(_("--bisect-terms requires 0 or 1 argument")); + return error(_("'%s' requires 0 or 1 argument"), + "git bisect terms"); res = bisect_terms(&terms, argc == 1 ? argv[0] : NULL); free_terms(&terms); return res; @@ -1315,29 +1339,16 @@ static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *pref struct bisect_terms terms = { 0 }; if (argc) - return error(_("--bisect-next requires 0 arguments")); + return error(_("'%s' requires 0 arguments"), + "git bisect next"); 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) +static int cmd_bisect__log(int argc UNUSED, const char **argv UNUSED, 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(); } @@ -1383,14 +1394,14 @@ static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSE struct bisect_terms terms = { 0 }; if (!argc) - return error(_("bisect run failed: no command provided.")); + return error(_("'%s' failed: no command provided."), "git bisect run"); 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) +int cmd_bisect(int argc, const char **argv, const char *prefix) { int res = 0; parse_opt_subcommand_fn *fn = NULL; @@ -1399,7 +1410,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) 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), @@ -1408,15 +1418,27 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) OPT_SUBCOMMAND("run", &fn, cmd_bisect__run), OPT_END() }; - argc = parse_options(argc, argv, prefix, options, - git_bisect_helper_usage, 0); - - if (!fn) - usage_with_options(git_bisect_helper_usage, options); - argc--; - argv++; - - res = fn(argc, argv, prefix); + argc = parse_options(argc, argv, prefix, options, git_bisect_usage, + PARSE_OPT_SUBCOMMAND_OPTIONAL); + + if (!fn) { + struct bisect_terms terms = { 0 }; + + if (!argc) + usage_msg_opt(_("need a command"), git_bisect_usage, options); + + set_terms(&terms, "bad", "good"); + get_terms(&terms); + if (check_and_set_terms(&terms, argv[0])) + usage_msg_optf(_("unknown command: '%s'"), git_bisect_usage, + options, argv[0]); + res = bisect_state(&terms, argv, argc); + free_terms(&terms); + } else { + argc--; + argv++; + res = fn(argc, argv, prefix); + } /* * Handle early success diff --git a/builtin/branch.c b/builtin/branch.c index 9470c980c1..f63fd45edb 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -581,13 +581,13 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int strbuf_release(&logmsg); strbuf_addf(&oldsection, "branch.%s", interpreted_oldname); - strbuf_release(&oldref); strbuf_addf(&newsection, "branch.%s", interpreted_newname); - strbuf_release(&newref); if (!copy && git_config_rename_section(oldsection.buf, newsection.buf) < 0) die(_("Branch is renamed, but update of config-file failed")); - if (copy && strcmp(oldname, newname) && git_config_copy_section(oldsection.buf, newsection.buf) < 0) + if (copy && strcmp(interpreted_oldname, interpreted_newname) && git_config_copy_section(oldsection.buf, newsection.buf) < 0) die(_("Branch is copied, but update of config-file failed")); + strbuf_release(&oldref); + strbuf_release(&newref); strbuf_release(&oldsection); strbuf_release(&newsection); } diff --git a/builtin/bugreport.c b/builtin/bugreport.c index 96052541cb..5bc254be80 100644 --- a/builtin/bugreport.c +++ b/builtin/bugreport.c @@ -106,6 +106,7 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix) const char *user_relative_path = NULL; char *prefixed_filename; size_t output_path_len; + int ret; const struct option bugreport_options[] = { OPT_CALLBACK_F(0, "diagnose", &diagnose, N_("mode"), @@ -182,7 +183,9 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix) user_relative_path); free(prefixed_filename); - UNLEAK(buffer); - UNLEAK(report_path); - return !!launch_editor(report_path.buf, NULL, NULL); + strbuf_release(&buffer); + + ret = !!launch_editor(report_path.buf, NULL, NULL); + strbuf_release(&report_path); + return ret; } diff --git a/builtin/bundle.c b/builtin/bundle.c index c12c09f854..acceef6200 100644 --- a/builtin/bundle.c +++ b/builtin/bundle.c @@ -55,13 +55,12 @@ static int parse_options_cmd_bundle(int argc, const char * const usagestr[], const struct option options[], char **bundle_file) { - int newargc; - newargc = parse_options(argc, argv, NULL, options, usagestr, + argc = parse_options(argc, argv, NULL, options, usagestr, PARSE_OPT_STOP_AT_NON_OPTION); - if (argc < 1) - usage_with_options(usagestr, options); + if (!argc) + usage_msg_opt(_("need a <file> argument"), usagestr, options); *bundle_file = prefix_filename(prefix, argv[0]); - return newargc; + return argc; } static int cmd_bundle_create(int argc, const char **argv, const char *prefix) { diff --git a/builtin/cat-file.c b/builtin/cat-file.c index b3be58b1fb..cc17635e76 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -132,8 +132,21 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, case 's': oi.sizep = &size; + + if (use_mailmap) { + oi.typep = &type; + oi.contentp = (void**)&buf; + } + if (oid_object_info_extended(the_repository, &oid, &oi, flags) < 0) die("git cat-file: could not get object info"); + + if (use_mailmap && (type == OBJ_COMMIT || type == OBJ_TAG)) { + size_t s = size; + buf = replace_idents_using_mailmap(buf, &s); + size = cast_size_t_to_ulong(s); + } + printf("%"PRIuMAX"\n", (uintmax_t)size); ret = 0; goto cleanup; @@ -431,6 +444,9 @@ static void batch_object_write(const char *obj_name, if (!data->skip_object_info) { int ret; + if (use_mailmap) + data->info.typep = &data->type; + if (pack) ret = packed_object_info(the_repository, pack, offset, &data->info); @@ -444,6 +460,18 @@ static void batch_object_write(const char *obj_name, fflush(stdout); return; } + + if (use_mailmap && (data->type == OBJ_COMMIT || data->type == OBJ_TAG)) { + size_t s = data->size; + char *buf = NULL; + + buf = repo_read_object_file(the_repository, &data->oid, &data->type, + &data->size); + buf = replace_idents_using_mailmap(buf, &s); + data->size = cast_size_t_to_ulong(s); + + free(buf); + } } strbuf_reset(scratch); diff --git a/builtin/checkout.c b/builtin/checkout.c index 3fa29a08ee..5963e1b74b 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -232,7 +232,7 @@ static int checkout_stage(int stage, const struct cache_entry *ce, int pos, pos++; } if (!overlay_mode) { - unlink_entry(ce); + unlink_entry(ce, NULL); return 0; } if (stage == 2) @@ -1270,7 +1270,7 @@ static int parse_branchname_arg(int argc, const char **argv, * between A and B, A...B names that merge base. * * (b) If <something> is _not_ a commit, either "--" is present - * or <something> is not a path, no -t or -b was given, and + * or <something> is not a path, no -t or -b was given, * and there is a tracking branch whose name is <something> * in one and only one remote (or if the branch exists on the * remote named in checkout.defaultRemote), then this is a @@ -1471,6 +1471,8 @@ static void die_if_some_operation_in_progress(void) "or \"git worktree add\".")); if (state.bisect_in_progress) warning(_("you are switching branch while bisecting")); + + wt_status_state_free_buffers(&state); } static int checkout_branch(struct checkout_opts *opts, diff --git a/builtin/clone.c b/builtin/clone.c index f518bb2dc1..5453ba5277 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -1271,6 +1271,27 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (refs) mapped_refs = wanted_peer_refs(refs, &remote->fetch); + if (!bundle_uri) { + /* + * Populate transport->got_remote_bundle_uri and + * transport->bundle_uri. We might get nothing. + */ + transport_get_remote_bundle_uri(transport); + + if (transport->bundles && + hashmap_get_size(&transport->bundles->bundles)) { + /* At this point, we need the_repository to match the cloned repo. */ + if (repo_init(the_repository, git_dir, work_tree)) + warning(_("failed to initialize the repo, skipping bundle URI")); + else if (fetch_bundle_list(the_repository, + transport->bundles)) + warning(_("failed to fetch advertised bundles")); + } else { + clear_bundle_list(transport->bundles); + FREE_AND_NULL(transport->bundles); + } + } + if (mapped_refs) { int hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport)); diff --git a/builtin/commit.c b/builtin/commit.c index 06b1330346..44b763d7cd 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -991,8 +991,11 @@ static int prepare_to_commit(const char *index_file, const char *prefix, struct object_id oid; const char *parent = "HEAD"; - if (!active_nr && read_cache() < 0) - die(_("Cannot read index")); + if (!active_nr) { + discard_cache(); + if (read_cache() < 0) + die(_("Cannot read index")); + } if (amend) parent = "HEAD^1"; @@ -1875,8 +1878,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix) apply_autostash(git_path_merge_autostash(the_repository)); cleanup: - UNLEAK(author_ident); - UNLEAK(err); - UNLEAK(sb); + strbuf_release(&author_ident); + strbuf_release(&err); + strbuf_release(&sb); return ret; } diff --git a/builtin/config.c b/builtin/config.c index 753e5fac29..060cf9f3e0 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -639,8 +639,9 @@ static char *default_user_config(void) int cmd_config(int argc, const char **argv, const char *prefix) { int nongit = !startup_info->have_repository; - char *value; + char *value = NULL; int flags = 0; + int ret = 0; given_config_source.file = xstrdup_or_null(getenv(CONFIG_ENVIRONMENT)); @@ -856,44 +857,38 @@ int cmd_config(int argc, const char **argv, const char *prefix) free(config_file); } else if (actions == ACTION_SET) { - int ret; check_write(); check_argc(argc, 2, 2); value = normalize_value(argv[0], argv[1]); - UNLEAK(value); ret = git_config_set_in_file_gently(given_config_source.file, argv[0], value); if (ret == CONFIG_NOTHING_SET) error(_("cannot overwrite multiple values with a single value\n" " Use a regexp, --add or --replace-all to change %s."), argv[0]); - return ret; } else if (actions == ACTION_SET_ALL) { check_write(); check_argc(argc, 2, 3); value = normalize_value(argv[0], argv[1]); - UNLEAK(value); - return git_config_set_multivar_in_file_gently(given_config_source.file, - argv[0], value, argv[2], - flags); + ret = git_config_set_multivar_in_file_gently(given_config_source.file, + argv[0], value, argv[2], + flags); } else if (actions == ACTION_ADD) { check_write(); check_argc(argc, 2, 2); value = normalize_value(argv[0], argv[1]); - UNLEAK(value); - return git_config_set_multivar_in_file_gently(given_config_source.file, - argv[0], value, - CONFIG_REGEX_NONE, - flags); + ret = git_config_set_multivar_in_file_gently(given_config_source.file, + argv[0], value, + CONFIG_REGEX_NONE, + flags); } else if (actions == ACTION_REPLACE_ALL) { check_write(); check_argc(argc, 2, 3); value = normalize_value(argv[0], argv[1]); - UNLEAK(value); - return git_config_set_multivar_in_file_gently(given_config_source.file, - argv[0], value, argv[2], - flags | CONFIG_FLAGS_MULTI_REPLACE); + ret = git_config_set_multivar_in_file_gently(given_config_source.file, + argv[0], value, argv[2], + flags | CONFIG_FLAGS_MULTI_REPLACE); } else if (actions == ACTION_GET) { check_argc(argc, 1, 2); @@ -934,26 +929,28 @@ int cmd_config(int argc, const char **argv, const char *prefix) flags | CONFIG_FLAGS_MULTI_REPLACE); } else if (actions == ACTION_RENAME_SECTION) { - int ret; check_write(); check_argc(argc, 2, 2); ret = git_config_rename_section_in_file(given_config_source.file, argv[0], argv[1]); if (ret < 0) return ret; - if (ret == 0) + else if (!ret) die(_("no such section: %s"), argv[0]); + else + ret = 0; } else if (actions == ACTION_REMOVE_SECTION) { - int ret; check_write(); check_argc(argc, 1, 1); ret = git_config_rename_section_in_file(given_config_source.file, argv[0], NULL); if (ret < 0) return ret; - if (ret == 0) + else if (!ret) die(_("no such section: %s"), argv[0]); + else + ret = 0; } else if (actions == ACTION_GET_COLOR) { check_argc(argc, 1, 2); @@ -966,5 +963,6 @@ int cmd_config(int argc, const char **argv, const char *prefix) return get_colorbool(argv[0], argc == 2); } - return 0; + free(value); + return ret; } diff --git a/builtin/diff.c b/builtin/diff.c index 163f2c6a87..26f1e532c6 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -612,7 +612,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) if (1 < rev.diffopt.skip_stat_unmatch) refresh_index_quietly(); release_revisions(&rev); - UNLEAK(ent); + object_array_clear(&ent); UNLEAK(blob); return result; } diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 3b3314e7b2..39a890fc00 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -409,7 +409,7 @@ static const char *anonymize_oid(const char *oid_hex) } static void show_filemodify(struct diff_queue_struct *q, - struct diff_options *options, void *data) + struct diff_options *options UNUSED, void *data) { int i; struct string_list *changed = data; diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index 6f30a4f93a..0feef8caf6 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -710,6 +710,7 @@ static int do_handle_client(struct fsmonitor_daemon_state *state, "fsmonitor: unsupported V1 protocol '%s'"), command); do_trivial = 1; + do_cookie = 1; } else { /* We have "builtin:*" */ @@ -719,6 +720,7 @@ static int do_handle_client(struct fsmonitor_daemon_state *state, "fsmonitor: invalid V2 protocol token '%s'", command); do_trivial = 1; + do_cookie = 1; } else { /* @@ -1209,7 +1211,7 @@ static int fsmonitor_run_daemon_1(struct fsmonitor_daemon_state *state) * events. */ if (pthread_create(&state->listener_thread, NULL, - fsm_listen__thread_proc, state) < 0) { + fsm_listen__thread_proc, state)) { ipc_server_stop_async(state->ipc_server_data); err = error(_("could not start fsmonitor listener thread")); goto cleanup; @@ -1220,7 +1222,7 @@ static int fsmonitor_run_daemon_1(struct fsmonitor_daemon_state *state) * Start the health thread to watch over our process. */ if (pthread_create(&state->health_thread, NULL, - fsm_health__thread_proc, state) < 0) { + fsm_health__thread_proc, state)) { ipc_server_stop_async(state->ipc_server_data); err = error(_("could not start fsmonitor health thread")); goto cleanup; diff --git a/builtin/log.c b/builtin/log.c index 89447a5083..057e299c24 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -52,6 +52,7 @@ static int decoration_style; static int decoration_given; static int use_mailmap_config = 1; static unsigned int force_in_body_from; +static int stdout_mboxrd; static const char *fmt_patch_subject_prefix = "PATCH"; static int fmt_patch_name_max = FORMAT_PATCH_NAME_MAX_DEFAULT; static const char *fmt_pretty; @@ -1077,6 +1078,10 @@ static int git_format_config(const char *var, const char *value, void *cb) cover_from_description_mode = parse_cover_from_description(value); return 0; } + if (!strcmp(var, "format.mboxrd")) { + stdout_mboxrd = git_config_bool(var, value); + return 0; + } return git_log_config(var, value, cb); } @@ -2105,6 +2110,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.diffopt.close_file, "--output", !!output_directory, "--output-directory"); + if (use_stdout && stdout_mboxrd) + rev.commit_format = CMIT_FMT_MBOXRD; + if (use_stdout) { setup_pager(); } else if (!rev.diffopt.close_file) { diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 4cf8a23648..a03b559eca 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -613,6 +613,7 @@ void overlay_tree_on_index(struct index_state *istate, if (!fn) fn = read_one_entry_quick; err = read_tree(the_repository, tree, &pathspec, fn, istate); + clear_pathspec(&pathspec); if (err) die("unable to read tree entries %s", tree_name); diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index e3767087bb..828dc81c42 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -3,6 +3,7 @@ #include "tree-walk.h" #include "xdiff-interface.h" #include "help.h" +#include "commit.h" #include "commit-reach.h" #include "merge-ort.h" #include "object-store.h" @@ -98,7 +99,7 @@ static void *origin(struct merge_list *entry, unsigned long *size) return NULL; } -static int show_outf(void *priv_, mmbuffer_t *mb, int nbuf) +static int show_outf(void *priv UNUSED, mmbuffer_t *mb, int nbuf) { int i; for (i = 0; i < nbuf; i++) @@ -406,6 +407,7 @@ struct merge_tree_options { }; static int real_merge(struct merge_tree_options *o, + const char *merge_base, const char *branch1, const char *branch2, const char *prefix) { @@ -432,16 +434,31 @@ static int real_merge(struct merge_tree_options *o, opt.branch1 = branch1; opt.branch2 = branch2; - /* - * Get the merge bases, in reverse order; see comment above - * merge_incore_recursive in merge-ort.h - */ - merge_bases = get_merge_bases(parent1, parent2); - if (!merge_bases && !o->allow_unrelated_histories) - die(_("refusing to merge unrelated histories")); - merge_bases = reverse_commit_list(merge_bases); + if (merge_base) { + struct commit *base_commit; + struct tree *base_tree, *parent1_tree, *parent2_tree; + + base_commit = lookup_commit_reference_by_name(merge_base); + if (!base_commit) + die(_("could not lookup commit %s"), merge_base); + + opt.ancestor = merge_base; + base_tree = get_commit_tree(base_commit); + parent1_tree = get_commit_tree(parent1); + parent2_tree = get_commit_tree(parent2); + merge_incore_nonrecursive(&opt, base_tree, parent1_tree, parent2_tree, &result); + } else { + /* + * Get the merge bases, in reverse order; see comment above + * merge_incore_recursive in merge-ort.h + */ + merge_bases = get_merge_bases(parent1, parent2); + if (!merge_bases && !o->allow_unrelated_histories) + die(_("refusing to merge unrelated histories")); + merge_bases = reverse_commit_list(merge_bases); + merge_incore_recursive(&opt, merge_bases, parent1, parent2, &result); + } - merge_incore_recursive(&opt, merge_bases, parent1, parent2, &result); if (result.clean < 0) die(_("failure to merge")); @@ -487,6 +504,7 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) struct merge_tree_options o = { .show_messages = -1 }; int expected_remaining_argc; int original_argc; + const char *merge_base = NULL; const char * const merge_tree_usage[] = { N_("git merge-tree [--write-tree] [<options>] <branch1> <branch2>"), @@ -515,6 +533,10 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) &o.use_stdin, N_("perform multiple merges, one per line of input"), PARSE_OPT_NONEG), + OPT_STRING(0, "merge-base", + &merge_base, + N_("commit"), + N_("specify a merge-base for the merge")), OPT_END() }; @@ -529,16 +551,35 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) if (o.mode == MODE_TRIVIAL) die(_("--trivial-merge is incompatible with all other options")); + if (merge_base) + die(_("--merge-base is incompatible with --stdin")); line_termination = '\0'; while (strbuf_getline_lf(&buf, stdin) != EOF) { struct strbuf **split; int result; + const char *input_merge_base = NULL; split = strbuf_split(&buf, ' '); - if (!split[0] || !split[1] || split[2]) + if (!split[0] || !split[1]) die(_("malformed input line: '%s'."), buf.buf); strbuf_rtrim(split[0]); - result = real_merge(&o, split[0]->buf, split[1]->buf, prefix); + strbuf_rtrim(split[1]); + + /* parse the merge-base */ + if (!strcmp(split[1]->buf, "--")) { + input_merge_base = split[0]->buf; + } + + if (input_merge_base && split[2] && split[3] && !split[4]) { + strbuf_rtrim(split[2]); + strbuf_rtrim(split[3]); + result = real_merge(&o, input_merge_base, split[2]->buf, split[3]->buf, prefix); + } else if (!input_merge_base && !split[2]) { + result = real_merge(&o, NULL, split[0]->buf, split[1]->buf, prefix); + } else { + die(_("malformed input line: '%s'."), buf.buf); + } + if (result < 0) die(_("merging cannot continue; got unclean result of %d"), result); strbuf_list_free(split); @@ -581,7 +622,7 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) /* Do the relevant type of merge */ if (o.mode == MODE_REAL) - return real_merge(&o, argv[0], argv[1], prefix); + return real_merge(&o, merge_base, argv[0], argv[1], prefix); else return trivial_merge(argv[0], argv[1], argv[2]); } diff --git a/builtin/merge.c b/builtin/merge.c index dd474371a2..74de2ebd2b 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -188,7 +188,7 @@ static struct strategy *get_strategy(const char *name) for (i = 0; i < main_cmds.cnt; i++) { int j, found = 0; struct cmdname *ent = main_cmds.names[i]; - for (j = 0; j < ARRAY_SIZE(all_strategy); j++) + for (j = 0; !found && j < ARRAY_SIZE(all_strategy); j++) if (!strncmp(ent->name, all_strategy[j].name, ent->len) && !all_strategy[j].name[ent->len]) found = 1; @@ -776,7 +776,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, } static void count_diff_files(struct diff_queue_struct *q, - struct diff_options *opt, void *data) + struct diff_options *opt UNUSED, void *data) { int *count = data; @@ -1789,5 +1789,6 @@ done: } strbuf_release(&buf); free(branch_to_free); + discard_index(&the_index); return ret; } diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 573d0b20b7..2193f80b89 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -4149,21 +4149,6 @@ static int option_parse_cruft_expiration(const struct option *opt, return 0; } -struct po_filter_data { - unsigned have_revs:1; - struct rev_info revs; -}; - -static struct list_objects_filter_options *po_filter_revs_init(void *value) -{ - struct po_filter_data *data = value; - - repo_init_revisions(the_repository, &data->revs, NULL); - data->have_revs = 1; - - return &data->revs.filter; -} - int cmd_pack_objects(int argc, const char **argv, const char *prefix) { int use_internal_rev_list = 0; @@ -4174,7 +4159,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) int rev_list_index = 0; int stdin_packs = 0; struct string_list keep_pack_list = STRING_LIST_INIT_NODUP; - struct po_filter_data pfd = { .have_revs = 0 }; + struct list_objects_filter_options filter_options = + LIST_OBJECTS_FILTER_INIT; struct option pack_objects_options[] = { OPT_SET_INT('q', "quiet", &progress, @@ -4265,7 +4251,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) &write_bitmap_index, N_("write a bitmap index if possible"), WRITE_BITMAP_QUIET, PARSE_OPT_HIDDEN), - OPT_PARSE_LIST_OBJECTS_FILTER_INIT(&pfd, po_filter_revs_init), + OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options), OPT_CALLBACK_F(0, "missing", NULL, N_("action"), N_("handling for missing objects"), PARSE_OPT_NONEG, option_parse_missing_action), @@ -4385,7 +4371,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) if (!rev_list_all || !rev_list_reflog || !rev_list_index) unpack_unreachable_expiration = 0; - if (pfd.have_revs && pfd.revs.filter.choice) { + if (filter_options.choice) { if (!pack_to_stdout) die(_("cannot use --filter without --stdout")); if (stdin_packs) @@ -4472,13 +4458,11 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) read_cruft_objects(); } else if (!use_internal_rev_list) { read_object_list_from_stdin(); - } else if (pfd.have_revs) { - get_object_list(&pfd.revs, rp.nr, rp.v); - release_revisions(&pfd.revs); } else { struct rev_info revs; repo_init_revisions(the_repository, &revs, NULL); + list_objects_filter_copy(&revs.filter, &filter_options); get_object_list(&revs, rp.nr, rp.v); release_revisions(&revs); } @@ -4513,6 +4497,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) reuse_packfile_objects); cleanup: + list_objects_filter_release(&filter_options); strvec_clear(&rp); return 0; diff --git a/builtin/range-diff.c b/builtin/range-diff.c index e2a74efb42..aecfae12d3 100644 --- a/builtin/range-diff.c +++ b/builtin/range-diff.c @@ -47,7 +47,7 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix) repo_diff_setup(the_repository, &diffopt); - options = parse_options_concat(range_diff_options, diffopt.parseopts); + options = add_diff_options(range_diff_options, &diffopt); argc = parse_options(argc, argv, prefix, options, builtin_range_diff_usage, PARSE_OPT_KEEP_DASHDASH); diff --git a/builtin/read-tree.c b/builtin/read-tree.c index f702f9d47b..3ce7541783 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -114,6 +114,7 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) int prefix_set = 0; struct lock_file lock_file = LOCK_INIT; const struct option read_tree_options[] = { + OPT__SUPER_PREFIX(&opts.super_prefix), OPT_CALLBACK_F(0, "index-output", NULL, N_("file"), N_("write resulting index to <file>"), PARSE_OPT_NONEG, index_output_cb), diff --git a/builtin/rebase.c b/builtin/rebase.c index b22768ca5b..a26cc0cfdb 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -113,7 +113,7 @@ struct rebase_options { int autostash; int committer_date_is_author_date; int ignore_date; - char *cmd; + struct string_list exec; int allow_empty_message; int rebase_merges, rebase_cousins; char *strategy, *strategy_opts; @@ -131,6 +131,7 @@ struct rebase_options { .default_backend = "merge", \ .flags = REBASE_NO_QUIET, \ .git_am_opts = STRVEC_INIT, \ + .exec = STRING_LIST_INIT_NODUP, \ .git_format_patch_opt = STRBUF_INIT, \ .fork_point = -1, \ } @@ -243,17 +244,6 @@ static int init_basic_state(struct replay_opts *opts, const char *head_name, return write_basic_state(opts, head_name, onto, orig_head); } -static void split_exec_commands(const char *cmd, struct string_list *commands) -{ - if (cmd && *cmd) { - string_list_split(commands, cmd, '\n', -1); - - /* rebase.c adds a new line to cmd after every command, - * so here the last command is always empty */ - string_list_remove_empty_items(commands, 0); - } -} - static int do_interactive_rebase(struct rebase_options *opts, unsigned flags) { int ret; @@ -261,7 +251,6 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags) struct strvec make_script_args = STRVEC_INIT; struct todo_list todo_list = TODO_LIST_INIT; struct replay_opts replay = get_replay_opts(opts); - struct string_list commands = STRING_LIST_INIT_DUP; if (get_revision_ranges(opts->upstream, opts->onto, &opts->orig_head->object.oid, &revisions, &shortrevisions)) @@ -297,14 +286,12 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags) &todo_list)) BUG("unusable todo list"); - split_exec_commands(opts->cmd, &commands); ret = complete_action(the_repository, &replay, flags, shortrevisions, opts->onto_name, opts->onto, - &opts->orig_head->object.oid, &commands, + &opts->orig_head->object.oid, &opts->exec, opts->autosquash, opts->update_refs, &todo_list); } - string_list_clear(&commands, 0); free(revisions); free(shortrevisions); todo_list_release(&todo_list); @@ -1032,7 +1019,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) struct object_id branch_base; int ignore_whitespace = 0; const char *gpg_sign = NULL; - struct string_list exec = STRING_LIST_INIT_NODUP; const char *rebase_merges = NULL; struct string_list strategy_options = STRING_LIST_INIT_NODUP; struct object_id squash_onto; @@ -1127,7 +1113,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) N_("GPG-sign commits"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, OPT_AUTOSTASH(&options.autostash), - OPT_STRING_LIST('x', "exec", &exec, N_("exec"), + OPT_STRING_LIST('x', "exec", &options.exec, N_("exec"), N_("add exec lines after each commit of the " "editable list")), OPT_BOOL_F(0, "allow-empty-message", @@ -1250,7 +1236,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (trace2_is_enabled()) { if (is_merge(&options)) trace2_cmd_mode("interactive"); - else if (exec.nr) + else if (options.exec.nr) trace2_cmd_mode("interactive-exec"); else trace2_cmd_mode(action_names[options.action]); @@ -1322,6 +1308,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (reset_head(the_repository, &ropts) < 0) die(_("could not move back to %s"), oid_to_hex(&options.orig_head->object.oid)); + strbuf_release(&head_msg); remove_branch_state(the_repository, 0); ret = finish_rebase(&options); goto cleanup; @@ -1377,7 +1364,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if ((options.flags & REBASE_INTERACTIVE_EXPLICIT) || (options.action != ACTION_NONE) || - (exec.nr > 0) || + (options.exec.nr > 0) || options.autosquash) { allow_preemptive_ff = 0; } @@ -1401,8 +1388,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) } } - for (i = 0; i < exec.nr; i++) - if (check_exec_cmd(exec.items[i].string)) + for (i = 0; i < options.exec.nr; i++) + if (check_exec_cmd(options.exec.items[i].string)) exit(1); if (!(options.flags & REBASE_NO_QUIET)) @@ -1421,17 +1408,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (gpg_sign) options.gpg_sign_opt = xstrfmt("-S%s", gpg_sign); - if (exec.nr) { - int i; - + if (options.exec.nr) imply_merge(&options, "--exec"); - strbuf_reset(&buf); - for (i = 0; i < exec.nr; i++) - strbuf_addf(&buf, "exec %s\n", exec.items[i].string); - options.cmd = xstrdup(buf.buf); - } - if (rebase_merges) { if (!*rebase_merges) ; /* default mode; do nothing */ @@ -1542,7 +1521,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (options.empty == EMPTY_UNSPECIFIED) { if (options.flags & REBASE_INTERACTIVE_EXPLICIT) options.empty = EMPTY_ASK; - else if (exec.nr > 0) + else if (options.exec.nr > 0) options.empty = EMPTY_KEEP; else options.empty = EMPTY_DROP; @@ -1828,10 +1807,12 @@ cleanup: strbuf_release(&revisions); free(options.reflog_action); free(options.head_name); + strvec_clear(&options.git_am_opts); free(options.gpg_sign_opt); - free(options.cmd); + string_list_clear(&options.exec, 0); free(options.strategy); strbuf_release(&options.git_format_patch_opt); free(squash_onto_name); + string_list_clear(&strategy_options, 0); return !!ret; } diff --git a/builtin/remote-ext.c b/builtin/remote-ext.c index fd3538d4f0..ee338bf440 100644 --- a/builtin/remote-ext.c +++ b/builtin/remote-ext.c @@ -169,6 +169,8 @@ static int command_loop(const char *child) while (1) { size_t i; + const char *arg; + if (!fgets(buffer, MAXCOMMAND - 1, stdin)) { if (ferror(stdin)) die("Command input error"); @@ -182,10 +184,10 @@ static int command_loop(const char *child) if (!strcmp(buffer, "capabilities")) { printf("*connect\n\n"); fflush(stdout); - } else if (!strncmp(buffer, "connect ", 8)) { + } else if (skip_prefix(buffer, "connect ", &arg)) { printf("\n"); fflush(stdout); - return run_child(child, buffer + 8); + return run_child(child, arg); } else { fprintf(stderr, "Bad command"); return 1; diff --git a/builtin/remote-fd.c b/builtin/remote-fd.c index 91dfe07e06..b2a3980b1d 100644 --- a/builtin/remote-fd.c +++ b/builtin/remote-fd.c @@ -40,7 +40,7 @@ static void command_loop(int input_fd, int output_fd) if (!strcmp(buffer, "capabilities")) { printf("*connect\n\n"); fflush(stdout); - } else if (!strncmp(buffer, "connect ", 8)) { + } else if (starts_with(buffer, "connect ")) { printf("\n"); fflush(stdout); if (bidirectional_transfer_loop(input_fd, diff --git a/builtin/repack.c b/builtin/repack.c index 65eb1b8bd2..c1402ad038 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -973,6 +973,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) item = string_list_append(&names, line.buf); item->util = populate_pack_exts(item->string); } + strbuf_release(&line); fclose(out); ret = finish_command(&cmd); if (ret) @@ -1175,7 +1176,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix) string_list_clear(&existing_nonkept_packs, 0); string_list_clear(&existing_kept_packs, 0); clear_pack_geometry(geometry); - strbuf_release(&line); return 0; } diff --git a/builtin/rerere.c b/builtin/rerere.c index 8b7392d5b4..94ffb8c21a 100644 --- a/builtin/rerere.c +++ b/builtin/rerere.c @@ -14,7 +14,7 @@ static const char * const rerere_usage[] = { NULL, }; -static int outf(void *dummy, mmbuffer_t *ptr, int nbuf) +static int outf(void *dummy UNUSED, mmbuffer_t *ptr, int nbuf) { int i; for (i = 0; i < nbuf; i++) diff --git a/builtin/reset.c b/builtin/reset.c index 1fa86edb4c..fea20a9ba0 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -133,7 +133,8 @@ static void print_new_head_line(struct commit *commit) } static void update_index_from_diff(struct diff_queue_struct *q, - struct diff_options *opt, void *data) + struct diff_options *opt UNUSED, + void *data) { int i; int intent_to_add = *(int *)data; @@ -485,5 +486,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) if (!pathspec.nr) remove_branch_state(the_repository, 0); + discard_index(&the_index); + return update_ref_status; } diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 1c344d74a7..e67999e5eb 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -530,6 +530,7 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix) strbuf_addstr(&parsed, " --"); sq_quote_argv(&parsed, argv); puts(parsed.buf); + strbuf_release(&parsed); return 0; } diff --git a/builtin/revert.c b/builtin/revert.c index 6a9b550a61..f2d86d2a8f 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -221,6 +221,7 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts) opts->strategy = xstrdup_or_null(opts->strategy); if (!opts->strategy && getenv("GIT_TEST_MERGE_ALGORITHM")) opts->strategy = xstrdup(getenv("GIT_TEST_MERGE_ALGORITHM")); + free(options); if (cmd == 'q') { int ret = sequencer_remove_state(opts); @@ -261,6 +262,9 @@ int cmd_cherry_pick(int argc, const char **argv, const char *prefix) opts.action = REPLAY_PICK; sequencer_init_config(&opts); res = run_sequencer(argc, argv, &opts); + if (opts.revs) + release_revisions(opts.revs); + free(opts.revs); if (res < 0) die(_("cherry-pick failed")); return res; diff --git a/builtin/rm.c b/builtin/rm.c index d4989d4d86..4a4aec0d00 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -86,7 +86,7 @@ static void submodules_absorb_gitdir_if_needed(void) continue; if (!submodule_uses_gitfile(name)) - absorb_git_dir_into_superproject(name); + absorb_git_dir_into_superproject(name, NULL); } } diff --git a/builtin/stash.c b/builtin/stash.c index 62e36718d3..bb0fd86143 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1689,8 +1689,10 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q } done: + strbuf_release(&patch); free_stash_info(&info); strbuf_release(&stash_msg_buf); + strbuf_release(&untracked_files); return ret; } diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 05f2c9bc98..4c173d8b37 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -113,10 +113,9 @@ static char *resolve_relative_url(const char *rel_url, const char *up_path, int } /* the result should be freed by the caller. */ -static char *get_submodule_displaypath(const char *path, const char *prefix) +static char *get_submodule_displaypath(const char *path, const char *prefix, + const char *super_prefix) { - const char *super_prefix = get_super_prefix(); - if (prefix && super_prefix) { BUG("cannot have prefix '%s' and superprefix '%s'", prefix, super_prefix); @@ -279,6 +278,7 @@ struct foreach_cb { int argc; const char **argv; const char *prefix; + const char *super_prefix; int quiet; int recursive; }; @@ -294,7 +294,8 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item, struct child_process cp = CHILD_PROCESS_INIT; char *displaypath; - displaypath = get_submodule_displaypath(path, info->prefix); + displaypath = get_submodule_displaypath(path, info->prefix, + info->super_prefix); sub = submodule_from_path(the_repository, null_oid(), path); @@ -364,10 +365,10 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item, cpr.dir = path; prepare_submodule_repo_env(&cpr.env); - strvec_pushl(&cpr.args, "--super-prefix", NULL); - strvec_pushf(&cpr.args, "%s/", displaypath); strvec_pushl(&cpr.args, "submodule--helper", "foreach", "--recursive", NULL); + strvec_pushl(&cpr.args, "--super-prefix", NULL); + strvec_pushf(&cpr.args, "%s/", displaypath); if (info->quiet) strvec_push(&cpr.args, "--quiet"); @@ -391,6 +392,7 @@ static int module_foreach(int argc, const char **argv, const char *prefix) struct pathspec pathspec = { 0 }; struct module_list list = MODULE_LIST_INIT; struct option module_foreach_options[] = { + OPT__SUPER_PREFIX(&info.super_prefix), OPT__QUIET(&info.quiet, N_("suppress output of entering each submodule command")), OPT_BOOL(0, "recursive", &info.recursive, N_("recurse into nested submodules")), @@ -435,11 +437,13 @@ static int starts_with_dot_dot_slash(const char *const path) struct init_cb { const char *prefix; + const char *super_prefix; unsigned int flags; }; #define INIT_CB_INIT { 0 } static void init_submodule(const char *path, const char *prefix, + const char *super_prefix, unsigned int flags) { const struct submodule *sub; @@ -447,7 +451,7 @@ static void init_submodule(const char *path, const char *prefix, const char *upd; char *url = NULL, *displaypath; - displaypath = get_submodule_displaypath(path, prefix); + displaypath = get_submodule_displaypath(path, prefix, super_prefix); sub = submodule_from_path(the_repository, null_oid(), path); @@ -523,7 +527,8 @@ static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data { struct init_cb *info = cb_data; - init_submodule(list_item->name, info->prefix, info->flags); + init_submodule(list_item->name, info->prefix, info->super_prefix, + info->flags); } static int module_init(int argc, const char **argv, const char *prefix) @@ -570,6 +575,7 @@ cleanup: struct status_cb { const char *prefix; + const char *super_prefix; unsigned int flags; }; #define STATUS_CB_INIT { 0 } @@ -608,7 +614,7 @@ static int handle_submodule_head_ref(const char *refname UNUSED, static void status_submodule(const char *path, const struct object_id *ce_oid, unsigned int ce_flags, const char *prefix, - unsigned int flags) + const char *super_prefix, unsigned int flags) { char *displaypath; struct strvec diff_files_args = STRVEC_INIT; @@ -624,7 +630,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, die(_("no submodule mapping found in .gitmodules for path '%s'"), path); - displaypath = get_submodule_displaypath(path, prefix); + displaypath = get_submodule_displaypath(path, prefix, super_prefix); if ((CE_STAGEMASK & ce_flags) >> CE_STAGESHIFT) { print_status(flags, 'U', path, null_oid(), displaypath); @@ -682,10 +688,10 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, cpr.dir = path; prepare_submodule_repo_env(&cpr.env); - strvec_push(&cpr.args, "--super-prefix"); - strvec_pushf(&cpr.args, "%s/", displaypath); strvec_pushl(&cpr.args, "submodule--helper", "status", "--recursive", NULL); + strvec_push(&cpr.args, "--super-prefix"); + strvec_pushf(&cpr.args, "%s/", displaypath); if (flags & OPT_CACHED) strvec_push(&cpr.args, "--cached"); @@ -709,7 +715,7 @@ static void status_submodule_cb(const struct cache_entry *list_item, struct status_cb *info = cb_data; status_submodule(list_item->name, &list_item->oid, list_item->ce_flags, - info->prefix, info->flags); + info->prefix, info->super_prefix, info->flags); } static int module_status(int argc, const char **argv, const char *prefix) @@ -719,6 +725,7 @@ static int module_status(int argc, const char **argv, const char *prefix) struct module_list list = MODULE_LIST_INIT; int quiet = 0; struct option module_status_options[] = { + OPT__SUPER_PREFIX(&info.super_prefix), OPT__QUIET(&quiet, N_("suppress submodule status output")), OPT_BIT(0, "cached", &info.flags, N_("use commit stored in the index instead of the one stored in the submodule HEAD"), OPT_CACHED), OPT_BIT(0, "recursive", &info.flags, N_("recurse into nested submodules"), OPT_RECURSIVE), @@ -787,6 +794,7 @@ struct summary_cb { int argc; const char **argv; const char *prefix; + const char *super_prefix; unsigned int cached: 1; unsigned int for_status: 1; unsigned int files: 1; @@ -948,7 +956,8 @@ static void generate_submodule_summary(struct summary_cb *info, dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7); } - displaypath = get_submodule_displaypath(p->sm_path, info->prefix); + displaypath = get_submodule_displaypath(p->sm_path, info->prefix, + info->super_prefix); if (!missing_src && !missing_dst) { struct child_process cp_rev_list = CHILD_PROCESS_INIT; @@ -1043,7 +1052,7 @@ static void prepare_submodule_summary(struct summary_cb *info, } static void submodule_summary_callback(struct diff_queue_struct *q, - struct diff_options *options, + struct diff_options *options UNUSED, void *data) { int i; @@ -1203,12 +1212,13 @@ static int module_summary(int argc, const char **argv, const char *prefix) struct sync_cb { const char *prefix; + const char *super_prefix; unsigned int flags; }; #define SYNC_CB_INIT { 0 } static void sync_submodule(const char *path, const char *prefix, - unsigned int flags) + const char *super_prefix, unsigned int flags) { const struct submodule *sub; char *remote_key = NULL; @@ -1239,7 +1249,7 @@ static void sync_submodule(const char *path, const char *prefix, super_config_url = xstrdup(""); } - displaypath = get_submodule_displaypath(path, prefix); + displaypath = get_submodule_displaypath(path, prefix, super_prefix); if (!(flags & OPT_QUIET)) printf(_("Synchronizing submodule url for '%s'\n"), @@ -1276,10 +1286,11 @@ static void sync_submodule(const char *path, const char *prefix, cpr.dir = path; prepare_submodule_repo_env(&cpr.env); - strvec_push(&cpr.args, "--super-prefix"); - strvec_pushf(&cpr.args, "%s/", displaypath); strvec_pushl(&cpr.args, "submodule--helper", "sync", "--recursive", NULL); + strvec_push(&cpr.args, "--super-prefix"); + strvec_pushf(&cpr.args, "%s/", displaypath); + if (flags & OPT_QUIET) strvec_push(&cpr.args, "--quiet"); @@ -1302,7 +1313,8 @@ static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data { struct sync_cb *info = cb_data; - sync_submodule(list_item->name, info->prefix, info->flags); + sync_submodule(list_item->name, info->prefix, info->super_prefix, + info->flags); } static int module_sync(int argc, const char **argv, const char *prefix) @@ -1313,6 +1325,7 @@ static int module_sync(int argc, const char **argv, const char *prefix) int quiet = 0; int recursive = 0; struct option module_sync_options[] = { + OPT__SUPER_PREFIX(&info.super_prefix), OPT__QUIET(&quiet, N_("suppress output of synchronizing submodule url")), OPT_BOOL(0, "recursive", &recursive, N_("recurse into nested submodules")), @@ -1365,7 +1378,7 @@ static void deinit_submodule(const char *path, const char *prefix, if (!sub || !sub->name) goto cleanup; - displaypath = get_submodule_displaypath(path, prefix); + displaypath = get_submodule_displaypath(path, prefix, NULL); /* remove the submodule work tree (unless the user already did it) */ if (is_directory(path)) { @@ -1379,7 +1392,7 @@ static void deinit_submodule(const char *path, const char *prefix, ".git file by using absorbgitdirs."), displaypath); - absorb_git_dir_into_superproject(path); + absorb_git_dir_into_superproject(path, NULL); } @@ -1883,6 +1896,7 @@ static void submodule_update_clone_release(struct submodule_update_clone *suc) struct update_data { const char *prefix; + const char *super_prefix; char *displaypath; enum submodule_update_type update_default; struct object_id suboid; @@ -1958,7 +1972,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce, enum submodule_update_type update_type; char *key; const struct update_data *ud = suc->update_data; - char *displaypath = get_submodule_displaypath(ce->name, ud->prefix); + char *displaypath = get_submodule_displaypath(ce->name, ud->prefix, + ud->super_prefix); struct strbuf sb = STRBUF_INIT; int needs_cloning = 0; int need_free_url = 0; @@ -2438,11 +2453,11 @@ static void update_data_to_args(const struct update_data *update_data, { enum submodule_update_type update_type = update_data->update_default; + strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL); if (update_data->displaypath) { strvec_push(args, "--super-prefix"); strvec_pushf(args, "%s/", update_data->displaypath); } - strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL); strvec_pushf(args, "--jobs=%d", update_data->max_jobs); if (update_data->quiet) strvec_push(args, "--quiet"); @@ -2608,7 +2623,8 @@ static int update_submodules(struct update_data *update_data) goto fail; update_data->displaypath = get_submodule_displaypath( - update_data->sm_path, update_data->prefix); + update_data->sm_path, update_data->prefix, + update_data->super_prefix); code = update_submodule(update_data); FREE_AND_NULL(update_data->displaypath); fail: @@ -2634,6 +2650,7 @@ static int module_update(int argc, const char **argv, const char *prefix) LIST_OBJECTS_FILTER_INIT; int ret; struct option module_update_options[] = { + OPT__SUPER_PREFIX(&opt.super_prefix), OPT__FORCE(&opt.force, N_("force checkout updates"), 0), OPT_BOOL(0, "init", &opt.init, N_("initialize uninitialized submodules before update")), @@ -2730,6 +2747,7 @@ static int module_update(int argc, const char **argv, const char *prefix) module_list_active(&list); info.prefix = opt.prefix; + info.super_prefix = opt.super_prefix; if (opt.quiet) info.flags |= OPT_QUIET; @@ -2828,7 +2846,9 @@ 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; + const char *super_prefix = NULL; struct option embed_gitdir_options[] = { + OPT__SUPER_PREFIX(&super_prefix), OPT_END() }; const char *const git_submodule_helper_usage[] = { @@ -2844,7 +2864,8 @@ 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); + absorb_git_dir_into_superproject(list.entries[i]->name, + super_prefix); ret = 0; cleanup: @@ -2876,7 +2897,7 @@ static int module_set_url(int argc, const char **argv, const char *prefix) config_name = xstrfmt("submodule.%s.url", path); config_set_in_gitmodules_file_gently(config_name, newurl); - sync_submodule(path, prefix, quiet ? OPT_QUIET : 0); + sync_submodule(path, prefix, NULL, quiet ? OPT_QUIET : 0); free(config_name); @@ -3198,9 +3219,8 @@ static void die_on_index_match(const char *path, int force) ensure_full_index(&the_index); /* - * Since there is only one pathspec, we just need - * need to check ps_matched[0] to know if a cache - * entry matched. + * Since there is only one pathspec, we just need to + * check ps_matched[0] to know if a cache entry matched. */ for (i = 0; i < the_index.cache_nr; i++) { ce_path_match(&the_index, the_index.cache[i], &ps, @@ -3353,8 +3373,6 @@ cleanup: int cmd_submodule__helper(int argc, const char **argv, const char *prefix) { - const char *cmd = argv[0]; - const char *subcmd; parse_opt_subcommand_fn *fn = NULL; const char *const usage[] = { N_("git submodule--helper <command>"), @@ -3378,18 +3396,6 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix) 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)); return fn(argc, argv, prefix); } diff --git a/builtin/unpack-file.c b/builtin/unpack-file.c index 9e8119dd35..88de32b7d7 100644 --- a/builtin/unpack-file.c +++ b/builtin/unpack-file.c @@ -19,6 +19,7 @@ static char *create_temp_file(struct object_id *oid) if (write_in_full(fd, buf, size) < 0) die_errno("unable to write temp-file"); close(fd); + free(buf); return path; } diff --git a/builtin/var.c b/builtin/var.c index 491db27429..a80c1df86f 100644 --- a/builtin/var.c +++ b/builtin/var.c @@ -11,12 +11,12 @@ static const char var_usage[] = "git var (-l | <variable>)"; static const char *editor(int flag) { - const char *pgm = git_editor(); - - if (!pgm && flag & IDENT_STRICT) - die("Terminal is dumb, but EDITOR unset"); + return git_editor(); +} - return pgm; +static const char *sequence_editor(int flag) +{ + return git_sequence_editor(); } static const char *pager(int flag) @@ -41,6 +41,7 @@ static struct git_var git_vars[] = { { "GIT_COMMITTER_IDENT", git_committer_info }, { "GIT_AUTHOR_IDENT", git_author_info }, { "GIT_EDITOR", editor }, + { "GIT_SEQUENCE_EDITOR", sequence_editor }, { "GIT_PAGER", pager }, { "GIT_DEFAULT_BRANCH", default_branch }, { "", NULL }, @@ -56,18 +57,15 @@ static void list_vars(void) printf("%s=%s\n", ptr->name, val); } -static const char *read_var(const char *var) +static const struct git_var *get_git_var(const char *var) { struct git_var *ptr; - const char *val; - val = NULL; for (ptr = git_vars; ptr->read; ptr++) { if (strcmp(var, ptr->name) == 0) { - val = ptr->read(IDENT_STRICT); - break; + return ptr; } } - return val; + return NULL; } static int show_config(const char *var, const char *value, void *cb) @@ -81,7 +79,9 @@ static int show_config(const char *var, const char *value, void *cb) int cmd_var(int argc, const char **argv, const char *prefix) { - const char *val = NULL; + const struct git_var *git_var; + const char *val; + if (argc != 2) usage(var_usage); @@ -91,10 +91,15 @@ int cmd_var(int argc, const char **argv, const char *prefix) return 0; } git_config(git_default_config, NULL); - val = read_var(argv[1]); - if (!val) + + git_var = get_git_var(argv[1]); + if (!git_var) usage(var_usage); + val = git_var->read(IDENT_STRICT); + if (!val) + return 1; + printf("%s\n", val); return 0; diff --git a/builtin/worktree.c b/builtin/worktree.c index 4a24d53be1..591d659fae 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -629,6 +629,7 @@ static int add(int ac, const char **av, const char *prefix) N_("try to match the new branch name with a remote-tracking branch")), OPT_END() }; + int ret; memset(&opts, 0, sizeof(opts)); opts.checkout = 1; @@ -705,9 +706,9 @@ static int add(int ac, const char **av, const char *prefix) die(_("--[no-]track can only be used if a new branch is created")); } - UNLEAK(path); - UNLEAK(opts); - return add_worktree(path, branch, &opts); + ret = add_worktree(path, branch, &opts); + free(path); + return ret; } static void show_worktree_porcelain(struct worktree *wt, int line_terminator) |
