]> git.proxmox.com Git - libgit2.git/commitdiff
Implement sending haves
authorCarlos Martín Nieto <carlos@cmartin.tk>
Sat, 30 Jul 2011 20:29:00 +0000 (22:29 +0200)
committerVicent Marti <tanoku@gmail.com>
Thu, 18 Aug 2011 00:34:07 +0000 (02:34 +0200)
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
src/fetch.c
src/pkt.c
src/pkt.h
src/remote.c
src/remote.h
src/transport.c
src/transport.h
src/transport_git.c

index 59beb1ea305d01f6906619368e3d4e427f46b1ff..c799c805f117a7f269d66a328510f7cb7d82455c 100644 (file)
@@ -38,8 +38,8 @@
  */
 static int whn_cmp(const void *a, const void *b)
 {
-       git_remote_head *heada = *(git_remote_head **)(a);
-       git_remote_head *headb = *(git_remote_head **)(b);
+       git_remote_head *heada = (git_remote_head *) a;
+       git_remote_head *headb = (git_remote_head *) b;
 
        return headb->type - heada->type;
 }
@@ -57,7 +57,7 @@ int git_fetch_list_want(git_headarray *whn_list, git_repository *repo, git_remot
        int error;
        unsigned int i;
 
-       error = git_vector_init(&list, whn_list->len, whn_cmp);
+       error = git_vector_init(&list, 16, whn_cmp);
        if (error < GIT_SUCCESS)
                return error;
 
@@ -182,8 +182,8 @@ int git_fetch_negotiate(git_headarray *list, git_repository *repo, git_remote *r
         * Now we have everything set up so we can start tell the server
         * what we want and what we have.
         */
-       git_remote_send_wants(remote, list);
-
+       git_transport_send_wants(remote->transport, list);
+       git_transport_send_haves(remote->transport, repo);
 
 cleanup:
        git_revwalk_free(walk);
index 06d1bc87b0a80ca769cca5ad6c452f5e4a6373ea..fbb5dfb0aaa2dfe767a790cf8bfdb3009e163e9f 100644 (file)
--- a/src/pkt.c
+++ b/src/pkt.c
@@ -27,6 +27,8 @@
 
 #include "git2/types.h"
 #include "git2/errors.h"
+#include "git2/refs.h"
+#include "git2/revwalk.h"
 
 #include "pkt.h"
 #include "util.h"
@@ -229,9 +231,70 @@ int git_pkt_send_wants(git_headarray *refs, int fd)
 
        for (i = 0; i < refs->len; ++i) {
                head = refs->heads[i];
+               if (head->type != GIT_WHN_WANT)
+                       continue;
+
                git_oid_fmt(buf + STRLEN(WANT_PREFIX), &head->oid);
-               printf("would send %s\n", buf);
+               printf("would send %s", buf);
+       }
+
+       /* TODO: git_pkt_send_flush(fd) */
+       printf("Wound send 0000\n");
+
+       return ret;
+}
+
+#define HAVE_PREFIX "0032have "
+
+int git_pkt_send_haves(git_repository *repo, int fd)
+{
+       unsigned int i;
+       int ret = GIT_SUCCESS;
+       char buf[STRLEN(HAVE_PREFIX) + GIT_OID_HEXSZ + 2];
+       git_oid oid;
+       git_revwalk *walk;
+       git_strarray refs;
+       git_reference *ref;
+       git_remote_head *head;
+
+       memcpy(buf, HAVE_PREFIX, STRLEN(HAVE_PREFIX));
+       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);
+       }
+
+       /* TODO: git_pkt_send_flush(fd) */
+       printf("Wound send 0000\n");
+
+cleanup:
+       git_revwalk_free(walk);
+       git_strarray_free(&refs);
        return ret;
 }
index 6dc5486cd6cc4d0603a87138676d1f1ac3b94ffd..43407037c993fed383921c31ffe57c103318cb0d 100644 (file)
--- a/src/pkt.h
+++ b/src/pkt.h
@@ -57,6 +57,8 @@ typedef struct {
 
 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_haves(git_repository *repo, int fd);
+int git_pkt_send_wants(git_headarray *refs, int fd);
 void git_pkt_free(git_pkt *pkt);
 
 #endif
index 997da00ceb1669d9bc608aab44301ee7a3f64b1b..2812f5de604a0a9791ceb61f2cf03bca1ccc6921 100644 (file)
 #include "repository.h"
 #include "remote.h"
 
-int git_remote_send_wants(git_remote *remote, git_headarray *list)
-{
-       return git_transport_send_wants(remote->transport, list);
-}
-
 static int refspec_parse(git_refspec *refspec, const char *str)
 {
        char *delim;
index e0c3fbf8d24cb9993b4b8a57044e031551eeedf0..129671fd2e1fff351f63eebf5ca4a1ab7b5a0db1 100644 (file)
@@ -1,9 +1,9 @@
 #ifndef INCLUDE_remote_h__
 #define INCLUDE_remote_h__
 
-#include "remote.h"
 #include "refspec.h"
 #include "transport.h"
+#include "repository.h"
 
 struct git_remote {
        char *name;
@@ -13,6 +13,4 @@ struct git_remote {
        git_transport *transport;
 };
 
-int git_remote_send_wants(git_remote *remote, git_headarray *list);
-
 #endif
index 96b79ddf4897a801a3b2d0e69f7f8497fc4d8a23..53caf9e1b170fd4d0b8390cc1e6b37db59118176 100644 (file)
@@ -85,6 +85,11 @@ int git_transport_send_wants(struct git_transport *transport, git_headarray *arr
        return transport->send_wants(transport, array);
 }
 
+int git_transport_send_haves(struct git_transport *transport, git_repository *repo)
+{
+       return transport->send_haves(transport, repo);
+}
+
 int git_transport_close(git_transport *transport)
 {
        return transport->close(transport);
index 9105ea453793ce9505428ae0bafdcf3c4dbf2af2..6e3501b99b97adc5ab8fe1081b43b2d5690bef4b 100644 (file)
@@ -60,6 +60,10 @@ struct git_transport {
         * Send the list of 'want' refs
         */
        int (*send_wants)(struct git_transport *transport, git_headarray *list);
+       /**
+        * Send the list of 'have' refs
+        */
+       int (*send_haves)(struct git_transport *transport, git_repository *repo);
        /**
         * Fetch the changes
         */
index 41b95ec2a2deff5b638a43f85fac5ab6a680f10a..0453ca0fd8faf4a387fb67211f6e822ce6b8c400 100644 (file)
@@ -281,6 +281,13 @@ static int git_send_wants(git_transport *transport, git_headarray *array)
        return git_pkt_send_wants(array, t->socket);
 }
 
+static int git_send_haves(git_transport *transport, git_repository *repo)
+{
+       transport_git *t = (transport_git *) transport;
+
+       return git_pkt_send_haves(repo, t->socket);
+}
+
 static int git_close(git_transport *transport)
 {
        transport_git *t = (transport_git*) transport;
@@ -326,6 +333,7 @@ int git_transport_git(git_transport **out)
        t->parent.connect = git_connect;
        t->parent.ls = git_ls;
        t->parent.send_wants = git_send_wants;
+       t->parent.send_haves = git_send_haves;
        t->parent.close = git_close;
        t->parent.free = git_free;