]>
git.proxmox.com Git - libgit2.git/blob - src/fetch.c
2 * Copyright (C) 2009-2011 the libgit2 contributors
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
8 #include "git2/remote.h"
10 #include "git2/refs.h"
11 #include "git2/revwalk.h"
14 #include "transport.h"
19 static int filter_wants(git_remote
*remote
)
23 git_transport
*t
= remote
->transport
;
24 git_repository
*repo
= remote
->repo
;
25 const git_refspec
*spec
;
29 error
= git_vector_init(&list
, 16, NULL
);
30 if (error
< GIT_SUCCESS
)
33 error
= t
->ls(t
, &refs
);
34 if (error
< GIT_SUCCESS
) {
35 error
= git__rethrow(error
, "Failed to get remote ref list");
40 * The fetch refspec can be NULL, and what this means is that the
41 * user didn't specify one. This is fine, as it means that we're
42 * not interested in any particular branch but just the remote's
43 * HEAD, which will be stored in FETCH_HEAD after the fetch.
45 spec
= git_remote_fetchspec(remote
);
48 * We need to handle HEAD separately, as we always want it, but it
49 * probably won't matcht he refspec.
52 if (refs
.len
> 0 && !strcmp(head
->name
, GIT_HEAD_FILE
)) {
53 if (git_odb_exists(repo
->db
, &head
->oid
))
56 remote
->need_pack
= 1;
59 error
= git_vector_insert(&list
, refs
.heads
[0]);
60 if (error
< GIT_SUCCESS
)
64 for (; i
< refs
.len
; ++i
) {
65 git_remote_head
*head
= refs
.heads
[i
];
67 /* If it doesn't match the refpec, we don't want it */
68 error
= git_refspec_src_match(spec
, head
->name
);
69 if (error
== GIT_ENOMATCH
)
71 if (error
< GIT_SUCCESS
) {
72 error
= git__rethrow(error
, "Error matching remote ref name");
76 /* If we have the object, mark it so we don't ask for it */
77 if (git_odb_exists(repo
->db
, &head
->oid
))
80 remote
->need_pack
= 1;
82 error
= git_vector_insert(&list
, head
);
83 if (error
< GIT_SUCCESS
)
87 remote
->refs
.len
= list
.length
;
88 remote
->refs
.heads
= (git_remote_head
**) list
.contents
;
93 git_vector_free(&list
);
98 * In this first version, we push all our refs in and start sending
99 * them out. When we get an ACK we hide that commit and continue
100 * traversing until we're done
102 int git_fetch_negotiate(git_remote
*remote
)
105 git_headarray
*list
= &remote
->refs
;
106 git_transport
*t
= remote
->transport
;
108 error
= filter_wants(remote
);
109 if (error
< GIT_SUCCESS
)
110 return git__rethrow(error
, "Failed to filter the reference list for wants");
112 /* Don't try to negotiate when we don't want anything */
115 if (!remote
->need_pack
)
119 * Now we have everything set up so we can start tell the server
120 * what we want and what we have.
122 error
= t
->send_wants(t
, list
);
123 if (error
< GIT_SUCCESS
)
124 return git__rethrow(error
, "Failed to send want list");
126 return t
->negotiate_fetch(t
, remote
->repo
, &remote
->refs
);
129 int git_fetch_download_pack(char **out
, git_remote
*remote
)
131 if(!remote
->need_pack
) {
136 return remote
->transport
->download_pack(out
, remote
->transport
, remote
->repo
);