Commit 7e1a94db by Carlos Martín Nieto Committed by Vicent Marti

Move have sending

Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
parent b4c90630
......@@ -51,7 +51,7 @@ static int whn_cmp(const void *a, const void *b)
int git_fetch_list_want(git_headarray *whn_list, git_repository *repo, git_remote *remote)
{
git_vector list;
git_headarray refs, lrefs;
git_headarray refs;
git_transport *t = remote->transport;
const git_refspec *spec;
int error;
......@@ -159,31 +159,49 @@ int git_fetch_negotiate(git_headarray *list, git_repository *repo, git_remote *r
unsigned int i;
char local[1024];
git_refspec *spec;
git_reference *ref;
git_strarray refs;
git_oid oid;
error = git_revwalk_new(&walk, repo);
if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to create walker");
/*
* Now we have everything set up so we can start tell the server
* what we want and what we have.
*/
git_transport_send_wants(remote->transport, list);
for (i = 0; i < list->len; ++i) {
git_reference *ref;
git_remote_head *head = list->heads[i];
error = git_reference_listall(&refs, repo, GIT_REF_LISTALL);
if (error < GIT_ERROR)
return git__rethrow(error, "Failed to list all references");
if (!head->local)
continue;
error = git_revwalk_new(&walk, repo);
if (error < GIT_ERROR) {
error = git__rethrow(error, "Failed to list all references");
goto cleanup;
}
error = git_revwalk_push(walk, &head->loid);
if (error < GIT_SUCCESS) {
error = git__rethrow(error, "Failed to push a local OID");
for (i = 0; i < refs.count; ++i) {
error = git_reference_lookup(&ref, repo, refs.strings[i]);
if (error < GIT_ERROR) {
error = git__rethrow(error, "Failed to lookup %s", refs.strings[i]);
goto cleanup;
}
error = git_revwalk_push(walk, git_reference_oid(ref));
if (error < GIT_ERROR) {
error = git__rethrow(error, "Failed to push %s", refs.strings[i]);
goto cleanup;
}
}
git_strarray_free(&refs);
/*
* Now we have everything set up so we can start tell the server
* what we want and what we have.
*/
git_transport_send_wants(remote->transport, list);
git_transport_send_haves(remote->transport, repo);
while ((error = git_revwalk_next(&oid, walk)) == GIT_SUCCESS) {
git_transport_send_have(remote->transport, &oid);
}
if (error == GIT_EREVWALKOVER)
error = GIT_SUCCESS;
/* TODO: git_pkt_send_flush(fd), or git_transport_flush() */
printf("Wound send 0000\n");
cleanup:
git_revwalk_free(walk);
......@@ -192,5 +210,8 @@ cleanup:
int git_fetch_download_pack(git_remote *remote)
{
/*
* First, we ignore any ACKs we receive and wait for a NACK
*/
return GIT_ENOTIMPLEMENTED;
}
......@@ -52,10 +52,38 @@ static int flush_pkt(git_pkt **out)
return GIT_SUCCESS;
}
static int ack_pkt(git_pkt **out, const char *line, size_t len)
{
git_pkt *pkt;
pkt = git__malloc(sizeof(git_pkt));
if (pkt == NULL)
return GIT_ENOMEM;
pkt->type = GIT_PKT_ACK;
*out = pkt;
return GIT_SUCCESS;
}
static int nack_pkt(git_pkt **out)
{
git_pkt *pkt;
pkt = git__malloc(sizeof(git_pkt));
if (pkt == NULL)
return GIT_ENOMEM;
pkt->type = GIT_PKT_NACK;
*out = pkt;
return GIT_SUCCESS;
}
/*
* Parse an other-ref line.
*/
int ref_pkt(git_pkt **out, const char *line, size_t len)
static int ref_pkt(git_pkt **out, const char *line, size_t len)
{
git_pkt_ref *pkt;
int error, has_caps = 0;
......@@ -185,11 +213,14 @@ int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_
len -= PKT_LEN_SIZE; /* the encoded length includes its own size */
/*
* For now, we're just going to assume we're parsing references
*/
/* Assming the minimal size is actually 4 */
if (!git__prefixcmp(line, "ACK"))
error = ack_pkt(head, line, len);
else if (!git__prefixcmp(line, "NACK"))
error = nack_pkt(head);
else
error = ref_pkt(head, line, len);
error = ref_pkt(head, line, len);
*out = line + len;
return error;
......@@ -239,62 +270,32 @@ int git_pkt_send_wants(git_headarray *refs, int fd)
}
/* TODO: git_pkt_send_flush(fd) */
printf("Wound send 0000\n");
printf("Would send 0000\n");
return ret;
}
/*
* TODO: this should be a more generic function, maybe to be used by
* git_pkt_send_wants, as it's not performance-critical
*/
#define HAVE_PREFIX "0032have "
int git_pkt_send_haves(git_repository *repo, int fd)
int git_pkt_send_have(git_oid *oid, int fd)
{
unsigned int i;
int ret = GIT_SUCCESS;
char buf[STRLEN(HAVE_PREFIX) + GIT_OID_HEXSZ + 2];
git_oid oid;
git_revwalk *walk;
git_strarray refs;
git_reference *ref;
git_remote_head *head;
memcpy(buf, HAVE_PREFIX, STRLEN(HAVE_PREFIX));
buf[sizeof(buf) - 2] = '\n';
buf[sizeof(buf) - 1] = '\0';
char buf[] = "0032have 0000000000000000000000000000000000000000\n";
ret = git_reference_listall(&refs, repo, GIT_REF_LISTALL);
if (ret < GIT_ERROR)
return git__rethrow(ret, "Failed to list all references");
git_oid_fmt(buf + STRLEN(HAVE_PREFIX), oid);
printf("would send %s", buf);
ret = git_revwalk_new(&walk, repo);
if (ret < GIT_ERROR) {
ret = git__rethrow(ret, "Failed to list all references");
goto cleanup;
}
for (i = 0; i < refs.count; ++i) {
ret = git_reference_lookup(&ref, repo, refs.strings[i]);
if (ret < GIT_ERROR) {
ret = git__rethrow(ret, "Failed to lookup %s", refs.strings[i]);
goto cleanup;
}
ret = git_revwalk_push(walk, git_reference_oid(ref));
if (ret < GIT_ERROR) {
ret = git__rethrow(ret, "Failed to push %s", refs.strings[i]);
goto cleanup;
}
}
while ((ret = git_revwalk_next(&oid, walk)) == GIT_SUCCESS) {
git_oid_fmt(buf + STRLEN(HAVE_PREFIX), &oid);
printf("would send %s", buf);
}
return ret;
}
/* TODO: git_pkt_send_flush(fd) */
printf("Wound send 0000\n");
int git_pkt_send_have(int fd)
{
char buf[] = "0009done\n";
printf("Would send %s", buf);
cleanup:
git_revwalk_free(walk);
git_strarray_free(&refs);
return ret;
return GIT_SUCCESS;
}
......@@ -34,6 +34,16 @@ enum git_pkt_type {
GIT_PKT_FLUSH,
GIT_PKT_REF,
GIT_PKT_HAVE,
GIT_PKT_ACK,
GIT_PKT_NACK,
};
/* Used for multi-ack */
enum git_ack_status {
GIT_ACK_NONE,
GIT_ACK_CONTINUE,
GIT_ACK_COMMON,
GIT_ACK_READY
};
/* This would be a flush pkt */
......@@ -55,10 +65,17 @@ typedef struct {
char *capabilities;
} git_pkt_ref;
/* Useful later */
typedef struct {
enum git_pkt_type type;
git_oid oid;
enum git_ack_status status;
} git_pkt_ack;
int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t len);
int git_pkt_send_flush(int s);
int git_pkt_send_haves(git_repository *repo, int fd);
int git_pkt_send_wants(git_headarray *refs, int fd);
int git_pkt_send_have(git_oid *oid, int fd);
void git_pkt_free(git_pkt *pkt);
#endif
......@@ -85,11 +85,15 @@ int git_transport_send_wants(struct git_transport *transport, git_headarray *arr
return transport->send_wants(transport, array);
}
int git_transport_send_haves(struct git_transport *transport, git_repository *repo)
int git_transport_send_have(struct git_transport *transport, git_oid *oid)
{
return transport->send_haves(transport, repo);
return transport->send_have(transport, oid);
}
int git_transport_send_done(struct git_transport *transport)
{
return transport->send_done(transport);
}
int git_transport_close(git_transport *transport)
{
return transport->close(transport);
......
......@@ -63,7 +63,7 @@ struct git_transport {
/**
* Send the list of 'have' refs
*/
int (*send_haves)(struct git_transport *transport, git_repository *repo);
int (*send_have)(struct git_transport *transport, git_oid *oid);
/**
* Fetch the changes
*/
......@@ -83,5 +83,7 @@ int git_transport_git(struct git_transport **transport);
int git_transport_dummy(struct git_transport **transport);
int git_transport_send_wants(struct git_transport *transport, git_headarray *array);
int git_transport_send_have(struct git_transport *transport, git_oid *oid);
int git_transport_send_done(struct git_transport *transport);
#endif
......@@ -281,11 +281,18 @@ static int git_send_wants(git_transport *transport, git_headarray *array)
return git_pkt_send_wants(array, t->socket);
}
static int git_send_haves(git_transport *transport, git_repository *repo)
static int git_send_have(git_transport *transport, git_oid *oid)
{
transport_git *t = (transport_git *) transport;
return git_pkt_send_haves(repo, t->socket);
return git_pkt_send_have(oid, t->socket);
}
static int git_send_done(git_transport *transport)
{
transport_git *t = (transport_git *) transport;
return git_pkt_send_done(t->socket);
}
static int git_close(git_transport *transport)
......@@ -333,7 +340,8 @@ int git_transport_git(git_transport **out)
t->parent.connect = git_connect;
t->parent.ls = git_ls;
t->parent.send_wants = git_send_wants;
t->parent.send_haves = git_send_haves;
t->parent.send_have = git_send_have;
t->parent.send_done = git_send_done;
t->parent.close = git_close;
t->parent.free = git_free;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment