int run_column_filter(int colopts, const struct column_options *opts) { struct argv_array *argv; if (fd_out != -1) return -1; memset(&column_process, 0, sizeof(column_process)); argv = &column_process.args; argv_array_push(argv, "column"); argv_array_pushf(argv, "--raw-mode=%d", colopts); if (opts && opts->width) argv_array_pushf(argv, "--width=%d", opts->width); if (opts && opts->indent) argv_array_pushf(argv, "--indent=%s", opts->indent); if (opts && opts->padding) argv_array_pushf(argv, "--padding=%d", opts->padding); fflush(stdout); column_process.in = -1; column_process.out = dup(1); column_process.git_cmd = 1; if (start_command(&column_process)) return -2; fd_out = dup(1); close(1); dup2(column_process.in, 1); close(column_process.in); return 0; }
static int restore_untracked(struct object_id *u_tree) { int res; struct child_process cp = CHILD_PROCESS_INIT; /* * We need to run restore files from a given index, but without * affecting the current index, so we use GIT_INDEX_FILE with * run_command to fork processes that will not interfere. */ cp.git_cmd = 1; argv_array_push(&cp.args, "read-tree"); argv_array_push(&cp.args, oid_to_hex(u_tree)); argv_array_pushf(&cp.env_array, "GIT_INDEX_FILE=%s", stash_index_path.buf); if (run_command(&cp)) { remove_path(stash_index_path.buf); return -1; } child_process_init(&cp); cp.git_cmd = 1; argv_array_pushl(&cp.args, "checkout-index", "--all", NULL); argv_array_pushf(&cp.env_array, "GIT_INDEX_FILE=%s", stash_index_path.buf); res = run_command(&cp); remove_path(stash_index_path.buf); return res; }
int try_merge_command(const char *strategy, size_t xopts_nr, const char **xopts, struct commit_list *common, const char *head_arg, struct commit_list *remotes) { struct argv_array args = ARGV_ARRAY_INIT; int i, ret; struct commit_list *j; argv_array_pushf(&args, "merge-%s", strategy); for (i = 0; i < xopts_nr; i++) argv_array_pushf(&args, "--%s", xopts[i]); for (j = common; j; j = j->next) argv_array_push(&args, merge_argument(j->item)); argv_array_push(&args, "--"); argv_array_push(&args, head_arg); for (j = remotes; j; j = j->next) argv_array_push(&args, merge_argument(j->item)); ret = run_command_v_opt(args.argv, RUN_GIT_CMD); argv_array_clear(&args); discard_cache(); if (read_cache() < 0) die(_("failed to read the cache")); resolve_undo_clear(); return ret; }
static int stash_patch(struct stash_info *info, struct pathspec ps, struct strbuf *out_patch, int quiet) { int ret = 0; struct child_process cp_read_tree = CHILD_PROCESS_INIT; struct child_process cp_add_i = CHILD_PROCESS_INIT; struct child_process cp_diff_tree = CHILD_PROCESS_INIT; struct index_state istate = { NULL }; remove_path(stash_index_path.buf); cp_read_tree.git_cmd = 1; argv_array_pushl(&cp_read_tree.args, "read-tree", "HEAD", NULL); argv_array_pushf(&cp_read_tree.env_array, "GIT_INDEX_FILE=%s", stash_index_path.buf); if (run_command(&cp_read_tree)) { ret = -1; goto done; } /* Find out what the user wants. */ cp_add_i.git_cmd = 1; argv_array_pushl(&cp_add_i.args, "add--interactive", "--patch=stash", "--", NULL); add_pathspecs(&cp_add_i.args, ps); argv_array_pushf(&cp_add_i.env_array, "GIT_INDEX_FILE=%s", stash_index_path.buf); if (run_command(&cp_add_i)) { ret = -1; goto done; } /* State of the working tree. */ if (write_index_as_tree(&info->w_tree, &istate, stash_index_path.buf, 0, NULL)) { ret = -1; goto done; } cp_diff_tree.git_cmd = 1; argv_array_pushl(&cp_diff_tree.args, "diff-tree", "-p", "HEAD", oid_to_hex(&info->w_tree), "--", NULL); if (pipe_command(&cp_diff_tree, NULL, 0, out_patch, 0, NULL, 0)) { ret = -1; goto done; } if (!out_patch->len) { if (!quiet) fprintf_ln(stderr, _("No changes selected")); ret = 1; } done: discard_index(&istate); remove_path(stash_index_path.buf); return ret; }
/* * If we are cherry-pick, and if the merge did not result in * hand-editing, we will hit this commit and inherit the original * author date and name. * If we are revert, or if our cherry-pick results in a hand merge, * we had better say that the current user is responsible for that. */ static int run_git_commit(const char *defmsg, struct replay_opts *opts, int allow_empty) { struct argv_array array; int rc; const char *value; argv_array_init(&array); argv_array_push(&array, "commit"); argv_array_push(&array, "-n"); if (opts->gpg_sign) argv_array_pushf(&array, "-S%s", opts->gpg_sign); if (opts->signoff) argv_array_push(&array, "-s"); if (!opts->edit) { argv_array_push(&array, "-F"); argv_array_push(&array, defmsg); if (!opts->signoff && !opts->record_origin && git_config_get_value("commit.cleanup", &value)) argv_array_push(&array, "--cleanup=verbatim"); } if (allow_empty) argv_array_push(&array, "--allow-empty"); if (opts->allow_empty_message) argv_array_push(&array, "--allow-empty-message"); rc = run_command_v_opt(array.argv, RUN_GIT_CMD); argv_array_clear(&array); return rc; }
static int upload_pack(void) { struct child_process cld = CHILD_PROCESS_INIT; argv_array_pushl(&cld.args, "upload-pack", "--strict", NULL); argv_array_pushf(&cld.args, "--timeout=%u", timeout); return run_service_command(&cld); }
static void read_alternate_refs(const char *path, alternate_ref_fn *cb, void *data) { struct child_process cmd = CHILD_PROCESS_INIT; struct strbuf line = STRBUF_INIT; FILE *fh; cmd.git_cmd = 1; argv_array_pushf(&cmd.args, "--git-dir=%s", path); argv_array_push(&cmd.args, "for-each-ref"); argv_array_push(&cmd.args, "--format=%(objectname) %(refname)"); cmd.env = local_repo_env; cmd.out = -1; if (start_command(&cmd)) return; fh = xfdopen(cmd.out, "r"); while (strbuf_getline_lf(&line, fh) != EOF) { struct object_id oid; if (get_oid_hex(line.buf, &oid) || line.buf[GIT_SHA1_HEXSZ] != ' ') { warning("invalid line while parsing alternate refs: %s", line.buf); break; } cb(line.buf + GIT_SHA1_HEXSZ + 1, &oid, data); } fclose(fh); finish_command(&cmd); }
static int stash_working_tree(struct stash_info *info, struct pathspec ps) { int ret = 0; struct rev_info rev; struct child_process cp_upd_index = CHILD_PROCESS_INIT; struct strbuf diff_output = STRBUF_INIT; struct index_state istate = { NULL }; init_revisions(&rev, NULL); set_alternate_index_output(stash_index_path.buf); if (reset_tree(&info->i_tree, 0, 0)) { ret = -1; goto done; } set_alternate_index_output(NULL); rev.prune_data = ps; rev.diffopt.output_format = DIFF_FORMAT_CALLBACK; rev.diffopt.format_callback = add_diff_to_buf; rev.diffopt.format_callback_data = &diff_output; if (read_cache_preload(&rev.diffopt.pathspec) < 0) { ret = -1; goto done; } add_pending_object(&rev, parse_object(the_repository, &info->b_commit), ""); if (run_diff_index(&rev, 0)) { ret = -1; goto done; } cp_upd_index.git_cmd = 1; argv_array_pushl(&cp_upd_index.args, "update-index", "-z", "--add", "--remove", "--stdin", NULL); argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s", stash_index_path.buf); if (pipe_command(&cp_upd_index, diff_output.buf, diff_output.len, NULL, 0, NULL, 0)) { ret = -1; goto done; } if (write_index_as_tree(&info->w_tree, &istate, stash_index_path.buf, 0, NULL)) { ret = -1; goto done; } done: discard_index(&istate); UNLEAK(rev); object_array_clear(&rev.pending); strbuf_release(&diff_output); remove_path(stash_index_path.buf); return ret; }
/* * If we are cherry-pick, and if the merge did not result in * hand-editing, we will hit this commit and inherit the original * author date and name. * If we are revert, or if our cherry-pick results in a hand merge, * we had better say that the current user is responsible for that. */ static int run_git_commit(const char *defmsg, struct replay_opts *opts, int allow_empty) { struct argv_array array; int rc; argv_array_init(&array); argv_array_push(&array, "commit"); argv_array_push(&array, "-n"); if (opts->gpg_sign) argv_array_pushf(&array, "-S%s", opts->gpg_sign); if (opts->signoff) argv_array_push(&array, "-s"); if (!opts->edit) { argv_array_push(&array, "-F"); argv_array_push(&array, defmsg); } if (allow_empty) argv_array_push(&array, "--allow-empty"); if (opts->allow_empty_message) argv_array_push(&array, "--allow-empty-message"); rc = run_command_v_opt(array.argv, RUN_GIT_CMD); argv_array_clear(&array); return rc; }
static void fill_alternate_refs_command(struct child_process *cmd, const char *repo_path) { const char *value; if (!git_config_get_value("core.alternateRefsCommand", &value)) { cmd->use_shell = 1; argv_array_push(&cmd->args, value); argv_array_push(&cmd->args, repo_path); } else { cmd->git_cmd = 1; argv_array_pushf(&cmd->args, "--git-dir=%s", repo_path); argv_array_push(&cmd->args, "for-each-ref"); argv_array_push(&cmd->args, "--format=%(objectname)"); if (!git_config_get_value("core.alternateRefsPrefixes", &value)) { argv_array_push(&cmd->args, "--"); argv_array_split(&cmd->args, value); } } cmd->env = local_repo_env; cmd->out = -1; }
void refspec_ref_prefixes(const struct refspec *rs, struct argv_array *ref_prefixes) { int i; for (i = 0; i < rs->nr; i++) { const struct refspec_item *item = &rs->items[i]; const char *prefix = NULL; if (item->exact_sha1) continue; if (rs->fetch == REFSPEC_FETCH) prefix = item->src; else if (item->dst) prefix = item->dst; else if (item->src && !item->exact_sha1) prefix = item->src; if (prefix) { if (item->pattern) { const char *glob = strchr(prefix, '*'); argv_array_pushf(ref_prefixes, "%.*s", (int)(glob - prefix), prefix); } else { expand_ref_prefix(ref_prefixes, prefix); } } } }
static void execv_dashed_external(const char **argv) { struct child_process cmd = CHILD_PROCESS_INIT; int status; if (get_super_prefix()) die("%s doesn't support --super-prefix", argv[0]); if (use_pager == -1 && !is_builtin(argv[0])) use_pager = check_pager_config(argv[0]); commit_pager_choice(); argv_array_pushf(&cmd.args, "git-%s", argv[0]); argv_array_pushv(&cmd.args, argv + 1); cmd.clean_on_exit = 1; cmd.wait_after_clean = 1; cmd.silent_exec_failure = 1; trace_argv_printf(cmd.args.argv, "trace: exec:"); /* * If we fail because the command is not found, it is * OK to return. Otherwise, we just pass along the status code, * or our usual generic code if we were not even able to exec * the program. */ status = run_command(&cmd); if (status >= 0) exit(status); else if (errno != ENOENT) exit(128); }
static void run_service(const char **argv, int buffer_input) { const char *encoding = getenv("HTTP_CONTENT_ENCODING"); const char *user = getenv("REMOTE_USER"); const char *host = getenv("REMOTE_ADDR"); int gzipped_request = 0; struct child_process cld = CHILD_PROCESS_INIT; ssize_t req_len = get_content_length(); if (encoding && !strcmp(encoding, "gzip")) gzipped_request = 1; else if (encoding && !strcmp(encoding, "x-gzip")) gzipped_request = 1; if (!user || !*user) user = "******"; if (!host || !*host) host = "(none)"; if (!getenv("GIT_COMMITTER_NAME")) argv_array_pushf(&cld.env_array, "GIT_COMMITTER_NAME=%s", user); if (!getenv("GIT_COMMITTER_EMAIL")) argv_array_pushf(&cld.env_array, "GIT_COMMITTER_EMAIL=%s@http.%s", user, host); cld.argv = argv; if (buffer_input || gzipped_request || req_len >= 0) cld.in = -1; cld.git_cmd = 1; cld.clean_on_exit = 1; cld.wait_after_clean = 1; if (start_command(&cld)) exit(1); close(1); if (gzipped_request) inflate_request(argv[0], cld.in, buffer_input, req_len); else if (buffer_input) copy_request(argv[0], cld.in, req_len); else if (req_len >= 0) pipe_fixed_length(argv[0], cld.in, req_len); else close(0); if (finish_command(&cld)) exit(1); }
/* * Append the appropriate environment variables to `env` and options to * `args` for running ssh in Git's SSH-tunneled transport. */ static void push_ssh_options(struct argv_array *args, struct argv_array *env, enum ssh_variant variant, const char *port, int flags) { if (variant == VARIANT_SSH && get_protocol_version_config() > 0) { argv_array_push(args, "-o"); argv_array_push(args, "SendEnv=" GIT_PROTOCOL_ENVIRONMENT); argv_array_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=version=%d", get_protocol_version_config()); } if (flags & CONNECT_IPV4) { switch (variant) { case VARIANT_AUTO: BUG("VARIANT_AUTO passed to push_ssh_options"); case VARIANT_SIMPLE: die("ssh variant 'simple' does not support -4"); case VARIANT_SSH: case VARIANT_PLINK: case VARIANT_PUTTY: case VARIANT_TORTOISEPLINK: argv_array_push(args, "-4"); } } else if (flags & CONNECT_IPV6) { switch (variant) { case VARIANT_AUTO: BUG("VARIANT_AUTO passed to push_ssh_options"); case VARIANT_SIMPLE: die("ssh variant 'simple' does not support -6"); case VARIANT_SSH: case VARIANT_PLINK: case VARIANT_PUTTY: case VARIANT_TORTOISEPLINK: argv_array_push(args, "-6"); } } if (variant == VARIANT_TORTOISEPLINK) argv_array_push(args, "-batch"); if (port) { switch (variant) { case VARIANT_AUTO: BUG("VARIANT_AUTO passed to push_ssh_options"); case VARIANT_SIMPLE: die("ssh variant 'simple' does not support setting port"); case VARIANT_SSH: argv_array_push(args, "-p"); break; case VARIANT_PLINK: case VARIANT_PUTTY: case VARIANT_TORTOISEPLINK: argv_array_push(args, "-P"); } argv_array_push(args, port); } }
static void wt_status_print_submodule_summary(struct wt_status *s, int uncommitted) { struct child_process sm_summary = CHILD_PROCESS_INIT; struct strbuf cmd_stdout = STRBUF_INIT; struct strbuf summary = STRBUF_INIT; char *summary_content; argv_array_pushf(&sm_summary.env_array, "GIT_INDEX_FILE=%s", s->index_file); argv_array_push(&sm_summary.args, "submodule"); argv_array_push(&sm_summary.args, "summary"); argv_array_push(&sm_summary.args, uncommitted ? "--files" : "--cached"); argv_array_push(&sm_summary.args, "--for-status"); argv_array_push(&sm_summary.args, "--summary-limit"); argv_array_pushf(&sm_summary.args, "%d", s->submodule_summary); if (!uncommitted) argv_array_push(&sm_summary.args, s->amend ? "HEAD^" : "HEAD"); sm_summary.git_cmd = 1; sm_summary.no_stdin = 1; capture_command(&sm_summary, &cmd_stdout, 1024); /* prepend header, only if there's an actual output */ if (cmd_stdout.len) { if (uncommitted) strbuf_addstr(&summary, _("Submodules changed but not updated:")); else strbuf_addstr(&summary, _("Submodule changes to be committed:")); strbuf_addstr(&summary, "\n\n"); } strbuf_addbuf(&summary, &cmd_stdout); strbuf_release(&cmd_stdout); if (s->display_comment_prefix) { size_t len; summary_content = strbuf_detach(&summary, &len); strbuf_add_commented_lines(&summary, summary_content, len); free(summary_content); } fputs(summary.buf, s->fp); strbuf_release(&summary); }
static void run_service(const char **argv) { const char *encoding = getenv("HTTP_CONTENT_ENCODING"); const char *user = getenv("REMOTE_USER"); const char *host = getenv("REMOTE_ADDR"); struct argv_array env = ARGV_ARRAY_INIT; int gzipped_request = 0; struct child_process cld; if (encoding && !strcmp(encoding, "gzip")) gzipped_request = 1; else if (encoding && !strcmp(encoding, "x-gzip")) gzipped_request = 1; if (!user || !*user) user = "******"; if (!host || !*host) host = "(none)"; if (!getenv("GIT_COMMITTER_NAME")) argv_array_pushf(&env, "GIT_COMMITTER_NAME=%s", user); if (!getenv("GIT_COMMITTER_EMAIL")) argv_array_pushf(&env, "GIT_COMMITTER_EMAIL=%s@http.%s", user, host); memset(&cld, 0, sizeof(cld)); cld.argv = argv; cld.env = env.argv; if (gzipped_request) cld.in = -1; cld.git_cmd = 1; if (start_command(&cld)) exit(1); close(1); if (gzipped_request) inflate_request(argv[0], cld.in); else close(0); if (finish_command(&cld)) exit(1); argv_array_clear(&env); }
static void add_repack_all_option(void) { if (prune_expire && !strcmp(prune_expire, "now")) argv_array_push(&repack, "-a"); else { argv_array_push(&repack, "-A"); if (prune_expire) argv_array_pushf(&repack, "--unpack-unreachable=%s", prune_expire); } }
static void prepare_push_cert_sha1(struct child_process *proc) { static int already_done; if (!push_cert.len) return; if (!already_done) { struct strbuf gpg_output = STRBUF_INIT; struct strbuf gpg_status = STRBUF_INIT; int bogs /* beginning_of_gpg_sig */; already_done = 1; if (write_sha1_file(push_cert.buf, push_cert.len, "blob", push_cert_sha1)) hashclr(push_cert_sha1); memset(&sigcheck, '\0', sizeof(sigcheck)); sigcheck.result = 'N'; bogs = parse_signature(push_cert.buf, push_cert.len); if (verify_signed_buffer(push_cert.buf, bogs, push_cert.buf + bogs, push_cert.len - bogs, &gpg_output, &gpg_status) < 0) { ; /* error running gpg */ } else { sigcheck.payload = push_cert.buf; sigcheck.gpg_output = gpg_output.buf; sigcheck.gpg_status = gpg_status.buf; parse_gpg_output(&sigcheck); } strbuf_release(&gpg_output); strbuf_release(&gpg_status); nonce_status = check_nonce(push_cert.buf, bogs); } if (!is_null_sha1(push_cert_sha1)) { argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT=%s", sha1_to_hex(push_cert_sha1)); argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_SIGNER=%s", sigcheck.signer ? sigcheck.signer : ""); argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_KEY=%s", sigcheck.key ? sigcheck.key : ""); argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_STATUS=%c", sigcheck.result); if (push_cert_nonce) { argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_NONCE=%s", push_cert_nonce); argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_NONCE_STATUS=%s", nonce_status); if (nonce_status == NONCE_SLOP) argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_NONCE_SLOP=%ld", nonce_stamp_slop); } } }
static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen) { struct child_process cld = CHILD_PROCESS_INIT; if (max_connections && live_children >= max_connections) { kill_some_child(); sleep(1); /* give it some time to die */ check_dead_children(); if (live_children >= max_connections) { close(incoming); logerror("Too many children, dropping connection"); return; } } if (addr->sa_family == AF_INET) { char buf[128] = ""; struct sockaddr_in *sin_addr = (void *) addr; inet_ntop(addr->sa_family, &sin_addr->sin_addr, buf, sizeof(buf)); argv_array_pushf(&cld.env_array, "REMOTE_ADDR=%s", buf); argv_array_pushf(&cld.env_array, "REMOTE_PORT=%d", ntohs(sin_addr->sin_port)); #ifndef NO_IPV6 } else if (addr->sa_family == AF_INET6) { char buf[128] = ""; struct sockaddr_in6 *sin6_addr = (void *) addr; inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(buf)); argv_array_pushf(&cld.env_array, "REMOTE_ADDR=[%s]", buf); argv_array_pushf(&cld.env_array, "REMOTE_PORT=%d", ntohs(sin6_addr->sin6_port)); #endif } cld.argv = cld_argv.argv; cld.in = incoming; cld.out = dup(incoming); if (start_command(&cld)) logerror("unable to fork"); else add_child(&cld, addr, addrlen); }
static const char *push_to_checkout(unsigned char *sha1, struct argv_array *env, const char *work_tree) { argv_array_pushf(env, "GIT_WORK_TREE=%s", absolute_path(work_tree)); if (run_hook_le(env->argv, push_to_checkout_hook, sha1_to_hex(sha1), NULL)) return "push-to-checkout hook declined"; else return NULL; }
/* * If we are cherry-pick, and if the merge did not result in * hand-editing, we will hit this commit and inherit the original * author date and name. * * If we are revert, or if our cherry-pick results in a hand merge, * we had better say that the current user is responsible for that. * * An exception is when run_git_commit() is called during an * interactive rebase: in that case, we will want to retain the * author metadata. */ static int run_git_commit(const char *defmsg, struct replay_opts *opts, int allow_empty, int edit, int amend, int cleanup_commit_message) { char **env = NULL; struct argv_array array; int rc; const char *value; if (is_rebase_i(opts)) { env = read_author_script(); if (!env) { const char *gpg_opt = gpg_sign_opt_quoted(opts); return error(_(staged_changes_advice), gpg_opt, gpg_opt); } } argv_array_init(&array); argv_array_push(&array, "commit"); argv_array_push(&array, "-n"); if (amend) argv_array_push(&array, "--amend"); if (opts->gpg_sign) argv_array_pushf(&array, "-S%s", opts->gpg_sign); if (opts->signoff) argv_array_push(&array, "-s"); if (defmsg) argv_array_pushl(&array, "-F", defmsg, NULL); if (cleanup_commit_message) argv_array_push(&array, "--cleanup=strip"); if (edit) argv_array_push(&array, "-e"); else if (!cleanup_commit_message && !opts->signoff && !opts->record_origin && git_config_get_value("commit.cleanup", &value)) argv_array_push(&array, "--cleanup=verbatim"); if (allow_empty) argv_array_push(&array, "--allow-empty"); if (opts->allow_empty_message) argv_array_push(&array, "--allow-empty-message"); rc = run_command_v_opt_cd_env(array.argv, RUN_GIT_CMD, NULL, (const char *const *)env); argv_array_clear(&array); free(env); return rc; }
/* * Note, "git status --porcelain" is used to determine if it's safe to * delete a whole worktree. "git status" does not ignore user * configuration, so if a normal "git status" shows "clean" for the * user, then it's ok to remove it. * * This assumption may be a bad one. We may want to ignore * (potentially bad) user settings and only delete a worktree when * it's absolutely safe to do so from _our_ point of view because we * know better. */ static void check_clean_worktree(struct worktree *wt, const char *original_path) { struct argv_array child_env = ARGV_ARRAY_INIT; struct child_process cp; char buf[1]; int ret; /* * Until we sort this out, all submodules are "dirty" and * will abort this function. */ validate_no_submodules(wt); argv_array_pushf(&child_env, "%s=%s/.git", GIT_DIR_ENVIRONMENT, wt->path); argv_array_pushf(&child_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, wt->path); memset(&cp, 0, sizeof(cp)); argv_array_pushl(&cp.args, "status", "--porcelain", "--ignore-submodules=none", NULL); cp.env = child_env.argv; cp.git_cmd = 1; cp.dir = wt->path; cp.out = -1; ret = start_command(&cp); if (ret) die_errno(_("failed to run 'git status' on '%s'"), original_path); ret = xread(cp.out, buf, sizeof(buf)); if (ret) die(_("'%s' is dirty, use --force to delete it"), original_path); close(cp.out); ret = finish_command(&cp); if (ret) die_errno(_("failed to run 'git status' on '%s', code %d"), original_path, ret); }
static void add_repack_all_option(struct string_list *keep_pack) { if (prune_expire && !strcmp(prune_expire, "now")) argv_array_push(&repack, "-a"); else { argv_array_push(&repack, "-A"); if (prune_expire) argv_array_pushf(&repack, "--unpack-unreachable=%s", prune_expire); } if (keep_pack) for_each_string_list(keep_pack, keep_one_pack, NULL); }
static int push_git(struct discovery *heads, int nr_spec, char **specs) { struct rpc_state rpc; int i, err; struct argv_array args; struct string_list_item *cas_option; struct strbuf preamble = STRBUF_INIT; argv_array_init(&args); argv_array_pushl(&args, "send-pack", "--stateless-rpc", "--helper-status", NULL); if (options.thin) argv_array_push(&args, "--thin"); if (options.dry_run) argv_array_push(&args, "--dry-run"); if (options.push_cert == SEND_PACK_PUSH_CERT_ALWAYS) argv_array_push(&args, "--signed=yes"); else if (options.push_cert == SEND_PACK_PUSH_CERT_IF_ASKED) argv_array_push(&args, "--signed=if-asked"); if (options.verbosity == 0) argv_array_push(&args, "--quiet"); else if (options.verbosity > 1) argv_array_push(&args, "--verbose"); for (i = 0; i < options.push_options.nr; i++) argv_array_pushf(&args, "--push-option=%s", options.push_options.items[i].string); argv_array_push(&args, options.progress ? "--progress" : "--no-progress"); for_each_string_list_item(cas_option, &cas_options) argv_array_push(&args, cas_option->string); argv_array_push(&args, url.buf); argv_array_push(&args, "--stdin"); for (i = 0; i < nr_spec; i++) packet_buf_write(&preamble, "%s\n", specs[i]); packet_buf_flush(&preamble); memset(&rpc, 0, sizeof(rpc)); rpc.service_name = "git-receive-pack", rpc.argv = args.argv; rpc.stdin_preamble = &preamble; err = rpc_service(&rpc, heads); if (rpc.result.len) write_or_die(1, rpc.result.buf, rpc.result.len); strbuf_release(&rpc.result); strbuf_release(&preamble); argv_array_clear(&args); return err; }
static void bisect_rev_setup(struct rev_info *revs, const char *prefix, const char *bad_format, const char *good_format, int read_paths) { struct argv_array rev_argv = ARGV_ARRAY_INIT; int i; init_revisions(revs, prefix); revs->abbrev = 0; revs->commit_format = CMIT_FMT_UNSPECIFIED; /* rev_argv.argv[0] will be ignored by setup_revisions */ argv_array_push(&rev_argv, "bisect_rev_setup"); argv_array_pushf(&rev_argv, bad_format, oid_to_hex(current_bad_oid)); for (i = 0; i < good_revs.nr; i++) argv_array_pushf(&rev_argv, good_format, sha1_to_hex(good_revs.sha1[i])); argv_array_push(&rev_argv, "--"); if (read_paths) read_bisect_paths(&rev_argv); setup_revisions(rev_argv.argc, rev_argv.argv, revs, NULL); /* XXX leak rev_argv, as "revs" may still be pointing to it */ }
static int diff_tree_binary(struct strbuf *out, struct object_id *w_commit) { struct child_process cp = CHILD_PROCESS_INIT; const char *w_commit_hex = oid_to_hex(w_commit); /* * Diff-tree would not be very hard to replace with a native function, * however it should be done together with apply_cached. */ cp.git_cmd = 1; argv_array_pushl(&cp.args, "diff-tree", "--binary", NULL); argv_array_pushf(&cp.args, "%s^2^..%s^2", w_commit_hex, w_commit_hex); return pipe_command(&cp, NULL, 0, out, 0, NULL, 0); }
/* Returns 1 if a shallow list is sent or 0 otherwise */ static int send_shallow_list(int depth, int deepen_rev_list, timestamp_t deepen_since, struct string_list *deepen_not, struct object_array *shallows) { int ret = 0; if (depth > 0 && deepen_rev_list) die("git upload-pack: deepen and deepen-since (or deepen-not) cannot be used together"); if (depth > 0) { deepen(depth, deepen_relative, shallows); ret = 1; } else if (deepen_rev_list) { struct argv_array av = ARGV_ARRAY_INIT; int i; argv_array_push(&av, "rev-list"); if (deepen_since) argv_array_pushf(&av, "--max-age=%"PRItime, deepen_since); if (deepen_not->nr) { argv_array_push(&av, "--not"); for (i = 0; i < deepen_not->nr; i++) { struct string_list_item *s = deepen_not->items + i; argv_array_push(&av, s->string); } argv_array_push(&av, "--not"); } for (i = 0; i < want_obj.nr; i++) { struct object *o = want_obj.objects[i].item; argv_array_push(&av, oid_to_hex(&o->oid)); } deepen_by_rev_list(av.argc, av.argv, shallows); argv_array_clear(&av); ret = 1; } else { if (shallows->nr > 0) { int i; for (i = 0; i < shallows->nr; i++) register_shallow(the_repository, &shallows->objects[i].item->oid); } } shallow_nr += shallows->nr; return ret; }
static void prepare_submodule_repo_env(struct argv_array *out) { const char * const *var; for (var = local_repo_env; *var; var++) { if (!strcmp(*var, CONFIG_DATA_ENVIRONMENT)) { struct strbuf sanitized_config = STRBUF_INIT; git_config_from_parameters(sanitize_submodule_config, &sanitized_config); argv_array_pushf(out, "%s=%s", *var, sanitized_config.buf); strbuf_release(&sanitized_config); } else { argv_array_push(out, *var); } } }
static int fetch_objs_via_rsync(struct transport *transport, int nr_objs, struct ref **to_fetch) { struct child_process rsync = CHILD_PROCESS_INIT; rsync.stdout_to_stderr = 1; argv_array_push(&rsync.args, "rsync"); argv_array_push(&rsync.args, (transport->verbose > 1) ? "-rv" : "-r"); argv_array_push(&rsync.args, "--ignore-existing"); argv_array_push(&rsync.args, "--exclude"); argv_array_push(&rsync.args, "info"); argv_array_pushf(&rsync.args, "%s/objects/", rsync_url(transport->url)); argv_array_push(&rsync.args, get_object_directory()); /* NEEDSWORK: handle one level of alternates */ return run_command(&rsync); }
static const char *update_worktree(unsigned char *sha1) { const char *retval; const char *work_tree = git_work_tree_cfg ? git_work_tree_cfg : ".."; struct argv_array env = ARGV_ARRAY_INIT; if (is_bare_repository()) return "denyCurrentBranch = updateInstead needs a worktree"; argv_array_pushf(&env, "GIT_DIR=%s", absolute_path(get_git_dir())); if (!find_hook(push_to_checkout_hook)) retval = push_to_deploy(sha1, &env, work_tree); else retval = push_to_checkout(sha1, &env, work_tree); argv_array_clear(&env); return retval; }