mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-04 17:13:25 +00:00
Move have sending
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
This commit is contained in:
parent
b4c9063040
commit
7e1a94db11
59
src/fetch.c
59
src/fetch.c
@ -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)
|
int git_fetch_list_want(git_headarray *whn_list, git_repository *repo, git_remote *remote)
|
||||||
{
|
{
|
||||||
git_vector list;
|
git_vector list;
|
||||||
git_headarray refs, lrefs;
|
git_headarray refs;
|
||||||
git_transport *t = remote->transport;
|
git_transport *t = remote->transport;
|
||||||
const git_refspec *spec;
|
const git_refspec *spec;
|
||||||
int error;
|
int error;
|
||||||
@ -159,31 +159,49 @@ int git_fetch_negotiate(git_headarray *list, git_repository *repo, git_remote *r
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
char local[1024];
|
char local[1024];
|
||||||
git_refspec *spec;
|
git_refspec *spec;
|
||||||
|
|
||||||
error = git_revwalk_new(&walk, repo);
|
|
||||||
if (error < GIT_SUCCESS)
|
|
||||||
return git__rethrow(error, "Failed to create walker");
|
|
||||||
|
|
||||||
for (i = 0; i < list->len; ++i) {
|
|
||||||
git_reference *ref;
|
git_reference *ref;
|
||||||
git_remote_head *head = list->heads[i];
|
git_strarray refs;
|
||||||
|
git_oid oid;
|
||||||
if (!head->local)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
error = git_revwalk_push(walk, &head->loid);
|
|
||||||
if (error < GIT_SUCCESS) {
|
|
||||||
error = git__rethrow(error, "Failed to push a local OID");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now we have everything set up so we can start tell the server
|
* Now we have everything set up so we can start tell the server
|
||||||
* what we want and what we have.
|
* what we want and what we have.
|
||||||
*/
|
*/
|
||||||
git_transport_send_wants(remote->transport, list);
|
git_transport_send_wants(remote->transport, list);
|
||||||
git_transport_send_haves(remote->transport, repo);
|
|
||||||
|
error = git_reference_listall(&refs, repo, GIT_REF_LISTALL);
|
||||||
|
if (error < GIT_ERROR)
|
||||||
|
return git__rethrow(error, "Failed to list all references");
|
||||||
|
|
||||||
|
error = git_revwalk_new(&walk, repo);
|
||||||
|
if (error < GIT_ERROR) {
|
||||||
|
error = git__rethrow(error, "Failed to list all references");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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:
|
cleanup:
|
||||||
git_revwalk_free(walk);
|
git_revwalk_free(walk);
|
||||||
@ -192,5 +210,8 @@ cleanup:
|
|||||||
|
|
||||||
int git_fetch_download_pack(git_remote *remote)
|
int git_fetch_download_pack(git_remote *remote)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* First, we ignore any ACKs we receive and wait for a NACK
|
||||||
|
*/
|
||||||
return GIT_ENOTIMPLEMENTED;
|
return GIT_ENOTIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
103
src/pkt.c
103
src/pkt.c
@ -52,10 +52,38 @@ static int flush_pkt(git_pkt **out)
|
|||||||
return GIT_SUCCESS;
|
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.
|
* 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;
|
git_pkt_ref *pkt;
|
||||||
int error, has_caps = 0;
|
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 */
|
len -= PKT_LEN_SIZE; /* the encoded length includes its own size */
|
||||||
|
|
||||||
/*
|
/* Assming the minimal size is actually 4 */
|
||||||
* For now, we're just going to assume we're parsing references
|
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;
|
*out = line + len;
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
@ -239,62 +270,32 @@ int git_pkt_send_wants(git_headarray *refs, int fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: git_pkt_send_flush(fd) */
|
/* TODO: git_pkt_send_flush(fd) */
|
||||||
printf("Wound send 0000\n");
|
printf("Would send 0000\n");
|
||||||
|
|
||||||
return ret;
|
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 "
|
#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;
|
int ret = GIT_SUCCESS;
|
||||||
char buf[STRLEN(HAVE_PREFIX) + GIT_OID_HEXSZ + 2];
|
char buf[] = "0032have 0000000000000000000000000000000000000000\n";
|
||||||
git_oid oid;
|
|
||||||
git_revwalk *walk;
|
|
||||||
git_strarray refs;
|
|
||||||
git_reference *ref;
|
|
||||||
git_remote_head *head;
|
|
||||||
|
|
||||||
memcpy(buf, HAVE_PREFIX, STRLEN(HAVE_PREFIX));
|
git_oid_fmt(buf + STRLEN(HAVE_PREFIX), oid);
|
||||||
buf[sizeof(buf) - 2] = '\n';
|
|
||||||
buf[sizeof(buf) - 1] = '\0';
|
|
||||||
|
|
||||||
ret = git_reference_listall(&refs, repo, GIT_REF_LISTALL);
|
|
||||||
if (ret < GIT_ERROR)
|
|
||||||
return git__rethrow(ret, "Failed to list all references");
|
|
||||||
|
|
||||||
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);
|
printf("would send %s", buf);
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: git_pkt_send_flush(fd) */
|
|
||||||
printf("Wound send 0000\n");
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
git_revwalk_free(walk);
|
|
||||||
git_strarray_free(&refs);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int git_pkt_send_have(int fd)
|
||||||
|
{
|
||||||
|
char buf[] = "0009done\n";
|
||||||
|
printf("Would send %s", buf);
|
||||||
|
|
||||||
|
return GIT_SUCCESS;
|
||||||
|
}
|
||||||
|
19
src/pkt.h
19
src/pkt.h
@ -34,6 +34,16 @@ enum git_pkt_type {
|
|||||||
GIT_PKT_FLUSH,
|
GIT_PKT_FLUSH,
|
||||||
GIT_PKT_REF,
|
GIT_PKT_REF,
|
||||||
GIT_PKT_HAVE,
|
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 */
|
/* This would be a flush pkt */
|
||||||
@ -55,10 +65,17 @@ typedef struct {
|
|||||||
char *capabilities;
|
char *capabilities;
|
||||||
} git_pkt_ref;
|
} 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_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_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_wants(git_headarray *refs, int fd);
|
||||||
|
int git_pkt_send_have(git_oid *oid, int fd);
|
||||||
void git_pkt_free(git_pkt *pkt);
|
void git_pkt_free(git_pkt *pkt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -85,11 +85,15 @@ int git_transport_send_wants(struct git_transport *transport, git_headarray *arr
|
|||||||
return transport->send_wants(transport, array);
|
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)
|
int git_transport_close(git_transport *transport)
|
||||||
{
|
{
|
||||||
return transport->close(transport);
|
return transport->close(transport);
|
||||||
|
@ -63,7 +63,7 @@ struct git_transport {
|
|||||||
/**
|
/**
|
||||||
* Send the list of 'have' refs
|
* 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
|
* 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_dummy(struct git_transport **transport);
|
||||||
|
|
||||||
int git_transport_send_wants(struct git_transport *transport, git_headarray *array);
|
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
|
#endif
|
||||||
|
@ -281,11 +281,18 @@ static int git_send_wants(git_transport *transport, git_headarray *array)
|
|||||||
return git_pkt_send_wants(array, t->socket);
|
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;
|
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)
|
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.connect = git_connect;
|
||||||
t->parent.ls = git_ls;
|
t->parent.ls = git_ls;
|
||||||
t->parent.send_wants = git_send_wants;
|
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.close = git_close;
|
||||||
t->parent.free = git_free;
|
t->parent.free = git_free;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user