#include "tag.h"
#include "refs.h"
#include "pkt-line.h"
-#include "exec_cmd.h"
+#include "run-command.h"
static const char send_pack_usage[] =
-"git-send-pack [--all] [--exec=git-receive-pack] <remote> [<head>...]\n"
-" --all and explicit <head> specification are mutually exclusive.";
-static const char *exec = "git-receive-pack";
+"git-send-pack [--all] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
+" --all and explicit <ref> specification are mutually exclusive.";
+static const char *receivepack = "git-receive-pack";
static int verbose;
static int send_all;
static int force_update;
*/
static int pack_objects(int fd, struct ref *refs)
{
- int pipe_fd[2];
- pid_t pid;
-
- if (pipe(pipe_fd) < 0)
- return error("send-pack: pipe failed");
- pid = fork();
- if (!pid) {
- /*
- * The child becomes pack-objects --revs; we feed
- * the revision parameters to it via its stdin and
- * let its stdout go back to the other end.
- */
- static const char *args[] = {
- "pack-objects",
- "--all-progress",
- "--revs",
- "--stdout",
- NULL,
- NULL,
- };
- if (use_thin_pack)
- args[4] = "--thin";
- dup2(pipe_fd[0], 0);
- dup2(fd, 1);
- close(pipe_fd[0]);
- close(pipe_fd[1]);
- close(fd);
- execv_git_cmd(args);
- die("git-pack-objects exec failed (%s)", strerror(errno));
- }
+ /*
+ * The child becomes pack-objects --revs; we feed
+ * the revision parameters to it via its stdin and
+ * let its stdout go back to the other end.
+ */
+ const char *args[] = {
+ "pack-objects",
+ "--all-progress",
+ "--revs",
+ "--stdout",
+ NULL,
+ NULL,
+ };
+ struct child_process po;
+
+ if (use_thin_pack)
+ args[4] = "--thin";
+ memset(&po, 0, sizeof(po));
+ po.argv = args;
+ po.in = -1;
+ po.out = fd;
+ po.git_cmd = 1;
+ if (start_command(&po))
+ die("git-pack-objects failed (%s)", strerror(errno));
/*
* We feed the pack-objects we just spawned with revision
* parameters by writing to the pipe.
*/
- close(pipe_fd[0]);
- close(fd);
-
while (refs) {
char buf[42];
memcpy(buf + 1, sha1_to_hex(refs->old_sha1), 40);
buf[0] = '^';
buf[41] = '\n';
- write(pipe_fd[1], buf, 42);
+ if (!write_or_whine(po.in, buf, 42,
+ "send-pack: send refs"))
+ break;
}
if (!is_null_sha1(refs->new_sha1)) {
memcpy(buf, sha1_to_hex(refs->new_sha1), 40);
buf[40] = '\n';
- write(pipe_fd[1], buf, 41);
+ if (!write_or_whine(po.in, buf, 41,
+ "send-pack: send refs"))
+ break;
}
refs = refs->next;
}
- close(pipe_fd[1]);
-
- for (;;) {
- int status, code;
- pid_t waiting = waitpid(pid, &status, 0);
- if (waiting < 0) {
- if (errno == EINTR)
- continue;
- return error("waitpid failed (%s)", strerror(errno));
- }
- if ((waiting != pid) || WIFSIGNALED(status) ||
- !WIFEXITED(status))
- return error("pack-objects died with strange error");
- code = WEXITSTATUS(status);
- if (code)
- return -code;
- return 0;
- }
+ if (finish_command(&po))
+ return error("pack-objects died with strange error");
+ return 0;
}
static void unmark_and_free(struct commit_list *list, unsigned int mark)
char *arg = *argv;
if (*arg == '-') {
- if (!strncmp(arg, "--exec=", 7)) {
- exec = arg + 7;
+ if (!prefixcmp(arg, "--receive-pack=")) {
+ receivepack = arg + 15;
+ continue;
+ }
+ if (!prefixcmp(arg, "--exec=")) {
+ receivepack = arg + 7;
continue;
}
if (!strcmp(arg, "--all")) {
usage(send_pack_usage);
verify_remote_names(nr_heads, heads);
- pid = git_connect(fd, dest, exec);
+ pid = git_connect(fd, dest, receivepack);
if (pid < 0)
return 1;
ret = send_pack(fd[0], fd[1], nr_heads, heads);