commit - 14778466f9e410d616fa844c9576ad0d4d1eb84f
commit + 3350156242bb705818218fc29cebbf2798228b94
blob - 910dea7f0ad927dbaa23003995c60934b1a6014a
blob + 4016f649d26812603b825e73b9cf0839b6ca3d8c
--- lib/fetch.c
+++ lib/fetch.c
char *tmppackpath = NULL, *tmpidxpath = NULL;
char *packpath = NULL, *idxpath = NULL, *id_str = NULL;
const char *repo_path = got_repo_get_path(repo);
+ struct got_pathlist_head have_refs;
struct got_pathlist_entry *pe;
char *path;
*pack_hash = NULL;
+ TAILQ_INIT(&have_refs);
+
if (asprintf(&path, "%s/%s/fetching.pack",
repo_path, GOT_OBJECTS_PACK_DIR) == -1) {
err = got_error_from_errno("asprintf");
err = got_error_from_errno("dup");
goto done;
}
- err = got_privsep_send_fetch_req(&ibuf, nfetchfd);
+ err = got_privsep_send_fetch_req(&ibuf, nfetchfd, &have_refs);
if (err != NULL)
goto done;
nfetchfd = -1;
blob - 2e254be89b81d4bebe1a43f8e7f6c95a9d69d77e
blob + 05435e3e27eea7688d03567a8c5ec462c53976ac
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
* one or more GOT_IMSG_TAG_TAGMSG messages.
*/
} __attribute__((__packed__));
+
+/* Structures for GOT_IMSG_FETCH_REQUEST data. */
+struct got_imsg_fetch_have_ref {
+ uint8_t id[SHA1_DIGEST_LENGTH];
+ size_t name_len;
+ /* Followed by name_len data bytes. */
+};
+struct got_imsg_fetch_have_refs {
+ size_t n_have_refs;
+ /* Followed by n_have_refs times of got_imsg_fetch_have_ref data. */
+};
/* Structures for GOT_IMSG_FETCH_SYMREFS data. */
struct got_imsg_fetch_symref {
struct got_object_id *);
const struct got_error *got_privsep_send_index_pack_done(struct imsgbuf *);
const struct got_error *got_privsep_wait_index_pack_done(struct imsgbuf *);
-const struct got_error *got_privsep_send_fetch_req(struct imsgbuf *, int);
+const struct got_error *got_privsep_send_fetch_req(struct imsgbuf *, int,
+ struct got_pathlist_head *);
const struct got_error *got_privsep_send_fetch_symrefs(struct imsgbuf *,
struct got_pathlist_head *);
const struct got_error *got_privsep_send_fetch_progress(struct imsgbuf *,
blob - 23b8318e31fac27d4a29d740ed4be0b84cdfbceb
blob + 6bd3dc90e688d5c8b9f5684562599a13ede9032c
--- lib/privsep.c
+++ lib/privsep.c
}
const struct got_error *
-got_privsep_send_fetch_req(struct imsgbuf *ibuf, int fd)
+got_privsep_send_fetch_req(struct imsgbuf *ibuf, int fd,
+ struct got_pathlist_head *have_refs)
{
const struct got_error *err = NULL;
+ struct ibuf *wbuf;
+ size_t len, n_have_refs = 0;
+ struct got_pathlist_entry *pe;
- if (imsg_compose(ibuf, GOT_IMSG_FETCH_REQUEST, 0, 0, fd,
- NULL, 0) == -1) {
- err = got_error_from_errno("imsg_compose FETCH_REQUEST");
+ len = sizeof(struct got_imsg_fetch_symrefs);
+ TAILQ_FOREACH(pe, have_refs, entry) {
+ struct got_object_id *id = pe->data;
+ len += sizeof(struct got_imsg_fetch_have_ref) +
+ pe->path_len + sizeof(id->sha1);
+ n_have_refs++;
+ }
+ if (len >= MAX_IMSGSIZE - IMSG_HEADER_SIZE) {
+ close(fd);
+ return got_error(GOT_ERR_NO_SPACE);
+ }
+
+ wbuf = imsg_create(ibuf, GOT_IMSG_FETCH_REQUEST, 0, 0, len);
+ if (wbuf == NULL) {
+ close(fd);
+ return got_error_from_errno("imsg_create FETCH_REQUEST");
+ }
+
+ /* Keep in sync with struct got_imsg_fetch_have_refs definition! */
+ if (imsg_add(wbuf, &n_have_refs, sizeof(n_have_refs)) == -1) {
+ err = got_error_from_errno("imsg_add FETCH_REQUEST");
+ ibuf_free(wbuf);
close(fd);
return err;
}
+
+ TAILQ_FOREACH(pe, have_refs, entry) {
+ const char *name = pe->path;
+ size_t name_len = pe->path_len;
+ struct got_object_id *id = pe->data;
+
+ /* Keep in sync with struct got_imsg_fetch_have_ref! */
+ if (imsg_add(wbuf, id->sha1, sizeof(id->sha1)) == -1) {
+ err = got_error_from_errno("imsg_add FETCH_REQUEST");
+ ibuf_free(wbuf);
+ close(fd);
+ return err;
+ }
+ if (imsg_add(wbuf, &name_len, sizeof(name_len)) == -1) {
+ err = got_error_from_errno("imsg_add FETCH_REQUEST");
+ ibuf_free(wbuf);
+ close(fd);
+ return err;
+ }
+ if (imsg_add(wbuf, name, name_len) == -1) {
+ err = got_error_from_errno("imsg_add FETCH_REQUEST");
+ ibuf_free(wbuf);
+ close(fd);
+ return err;
+ }
+ }
+
+ wbuf->fd = fd;
+ imsg_close(ibuf, wbuf);
return flush_imsg(ibuf);
}
blob - 507b79d036a9965abbb57d877bfe59dec7b2798e
blob + 0bdfc1bbd351d96517b0f716cbfebdbd855a98ce
--- libexec/got-fetch-pack/got-fetch-pack.c
+++ libexec/got-fetch-pack/got-fetch-pack.c
struct got_object *indexed;
static int chattygit;
static char *fetchbranch;
-static char *upstream = "origin";
static struct got_object_id zhash = {.sha1={0}};
int
return 0;
}
-/* TODO: This should not access the file system! */
-int
-got_resolve_remote_ref(struct got_object_id *id, char *ref)
+static const struct got_error *
+match_remote_ref(struct got_pathlist_head *have_refs, struct got_object_id *id,
+ char *refname, char *id_str)
{
- char buf[128], *s;
- int r, f;
+ struct got_pathlist_entry *pe;
- if (!got_parse_sha1_digest(id->sha1, ref))
- return 0;
+ memset(id, 0, sizeof(*id));
- /* Slightly special handling: translate remote refs to local ones. */
- if (strcmp(ref, "HEAD") == 0) {
- if (snprintf(buf, sizeof(buf), ".git/HEAD") >= sizeof(buf))
- return -1;
- } else if (strstr(ref, "refs/heads") == ref) {
- ref += strlen("refs/heads");
- if (snprintf(buf, sizeof(buf),
- ".git/refs/remotes/%s/%s", upstream, ref) >= sizeof(buf))
- return -1;
- } else if (strstr(ref, "refs/tags") == ref) {
- ref += strlen("refs/tags");
- if (snprintf(buf, sizeof(buf),
- ".git/refs/tags/%s/%s", upstream, ref) >= sizeof(buf))
- return -1;
- } else {
- return -1;
+ TAILQ_FOREACH(pe, have_refs, entry) {
+ if (strcmp(pe->path, refname) == 0) {
+ if (!got_parse_sha1_digest(id->sha1, id_str))
+ return got_error(GOT_ERR_BAD_OBJ_ID_STR);
+ break;
+ }
}
-
- r = -1;
- s = buf;
- if ((f = open(s, O_RDONLY)) == -1)
- goto err;
- if (readn(f, buf, sizeof(buf)) < 40)
- goto err;
- if (!got_parse_sha1_digest(id->sha1, buf))
- goto err;
-err:
- close(f);
- if (r == -1 && strstr(buf, "ref:") == buf)
- return got_resolve_remote_ref(id, buf + strlen("ref:"));
- return r;
+ return NULL;
}
static int
static const struct got_error *
fetch_pack(int fd, int packfd, struct got_object_id *packid,
- struct imsgbuf *ibuf)
+ struct got_pathlist_head *have_refs, struct imsgbuf *ibuf)
{
const struct got_error *err = NULL;
char buf[GOT_PKTMAX], *sp[3];
goto done;
}
- if (got_resolve_remote_ref(&have[nref], sp[1]) == -1)
- memset(&have[nref], 0, sizeof(have[nref]));
+ err = match_remote_ref(have_refs, &have[nref], sp[0], sp[1]);
+ if (err)
+ goto done;
+
err = got_privsep_send_fetch_progress(ibuf, &want[nref], sp[1]);
if (err)
goto done;
struct got_object_id packid;
struct imsgbuf ibuf;
struct imsg imsg;
+ struct got_pathlist_head have_refs;
+ struct got_imsg_fetch_have_refs *fetch_have_refs = NULL;
+ size_t datalen;
+
+ TAILQ_INIT(&have_refs);
if (getenv("GOT_DEBUG") != NULL) {
fprintf(stderr, "fetch-pack being chatty!\n");
err = got_error(GOT_ERR_PRIVSEP_MSG);
goto done;
}
- if (imsg.hdr.len - IMSG_HEADER_SIZE != 0) {
+ datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
+ if (datalen < sizeof(struct got_imsg_fetch_have_refs)) {
err = got_error(GOT_ERR_PRIVSEP_LEN);
goto done;
}
+ fetch_have_refs = (struct got_imsg_fetch_have_refs *)imsg.data;
+ if (datalen != sizeof(struct got_imsg_fetch_have_refs) +
+ sizeof(struct got_imsg_fetch_have_ref) *
+ fetch_have_refs->n_have_refs) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ goto done;
+ }
+ if (fetch_have_refs->n_have_refs != 0) {
+ /* TODO: Incremental fetch support */
+ err = got_error(GOT_ERR_NOT_IMPL);
+ goto done;
+ }
fetchfd = imsg.fd;
if ((err = got_privsep_recv_imsg(&imsg, &ibuf, 0)) != 0) {
}
packfd = imsg.fd;
- err = fetch_pack(fetchfd, packfd, &packid, &ibuf);
+ err = fetch_pack(fetchfd, packfd, &packid, &have_refs, &ibuf);
if (err)
goto done;
done: