use child_process members "args" and "env" directly

Build argument list and environment of child processes by using
struct child_process and populating its members "args" and "env"
directly instead of maintaining separate strvecs and letting
run_command_v_opt() and friends populate these members.  This is
simpler, shorter and slightly more efficient.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
This commit is contained in:
René Scharfe 2022-10-30 12:51:14 +01:00 committed by Taylor Blau
parent 4120294cbf
commit 0e90673957
13 changed files with 185 additions and 206 deletions

View File

@ -997,18 +997,17 @@ static int run_diff(struct add_i_state *s, const struct pathspec *ps,
count = list_and_choose(s, files, opts); count = list_and_choose(s, files, opts);
opts->flags = 0; opts->flags = 0;
if (count > 0) { if (count > 0) {
struct strvec args = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
strvec_pushl(&args, "git", "diff", "-p", "--cached", strvec_pushl(&cmd.args, "git", "diff", "-p", "--cached",
oid_to_hex(!is_initial ? &oid : oid_to_hex(!is_initial ? &oid :
s->r->hash_algo->empty_tree), s->r->hash_algo->empty_tree),
"--", NULL); "--", NULL);
for (i = 0; i < files->items.nr; i++) for (i = 0; i < files->items.nr; i++)
if (files->selected[i]) if (files->selected[i])
strvec_push(&args, strvec_push(&cmd.args,
files->items.items[i].string); files->items.items[i].string);
res = run_command_v_opt(args.v, 0); res = run_command(&cmd);
strvec_clear(&args);
} }
putchar('\n'); putchar('\n');

View File

@ -240,8 +240,8 @@ static int refresh(int verbose, const struct pathspec *pathspec)
int run_add_interactive(const char *revision, const char *patch_mode, int run_add_interactive(const char *revision, const char *patch_mode,
const struct pathspec *pathspec) const struct pathspec *pathspec)
{ {
int status, i; int i;
struct strvec argv = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
int use_builtin_add_i = int use_builtin_add_i =
git_env_bool("GIT_TEST_ADD_I_USE_BUILTIN", -1); git_env_bool("GIT_TEST_ADD_I_USE_BUILTIN", -1);
@ -272,19 +272,18 @@ int run_add_interactive(const char *revision, const char *patch_mode,
return !!run_add_p(the_repository, mode, revision, pathspec); return !!run_add_p(the_repository, mode, revision, pathspec);
} }
strvec_push(&argv, "add--interactive"); strvec_push(&cmd.args, "add--interactive");
if (patch_mode) if (patch_mode)
strvec_push(&argv, patch_mode); strvec_push(&cmd.args, patch_mode);
if (revision) if (revision)
strvec_push(&argv, revision); strvec_push(&cmd.args, revision);
strvec_push(&argv, "--"); strvec_push(&cmd.args, "--");
for (i = 0; i < pathspec->nr; i++) for (i = 0; i < pathspec->nr; i++)
/* pass original pathspec, to be re-parsed */ /* pass original pathspec, to be re-parsed */
strvec_push(&argv, pathspec->items[i].original); strvec_push(&cmd.args, pathspec->items[i].original);
status = run_command_v_opt(argv.v, RUN_GIT_CMD); cmd.git_cmd = 1;
strvec_clear(&argv); return run_command(&cmd);
return status;
} }
int interactive_add(const char **argv, const char *prefix, int patch) int interactive_add(const char **argv, const char *prefix, int patch)

View File

@ -220,18 +220,17 @@ static int bisect_reset(const char *commit)
} }
if (!ref_exists("BISECT_HEAD")) { if (!ref_exists("BISECT_HEAD")) {
struct strvec argv = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
strvec_pushl(&argv, "checkout", branch.buf, "--", NULL); cmd.git_cmd = 1;
if (run_command_v_opt(argv.v, RUN_GIT_CMD)) { strvec_pushl(&cmd.args, "checkout", branch.buf, "--", NULL);
if (run_command(&cmd)) {
error(_("could not check out original" error(_("could not check out original"
" HEAD '%s'. Try 'git bisect" " HEAD '%s'. Try 'git bisect"
" reset <commit>'."), branch.buf); " reset <commit>'."), branch.buf);
strbuf_release(&branch); strbuf_release(&branch);
strvec_clear(&argv);
return -1; return -1;
} }
strvec_clear(&argv);
} }
strbuf_release(&branch); strbuf_release(&branch);
@ -1098,40 +1097,38 @@ static enum bisect_error bisect_skip(struct bisect_terms *terms, const char **ar
static int bisect_visualize(struct bisect_terms *terms, const char **argv, int argc) static int bisect_visualize(struct bisect_terms *terms, const char **argv, int argc)
{ {
struct strvec args = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
int flags = RUN_COMMAND_NO_STDIN, res = 0;
struct strbuf sb = STRBUF_INIT; struct strbuf sb = STRBUF_INIT;
if (bisect_next_check(terms, NULL) != 0) if (bisect_next_check(terms, NULL) != 0)
return BISECT_FAILED; return BISECT_FAILED;
cmd.no_stdin = 1;
if (!argc) { if (!argc) {
if ((getenv("DISPLAY") || getenv("SESSIONNAME") || getenv("MSYSTEM") || if ((getenv("DISPLAY") || getenv("SESSIONNAME") || getenv("MSYSTEM") ||
getenv("SECURITYSESSIONID")) && exists_in_PATH("gitk")) { getenv("SECURITYSESSIONID")) && exists_in_PATH("gitk")) {
strvec_push(&args, "gitk"); strvec_push(&cmd.args, "gitk");
} else { } else {
strvec_push(&args, "log"); strvec_push(&cmd.args, "log");
flags |= RUN_GIT_CMD; cmd.git_cmd = 1;
} }
} else { } else {
if (argv[0][0] == '-') { if (argv[0][0] == '-') {
strvec_push(&args, "log"); strvec_push(&cmd.args, "log");
flags |= RUN_GIT_CMD; cmd.git_cmd = 1;
} else if (strcmp(argv[0], "tig") && !starts_with(argv[0], "git")) } else if (strcmp(argv[0], "tig") && !starts_with(argv[0], "git"))
flags |= RUN_GIT_CMD; cmd.git_cmd = 1;
strvec_pushv(&args, argv); strvec_pushv(&cmd.args, argv);
} }
strvec_pushl(&args, "--bisect", "--", NULL); strvec_pushl(&cmd.args, "--bisect", "--", NULL);
strbuf_read_file(&sb, git_path_bisect_names(), 0); strbuf_read_file(&sb, git_path_bisect_names(), 0);
sq_dequote_to_strvec(sb.buf, &args); sq_dequote_to_strvec(sb.buf, &cmd.args);
strbuf_release(&sb); strbuf_release(&sb);
res = run_command_v_opt(args.v, flags); return run_command(&cmd);
strvec_clear(&args);
return res;
} }
static int get_first_good(const char *refname UNUSED, static int get_first_good(const char *refname UNUSED,

View File

@ -653,9 +653,9 @@ static void update_head(const struct ref *our, const struct ref *remote,
static int git_sparse_checkout_init(const char *repo) static int git_sparse_checkout_init(const char *repo)
{ {
struct strvec argv = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
int result = 0; int result = 0;
strvec_pushl(&argv, "-C", repo, "sparse-checkout", "set", NULL); strvec_pushl(&cmd.args, "-C", repo, "sparse-checkout", "set", NULL);
/* /*
* We must apply the setting in the current process * We must apply the setting in the current process
@ -663,12 +663,12 @@ static int git_sparse_checkout_init(const char *repo)
*/ */
core_apply_sparse_checkout = 1; core_apply_sparse_checkout = 1;
if (run_command_v_opt(argv.v, RUN_GIT_CMD)) { cmd.git_cmd = 1;
if (run_command(&cmd)) {
error(_("failed to initialize sparse-checkout")); error(_("failed to initialize sparse-checkout"));
result = 1; result = 1;
} }
strvec_clear(&argv);
return result; return result;
} }
@ -733,37 +733,38 @@ static int checkout(int submodule_progress, int filter_submodules)
oid_to_hex(&oid), "1", NULL); oid_to_hex(&oid), "1", NULL);
if (!err && (option_recurse_submodules.nr > 0)) { if (!err && (option_recurse_submodules.nr > 0)) {
struct strvec args = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
strvec_pushl(&args, "submodule", "update", "--require-init", "--recursive", NULL); strvec_pushl(&cmd.args, "submodule", "update", "--require-init",
"--recursive", NULL);
if (option_shallow_submodules == 1) if (option_shallow_submodules == 1)
strvec_push(&args, "--depth=1"); strvec_push(&cmd.args, "--depth=1");
if (max_jobs != -1) if (max_jobs != -1)
strvec_pushf(&args, "--jobs=%d", max_jobs); strvec_pushf(&cmd.args, "--jobs=%d", max_jobs);
if (submodule_progress) if (submodule_progress)
strvec_push(&args, "--progress"); strvec_push(&cmd.args, "--progress");
if (option_verbosity < 0) if (option_verbosity < 0)
strvec_push(&args, "--quiet"); strvec_push(&cmd.args, "--quiet");
if (option_remote_submodules) { if (option_remote_submodules) {
strvec_push(&args, "--remote"); strvec_push(&cmd.args, "--remote");
strvec_push(&args, "--no-fetch"); strvec_push(&cmd.args, "--no-fetch");
} }
if (filter_submodules && filter_options.choice) if (filter_submodules && filter_options.choice)
strvec_pushf(&args, "--filter=%s", strvec_pushf(&cmd.args, "--filter=%s",
expand_list_objects_filter_spec(&filter_options)); expand_list_objects_filter_spec(&filter_options));
if (option_single_branch >= 0) if (option_single_branch >= 0)
strvec_push(&args, option_single_branch ? strvec_push(&cmd.args, option_single_branch ?
"--single-branch" : "--single-branch" :
"--no-single-branch"); "--no-single-branch");
err = run_command_v_opt(args.v, RUN_GIT_CMD); cmd.git_cmd = 1;
strvec_clear(&args); err = run_command(&cmd);
} }
return err; return err;

View File

@ -1910,20 +1910,16 @@ static char *schtasks_task_name(const char *frequency)
static int schtasks_remove_task(enum schedule_priority schedule) static int schtasks_remove_task(enum schedule_priority schedule)
{ {
const char *cmd = "schtasks"; const char *cmd = "schtasks";
int result; struct child_process child = CHILD_PROCESS_INIT;
struct strvec args = STRVEC_INIT;
const char *frequency = get_frequency(schedule); const char *frequency = get_frequency(schedule);
char *name = schtasks_task_name(frequency); char *name = schtasks_task_name(frequency);
get_schedule_cmd(&cmd, NULL); get_schedule_cmd(&cmd, NULL);
strvec_split(&args, cmd); strvec_split(&child.args, cmd);
strvec_pushl(&args, "/delete", "/tn", name, "/f", NULL); strvec_pushl(&child.args, "/delete", "/tn", name, "/f", NULL);
result = run_command_v_opt(args.v, 0);
strvec_clear(&args);
free(name); free(name);
return result;
return run_command(&child);
} }
static int schtasks_remove_tasks(void) static int schtasks_remove_tasks(void)

View File

@ -372,22 +372,22 @@ static void reset_hard(const struct object_id *oid)
static void restore_state(const struct object_id *head, static void restore_state(const struct object_id *head,
const struct object_id *stash) const struct object_id *stash)
{ {
struct strvec args = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
reset_hard(head); reset_hard(head);
if (is_null_oid(stash)) if (is_null_oid(stash))
goto refresh_cache; goto refresh_cache;
strvec_pushl(&args, "stash", "apply", "--index", "--quiet", NULL); strvec_pushl(&cmd.args, "stash", "apply", "--index", "--quiet", NULL);
strvec_push(&args, oid_to_hex(stash)); strvec_push(&cmd.args, oid_to_hex(stash));
/* /*
* It is OK to ignore error here, for example when there was * It is OK to ignore error here, for example when there was
* nothing to restore. * nothing to restore.
*/ */
run_command_v_opt(args.v, RUN_GIT_CMD); cmd.git_cmd = 1;
strvec_clear(&args); run_command(&cmd);
refresh_cache: refresh_cache:
if (discard_cache() < 0 || read_cache() < 0) if (discard_cache() < 0 || read_cache() < 0)

View File

@ -515,76 +515,75 @@ static void parse_repo_refspecs(int argc, const char **argv, const char **repo,
*/ */
static int run_fetch(const char *repo, const char **refspecs) static int run_fetch(const char *repo, const char **refspecs)
{ {
struct strvec args = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
int ret;
strvec_pushl(&args, "fetch", "--update-head-ok", NULL); strvec_pushl(&cmd.args, "fetch", "--update-head-ok", NULL);
/* Shared options */ /* Shared options */
argv_push_verbosity(&args); argv_push_verbosity(&cmd.args);
if (opt_progress) if (opt_progress)
strvec_push(&args, opt_progress); strvec_push(&cmd.args, opt_progress);
/* Options passed to git-fetch */ /* Options passed to git-fetch */
if (opt_all) if (opt_all)
strvec_push(&args, opt_all); strvec_push(&cmd.args, opt_all);
if (opt_append) if (opt_append)
strvec_push(&args, opt_append); strvec_push(&cmd.args, opt_append);
if (opt_upload_pack) if (opt_upload_pack)
strvec_push(&args, opt_upload_pack); strvec_push(&cmd.args, opt_upload_pack);
argv_push_force(&args); argv_push_force(&cmd.args);
if (opt_tags) if (opt_tags)
strvec_push(&args, opt_tags); strvec_push(&cmd.args, opt_tags);
if (opt_prune) if (opt_prune)
strvec_push(&args, opt_prune); strvec_push(&cmd.args, opt_prune);
if (recurse_submodules_cli != RECURSE_SUBMODULES_DEFAULT) if (recurse_submodules_cli != RECURSE_SUBMODULES_DEFAULT)
switch (recurse_submodules_cli) { switch (recurse_submodules_cli) {
case RECURSE_SUBMODULES_ON: case RECURSE_SUBMODULES_ON:
strvec_push(&args, "--recurse-submodules=on"); strvec_push(&cmd.args, "--recurse-submodules=on");
break; break;
case RECURSE_SUBMODULES_OFF: case RECURSE_SUBMODULES_OFF:
strvec_push(&args, "--recurse-submodules=no"); strvec_push(&cmd.args, "--recurse-submodules=no");
break; break;
case RECURSE_SUBMODULES_ON_DEMAND: case RECURSE_SUBMODULES_ON_DEMAND:
strvec_push(&args, "--recurse-submodules=on-demand"); strvec_push(&cmd.args, "--recurse-submodules=on-demand");
break; break;
default: default:
BUG("submodule recursion option not understood"); BUG("submodule recursion option not understood");
} }
if (max_children) if (max_children)
strvec_push(&args, max_children); strvec_push(&cmd.args, max_children);
if (opt_dry_run) if (opt_dry_run)
strvec_push(&args, "--dry-run"); strvec_push(&cmd.args, "--dry-run");
if (opt_keep) if (opt_keep)
strvec_push(&args, opt_keep); strvec_push(&cmd.args, opt_keep);
if (opt_depth) if (opt_depth)
strvec_push(&args, opt_depth); strvec_push(&cmd.args, opt_depth);
if (opt_unshallow) if (opt_unshallow)
strvec_push(&args, opt_unshallow); strvec_push(&cmd.args, opt_unshallow);
if (opt_update_shallow) if (opt_update_shallow)
strvec_push(&args, opt_update_shallow); strvec_push(&cmd.args, opt_update_shallow);
if (opt_refmap) if (opt_refmap)
strvec_push(&args, opt_refmap); strvec_push(&cmd.args, opt_refmap);
if (opt_ipv4) if (opt_ipv4)
strvec_push(&args, opt_ipv4); strvec_push(&cmd.args, opt_ipv4);
if (opt_ipv6) if (opt_ipv6)
strvec_push(&args, opt_ipv6); strvec_push(&cmd.args, opt_ipv6);
if (opt_show_forced_updates > 0) if (opt_show_forced_updates > 0)
strvec_push(&args, "--show-forced-updates"); strvec_push(&cmd.args, "--show-forced-updates");
else if (opt_show_forced_updates == 0) else if (opt_show_forced_updates == 0)
strvec_push(&args, "--no-show-forced-updates"); strvec_push(&cmd.args, "--no-show-forced-updates");
if (set_upstream) if (set_upstream)
strvec_push(&args, set_upstream); strvec_push(&cmd.args, set_upstream);
strvec_pushv(&args, opt_fetch.v); strvec_pushv(&cmd.args, opt_fetch.v);
if (repo) { if (repo) {
strvec_push(&args, repo); strvec_push(&cmd.args, repo);
strvec_pushv(&args, refspecs); strvec_pushv(&cmd.args, refspecs);
} else if (*refspecs) } else if (*refspecs)
BUG("refspecs without repo?"); BUG("refspecs without repo?");
ret = run_command_v_opt(args.v, RUN_GIT_CMD | RUN_CLOSE_OBJECT_STORE); cmd.git_cmd = 1;
strvec_clear(&args); cmd.close_object_store = 1;
return ret; return run_command(&cmd);
} }
/** /**
@ -653,52 +652,50 @@ static int update_submodules(void)
*/ */
static int run_merge(void) static int run_merge(void)
{ {
int ret; struct child_process cmd = CHILD_PROCESS_INIT;
struct strvec args = STRVEC_INIT;
strvec_pushl(&args, "merge", NULL); strvec_pushl(&cmd.args, "merge", NULL);
/* Shared options */ /* Shared options */
argv_push_verbosity(&args); argv_push_verbosity(&cmd.args);
if (opt_progress) if (opt_progress)
strvec_push(&args, opt_progress); strvec_push(&cmd.args, opt_progress);
/* Options passed to git-merge */ /* Options passed to git-merge */
if (opt_diffstat) if (opt_diffstat)
strvec_push(&args, opt_diffstat); strvec_push(&cmd.args, opt_diffstat);
if (opt_log) if (opt_log)
strvec_push(&args, opt_log); strvec_push(&cmd.args, opt_log);
if (opt_signoff) if (opt_signoff)
strvec_push(&args, opt_signoff); strvec_push(&cmd.args, opt_signoff);
if (opt_squash) if (opt_squash)
strvec_push(&args, opt_squash); strvec_push(&cmd.args, opt_squash);
if (opt_commit) if (opt_commit)
strvec_push(&args, opt_commit); strvec_push(&cmd.args, opt_commit);
if (opt_edit) if (opt_edit)
strvec_push(&args, opt_edit); strvec_push(&cmd.args, opt_edit);
if (cleanup_arg) if (cleanup_arg)
strvec_pushf(&args, "--cleanup=%s", cleanup_arg); strvec_pushf(&cmd.args, "--cleanup=%s", cleanup_arg);
if (opt_ff) if (opt_ff)
strvec_push(&args, opt_ff); strvec_push(&cmd.args, opt_ff);
if (opt_verify) if (opt_verify)
strvec_push(&args, opt_verify); strvec_push(&cmd.args, opt_verify);
if (opt_verify_signatures) if (opt_verify_signatures)
strvec_push(&args, opt_verify_signatures); strvec_push(&cmd.args, opt_verify_signatures);
strvec_pushv(&args, opt_strategies.v); strvec_pushv(&cmd.args, opt_strategies.v);
strvec_pushv(&args, opt_strategy_opts.v); strvec_pushv(&cmd.args, opt_strategy_opts.v);
if (opt_gpg_sign) if (opt_gpg_sign)
strvec_push(&args, opt_gpg_sign); strvec_push(&cmd.args, opt_gpg_sign);
if (opt_autostash == 0) if (opt_autostash == 0)
strvec_push(&args, "--no-autostash"); strvec_push(&cmd.args, "--no-autostash");
else if (opt_autostash == 1) else if (opt_autostash == 1)
strvec_push(&args, "--autostash"); strvec_push(&cmd.args, "--autostash");
if (opt_allow_unrelated_histories > 0) if (opt_allow_unrelated_histories > 0)
strvec_push(&args, "--allow-unrelated-histories"); strvec_push(&cmd.args, "--allow-unrelated-histories");
strvec_push(&args, "FETCH_HEAD"); strvec_push(&cmd.args, "FETCH_HEAD");
ret = run_command_v_opt(args.v, RUN_GIT_CMD); cmd.git_cmd = 1;
strvec_clear(&args); return run_command(&cmd);
return ret;
} }
/** /**
@ -879,43 +876,41 @@ static int get_rebase_newbase_and_upstream(struct object_id *newbase,
static int run_rebase(const struct object_id *newbase, static int run_rebase(const struct object_id *newbase,
const struct object_id *upstream) const struct object_id *upstream)
{ {
int ret; struct child_process cmd = CHILD_PROCESS_INIT;
struct strvec args = STRVEC_INIT;
strvec_push(&args, "rebase"); strvec_push(&cmd.args, "rebase");
/* Shared options */ /* Shared options */
argv_push_verbosity(&args); argv_push_verbosity(&cmd.args);
/* Options passed to git-rebase */ /* Options passed to git-rebase */
if (opt_rebase == REBASE_MERGES) if (opt_rebase == REBASE_MERGES)
strvec_push(&args, "--rebase-merges"); strvec_push(&cmd.args, "--rebase-merges");
else if (opt_rebase == REBASE_INTERACTIVE) else if (opt_rebase == REBASE_INTERACTIVE)
strvec_push(&args, "--interactive"); strvec_push(&cmd.args, "--interactive");
if (opt_diffstat) if (opt_diffstat)
strvec_push(&args, opt_diffstat); strvec_push(&cmd.args, opt_diffstat);
strvec_pushv(&args, opt_strategies.v); strvec_pushv(&cmd.args, opt_strategies.v);
strvec_pushv(&args, opt_strategy_opts.v); strvec_pushv(&cmd.args, opt_strategy_opts.v);
if (opt_gpg_sign) if (opt_gpg_sign)
strvec_push(&args, opt_gpg_sign); strvec_push(&cmd.args, opt_gpg_sign);
if (opt_signoff) if (opt_signoff)
strvec_push(&args, opt_signoff); strvec_push(&cmd.args, opt_signoff);
if (opt_autostash == 0) if (opt_autostash == 0)
strvec_push(&args, "--no-autostash"); strvec_push(&cmd.args, "--no-autostash");
else if (opt_autostash == 1) else if (opt_autostash == 1)
strvec_push(&args, "--autostash"); strvec_push(&cmd.args, "--autostash");
if (opt_verify_signatures && if (opt_verify_signatures &&
!strcmp(opt_verify_signatures, "--verify-signatures")) !strcmp(opt_verify_signatures, "--verify-signatures"))
warning(_("ignoring --verify-signatures for rebase")); warning(_("ignoring --verify-signatures for rebase"));
strvec_push(&args, "--onto"); strvec_push(&cmd.args, "--onto");
strvec_push(&args, oid_to_hex(newbase)); strvec_push(&cmd.args, oid_to_hex(newbase));
strvec_push(&args, oid_to_hex(upstream)); strvec_push(&cmd.args, oid_to_hex(upstream));
ret = run_command_v_opt(args.v, RUN_GIT_CMD); cmd.git_cmd = 1;
strvec_clear(&args); return run_command(&cmd);
return ret;
} }
static int get_can_ff(struct object_id *orig_head, static int get_can_ff(struct object_id *orig_head,

View File

@ -1510,37 +1510,35 @@ static int update(int argc, const char **argv, const char *prefix)
N_("prune remotes after fetching")), N_("prune remotes after fetching")),
OPT_END() OPT_END()
}; };
struct strvec fetch_argv = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
int default_defined = 0; int default_defined = 0;
int retval;
argc = parse_options(argc, argv, prefix, options, argc = parse_options(argc, argv, prefix, options,
builtin_remote_update_usage, builtin_remote_update_usage,
PARSE_OPT_KEEP_ARGV0); PARSE_OPT_KEEP_ARGV0);
strvec_push(&fetch_argv, "fetch"); strvec_push(&cmd.args, "fetch");
if (prune != -1) if (prune != -1)
strvec_push(&fetch_argv, prune ? "--prune" : "--no-prune"); strvec_push(&cmd.args, prune ? "--prune" : "--no-prune");
if (verbose) if (verbose)
strvec_push(&fetch_argv, "-v"); strvec_push(&cmd.args, "-v");
strvec_push(&fetch_argv, "--multiple"); strvec_push(&cmd.args, "--multiple");
if (argc < 2) if (argc < 2)
strvec_push(&fetch_argv, "default"); strvec_push(&cmd.args, "default");
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
strvec_push(&fetch_argv, argv[i]); strvec_push(&cmd.args, argv[i]);
if (strcmp(fetch_argv.v[fetch_argv.nr-1], "default") == 0) { if (strcmp(cmd.args.v[cmd.args.nr-1], "default") == 0) {
git_config(get_remote_default, &default_defined); git_config(get_remote_default, &default_defined);
if (!default_defined) { if (!default_defined) {
strvec_pop(&fetch_argv); strvec_pop(&cmd.args);
strvec_push(&fetch_argv, "--all"); strvec_push(&cmd.args, "--all");
} }
} }
retval = run_command_v_opt(fetch_argv.v, RUN_GIT_CMD); cmd.git_cmd = 1;
strvec_clear(&fetch_argv); return run_command(&cmd);
return retval;
} }
static int remove_all_fetch_refspecs(const char *key) static int remove_all_fetch_refspecs(const char *key)

27
diff.c
View File

@ -4278,35 +4278,34 @@ static void run_external_diff(const char *pgm,
const char *xfrm_msg, const char *xfrm_msg,
struct diff_options *o) struct diff_options *o)
{ {
struct strvec argv = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
struct strvec env = STRVEC_INIT;
struct diff_queue_struct *q = &diff_queued_diff; struct diff_queue_struct *q = &diff_queued_diff;
strvec_push(&argv, pgm); strvec_push(&cmd.args, pgm);
strvec_push(&argv, name); strvec_push(&cmd.args, name);
if (one && two) { if (one && two) {
add_external_diff_name(o->repo, &argv, name, one); add_external_diff_name(o->repo, &cmd.args, name, one);
if (!other) if (!other)
add_external_diff_name(o->repo, &argv, name, two); add_external_diff_name(o->repo, &cmd.args, name, two);
else { else {
add_external_diff_name(o->repo, &argv, other, two); add_external_diff_name(o->repo, &cmd.args, other, two);
strvec_push(&argv, other); strvec_push(&cmd.args, other);
strvec_push(&argv, xfrm_msg); strvec_push(&cmd.args, xfrm_msg);
} }
} }
strvec_pushf(&env, "GIT_DIFF_PATH_COUNTER=%d", ++o->diff_path_counter); strvec_pushf(&cmd.env, "GIT_DIFF_PATH_COUNTER=%d",
strvec_pushf(&env, "GIT_DIFF_PATH_TOTAL=%d", q->nr); ++o->diff_path_counter);
strvec_pushf(&cmd.env, "GIT_DIFF_PATH_TOTAL=%d", q->nr);
diff_free_filespec_data(one); diff_free_filespec_data(one);
diff_free_filespec_data(two); diff_free_filespec_data(two);
if (run_command_v_opt_cd_env(argv.v, RUN_USING_SHELL, NULL, env.v)) cmd.use_shell = 1;
if (run_command(&cmd))
die(_("external diff died, stopping at %s"), name); die(_("external diff died, stopping at %s"), name);
remove_tempfile(); remove_tempfile();
strvec_clear(&argv);
strvec_clear(&env);
} }
static int similarity_index(struct diff_filepair *p) static int similarity_index(struct diff_filepair *p)

15
git.c
View File

@ -787,7 +787,7 @@ static int run_argv(int *argcp, const char ***argv)
if (!done_alias) if (!done_alias)
handle_builtin(*argcp, *argv); handle_builtin(*argcp, *argv);
else if (get_builtin(**argv)) { else if (get_builtin(**argv)) {
struct strvec args = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
int i; int i;
/* /*
@ -804,18 +804,21 @@ static int run_argv(int *argcp, const char ***argv)
commit_pager_choice(); commit_pager_choice();
strvec_push(&args, "git"); strvec_push(&cmd.args, "git");
for (i = 0; i < *argcp; i++) for (i = 0; i < *argcp; i++)
strvec_push(&args, (*argv)[i]); strvec_push(&cmd.args, (*argv)[i]);
trace_argv_printf(args.v, "trace: exec:"); trace_argv_printf(cmd.args.v, "trace: exec:");
/* /*
* if we fail because the command is not found, it is * if we fail because the command is not found, it is
* OK to return. Otherwise, we just pass along the status code. * OK to return. Otherwise, we just pass along the status code.
*/ */
i = run_command_v_opt_tr2(args.v, RUN_SILENT_EXEC_FAILURE | cmd.silent_exec_failure = 1;
RUN_CLEAN_ON_EXIT | RUN_WAIT_AFTER_CLEAN, "git_alias"); cmd.clean_on_exit = 1;
cmd.wait_after_clean = 1;
cmd.trace2_child_class = "git_alias";
i = run_command(&cmd);
if (i >= 0 || errno != ENOENT) if (i >= 0 || errno != ENOENT)
exit(i); exit(i);
die("could not execute builtin %s", **argv); die("could not execute builtin %s", **argv);

18
merge.c
View File

@ -19,22 +19,22 @@ int try_merge_command(struct repository *r,
const char **xopts, struct commit_list *common, const char **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes) const char *head_arg, struct commit_list *remotes)
{ {
struct strvec args = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
int i, ret; int i, ret;
struct commit_list *j; struct commit_list *j;
strvec_pushf(&args, "merge-%s", strategy); strvec_pushf(&cmd.args, "merge-%s", strategy);
for (i = 0; i < xopts_nr; i++) for (i = 0; i < xopts_nr; i++)
strvec_pushf(&args, "--%s", xopts[i]); strvec_pushf(&cmd.args, "--%s", xopts[i]);
for (j = common; j; j = j->next) for (j = common; j; j = j->next)
strvec_push(&args, merge_argument(j->item)); strvec_push(&cmd.args, merge_argument(j->item));
strvec_push(&args, "--"); strvec_push(&cmd.args, "--");
strvec_push(&args, head_arg); strvec_push(&cmd.args, head_arg);
for (j = remotes; j; j = j->next) for (j = remotes; j; j = j->next)
strvec_push(&args, merge_argument(j->item)); strvec_push(&cmd.args, merge_argument(j->item));
ret = run_command_v_opt(args.v, RUN_GIT_CMD); cmd.git_cmd = 1;
strvec_clear(&args); ret = run_command(&cmd);
discard_index(r->index); discard_index(r->index);
if (repo_read_index(r) < 0) if (repo_read_index(r) < 0)

View File

@ -69,21 +69,18 @@ static void setup_enlistment_directory(int argc, const char **argv,
static int run_git(const char *arg, ...) static int run_git(const char *arg, ...)
{ {
struct strvec argv = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
va_list args; va_list args;
const char *p; const char *p;
int res;
va_start(args, arg); va_start(args, arg);
strvec_push(&argv, arg); strvec_push(&cmd.args, arg);
while ((p = va_arg(args, const char *))) while ((p = va_arg(args, const char *)))
strvec_push(&argv, p); strvec_push(&cmd.args, p);
va_end(args); va_end(args);
res = run_command_v_opt(argv.v, RUN_GIT_CMD); cmd.git_cmd = 1;
return run_command(&cmd);
strvec_clear(&argv);
return res;
} }
struct scalar_config { struct scalar_config {

View File

@ -3183,18 +3183,15 @@ static int rollback_is_safe(void)
static int reset_merge(const struct object_id *oid) static int reset_merge(const struct object_id *oid)
{ {
int ret; struct child_process cmd = CHILD_PROCESS_INIT;
struct strvec argv = STRVEC_INIT;
strvec_pushl(&argv, "reset", "--merge", NULL); cmd.git_cmd = 1;
strvec_pushl(&cmd.args, "reset", "--merge", NULL);
if (!is_null_oid(oid)) if (!is_null_oid(oid))
strvec_push(&argv, oid_to_hex(oid)); strvec_push(&cmd.args, oid_to_hex(oid));
ret = run_command_v_opt(argv.v, RUN_GIT_CMD); return run_command(&cmd);
strvec_clear(&argv);
return ret;
} }
static int rollback_single_pick(struct repository *r) static int rollback_single_pick(struct repository *r)
@ -4866,14 +4863,14 @@ cleanup_head_ref:
static int continue_single_pick(struct repository *r, struct replay_opts *opts) static int continue_single_pick(struct repository *r, struct replay_opts *opts)
{ {
struct strvec argv = STRVEC_INIT; struct child_process cmd = CHILD_PROCESS_INIT;
int ret;
if (!refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") && if (!refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&
!refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD")) !refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD"))
return error(_("no cherry-pick or revert in progress")); return error(_("no cherry-pick or revert in progress"));
strvec_push(&argv, "commit"); cmd.git_cmd = 1;
strvec_push(&cmd.args, "commit");
/* /*
* continue_single_pick() handles the case of recovering from a * continue_single_pick() handles the case of recovering from a
@ -4886,11 +4883,9 @@ static int continue_single_pick(struct repository *r, struct replay_opts *opts)
* Include --cleanup=strip as well because we don't want the * Include --cleanup=strip as well because we don't want the
* "# Conflicts:" messages. * "# Conflicts:" messages.
*/ */
strvec_pushl(&argv, "--no-edit", "--cleanup=strip", NULL); strvec_pushl(&cmd.args, "--no-edit", "--cleanup=strip", NULL);
ret = run_command_v_opt(argv.v, RUN_GIT_CMD); return run_command(&cmd);
strvec_clear(&argv);
return ret;
} }
static int commit_staged_changes(struct repository *r, static int commit_staged_changes(struct repository *r,