Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Martí <vicent@github.com>2013-11-11 18:47:15 +0400
committerVicent Martí <vicent@github.com>2013-11-11 18:47:15 +0400
commit6414fd338df89eaa5bd4c64f7ab310fb7d5758bb (patch)
tree4af0ea37b387c791bd89e73edea10e3353c54423 /src/transports
parent5e1281f873e7eb5b51569ef33218dd20b69ff707 (diff)
parenta6192d7c98976edb0ce4fd10438ac7a19c283598 (diff)
Merge pull request #1956 from libgit2/cmn/fetch-default-head
Remote revamp (director's cut)
Diffstat (limited to 'src/transports')
-rw-r--r--src/transports/local.c10
-rw-r--r--src/transports/smart.c44
-rw-r--r--src/transports/smart.h3
-rw-r--r--src/transports/smart_protocol.c26
4 files changed, 52 insertions, 31 deletions
diff --git a/src/transports/local.c b/src/transports/local.c
index 3163d2eac..4502f0202 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -213,21 +213,17 @@ static int local_connect(
return 0;
}
-static int local_ls(git_transport *transport, git_headlist_cb list_cb, void *payload)
+static int local_ls(const git_remote_head ***out, size_t *size, git_transport *transport)
{
transport_local *t = (transport_local *)transport;
- unsigned int i;
- git_remote_head *head = NULL;
if (!t->have_refs) {
giterr_set(GITERR_NET, "The transport has not yet loaded the refs");
return -1;
}
- git_vector_foreach(&t->refs, i, head) {
- if (list_cb(head, payload))
- return GIT_EUSER;
- }
+ *out = (const git_remote_head **) t->refs.contents;
+ *size = t->refs.length;
return 0;
}
diff --git a/src/transports/smart.c b/src/transports/smart.c
index a681d5f40..5242beb65 100644
--- a/src/transports/smart.c
+++ b/src/transports/smart.c
@@ -63,6 +63,24 @@ static int git_smart__set_callbacks(
return 0;
}
+int git_smart__update_heads(transport_smart *t)
+{
+ size_t i;
+ git_pkt *pkt;
+
+ git_vector_clear(&t->heads);
+ git_vector_foreach(&t->refs, i, pkt) {
+ git_pkt_ref *ref = (git_pkt_ref *) pkt;
+ if (pkt->type != GIT_PKT_REF)
+ continue;
+
+ if (git_vector_insert(&t->heads, &ref->head) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
static int git_smart__connect(
git_transport *transport,
const char *url,
@@ -140,6 +158,9 @@ static int git_smart__connect(
git_pkt_free((git_pkt *)first);
}
+ /* Keep a list of heads for _ls */
+ git_smart__update_heads(t);
+
if (t->rpc && git_smart__reset_stream(t, false) < 0)
return -1;
@@ -149,28 +170,17 @@ static int git_smart__connect(
return 0;
}
-static int git_smart__ls(git_transport *transport, git_headlist_cb list_cb, void *payload)
+static int git_smart__ls(const git_remote_head ***out, size_t *size, git_transport *transport)
{
transport_smart *t = (transport_smart *)transport;
- unsigned int i;
- git_pkt *p = NULL;
if (!t->have_refs) {
giterr_set(GITERR_NET, "The transport has not yet loaded the refs");
return -1;
}
- git_vector_foreach(&t->refs, i, p) {
- git_pkt_ref *pkt = NULL;
-
- if (p->type != GIT_PKT_REF)
- continue;
-
- pkt = (git_pkt_ref *)p;
-
- if (list_cb(&pkt->head, payload))
- return GIT_EUSER;
- }
+ *out = (const git_remote_head **) t->heads.contents;
+ *size = t->heads.length;
return 0;
}
@@ -293,6 +303,7 @@ static void git_smart__free(git_transport *transport)
/* Free the subtransport */
t->wrapped->free(t->wrapped);
+ git_vector_free(&t->heads);
git_vector_foreach(refs, i, p)
git_pkt_free(p);
@@ -340,6 +351,11 @@ int git_transport_smart(git_transport **out, git_remote *owner, void *param)
return -1;
}
+ if (git_vector_init(&t->heads, 16, ref_name_cmp) < 0) {
+ git__free(t);
+ return -1;
+ }
+
if (definition->callback(&t->wrapped, &t->parent) < 0) {
git__free(t);
return -1;
diff --git a/src/transports/smart.h b/src/transports/smart.h
index 5232e54de..32f0be7f2 100644
--- a/src/transports/smart.h
+++ b/src/transports/smart.h
@@ -140,6 +140,7 @@ typedef struct {
git_smart_subtransport_stream *current_stream;
transport_smart_caps caps;
git_vector refs;
+ git_vector heads;
git_vector common;
git_atomic cancelled;
packetsize_cb packetsize_cb;
@@ -173,6 +174,8 @@ int git_smart__download_pack(
int git_smart__negotiation_step(git_transport *transport, void *data, size_t len);
int git_smart__get_push_stream(transport_smart *t, git_smart_subtransport_stream **out);
+int git_smart__update_heads(transport_smart *t);
+
/* smart_pkt.c */
int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t len);
int git_pkt_buffer_flush(git_buf *buf);
diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c
index 4e9e112f4..7288a4820 100644
--- a/src/transports/smart_protocol.c
+++ b/src/transports/smart_protocol.c
@@ -269,7 +269,7 @@ static int wait_while_ack(gitno_buffer *buf)
return 0;
}
-int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, const git_remote_head * const *refs, size_t count)
+int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, const git_remote_head * const *wants, size_t count)
{
transport_smart *t = (transport_smart *)transport;
gitno_buffer *buf = &t->buffer;
@@ -279,19 +279,20 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c
unsigned int i;
git_oid oid;
- /* No own logic, do our thing */
- if ((error = git_pkt_buffer_wants(refs, count, &t->caps, &data)) < 0)
+ if ((error = git_pkt_buffer_wants(wants, count, &t->caps, &data)) < 0)
return error;
if ((error = fetch_setup_walk(&walk, repo)) < 0)
goto on_error;
+
/*
- * We don't support any kind of ACK extensions, so the negotiation
- * boils down to sending what we have and listening for an ACK
- * every once in a while.
+ * Our support for ACK extensions is simply to parse them. On
+ * the first ACK we will accept that as enough common
+ * objects. We give up if we haven't found an answer in the
+ * first 256 we send.
*/
i = 0;
- while (true) {
+ while (i < 256) {
error = git_revwalk_next(&oid, walk);
if (error < 0) {
@@ -349,7 +350,7 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c
git_pkt_ack *pkt;
unsigned int i;
- if ((error = git_pkt_buffer_wants(refs, count, &t->caps, &data)) < 0)
+ if ((error = git_pkt_buffer_wants(wants, count, &t->caps, &data)) < 0)
goto on_error;
git_vector_foreach(&t->common, i, pkt) {
@@ -369,7 +370,7 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c
git_pkt_ack *pkt;
unsigned int i;
- if ((error = git_pkt_buffer_wants(refs, count, &t->caps, &data)) < 0)
+ if ((error = git_pkt_buffer_wants(wants, count, &t->caps, &data)) < 0)
goto on_error;
git_vector_foreach(&t->common, i, pkt) {
@@ -943,8 +944,13 @@ int git_smart__push(git_transport *transport, git_push *push)
push->transfer_progress_cb(push->pb->nr_written, push->pb->nr_objects, packbuilder_payload.last_bytes, push->transfer_progress_cb_payload);
}
- if (push->status.length)
+ if (push->status.length) {
error = update_refs_from_report(&t->refs, &push->specs, &push->status);
+ if (error < 0)
+ goto done;
+
+ error = git_smart__update_heads(t);
+ }
done:
git_buf_free(&pktline);