mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-04 15:07:41 +00:00
Use common capabilities
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
This commit is contained in:
parent
48a65a071d
commit
0437d991bf
36
src/pkt.c
36
src/pkt.c
@ -269,13 +269,35 @@ int git_pkt_send_flush(int s)
|
|||||||
return gitno_send(s, flush, STRLEN(flush), 0);
|
return gitno_send(s, flush, STRLEN(flush), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int send_want_with_caps(git_remote_head *head, git_transport_caps *caps, int fd)
|
||||||
|
{
|
||||||
|
char capstr[20]; /* Longer than we need */
|
||||||
|
char oid[GIT_OID_HEXSZ +1] = {0}, *cmd;
|
||||||
|
int error, len;
|
||||||
|
|
||||||
|
if (caps->ofs_delta)
|
||||||
|
strcpy(capstr, GIT_CAP_OFS_DELTA);
|
||||||
|
|
||||||
|
len = STRLEN("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + strlen(capstr) + 1 /* LF */;
|
||||||
|
cmd = git__malloc(len + 1);
|
||||||
|
if (cmd == NULL)
|
||||||
|
return GIT_ENOMEM;
|
||||||
|
|
||||||
|
git_oid_fmt(oid, &head->oid);
|
||||||
|
memset(cmd, 0x0, len + 1);
|
||||||
|
snprintf(cmd, len + 1, "%04xwant %s%c%s\n", len, oid, 0, capstr);
|
||||||
|
error = gitno_send(fd, cmd, len, 0);
|
||||||
|
free(cmd);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All "want" packets have the same length and format, so what we do
|
* All "want" packets have the same length and format, so what we do
|
||||||
* is overwrite the OID each time.
|
* is overwrite the OID each time.
|
||||||
*/
|
*/
|
||||||
#define WANT_PREFIX "0032want "
|
#define WANT_PREFIX "0032want "
|
||||||
|
|
||||||
int git_pkt_send_wants(git_headarray *refs, int fd)
|
int git_pkt_send_wants(git_headarray *refs, git_transport_caps *caps, int fd)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret = GIT_SUCCESS;
|
int ret = GIT_SUCCESS;
|
||||||
@ -286,10 +308,18 @@ int git_pkt_send_wants(git_headarray *refs, int fd)
|
|||||||
buf[sizeof(buf) - 2] = '\n';
|
buf[sizeof(buf) - 2] = '\n';
|
||||||
buf[sizeof(buf) - 1] = '\0';
|
buf[sizeof(buf) - 1] = '\0';
|
||||||
|
|
||||||
for (i = 0; i < refs->len; ++i) {
|
if (refs->len > 0 && caps->common) {
|
||||||
|
/* Some capabilities are active, so we need to send what we support */
|
||||||
|
send_want_with_caps(refs->heads[0], caps, fd);
|
||||||
|
i = 1;
|
||||||
|
} else {
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < refs->len; ++i) {
|
||||||
head = refs->heads[i];
|
head = refs->heads[i];
|
||||||
if (head->type != GIT_WHN_WANT)
|
if (head->type != GIT_WHN_WANT)
|
||||||
continue;
|
continue; /* FIXME: return? refs shouldn't have any other type */
|
||||||
|
|
||||||
git_oid_fmt(buf + STRLEN(WANT_PREFIX), &head->oid);
|
git_oid_fmt(buf + STRLEN(WANT_PREFIX), &head->oid);
|
||||||
gitno_send(fd, buf, STRLEN(buf), 0);
|
gitno_send(fd, buf, STRLEN(buf), 0);
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#define INCLUDE_pkt_h__
|
#define INCLUDE_pkt_h__
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "transport.h"
|
||||||
#include "git2/net.h"
|
#include "git2/net.h"
|
||||||
|
|
||||||
enum git_pkt_type {
|
enum git_pkt_type {
|
||||||
@ -76,7 +77,7 @@ typedef struct {
|
|||||||
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_done(int s);
|
int git_pkt_send_done(int s);
|
||||||
int git_pkt_send_wants(git_headarray *refs, int fd);
|
int git_pkt_send_wants(git_headarray *refs, git_transport_caps *caps, int fd);
|
||||||
int git_pkt_send_have(git_oid *oid, 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);
|
||||||
|
|
||||||
|
@ -5,6 +5,13 @@
|
|||||||
#include "git2/net.h"
|
#include "git2/net.h"
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
|
|
||||||
|
#define GIT_CAP_OFS_DELTA "ofs-delta"
|
||||||
|
|
||||||
|
typedef struct git_transport_caps {
|
||||||
|
int common:1,
|
||||||
|
ofs_delta:1;
|
||||||
|
} git_transport_caps;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A day in the life of a network operation
|
* A day in the life of a network operation
|
||||||
* ========================================
|
* ========================================
|
||||||
|
@ -41,6 +41,7 @@ typedef struct {
|
|||||||
int socket;
|
int socket;
|
||||||
git_vector refs;
|
git_vector refs;
|
||||||
git_remote_head **heads;
|
git_remote_head **heads;
|
||||||
|
git_transport_caps caps;
|
||||||
} transport_git;
|
} transport_git;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -218,6 +219,36 @@ static int store_refs(transport_git *t)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int detect_caps(transport_git *t)
|
||||||
|
{
|
||||||
|
git_vector *refs = &t->refs;
|
||||||
|
git_pkt_ref *pkt;
|
||||||
|
git_transport_caps *caps = &t->caps;
|
||||||
|
const char *ptr;
|
||||||
|
|
||||||
|
pkt = git_vector_get(refs, 0);
|
||||||
|
/* No refs or capabilites, odd but not a problem */
|
||||||
|
if (pkt == NULL || pkt->capabilities == NULL)
|
||||||
|
return GIT_SUCCESS;
|
||||||
|
|
||||||
|
ptr = pkt->capabilities;
|
||||||
|
while (ptr != NULL && *ptr != '\0') {
|
||||||
|
if (*ptr == ' ')
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
if(!git__prefixcmp(ptr, GIT_CAP_OFS_DELTA)) {
|
||||||
|
caps->common = caps->ofs_delta = 1;
|
||||||
|
ptr += STRLEN(GIT_CAP_OFS_DELTA);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We don't know this capability, so skip it */
|
||||||
|
ptr = strchr(ptr, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
return GIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since this is a network connection, we need to parse and store the
|
* Since this is a network connection, we need to parse and store the
|
||||||
* pkt-lines at this stage and keep them there.
|
* pkt-lines at this stage and keep them there.
|
||||||
@ -242,6 +273,10 @@ static int git_connect(git_transport *transport, int direction)
|
|||||||
|
|
||||||
t->parent.connected = 1;
|
t->parent.connected = 1;
|
||||||
error = store_refs(t);
|
error = store_refs(t);
|
||||||
|
if (error < GIT_SUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
error = detect_caps(t);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (error < GIT_SUCCESS) {
|
if (error < GIT_SUCCESS) {
|
||||||
@ -280,7 +315,7 @@ static int git_send_wants(git_transport *transport, git_headarray *array)
|
|||||||
{
|
{
|
||||||
transport_git *t = (transport_git *) transport;
|
transport_git *t = (transport_git *) transport;
|
||||||
|
|
||||||
return git_pkt_send_wants(array, t->socket);
|
return git_pkt_send_wants(array, &t->caps, t->socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int git_send_have(git_transport *transport, git_oid *oid)
|
static int git_send_have(git_transport *transport, git_oid *oid)
|
||||||
|
Loading…
Reference in New Issue
Block a user