Merge branch 'rs/no-more-run-command-v'

Simplify the run-command API.

* rs/no-more-run-command-v:
  replace and remove run_command_v_opt()
  replace and remove run_command_v_opt_cd_env_tr2()
  replace and remove run_command_v_opt_tr2()
  replace and remove run_command_v_opt_cd_env()
  use child_process members "args" and "env" directly
  use child_process member "args" instead of string array variable
  sequencer: simplify building argument list in do_exec()
  bisect--helper: factor out do_bisect_run()
  bisect: simplify building "checkout" argument list
  am: simplify building "show" argument list
  run-command: fix return value comment
  merge: remove always-the-same "verbose" arguments
This commit is contained in:
Taylor Blau 2022-11-08 17:15:12 -05:00
commit be4ac3b197
27 changed files with 344 additions and 381 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);
opts->flags = 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 :
s->r->hash_algo->empty_tree),
"--", NULL);
for (i = 0; i < files->items.nr; i++)
if (files->selected[i])
strvec_push(&args,
strvec_push(&cmd.args,
files->items.items[i].string);
res = run_command_v_opt(args.v, 0);
strvec_clear(&args);
res = run_command(&cmd);
}
putchar('\n');

View File

@ -22,8 +22,6 @@ static struct oid_array skipped_revs;
static struct object_id *current_bad_oid;
static const char *argv_checkout[] = {"checkout", "-q", NULL, "--", NULL};
static const char *term_bad;
static const char *term_good;
@ -729,20 +727,22 @@ static int is_expected_rev(const struct object_id *oid)
enum bisect_error bisect_checkout(const struct object_id *bisect_rev,
int no_checkout)
{
char bisect_rev_hex[GIT_MAX_HEXSZ + 1];
struct commit *commit;
struct pretty_print_context pp = {0};
struct strbuf commit_msg = STRBUF_INIT;
oid_to_hex_r(bisect_rev_hex, bisect_rev);
update_ref(NULL, "BISECT_EXPECTED_REV", bisect_rev, NULL, 0, UPDATE_REFS_DIE_ON_ERR);
argv_checkout[2] = bisect_rev_hex;
if (no_checkout) {
update_ref(NULL, "BISECT_HEAD", bisect_rev, NULL, 0,
UPDATE_REFS_DIE_ON_ERR);
} else {
if (run_command_v_opt(argv_checkout, RUN_GIT_CMD))
struct child_process cmd = CHILD_PROCESS_INIT;
cmd.git_cmd = 1;
strvec_pushl(&cmd.args, "checkout", "-q",
oid_to_hex(bisect_rev), "--", NULL);
if (run_command(&cmd))
/*
* Errors in `run_command()` itself, signaled by res < 0,
* and errors in the child process, signaled by res > 0

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,
const struct pathspec *pathspec)
{
int status, i;
struct strvec argv = STRVEC_INIT;
int i;
struct child_process cmd = CHILD_PROCESS_INIT;
int use_builtin_add_i =
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);
}
strvec_push(&argv, "add--interactive");
strvec_push(&cmd.args, "add--interactive");
if (patch_mode)
strvec_push(&argv, patch_mode);
strvec_push(&cmd.args, patch_mode);
if (revision)
strvec_push(&argv, revision);
strvec_push(&argv, "--");
strvec_push(&cmd.args, revision);
strvec_push(&cmd.args, "--");
for (i = 0; i < pathspec->nr; i++)
/* 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);
strvec_clear(&argv);
return status;
cmd.git_cmd = 1;
return run_command(&cmd);
}
int interactive_add(const char **argv, const char *prefix, int patch)

View File

@ -2187,14 +2187,12 @@ static int show_patch(struct am_state *state, enum show_patch_type sub_mode)
int len;
if (!is_null_oid(&state->orig_commit)) {
const char *av[4] = { "show", NULL, "--", NULL };
char *new_oid_str;
int ret;
struct child_process cmd = CHILD_PROCESS_INIT;
av[1] = new_oid_str = xstrdup(oid_to_hex(&state->orig_commit));
ret = run_command_v_opt(av, RUN_GIT_CMD);
free(new_oid_str);
return ret;
strvec_pushl(&cmd.args, "show", oid_to_hex(&state->orig_commit),
"--", NULL);
cmd.git_cmd = 1;
return run_command(&cmd);
}
switch (sub_mode) {

View File

@ -220,18 +220,17 @@ static int bisect_reset(const char *commit)
}
if (!ref_exists("BISECT_HEAD")) {
struct strvec argv = STRVEC_INIT;
struct child_process cmd = CHILD_PROCESS_INIT;
strvec_pushl(&argv, "checkout", branch.buf, "--", NULL);
if (run_command_v_opt(argv.v, RUN_GIT_CMD)) {
cmd.git_cmd = 1;
strvec_pushl(&cmd.args, "checkout", branch.buf, "--", NULL);
if (run_command(&cmd)) {
error(_("could not check out original"
" HEAD '%s'. Try 'git bisect"
" reset <commit>'."), branch.buf);
strbuf_release(&branch);
strvec_clear(&argv);
return -1;
}
strvec_clear(&argv);
}
strbuf_release(&branch);
@ -765,10 +764,12 @@ static enum bisect_error bisect_start(struct bisect_terms *terms, const char **a
strbuf_read_file(&start_head, git_path_bisect_start(), 0);
strbuf_trim(&start_head);
if (!no_checkout) {
const char *argv[] = { "checkout", start_head.buf,
"--", NULL };
struct child_process cmd = CHILD_PROCESS_INIT;
if (run_command_v_opt(argv, RUN_GIT_CMD)) {
cmd.git_cmd = 1;
strvec_pushl(&cmd.args, "checkout", start_head.buf,
"--", NULL);
if (run_command(&cmd)) {
res = error(_("checking out '%s' failed."
" Try 'git bisect start "
"<valid-branch>'."),
@ -1098,40 +1099,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)
{
struct strvec args = STRVEC_INIT;
int flags = RUN_COMMAND_NO_STDIN, res = 0;
struct child_process cmd = CHILD_PROCESS_INIT;
struct strbuf sb = STRBUF_INIT;
if (bisect_next_check(terms, NULL) != 0)
return BISECT_FAILED;
cmd.no_stdin = 1;
if (!argc) {
if ((getenv("DISPLAY") || getenv("SESSIONNAME") || getenv("MSYSTEM") ||
getenv("SECURITYSESSIONID")) && exists_in_PATH("gitk")) {
strvec_push(&args, "gitk");
strvec_push(&cmd.args, "gitk");
} else {
strvec_push(&args, "log");
flags |= RUN_GIT_CMD;
strvec_push(&cmd.args, "log");
cmd.git_cmd = 1;
}
} else {
if (argv[0][0] == '-') {
strvec_push(&args, "log");
flags |= RUN_GIT_CMD;
strvec_push(&cmd.args, "log");
cmd.git_cmd = 1;
} 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);
sq_dequote_to_strvec(sb.buf, &args);
sq_dequote_to_strvec(sb.buf, &cmd.args);
strbuf_release(&sb);
res = run_command_v_opt(args.v, flags);
strvec_clear(&args);
return res;
return run_command(&cmd);
}
static int get_first_good(const char *refname UNUSED,
@ -1142,8 +1141,17 @@ static int get_first_good(const char *refname UNUSED,
return 1;
}
static int verify_good(const struct bisect_terms *terms,
const char **quoted_argv)
static int do_bisect_run(const char *command)
{
struct child_process cmd = CHILD_PROCESS_INIT;
printf(_("running %s\n"), command);
cmd.use_shell = 1;
strvec_push(&cmd.args, command);
return run_command(&cmd);
}
static int verify_good(const struct bisect_terms *terms, const char *command)
{
int rc;
enum bisect_error res;
@ -1163,8 +1171,7 @@ static int verify_good(const struct bisect_terms *terms,
if (res != BISECT_OK)
return -1;
printf(_("running %s\n"), quoted_argv[0]);
rc = run_command_v_opt(quoted_argv, RUN_USING_SHELL);
rc = do_bisect_run(command);
res = bisect_checkout(&current_rev, no_checkout);
if (res != BISECT_OK)
@ -1177,7 +1184,6 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc)
{
int res = BISECT_OK;
struct strbuf command = STRBUF_INIT;
struct strvec run_args = STRVEC_INIT;
const char *new_state;
int temporary_stdout_fd, saved_stdout;
int is_first_run = 1;
@ -1192,11 +1198,8 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc)
return BISECT_FAILED;
}
strvec_push(&run_args, command.buf);
while (1) {
printf(_("running %s\n"), command.buf);
res = run_command_v_opt(run_args.v, RUN_USING_SHELL);
res = do_bisect_run(command.buf);
/*
* Exit code 126 and 127 can either come from the shell
@ -1206,7 +1209,7 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc)
* missing or non-executable script.
*/
if (is_first_run && (res == 126 || res == 127)) {
int rc = verify_good(terms, run_args.v);
int rc = verify_good(terms, command.buf);
is_first_run = 0;
if (rc < 0) {
error(_("unable to verify '%s' on good"
@ -1273,7 +1276,6 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc)
}
strbuf_release(&command);
strvec_clear(&run_args);
return res;
}

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)
{
struct strvec argv = STRVEC_INIT;
struct child_process cmd = CHILD_PROCESS_INIT;
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
@ -663,12 +663,12 @@ static int git_sparse_checkout_init(const char *repo)
*/
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"));
result = 1;
}
strvec_clear(&argv);
return result;
}
@ -733,37 +733,38 @@ static int checkout(int submodule_progress, int filter_submodules)
oid_to_hex(&oid), "1", NULL);
if (!err && (option_recurse_submodules.nr > 0)) {
struct strvec args = STRVEC_INIT;
strvec_pushl(&args, "submodule", "update", "--require-init", "--recursive", NULL);
struct child_process cmd = CHILD_PROCESS_INIT;
strvec_pushl(&cmd.args, "submodule", "update", "--require-init",
"--recursive", NULL);
if (option_shallow_submodules == 1)
strvec_push(&args, "--depth=1");
strvec_push(&cmd.args, "--depth=1");
if (max_jobs != -1)
strvec_pushf(&args, "--jobs=%d", max_jobs);
strvec_pushf(&cmd.args, "--jobs=%d", max_jobs);
if (submodule_progress)
strvec_push(&args, "--progress");
strvec_push(&cmd.args, "--progress");
if (option_verbosity < 0)
strvec_push(&args, "--quiet");
strvec_push(&cmd.args, "--quiet");
if (option_remote_submodules) {
strvec_push(&args, "--remote");
strvec_push(&args, "--no-fetch");
strvec_push(&cmd.args, "--remote");
strvec_push(&cmd.args, "--no-fetch");
}
if (filter_submodules && filter_options.choice)
strvec_pushf(&args, "--filter=%s",
strvec_pushf(&cmd.args, "--filter=%s",
expand_list_objects_filter_spec(&filter_options));
if (option_single_branch >= 0)
strvec_push(&args, option_single_branch ?
strvec_push(&cmd.args, option_single_branch ?
"--single-branch" :
"--no-single-branch");
err = run_command_v_opt(args.v, RUN_GIT_CMD);
strvec_clear(&args);
cmd.git_cmd = 1;
err = run_command(&cmd);
}
return err;
@ -864,11 +865,15 @@ static void write_refspec_config(const char *src_ref_prefix,
static void dissociate_from_references(void)
{
static const char* argv[] = { "repack", "-a", "-d", NULL };
char *alternates = git_pathdup("objects/info/alternates");
if (!access(alternates, F_OK)) {
if (run_command_v_opt(argv, RUN_GIT_CMD|RUN_COMMAND_NO_STDIN))
struct child_process cmd = CHILD_PROCESS_INIT;
cmd.git_cmd = 1;
cmd.no_stdin = 1;
strvec_pushl(&cmd.args, "repack", "-a", "-d", NULL);
if (run_command(&cmd))
die(_("cannot repack to clean up"));
if (unlink(alternates) && errno != ENOENT)
die_errno(_("cannot unlink temporary alternates file"));

View File

@ -44,8 +44,11 @@ static int difftool_config(const char *var, const char *value, void *cb)
static int print_tool_help(void)
{
const char *argv[] = { "mergetool", "--tool-help=diff", NULL };
return run_command_v_opt(argv, RUN_GIT_CMD);
struct child_process cmd = CHILD_PROCESS_INIT;
cmd.git_cmd = 1;
strvec_pushl(&cmd.args, "mergetool", "--tool-help=diff", NULL);
return run_command(&cmd);
}
static int parse_index_info(char *p, int *mode1, int *mode2,
@ -360,8 +363,8 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
struct pair_entry *entry;
struct index_state wtindex;
struct checkout lstate, rstate;
int flags = RUN_GIT_CMD, err = 0;
const char *helper_argv[] = { "difftool--helper", NULL, NULL, NULL };
int err = 0;
struct child_process cmd = CHILD_PROCESS_INIT;
struct hashmap wt_modified, tmp_modified;
int indices_loaded = 0;
@ -563,16 +566,17 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
}
strbuf_setlen(&ldir, ldir_len);
helper_argv[1] = ldir.buf;
strbuf_setlen(&rdir, rdir_len);
helper_argv[2] = rdir.buf;
if (extcmd) {
helper_argv[0] = extcmd;
flags = 0;
} else
strvec_push(&cmd.args, extcmd);
} else {
strvec_push(&cmd.args, "difftool--helper");
cmd.git_cmd = 1;
setenv("GIT_DIFFTOOL_DIRDIFF", "true", 1);
ret = run_command_v_opt(helper_argv, flags);
}
strvec_pushl(&cmd.args, ldir.buf, rdir.buf, NULL);
ret = run_command(&cmd);
/* TODO: audit for interaction with sparse-index. */
ensure_full_index(&wtindex);

View File

@ -1972,14 +1972,17 @@ static int fetch_multiple(struct string_list *list, int max_children)
} else
for (i = 0; i < list->nr; i++) {
const char *name = list->items[i].string;
strvec_push(&argv, name);
struct child_process cmd = CHILD_PROCESS_INIT;
strvec_pushv(&cmd.args, argv.v);
strvec_push(&cmd.args, name);
if (verbosity >= 0)
printf(_("Fetching %s\n"), name);
if (run_command_v_opt(argv.v, RUN_GIT_CMD)) {
cmd.git_cmd = 1;
if (run_command(&cmd)) {
error(_("could not fetch %s"), name);
result = 1;
}
strvec_pop(&argv);
}
strvec_clear(&argv);

View File

@ -167,9 +167,11 @@ static void gc_config(void)
struct maintenance_run_opts;
static int maintenance_task_pack_refs(MAYBE_UNUSED struct maintenance_run_opts *opts)
{
const char *argv[] = { "pack-refs", "--all", "--prune", NULL };
struct child_process cmd = CHILD_PROCESS_INIT;
return run_command_v_opt(argv, RUN_GIT_CMD);
cmd.git_cmd = 1;
strvec_pushl(&cmd.args, "pack-refs", "--all", "--prune", NULL);
return run_command(&cmd);
}
static int too_many_loose_objects(void)
@ -535,9 +537,15 @@ static void gc_before_repack(void)
if (pack_refs && maintenance_task_pack_refs(NULL))
die(FAILED_RUN, "pack-refs");
if (prune_reflogs && run_command_v_opt(reflog.v, RUN_GIT_CMD))
if (prune_reflogs) {
struct child_process cmd = CHILD_PROCESS_INIT;
cmd.git_cmd = 1;
strvec_pushv(&cmd.args, reflog.v);
if (run_command(&cmd))
die(FAILED_RUN, reflog.v[0]);
}
}
int cmd_gc(int argc, const char **argv, const char *prefix)
{
@ -550,6 +558,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
int daemonized = 0;
int keep_largest_pack = -1;
timestamp_t dummy;
struct child_process rerere_cmd = CHILD_PROCESS_INIT;
struct option builtin_gc_options[] = {
OPT__QUIET(&quiet, N_("suppress progress reporting")),
@ -675,11 +684,17 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
gc_before_repack();
if (!repository_format_precious_objects) {
if (run_command_v_opt(repack.v,
RUN_GIT_CMD | RUN_CLOSE_OBJECT_STORE))
struct child_process repack_cmd = CHILD_PROCESS_INIT;
repack_cmd.git_cmd = 1;
repack_cmd.close_object_store = 1;
strvec_pushv(&repack_cmd.args, repack.v);
if (run_command(&repack_cmd))
die(FAILED_RUN, repack.v[0]);
if (prune_expire) {
struct child_process prune_cmd = CHILD_PROCESS_INIT;
/* run `git prune` even if using cruft packs */
strvec_push(&prune, prune_expire);
if (quiet)
@ -687,18 +702,26 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
if (has_promisor_remote())
strvec_push(&prune,
"--exclude-promisor-objects");
if (run_command_v_opt(prune.v, RUN_GIT_CMD))
prune_cmd.git_cmd = 1;
strvec_pushv(&prune_cmd.args, prune.v);
if (run_command(&prune_cmd))
die(FAILED_RUN, prune.v[0]);
}
}
if (prune_worktrees_expire) {
struct child_process prune_worktrees_cmd = CHILD_PROCESS_INIT;
strvec_push(&prune_worktrees, prune_worktrees_expire);
if (run_command_v_opt(prune_worktrees.v, RUN_GIT_CMD))
prune_worktrees_cmd.git_cmd = 1;
strvec_pushv(&prune_worktrees_cmd.args, prune_worktrees.v);
if (run_command(&prune_worktrees_cmd))
die(FAILED_RUN, prune_worktrees.v[0]);
}
if (run_command_v_opt(rerere.v, RUN_GIT_CMD))
rerere_cmd.git_cmd = 1;
strvec_pushv(&rerere_cmd.args, rerere.v);
if (run_command(&rerere_cmd))
die(FAILED_RUN, rerere.v[0]);
report_garbage = report_pack_garbage;
@ -1913,20 +1936,16 @@ static char *schtasks_task_name(const char *frequency)
static int schtasks_remove_task(enum schedule_priority schedule)
{
const char *cmd = "schtasks";
int result;
struct strvec args = STRVEC_INIT;
struct child_process child = CHILD_PROCESS_INIT;
const char *frequency = get_frequency(schedule);
char *name = schtasks_task_name(frequency);
get_schedule_cmd(&cmd, NULL);
strvec_split(&args, cmd);
strvec_pushl(&args, "/delete", "/tn", name, "/f", NULL);
result = run_command_v_opt(args.v, 0);
strvec_clear(&args);
strvec_split(&child.args, cmd);
strvec_pushl(&child.args, "/delete", "/tn", name, "/f", NULL);
free(name);
return result;
return run_command(&child);
}
static int schtasks_remove_tasks(void)

View File

@ -12,6 +12,7 @@ static int merge_entry(int pos, const char *path)
const char *arguments[] = { pgm, "", "", "", path, "", "", "", NULL };
char hexbuf[4][GIT_MAX_HEXSZ + 1];
char ownbuf[4][60];
struct child_process cmd = CHILD_PROCESS_INIT;
if (pos >= active_nr)
die("git merge-index: %s not in the cache", path);
@ -31,7 +32,8 @@ static int merge_entry(int pos, const char *path)
if (!found)
die("git merge-index: %s not in the cache", path);
if (run_command_v_opt(arguments, 0)) {
strvec_pushv(&cmd.args, arguments);
if (run_command(&cmd)) {
if (one_shot)
err++;
else {

View File

@ -345,60 +345,49 @@ out:
return rc;
}
static void read_empty(const struct object_id *oid, int verbose)
static void read_empty(const struct object_id *oid)
{
int i = 0;
const char *args[7];
struct child_process cmd = CHILD_PROCESS_INIT;
args[i++] = "read-tree";
if (verbose)
args[i++] = "-v";
args[i++] = "-m";
args[i++] = "-u";
args[i++] = empty_tree_oid_hex();
args[i++] = oid_to_hex(oid);
args[i] = NULL;
strvec_pushl(&cmd.args, "read-tree", "-m", "-u", empty_tree_oid_hex(),
oid_to_hex(oid), NULL);
cmd.git_cmd = 1;
if (run_command_v_opt(args, RUN_GIT_CMD))
if (run_command(&cmd))
die(_("read-tree failed"));
}
static void reset_hard(const struct object_id *oid, int verbose)
static void reset_hard(const struct object_id *oid)
{
int i = 0;
const char *args[6];
struct child_process cmd = CHILD_PROCESS_INIT;
args[i++] = "read-tree";
if (verbose)
args[i++] = "-v";
args[i++] = "--reset";
args[i++] = "-u";
args[i++] = oid_to_hex(oid);
args[i] = NULL;
strvec_pushl(&cmd.args, "read-tree", "-v", "--reset", "-u",
oid_to_hex(oid), NULL);
cmd.git_cmd = 1;
if (run_command_v_opt(args, RUN_GIT_CMD))
if (run_command(&cmd))
die(_("read-tree failed"));
}
static void restore_state(const struct object_id *head,
const struct object_id *stash)
{
struct strvec args = STRVEC_INIT;
struct child_process cmd = CHILD_PROCESS_INIT;
reset_hard(head, 1);
reset_hard(head);
if (is_null_oid(stash))
goto refresh_cache;
strvec_pushl(&args, "stash", "apply", "--index", "--quiet", NULL);
strvec_push(&args, oid_to_hex(stash));
strvec_pushl(&cmd.args, "stash", "apply", "--index", "--quiet", NULL);
strvec_push(&cmd.args, oid_to_hex(stash));
/*
* It is OK to ignore error here, for example when there was
* nothing to restore.
*/
run_command_v_opt(args.v, RUN_GIT_CMD);
strvec_clear(&args);
cmd.git_cmd = 1;
run_command(&cmd);
refresh_cache:
if (discard_cache() < 0 || read_cache() < 0)
@ -1470,7 +1459,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
check_trust_level);
remote_head_oid = &remoteheads->item->object.oid;
read_empty(remote_head_oid, 0);
read_empty(remote_head_oid);
update_ref("initial pull", "HEAD", remote_head_oid, NULL, 0,
UPDATE_REFS_DIE_ON_ERR);
goto done;

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

View File

@ -92,13 +92,15 @@ static int verbose;
static int fetch_remote(const char *name)
{
const char *argv[] = { "fetch", name, NULL, NULL };
if (verbose) {
argv[1] = "-v";
argv[2] = name;
}
struct child_process cmd = CHILD_PROCESS_INIT;
strvec_push(&cmd.args, "fetch");
if (verbose)
strvec_push(&cmd.args, "-v");
strvec_push(&cmd.args, name);
cmd.git_cmd = 1;
printf_ln(_("Updating %s"), name);
if (run_command_v_opt(argv, RUN_GIT_CMD))
if (run_command(&cmd))
return error(_("Could not fetch %s"), name);
return 0;
}
@ -1508,37 +1510,35 @@ static int update(int argc, const char **argv, const char *prefix)
N_("prune remotes after fetching")),
OPT_END()
};
struct strvec fetch_argv = STRVEC_INIT;
struct child_process cmd = CHILD_PROCESS_INIT;
int default_defined = 0;
int retval;
argc = parse_options(argc, argv, prefix, options,
builtin_remote_update_usage,
PARSE_OPT_KEEP_ARGV0);
strvec_push(&fetch_argv, "fetch");
strvec_push(&cmd.args, "fetch");
if (prune != -1)
strvec_push(&fetch_argv, prune ? "--prune" : "--no-prune");
strvec_push(&cmd.args, prune ? "--prune" : "--no-prune");
if (verbose)
strvec_push(&fetch_argv, "-v");
strvec_push(&fetch_argv, "--multiple");
strvec_push(&cmd.args, "-v");
strvec_push(&cmd.args, "--multiple");
if (argc < 2)
strvec_push(&fetch_argv, "default");
strvec_push(&cmd.args, "default");
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);
if (!default_defined) {
strvec_pop(&fetch_argv);
strvec_push(&fetch_argv, "--all");
strvec_pop(&cmd.args);
strvec_push(&cmd.args, "--all");
}
}
retval = run_command_v_opt(fetch_argv.v, RUN_GIT_CMD);
strvec_clear(&fetch_argv);
return retval;
cmd.git_cmd = 1;
return run_command(&cmd);
}
static int remove_all_fetch_refspecs(const char *key)

View File

@ -196,16 +196,19 @@ static int read_yes_no_answer(void)
static int ask_yes_no_if_possible(const char *format, ...)
{
char question[4096];
const char *retry_hook[] = { NULL, NULL, NULL };
const char *retry_hook;
va_list args;
va_start(args, format);
vsnprintf(question, sizeof(question), format, args);
va_end(args);
if ((retry_hook[0] = mingw_getenv("GIT_ASK_YESNO"))) {
retry_hook[1] = question;
return !run_command_v_opt(retry_hook, 0);
retry_hook = mingw_getenv("GIT_ASK_YESNO");
if (retry_hook) {
struct child_process cmd = CHILD_PROCESS_INIT;
strvec_pushl(&cmd.args, retry_hook, question, NULL);
return !run_command(&cmd);
}
if (!isatty(_fileno(stdin)) || !isatty(_fileno(stderr)))

27
diff.c
View File

@ -4301,35 +4301,34 @@ static void run_external_diff(const char *pgm,
const char *xfrm_msg,
struct diff_options *o)
{
struct strvec argv = STRVEC_INIT;
struct strvec env = STRVEC_INIT;
struct child_process cmd = CHILD_PROCESS_INIT;
struct diff_queue_struct *q = &diff_queued_diff;
strvec_push(&argv, pgm);
strvec_push(&argv, name);
strvec_push(&cmd.args, pgm);
strvec_push(&cmd.args, name);
if (one && two) {
add_external_diff_name(o->repo, &argv, name, one);
add_external_diff_name(o->repo, &cmd.args, name, one);
if (!other)
add_external_diff_name(o->repo, &argv, name, two);
add_external_diff_name(o->repo, &cmd.args, name, two);
else {
add_external_diff_name(o->repo, &argv, other, two);
strvec_push(&argv, other);
strvec_push(&argv, xfrm_msg);
add_external_diff_name(o->repo, &cmd.args, other, two);
strvec_push(&cmd.args, other);
strvec_push(&cmd.args, xfrm_msg);
}
}
strvec_pushf(&env, "GIT_DIFF_PATH_COUNTER=%d", ++o->diff_path_counter);
strvec_pushf(&env, "GIT_DIFF_PATH_TOTAL=%d", q->nr);
strvec_pushf(&cmd.env, "GIT_DIFF_PATH_COUNTER=%d",
++o->diff_path_counter);
strvec_pushf(&cmd.env, "GIT_DIFF_PATH_TOTAL=%d", q->nr);
diff_free_filespec_data(one);
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);
remove_tempfile();
strvec_clear(&argv);
strvec_clear(&env);
}
static int similarity_index(struct diff_filepair *p)

View File

@ -54,10 +54,14 @@ enum ipc_active_state fsmonitor_ipc__get_state(void)
static int spawn_daemon(void)
{
const char *args[] = { "fsmonitor--daemon", "start", NULL };
struct child_process cmd = CHILD_PROCESS_INIT;
return run_command_v_opt_tr2(args, RUN_COMMAND_NO_STDIN | RUN_GIT_CMD,
"fsmonitor");
cmd.git_cmd = 1;
cmd.no_stdin = 1;
cmd.trace2_child_class = "fsmonitor";
strvec_pushl(&cmd.args, "fsmonitor--daemon", "start", NULL);
return run_command(&cmd);
}
int fsmonitor_ipc__send_query(const char *since_token,

15
git.c
View File

@ -787,7 +787,7 @@ static int run_argv(int *argcp, const char ***argv)
if (!done_alias)
handle_builtin(*argcp, *argv);
else if (get_builtin(**argv)) {
struct strvec args = STRVEC_INIT;
struct child_process cmd = CHILD_PROCESS_INIT;
int i;
/*
@ -804,18 +804,21 @@ static int run_argv(int *argcp, const char ***argv)
commit_pager_choice();
strvec_push(&args, "git");
strvec_push(&cmd.args, "git");
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
* OK to return. Otherwise, we just pass along the status code.
*/
i = run_command_v_opt_tr2(args.v, RUN_SILENT_EXEC_FAILURE |
RUN_CLEAN_ON_EXIT | RUN_WAIT_AFTER_CLEAN, "git_alias");
cmd.silent_exec_failure = 1;
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)
exit(i);
die("could not execute builtin %s", **argv);

View File

@ -193,7 +193,7 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
struct strbuf cmd = STRBUF_INIT;
struct strbuf_expand_dict_entry dict[6];
struct strbuf path_sq = STRBUF_INIT;
const char *args[] = { NULL, NULL };
struct child_process child = CHILD_PROCESS_INIT;
int status, fd, i;
struct stat st;
enum ll_merge_result ret;
@ -219,8 +219,9 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict);
args[0] = cmd.buf;
status = run_command_v_opt(args, RUN_USING_SHELL);
child.use_shell = 1;
strvec_push(&child.args, cmd.buf);
status = run_command(&child);
fd = open(temp[1], O_RDONLY);
if (fd < 0)
goto bad;

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 *head_arg, struct commit_list *remotes)
{
struct strvec args = STRVEC_INIT;
struct child_process cmd = CHILD_PROCESS_INIT;
int i, ret;
struct commit_list *j;
strvec_pushf(&args, "merge-%s", strategy);
strvec_pushf(&cmd.args, "merge-%s", strategy);
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)
strvec_push(&args, merge_argument(j->item));
strvec_push(&args, "--");
strvec_push(&args, head_arg);
strvec_push(&cmd.args, merge_argument(j->item));
strvec_push(&cmd.args, "--");
strvec_push(&cmd.args, head_arg);
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);
strvec_clear(&args);
cmd.git_cmd = 1;
ret = run_command(&cmd);
discard_index(r->index);
if (repo_read_index(r) < 0)

View File

@ -1004,41 +1004,6 @@ int run_command(struct child_process *cmd)
return finish_command(cmd);
}
int run_command_v_opt(const char **argv, int opt)
{
return run_command_v_opt_cd_env(argv, opt, NULL, NULL);
}
int run_command_v_opt_tr2(const char **argv, int opt, const char *tr2_class)
{
return run_command_v_opt_cd_env_tr2(argv, opt, NULL, NULL, tr2_class);
}
int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env)
{
return run_command_v_opt_cd_env_tr2(argv, opt, dir, env, NULL);
}
int run_command_v_opt_cd_env_tr2(const char **argv, int opt, const char *dir,
const char *const *env, const char *tr2_class)
{
struct child_process cmd = CHILD_PROCESS_INIT;
strvec_pushv(&cmd.args, argv);
cmd.no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0;
cmd.git_cmd = opt & RUN_GIT_CMD ? 1 : 0;
cmd.stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;
cmd.silent_exec_failure = opt & RUN_SILENT_EXEC_FAILURE ? 1 : 0;
cmd.use_shell = opt & RUN_USING_SHELL ? 1 : 0;
cmd.clean_on_exit = opt & RUN_CLEAN_ON_EXIT ? 1 : 0;
cmd.wait_after_clean = opt & RUN_WAIT_AFTER_CLEAN ? 1 : 0;
cmd.close_object_store = opt & RUN_CLOSE_OBJECT_STORE ? 1 : 0;
cmd.dir = dir;
if (env)
strvec_pushv(&cmd.env, (const char **)env);
cmd.trace2_child_class = tr2_class;
return run_command(&cmd);
}
#ifndef NO_PTHREADS
static pthread_t main_thread;
static int main_thread_set;

View File

@ -150,9 +150,7 @@ struct child_process {
}
/**
* The functions: child_process_init, start_command, finish_command,
* run_command, run_command_v_opt, run_command_v_opt_cd_env, child_process_clear
* do the following:
* The functions: start_command, finish_command, run_command do the following:
*
* - If a system call failed, errno is set and -1 is returned. A diagnostic
* is printed.
@ -224,36 +222,6 @@ int run_command(struct child_process *);
*/
int run_auto_maintenance(int quiet);
#define RUN_COMMAND_NO_STDIN (1<<0)
#define RUN_GIT_CMD (1<<1)
#define RUN_COMMAND_STDOUT_TO_STDERR (1<<2)
#define RUN_SILENT_EXEC_FAILURE (1<<3)
#define RUN_USING_SHELL (1<<4)
#define RUN_CLEAN_ON_EXIT (1<<5)
#define RUN_WAIT_AFTER_CLEAN (1<<6)
#define RUN_CLOSE_OBJECT_STORE (1<<7)
/**
* Convenience functions that encapsulate a sequence of
* start_command() followed by finish_command(). The argument argv
* specifies the program and its arguments. The argument opt is zero
* or more of the flags `RUN_COMMAND_NO_STDIN`, `RUN_GIT_CMD`,
* `RUN_COMMAND_STDOUT_TO_STDERR`, or `RUN_SILENT_EXEC_FAILURE`
* that correspond to the members .no_stdin, .git_cmd,
* .stdout_to_stderr, .silent_exec_failure of `struct child_process`.
* The argument dir corresponds the member .dir. The argument env
* corresponds to the member .env.
*/
int run_command_v_opt(const char **argv, int opt);
int run_command_v_opt_tr2(const char **argv, int opt, const char *tr2_class);
/*
* env (the environment) is to be formatted like environ: "VAR=VALUE".
* To unset an environment variable use just "VAR".
*/
int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env);
int run_command_v_opt_cd_env_tr2(const char **argv, int opt, const char *dir,
const char *const *env, const char *tr2_class);
/**
* Execute the given command, sending "in" to its stdin, and capturing its
* stdout and stderr in the "out" and "err" strbufs. Any of the three may

View File

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

View File

@ -3183,18 +3183,15 @@ static int rollback_is_safe(void)
static int reset_merge(const struct object_id *oid)
{
int ret;
struct strvec argv = STRVEC_INIT;
struct child_process cmd = CHILD_PROCESS_INIT;
strvec_pushl(&argv, "reset", "--merge", NULL);
cmd.git_cmd = 1;
strvec_pushl(&cmd.args, "reset", "--merge", NULL);
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);
strvec_clear(&argv);
return ret;
return run_command(&cmd);
}
static int rollback_single_pick(struct repository *r)
@ -3558,12 +3555,13 @@ static int error_failed_squash(struct repository *r,
static int do_exec(struct repository *r, const char *command_line)
{
const char *child_argv[] = { NULL, NULL };
struct child_process cmd = CHILD_PROCESS_INIT;
int dirty, status;
fprintf(stderr, _("Executing: %s\n"), command_line);
child_argv[0] = command_line;
status = run_command_v_opt(child_argv, RUN_USING_SHELL);
cmd.use_shell = 1;
strvec_push(&cmd.args, command_line);
status = run_command(&cmd);
/* force re-reading of the cache */
if (discard_index(r->index) < 0 || repo_read_index(r) < 0)
@ -4867,14 +4865,14 @@ cleanup_head_ref:
static int continue_single_pick(struct repository *r, struct replay_opts *opts)
{
struct strvec argv = STRVEC_INIT;
int ret;
struct child_process cmd = CHILD_PROCESS_INIT;
if (!refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&
!refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD"))
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
@ -4887,11 +4885,9 @@ static int continue_single_pick(struct repository *r, struct replay_opts *opts)
* Include --cleanup=strip as well because we don't want the
* "# 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);
strvec_clear(&argv);
return ret;
return run_command(&cmd);
}
static int commit_staged_changes(struct repository *r,

17
shell.c
View File

@ -52,21 +52,24 @@ static void cd_to_homedir(void)
static void run_shell(void)
{
int done = 0;
static const char *help_argv[] = { HELP_COMMAND, NULL };
struct child_process help_cmd = CHILD_PROCESS_INIT;
if (!access(NOLOGIN_COMMAND, F_OK)) {
/* Interactive login disabled. */
const char *argv[] = { NOLOGIN_COMMAND, NULL };
struct child_process nologin_cmd = CHILD_PROCESS_INIT;
int status;
status = run_command_v_opt(argv, 0);
strvec_push(&nologin_cmd.args, NOLOGIN_COMMAND);
status = run_command(&nologin_cmd);
if (status < 0)
exit(127);
exit(status);
}
/* Print help if enabled */
run_command_v_opt(help_argv, RUN_SILENT_EXEC_FAILURE);
help_cmd.silent_exec_failure = 1;
strvec_push(&help_cmd.args, HELP_COMMAND);
run_command(&help_cmd);
do {
const char *prog;
@ -125,9 +128,13 @@ static void run_shell(void)
!strcmp(prog, "exit") || !strcmp(prog, "bye")) {
done = 1;
} else if (is_valid_cmd_name(prog)) {
struct child_process cmd = CHILD_PROCESS_INIT;
full_cmd = make_cmd(prog);
argv[0] = full_cmd;
code = run_command_v_opt(argv, RUN_SILENT_EXEC_FAILURE);
cmd.silent_exec_failure = 1;
strvec_pushv(&cmd.args, argv);
code = run_command(&cmd);
if (code == -1 && errno == ENOENT) {
fprintf(stderr, "unrecognized command '%s'\n", prog);
}

View File

@ -8,7 +8,7 @@ int cmd_main(int argc, const char **argv)
struct strbuf buf = STRBUF_INIT;
FILE *f;
int i;
const char *child_argv[] = { NULL, NULL };
struct child_process cmd = CHILD_PROCESS_INIT;
/* First, print all parameters into $TRASH_DIRECTORY/ssh-output */
if (!trash_directory)
@ -25,6 +25,7 @@ int cmd_main(int argc, const char **argv)
/* Now, evaluate the *last* parameter */
if (argc < 2)
return 0;
child_argv[0] = argv[argc - 1];
return run_command_v_opt(child_argv, RUN_USING_SHELL);
cmd.use_shell = 1;
strvec_push(&cmd.args, argv[argc - 1]);
return run_command(&cmd);
}

View File

@ -132,6 +132,7 @@ static int ut_003error(int argc, const char **argv)
*/
static int ut_004child(int argc, const char **argv)
{
struct child_process cmd = CHILD_PROCESS_INIT;
int result;
/*
@ -141,7 +142,8 @@ static int ut_004child(int argc, const char **argv)
if (!argc)
return 0;
result = run_command_v_opt(argv, 0);
strvec_pushv(&cmd.args, argv);
result = run_command(&cmd);
exit(result);
}

View File

@ -10,9 +10,11 @@
*
* Example:
*
* struct child_process child = CHILD_PROCESS_INIT;
* struct tmp_objdir *t = tmp_objdir_create("incoming");
* if (!run_command_v_opt_cd_env(cmd, 0, NULL, tmp_objdir_env(t)) &&
* !tmp_objdir_migrate(t))
* strvec_push(&child.args, cmd);
* strvec_pushv(&child.env, tmp_objdir_env(t));
* if (!run_command(&child)) && !tmp_objdir_migrate(t))
* printf("success!\n");
* else
* die("failed...tmp_objdir will clean up for us");