#define USE_THE_REPOSITORY_VARIABLE
#include "git-compat-util.h"
#include "transport.h"
#include "quote.h"
#include "run-command.h"
#include "commit.h"
#include "environment.h"
#include "gettext.h"
#include "hex.h"
#include "object-name.h"
#include "repository.h"
#include "remote.h"
#include "string-list.h"
#include "thread-utils.h"
#include "sigchain.h"
#include "strvec.h"
#include "refs.h"
#include "refspec.h"
#include "transport-internal.h"
#include "protocol.h"
#include "packfile.h"
static int debug;
struct helper_data { … };
static void sendline(struct helper_data *helper, struct strbuf *buffer)
{ … }
static int recvline_fh(FILE *helper, struct strbuf *buffer)
{ … }
static int recvline(struct helper_data *helper, struct strbuf *buffer)
{ … }
static int write_constant_gently(int fd, const char *str)
{ … }
static void write_constant(int fd, const char *str)
{ … }
static const char *remove_ext_force(const char *url)
{ … }
static void do_take_over(struct transport *transport)
{ … }
static void standard_options(struct transport *t);
static struct child_process *get_helper(struct transport *transport)
{ … }
static int disconnect_helper(struct transport *transport)
{ … }
static const char *unsupported_options[] = …;
static const char *boolean_options[] = …;
static int strbuf_set_helper_option(struct helper_data *data,
struct strbuf *buf)
{ … }
static int string_list_set_helper_option(struct helper_data *data,
const char *name,
struct string_list *list)
{ … }
static int set_helper_option(struct transport *transport,
const char *name, const char *value)
{ … }
static void standard_options(struct transport *t)
{ … }
static int release_helper(struct transport *transport)
{ … }
static int fetch_with_fetch(struct transport *transport,
int nr_heads, struct ref **to_fetch)
{ … }
static int get_importer(struct transport *transport, struct child_process *fastimport)
{ … }
static int get_exporter(struct transport *transport,
struct child_process *fastexport,
struct string_list *revlist_args)
{ … }
static int fetch_with_import(struct transport *transport,
int nr_heads, struct ref **to_fetch)
{ … }
static int run_connect(struct transport *transport, struct strbuf *cmdbuf)
{ … }
static int process_connect_service(struct transport *transport,
const char *name, const char *exec)
{ … }
static int process_connect(struct transport *transport,
int for_push)
{ … }
static int connect_helper(struct transport *transport, const char *name,
const char *exec, int fd[2])
{ … }
static struct ref *get_refs_list_using_list(struct transport *transport,
int for_push);
static int fetch_refs(struct transport *transport,
int nr_heads, struct ref **to_fetch)
{ … }
struct push_update_ref_state { … };
static int push_update_ref_status(struct strbuf *buf,
struct push_update_ref_state *state,
struct ref *remote_refs)
{ … }
static int push_update_refs_status(struct helper_data *data,
struct ref *remote_refs,
int flags)
{ … }
static void set_common_push_options(struct transport *transport,
const char *name, int flags)
{ … }
static int push_refs_with_push(struct transport *transport,
struct ref *remote_refs, int flags)
{ … }
static int push_refs_with_export(struct transport *transport,
struct ref *remote_refs, int flags)
{ … }
static int push_refs(struct transport *transport,
struct ref *remote_refs, int flags)
{ … }
static int has_attribute(const char *attrs, const char *attr)
{ … }
static struct ref *get_refs_list(struct transport *transport, int for_push,
struct transport_ls_refs_options *transport_options)
{ … }
static struct ref *get_refs_list_using_list(struct transport *transport,
int for_push)
{ … }
static int get_bundle_uri(struct transport *transport)
{ … }
static struct transport_vtable vtable = …;
int transport_helper_init(struct transport *transport, const char *name)
{ … }
#define BUFFERSIZE …
#define PBUFFERSIZE …
__attribute__((format (printf, 1, 2)))
static void transfer_debug(const char *fmt, ...)
{ … }
#define SSTATE_TRANSFERRING …
#define SSTATE_FLUSHING …
#define SSTATE_FINISHED …
#define STATE_NEEDS_READING(state) …
#define STATE_NEEDS_WRITING(state) …
#define STATE_NEEDS_CLOSING(state) …
struct unidirectional_transfer { … };
static void udt_close_if_finished(struct unidirectional_transfer *t)
{ … }
static int udt_do_read(struct unidirectional_transfer *t)
{ … }
static int udt_do_write(struct unidirectional_transfer *t)
{ … }
struct bidirectional_transfer_state { … };
static void *udt_copy_task_routine(void *udt)
{ … }
#ifndef NO_PTHREADS
static int tloop_join(pthread_t thread, const char *name)
{ … }
static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s)
{ … }
#else
static void udt_kill_transfer(struct unidirectional_transfer *t)
{
t->state = SSTATE_FINISHED;
if (!t->src_is_sock)
close(t->src);
if (t->dest_is_sock)
shutdown(t->dest, SHUT_WR);
else
close(t->dest);
}
static int tloop_join(pid_t pid, const char *name)
{
int tret;
if (waitpid(pid, &tret, 0) < 0) {
error_errno(_("%s process failed to wait"), name);
return 1;
}
if (!WIFEXITED(tret) || WEXITSTATUS(tret)) {
error(_("%s process failed"), name);
return 1;
}
return 0;
}
static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s)
{
pid_t pid1, pid2;
int ret = 0;
pid1 = fork();
if (pid1 < 0)
die_errno(_("can't start thread for copying data"));
else if (pid1 == 0) {
udt_kill_transfer(&s->ptg);
exit(udt_copy_task_routine(&s->gtp) ? 0 : 1);
}
pid2 = fork();
if (pid2 < 0)
die_errno(_("can't start thread for copying data"));
else if (pid2 == 0) {
udt_kill_transfer(&s->gtp);
exit(udt_copy_task_routine(&s->ptg) ? 0 : 1);
}
udt_kill_transfer(&s->gtp);
udt_kill_transfer(&s->ptg);
ret |= tloop_join(pid1, "Git to program copy");
ret |= tloop_join(pid2, "Program to git copy");
return ret;
}
#endif
int bidirectional_transfer_loop(int input, int output)
{ … }
void reject_atomic_push(struct ref *remote_refs, int mirror_mode)
{ … }