#include "cache.h"
#include "transport.h"
#include "run-command.h"
+#ifndef NO_CURL
#include "http.h"
+#endif
#include "pkt-line.h"
#include "fetch-pack.h"
+#include "send-pack.h"
#include "walker.h"
#include "bundle.h"
#include "dir.h"
return;
for (;;) {
- int cmp, len;
+ int cmp = cmp, len;
if (!fgets(buffer, sizeof(buffer), f)) {
fclose(f);
}
}
-static struct ref *get_refs_via_rsync(const struct transport *transport)
+static struct ref *get_refs_via_rsync(struct transport *transport)
{
struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;
struct ref dummy, *tail = &dummy;
struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;
int result = 0, i;
struct child_process rsync;
- const char *args[8];
+ const char *args[10];
+
+ if (flags & TRANSPORT_PUSH_MIRROR)
+ return error("rsync transport does not support mirror mode");
/* first push the objects */
memset(&rsync, 0, sizeof(rsync));
rsync.argv = args;
rsync.stdout_to_stderr = 1;
- args[0] = "rsync";
- args[1] = (transport->verbose > 0) ? "-av" : "-a";
- args[2] = "--ignore-existing";
- args[3] = "--exclude";
- args[4] = "info";
- args[5] = get_object_directory();;
- args[6] = buf.buf;
- args[7] = NULL;
+ i = 0;
+ args[i++] = "rsync";
+ args[i++] = "-a";
+ if (flags & TRANSPORT_PUSH_DRY_RUN)
+ args[i++] = "--dry-run";
+ if (transport->verbose > 0)
+ args[i++] = "-v";
+ args[i++] = "--ignore-existing";
+ args[i++] = "--exclude";
+ args[i++] = "info";
+ args[i++] = get_object_directory();
+ args[i++] = buf.buf;
+ args[i++] = NULL;
if (run_command(&rsync))
return error("Could not push objects to %s", transport->url);
} else if (write_refs_to_temp_dir(&temp_dir, refspec_nr, refspec))
return -1;
- i = (flags & TRANSPORT_PUSH_FORCE) ? 2 : 3;
+ i = 2;
+ if (flags & TRANSPORT_PUSH_DRY_RUN)
+ args[i++] = "--dry-run";
+ if (!(flags & TRANSPORT_PUSH_FORCE))
+ args[i++] = "--ignore-existing";
args[i++] = temp_dir.buf;
args[i++] = transport->url;
args[i++] = NULL;
return 0;
}
-static int curl_transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags) {
+#ifndef NO_CURL
+static int curl_transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags)
+{
const char **argv;
int argc;
int err;
+ if (flags & TRANSPORT_PUSH_MIRROR)
+ return error("http transport does not support mirror mode");
+
argv = xmalloc((refspec_nr + 11) * sizeof(char *));
argv[0] = "http-push";
argc = 1;
argv[argc++] = "--all";
if (flags & TRANSPORT_PUSH_FORCE)
argv[argc++] = "--force";
+ if (flags & TRANSPORT_PUSH_DRY_RUN)
+ argv[argc++] = "--dry-run";
argv[argc++] = transport->url;
while (refspec_nr--)
argv[argc++] = *refspec++;
return !!err;
}
-#ifndef NO_CURL
static int missing__target(int code, int result)
{
return /* file:// URL -- do we ever use one??? */
#define missing_target(a) missing__target((a)->http_code, (a)->curl_result)
-static struct ref *get_refs_via_curl(const struct transport *transport)
+static struct ref *get_refs_via_curl(struct transport *transport)
{
struct buffer buffer;
char *data, *start, *mid;
return fetch_objs_via_walker(transport, nr_objs, to_fetch);
}
-#else
-
-static struct ref *get_refs_via_curl(const struct transport *transport)
-{
- die("Cannot fetch from '%s' without curl ...", transport->url);
- return NULL;
-}
-
-static int fetch_objs_via_curl(struct transport *transport,
- int nr_objs, struct ref **to_fetch)
-{
- die("Cannot fetch from '%s' without curl ...", transport->url);
- return -1;
-}
-
#endif
struct bundle_transport_data {
struct bundle_header header;
};
-static struct ref *get_refs_from_bundle(const struct transport *transport)
+static struct ref *get_refs_from_bundle(struct transport *transport)
{
struct bundle_transport_data *data = transport->data;
struct ref *result = NULL;
return 1;
}
-static struct ref *get_refs_via_connect(const struct transport *transport)
+static struct ref *get_refs_via_connect(struct transport *transport)
{
struct git_transport_data *data = transport->data;
struct ref *refs;
int fd[2];
- pid_t pid;
char *dest = xstrdup(transport->url);
-
- pid = git_connect(fd, dest, data->uploadpack, 0);
-
- if (pid < 0)
- die("Failed to connect to \"%s\"", transport->url);
+ struct child_process *conn = git_connect(fd, dest, data->uploadpack, 0);
get_remote_heads(fd[0], &refs, 0, NULL, 0);
packet_flush(fd[1]);
- finish_connect(pid);
+ finish_connect(conn);
free(dest);
return 0;
}
-static int git_transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags) {
+static int git_transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags)
+{
struct git_transport_data *data = transport->data;
- const char **argv;
- char *rem;
- int argc;
- int err;
+ struct send_pack_args args;
- argv = xmalloc((refspec_nr + 11) * sizeof(char *));
- argv[0] = "send-pack";
- argc = 1;
- if (flags & TRANSPORT_PUSH_ALL)
- argv[argc++] = "--all";
- if (flags & TRANSPORT_PUSH_FORCE)
- argv[argc++] = "--force";
- if (data->receivepack) {
- char *rp = xmalloc(strlen(data->receivepack) + 16);
- sprintf(rp, "--receive-pack=%s", data->receivepack);
- argv[argc++] = rp;
- }
- if (data->thin)
- argv[argc++] = "--thin";
- rem = xmalloc(strlen(transport->remote->name) + 10);
- sprintf(rem, "--remote=%s", transport->remote->name);
- argv[argc++] = rem;
- argv[argc++] = transport->url;
- while (refspec_nr--)
- argv[argc++] = *refspec++;
- argv[argc] = NULL;
- err = run_command_v_opt(argv, RUN_GIT_CMD);
- switch (err) {
- case -ERR_RUN_COMMAND_FORK:
- error("unable to fork for %s", argv[0]);
- case -ERR_RUN_COMMAND_EXEC:
- error("unable to exec %s", argv[0]);
- break;
- case -ERR_RUN_COMMAND_WAITPID:
- case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
- case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
- case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
- error("%s died with strange error", argv[0]);
- }
- return !!err;
+ args.receivepack = data->receivepack;
+ args.send_all = !!(flags & TRANSPORT_PUSH_ALL);
+ args.send_mirror = !!(flags & TRANSPORT_PUSH_MIRROR);
+ args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
+ args.use_thin_pack = data->thin;
+ args.verbose = transport->verbose;
+ args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
+
+ return send_pack(&args, transport->url, transport->remote, refspec_nr, refspec);
}
static int disconnect_git(struct transport *transport)
} else if (!prefixcmp(url, "http://")
|| !prefixcmp(url, "https://")
|| !prefixcmp(url, "ftp://")) {
+#ifdef NO_CURL
+ error("git was compiled without libcurl support.");
+#else
ret->get_refs_list = get_refs_via_curl;
ret->fetch = fetch_objs_via_curl;
ret->push = curl_transport_push;
+#endif
ret->disconnect = disconnect_walker;
} else if (is_local(url) && is_file(url)) {
return transport->push(transport, refspec_nr, refspec, flags);
}
-struct ref *transport_get_remote_refs(struct transport *transport)
+const struct ref *transport_get_remote_refs(struct transport *transport)
{
if (!transport->remote_refs)
transport->remote_refs = transport->get_refs_list(transport);