commit - bb64b79860632effc06224a66e840f56e41f6ac6
commit + d9b4d0c08e6fbfa54a11af8518a888425632c912
blob - b5bed4ad76b6c5e4ce90833eb8d31dbc4e39147c
blob + c3c32e39f4990b11e465475f5888368aaaac553f
--- got/got.c
+++ got/got.c
const struct got_error *err = NULL;
const char *uri, *branch_filter, *dirname;
char *proto, *host, *port, *repo_name, *server_path;
- char *default_destdir = NULL;
+ char *default_destdir = NULL, *id_str = NULL;
const char *repo_path;
struct got_repository *repo = NULL;
+ struct got_pathlist_head refs, symrefs;
+ struct got_pathlist_entry *pe;
+ struct got_object_id *pack_hash = NULL;
int ch;
+ TAILQ_INIT(&refs);
+ TAILQ_INIT(&symrefs);
+
while ((ch = getopt(argc, argv, "b:")) != -1) {
switch (ch) {
case 'b':
if (err)
goto done;
- err = got_fetch(proto, host, port, server_path, repo_name,
- branch_filter, repo);
+ err = got_fetch(&pack_hash, &refs, &symrefs,
+ proto, host, port, server_path, repo_name, branch_filter, repo);
+ if (err)
+ goto done;
+
+ err = got_object_id_str(&id_str, pack_hash);
+ if (err)
+ goto done;
+ printf("Fetched %s.pack\n", id_str);
+ free(id_str);
+
+ /* Set up references provided with the pack file. */
+ TAILQ_FOREACH(pe, &refs, entry) {
+ const char *refname = pe->path;
+ struct got_object_id *id = pe->data;
+ struct got_reference *ref;
+
+ err = got_object_id_str(&id_str, id);
+ if (err)
+ goto done;
+
+ err = got_ref_alloc(&ref, refname, id);
+ if (err) {
+ free(id_str);
+ goto done;
+ }
+
+ printf("%s: %s\n", got_ref_get_name(ref), id_str);
+ free(id_str);
+ err = got_ref_write(ref, repo);
+ got_ref_close(ref);
+ if (err)
+ goto done;
+ }
+
+ /* Set the HEAD reference if the server provided one. */
+ TAILQ_FOREACH(pe, &symrefs, entry) {
+ struct got_reference *symref, *target_ref;
+ const char *refname = pe->path;
+ const char *target = pe->data;
+
+ if (strcmp(refname, GOT_REF_HEAD) != 0)
+ continue;
+
+ err = got_ref_open(&target_ref, repo, target, 0);
+ if (err) {
+ if (err->code == GOT_ERR_NOT_REF)
+ continue;
+ goto done;
+ }
+
+ err = got_ref_alloc_symref(&symref, GOT_REF_HEAD, target_ref);
+ got_ref_close(target_ref);
+ if (err)
+ goto done;
+
+ printf("Setting %s to %s\n", GOT_REF_HEAD,
+ got_ref_get_symref_target(symref));
+
+ err = got_ref_write(symref, repo);
+ got_ref_close(symref);
+ break;
+ }
+
done:
if (repo)
got_repo_close(repo);
+ TAILQ_FOREACH(pe, &refs, entry) {
+ free((void *)pe->path);
+ free(pe->data);
+ }
+ got_pathlist_free(&refs);
+ TAILQ_FOREACH(pe, &symrefs, entry) {
+ free((void *)pe->path);
+ free(pe->data);
+ }
+ got_pathlist_free(&symrefs);
+ free(pack_hash);
free(proto);
free(host);
free(port);
blob - 76bf04d5f314663647550667aff141ee3b18cde1
blob + 7b366507306fb9ce4b3c3a9d29e4d2b1044d2f19
--- include/got_fetch.h
+++ include/got_fetch.h
const struct got_error *got_fetch_parse_uri(char **, char **, char **,
char **, char **, const char *);
-const struct got_error *got_fetch(const char *, const char *,
- const char *, const char *, const char *, const char *,
- struct got_repository *);
+
+const struct got_error *got_fetch(struct got_object_id **,
+ struct got_pathlist_head *, struct got_pathlist_head *,
+ const char *, const char *, const char *, const char *,
+ const char *, const char *, struct got_repository *);
blob - 4b57d0579703a7ad6c7c7179a89bd26fb80877a7
blob + 72d9e46a78e681b87484330a8bff24cf22c5be07
--- lib/fetch.c
+++ lib/fetch.c
}
const struct got_error*
-got_fetch(const char *proto, const char *host, const char *port,
- const char *server_path, const char *repo_name,
+got_fetch(struct got_object_id **pack_hash, struct got_pathlist_head *refs,
+ struct got_pathlist_head *symrefs, const char *proto, const char *host,
+ const char *port, const char *server_path, const char *repo_name,
const char *branch_filter, struct got_repository *repo)
{
int imsg_fetchfds[2], imsg_idxfds[2], fetchfd = -1;
int packfd = -1, npackfd = -1, idxfd = -1, nidxfd = -1;
int status, done = 0;
- struct got_object_id *packhash = NULL;
const struct got_error *err;
struct imsgbuf ibuf;
pid_t pid;
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 symrefs;
struct got_pathlist_entry *pe;
char *path;
- TAILQ_INIT(&symrefs);
+ *pack_hash = NULL;
fetchfd = -1;
}
while (!done) {
- struct got_object_id *id;
- char *refname;
+ struct got_object_id *id = NULL;
+ char *refname = NULL;
err = got_privsep_recv_fetch_progress(&done,
- &id, &refname, &symrefs, &ibuf);
+ &id, &refname, symrefs, &ibuf);
if (err != NULL)
goto done;
- if (done) {
- packhash = got_object_id_dup(id);
- if (packhash == NULL) {
- err = got_error_from_errno(
- "got_object_id_dup");
- goto done;
- }
- printf("symrefs:");
- TAILQ_FOREACH(pe, &symrefs, entry) {
- printf(" %s:%s", pe->path,
- (const char *)pe->data);
- }
- printf("\n");
- } else if (refname && id) {
- struct got_reference *ref;
- char *id_str;
- /* TODO Use a progress callback */
- err = got_object_id_str(&id_str, id);
+ if (done)
+ *pack_hash = id;
+ else if (refname && id) {
+ err = got_pathlist_append(refs, refname, id);
if (err)
goto done;
- printf( "%.12s %s\n", id_str, refname);
-
- err = got_ref_alloc(&ref, refname, id);
- if (err)
- goto done;
-
- err = got_ref_write(ref, repo);
- got_ref_close(ref);
- if (err)
- goto done;
}
+ /* TODO remote status / download progress callback */
}
if (waitpid(pid, &status, 0) == -1) {
err = got_error_from_errno("waitpid");
}
imsg_init(&ibuf, imsg_idxfds[0]);
- err = got_privsep_send_index_pack_req(&ibuf, npackfd, packhash);
+ err = got_privsep_send_index_pack_req(&ibuf, npackfd, *pack_hash);
if (err != NULL)
goto done;
npackfd = -1;
goto done;
}
- err = got_object_id_str(&id_str, packhash);
+ err = got_object_id_str(&id_str, *pack_hash);
if (err)
goto done;
if (asprintf(&packpath, "%s/objects/pack/pack-%s.pack",
goto done;
}
- /* Set the HEAD reference if the server provided one. */
- TAILQ_FOREACH(pe, &symrefs, entry) {
- struct got_reference *symref, *target_ref;
- const char *refname = pe->path;
- const char *target = pe->data;
-
- if (strcmp(refname, GOT_REF_HEAD) != 0)
- continue;
-
- err = got_ref_open(&target_ref, repo, target, 0);
- if (err) {
- if (err->code == GOT_ERR_NOT_REF)
- continue;
- goto done;
- }
-
- err = got_ref_alloc_symref(&symref, GOT_REF_HEAD, target_ref);
- got_ref_close(target_ref);
- if (err)
- goto done;
-
- err = got_ref_write(symref, repo);
- got_ref_close(symref);
- if (err)
- goto done;
- break;
- }
-
done:
if (fetchfd != -1 && close(fetchfd) == -1 && err == NULL)
err = got_error_from_errno("close");
free(tmpidxpath);
free(idxpath);
free(packpath);
- free(packhash);
- TAILQ_FOREACH(pe, &symrefs, entry) {
- free((void *)pe->path);
- free(pe->data);
- }
- got_pathlist_free(&symrefs);
+ if (err) {
+ free(*pack_hash);
+ *pack_hash = NULL;
+ TAILQ_FOREACH(pe, refs, entry) {
+ free((void *)pe->path);
+ free(pe->data);
+ }
+ got_pathlist_free(refs);
+ TAILQ_FOREACH(pe, symrefs, entry) {
+ free((void *)pe->path);
+ free(pe->data);
+ }
+ got_pathlist_free(symrefs);
+ }
return err;
}