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:
Diffstat (limited to 'src/fetch.c')
-rw-r--r--src/fetch.c158
1 files changed, 42 insertions, 116 deletions
diff --git a/src/fetch.c b/src/fetch.c
index c92cf4ef5..b60a95232 100644
--- a/src/fetch.c
+++ b/src/fetch.c
@@ -1,18 +1,16 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
-#include "git2/remote.h"
#include "git2/oid.h"
#include "git2/refs.h"
#include "git2/revwalk.h"
-#include "git2/indexer.h"
+#include "git2/transport.h"
#include "common.h"
-#include "transport.h"
#include "remote.h"
#include "refspec.h"
#include "pack.h"
@@ -21,7 +19,7 @@
struct filter_payload {
git_remote *remote;
- const git_refspec *spec;
+ const git_refspec *spec, *tagspec;
git_odb *odb;
int found_head;
};
@@ -29,18 +27,21 @@ struct filter_payload {
static int filter_ref__cb(git_remote_head *head, void *payload)
{
struct filter_payload *p = payload;
+ int match = 0;
- if (!p->found_head && strcmp(head->name, GIT_HEAD_FILE) == 0) {
+ if (!git_reference_is_valid_name(head->name))
+ return 0;
+
+ if (!p->found_head && strcmp(head->name, GIT_HEAD_FILE) == 0)
p->found_head = 1;
- } else {
- /* If it doesn't match the refpec, we don't want it */
- if (!git_refspec_src_matches(p->spec, head->name))
- return 0;
-
- /* Don't even try to ask for the annotation target */
- if (!git__suffixcmp(head->name, "^{}"))
- return 0;
- }
+ else if (git_refspec_src_matches(p->spec, head->name))
+ match = 1;
+ else if (p->remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_ALL &&
+ git_refspec_src_matches(p->tagspec, head->name))
+ match = 1;
+
+ if (!match)
+ return 0;
/* If we have the object, mark it so we don't ask for it */
if (git_odb_exists(p->odb, &head->oid))
@@ -54,8 +55,12 @@ static int filter_ref__cb(git_remote_head *head, void *payload)
static int filter_wants(git_remote *remote)
{
struct filter_payload p;
+ git_refspec tagspec;
+ int error = -1;
git_vector_clear(&remote->refs);
+ if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0)
+ return error;
/*
* The fetch refspec can be NULL, and what this means is that the
@@ -64,13 +69,19 @@ static int filter_wants(git_remote *remote)
* HEAD, which will be stored in FETCH_HEAD after the fetch.
*/
p.spec = git_remote_fetchspec(remote);
+ p.tagspec = &tagspec;
p.found_head = 0;
p.remote = remote;
if (git_repository_odb__weakptr(&p.odb, remote->repo) < 0)
- return -1;
+ goto cleanup;
- return remote->transport->ls(remote->transport, &filter_ref__cb, &p);
+ error = git_remote_ls(remote, filter_ref__cb, &p);
+
+cleanup:
+ git_refspec__free(&tagspec);
+
+ return error;
}
/*
@@ -81,7 +92,7 @@ static int filter_wants(git_remote *remote)
int git_fetch_negotiate(git_remote *remote)
{
git_transport *t = remote->transport;
-
+
if (filter_wants(remote) < 0) {
giterr_set(GITERR_NET, "Failed to filter the reference list for wants");
return -1;
@@ -92,109 +103,24 @@ int git_fetch_negotiate(git_remote *remote)
return 0;
/*
- * Now we have everything set up so we can start tell the server
- * what we want and what we have.
+ * Now we have everything set up so we can start tell the
+ * server what we want and what we have.
*/
- return t->negotiate_fetch(t, remote->repo, &remote->refs);
+ return t->negotiate_fetch(t,
+ remote->repo,
+ (const git_remote_head * const *)remote->refs.contents,
+ remote->refs.length);
}
-int git_fetch_download_pack(git_remote *remote, git_off_t *bytes, git_indexer_stats *stats)
+int git_fetch_download_pack(
+ git_remote *remote,
+ git_transfer_progress_callback progress_cb,
+ void *progress_payload)
{
+ git_transport *t = remote->transport;
+
if(!remote->need_pack)
return 0;
- return remote->transport->download_pack(remote->transport, remote->repo, bytes, stats);
-}
-
-/* Receiving data from a socket and storing it is pretty much the same for git and HTTP */
-int git_fetch__download_pack(
- const char *buffered,
- size_t buffered_size,
- GIT_SOCKET fd,
- git_repository *repo,
- git_off_t *bytes,
- git_indexer_stats *stats)
-{
- int recvd;
- char buff[1024];
- gitno_buffer buf;
- git_indexer_stream *idx;
-
- gitno_buffer_setup(&buf, buff, sizeof(buff), fd);
-
- if (memcmp(buffered, "PACK", strlen("PACK"))) {
- giterr_set(GITERR_NET, "The pack doesn't start with the signature");
- return -1;
- }
-
- if (git_indexer_stream_new(&idx, git_repository_path(repo)) < 0)
- return -1;
-
- memset(stats, 0, sizeof(git_indexer_stats));
- if (git_indexer_stream_add(idx, buffered, buffered_size, stats) < 0)
- goto on_error;
-
- *bytes = buffered_size;
-
- do {
- if (git_indexer_stream_add(idx, buf.data, buf.offset, stats) < 0)
- goto on_error;
-
- gitno_consume_n(&buf, buf.offset);
- if ((recvd = gitno_recv(&buf)) < 0)
- goto on_error;
-
- *bytes += recvd;
- } while(recvd > 0);
-
- if (git_indexer_stream_finalize(idx, stats))
- goto on_error;
-
- git_indexer_stream_free(idx);
- return 0;
-
-on_error:
- git_indexer_stream_free(idx);
- return -1;
-}
-
-int git_fetch_setup_walk(git_revwalk **out, git_repository *repo)
-{
- git_revwalk *walk;
- git_strarray refs;
- unsigned int i;
- git_reference *ref;
-
- if (git_reference_list(&refs, repo, GIT_REF_LISTALL) < 0)
- return -1;
-
- if (git_revwalk_new(&walk, repo) < 0)
- return -1;
-
- git_revwalk_sorting(walk, GIT_SORT_TIME);
-
- for (i = 0; i < refs.count; ++i) {
- /* No tags */
- if (!git__prefixcmp(refs.strings[i], GIT_REFS_TAGS_DIR))
- continue;
-
- if (git_reference_lookup(&ref, repo, refs.strings[i]) < 0)
- goto on_error;
-
- if (git_reference_type(ref) == GIT_REF_SYMBOLIC)
- continue;
- if (git_revwalk_push(walk, git_reference_oid(ref)) < 0)
- goto on_error;
-
- git_reference_free(ref);
- }
-
- git_strarray_free(&refs);
- *out = walk;
- return 0;
-
-on_error:
- git_reference_free(ref);
- git_strarray_free(&refs);
- return -1;
+ return t->download_pack(t, remote->repo, &remote->stats, progress_cb, progress_payload);
}