File Coverage

deps/libgit2/src/fetch.c
Criterion Covered Total %
statement 0 64 0.0
branch 0 44 0.0
condition n/a
subroutine n/a
pod n/a
total 0 108 0.0


line stmt bran cond sub pod time code
1             /*
2             * Copyright (C) the libgit2 contributors. All rights reserved.
3             *
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.
6             */
7              
8             #include "fetch.h"
9              
10             #include "git2/oid.h"
11             #include "git2/refs.h"
12             #include "git2/revwalk.h"
13             #include "git2/transport.h"
14              
15             #include "remote.h"
16             #include "refspec.h"
17             #include "pack.h"
18             #include "netops.h"
19             #include "repository.h"
20             #include "refs.h"
21              
22 0           static int maybe_want(git_remote *remote, git_remote_head *head, git_odb *odb, git_refspec *tagspec, git_remote_autotag_option_t tagopt)
23             {
24 0           int match = 0;
25              
26 0 0         if (!git_reference_is_valid_name(head->name))
27 0           return 0;
28              
29 0 0         if (tagopt == GIT_REMOTE_DOWNLOAD_TAGS_ALL) {
30             /*
31             * If tagopt is --tags, always request tags
32             * in addition to the remote's refspecs
33             */
34 0 0         if (git_refspec_src_matches(tagspec, head->name))
35 0           match = 1;
36             }
37              
38 0 0         if (!match && git_remote__matching_refspec(remote, head->name))
    0          
39 0           match = 1;
40              
41 0 0         if (!match)
42 0           return 0;
43              
44             /* If we have the object, mark it so we don't ask for it */
45 0 0         if (git_odb_exists(odb, &head->oid)) {
46 0           head->local = 1;
47             }
48             else
49 0           remote->need_pack = 1;
50              
51 0           return git_vector_insert(&remote->refs, head);
52             }
53              
54 0           static int filter_wants(git_remote *remote, const git_fetch_options *opts)
55             {
56             git_remote_head **heads;
57             git_refspec tagspec, head;
58 0           int error = 0;
59             git_odb *odb;
60             size_t i, heads_len;
61 0           git_remote_autotag_option_t tagopt = remote->download_tags;
62              
63 0 0         if (opts && opts->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED)
    0          
64 0           tagopt = opts->download_tags;
65              
66 0           git_vector_clear(&remote->refs);
67 0 0         if ((error = git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true)) < 0)
68 0           return error;
69              
70             /*
71             * The fetch refspec can be NULL, and what this means is that the
72             * user didn't specify one. This is fine, as it means that we're
73             * not interested in any particular branch but just the remote's
74             * HEAD, which will be stored in FETCH_HEAD after the fetch.
75             */
76 0 0         if (remote->active_refspecs.length == 0) {
77 0 0         if ((error = git_refspec__parse(&head, "HEAD", true)) < 0)
78 0           goto cleanup;
79              
80 0           error = git_refspec__dwim_one(&remote->active_refspecs, &head, &remote->refs);
81 0           git_refspec__dispose(&head);
82              
83 0 0         if (error < 0)
84 0           goto cleanup;
85             }
86              
87 0 0         if (git_repository_odb__weakptr(&odb, remote->repo) < 0)
88 0           goto cleanup;
89              
90 0 0         if (git_remote_ls((const git_remote_head ***)&heads, &heads_len, remote) < 0)
91 0           goto cleanup;
92              
93 0 0         for (i = 0; i < heads_len; i++) {
94 0 0         if ((error = maybe_want(remote, heads[i], odb, &tagspec, tagopt)) < 0)
95 0           break;
96             }
97              
98             cleanup:
99 0           git_refspec__dispose(&tagspec);
100              
101 0           return error;
102             }
103              
104             /*
105             * In this first version, we push all our refs in and start sending
106             * them out. When we get an ACK we hide that commit and continue
107             * traversing until we're done
108             */
109 0           int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts)
110             {
111 0           git_transport *t = remote->transport;
112              
113 0           remote->need_pack = 0;
114              
115 0 0         if (filter_wants(remote, opts) < 0) {
116 0           git_error_set(GIT_ERROR_NET, "failed to filter the reference list for wants");
117 0           return -1;
118             }
119              
120             /* Don't try to negotiate when we don't want anything */
121 0 0         if (!remote->need_pack)
122 0           return 0;
123              
124             /*
125             * Now we have everything set up so we can start tell the
126             * server what we want and what we have.
127             */
128 0           return t->negotiate_fetch(t,
129             remote->repo,
130 0           (const git_remote_head * const *)remote->refs.contents,
131             remote->refs.length);
132             }
133              
134 0           int git_fetch_download_pack(git_remote *remote, const git_remote_callbacks *callbacks)
135             {
136 0           git_transport *t = remote->transport;
137 0           git_indexer_progress_cb progress = NULL;
138 0           void *payload = NULL;
139              
140 0 0         if (!remote->need_pack)
141 0           return 0;
142              
143 0 0         if (callbacks) {
144 0           progress = callbacks->transfer_progress;
145 0           payload = callbacks->payload;
146             }
147              
148 0           return t->download_pack(t, remote->repo, &remote->stats, progress, payload);
149             }
150              
151 0           int git_fetch_options_init(git_fetch_options *opts, unsigned int version)
152             {
153 0 0         GIT_INIT_STRUCTURE_FROM_TEMPLATE(
154             opts, version, git_fetch_options, GIT_FETCH_OPTIONS_INIT);
155 0           return 0;
156             }
157              
158 0           int git_fetch_init_options(git_fetch_options *opts, unsigned int version)
159             {
160 0           return git_fetch_options_init(opts, version);
161             }