]> git.proxmox.com Git - libgit2.git/blame - src/fetch.c
Add BD on ca-certificates
[libgit2.git] / src / fetch.c
CommitLineData
e1f4a761 1/*
359fc2d2 2 * Copyright (C) the libgit2 contributors. All rights reserved.
e1f4a761 3 *
bb742ede
VM
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.
e1f4a761
CMN
6 */
7
eae0bfdc
PP
8#include "fetch.h"
9
e1f4a761
CMN
10#include "git2/oid.h"
11#include "git2/refs.h"
65fbc48a 12#include "git2/revwalk.h"
41fb1ca0 13#include "git2/transport.h"
e1f4a761 14
e1f4a761
CMN
15#include "remote.h"
16#include "refspec.h"
01ad7b3a 17#include "pack.h"
2c982daa 18#include "netops.h"
114f5a6c
RB
19#include "repository.h"
20#include "refs.h"
7bcd9e23 21
35a8a8c5 22static int maybe_want(git_remote *remote, git_remote_head *head, git_odb *odb, git_refspec *tagspec, git_remote_autotag_option_t tagopt)
d88d4311 23{
3230a44f 24 int match = 0;
e1f4a761 25
3230a44f
CMN
26 if (!git_reference_is_valid_name(head->name))
27 return 0;
28
35a8a8c5 29 if (tagopt == GIT_REMOTE_DOWNLOAD_TAGS_ALL) {
505b5d0c 30 /*
e284c451
POL
31 * If tagopt is --tags, always request tags
32 * in addition to the remote's refspecs
505b5d0c 33 */
359dce72 34 if (git_refspec_src_matches(tagspec, head->name))
3230a44f 35 match = 1;
e284c451
POL
36 }
37
38 if (!match && git_remote__matching_refspec(remote, head->name))
39 match = 1;
11678b37 40
3230a44f
CMN
41 if (!match)
42 return 0;
e1f4a761 43
d88d4311 44 /* If we have the object, mark it so we don't ask for it */
3536c168 45 if (git_odb_exists(odb, &head->oid)) {
d88d4311 46 head->local = 1;
3536c168 47 }
d88d4311 48 else
359dce72 49 remote->need_pack = 1;
d88d4311 50
359dce72 51 return git_vector_insert(&remote->refs, head);
d88d4311
VM
52}
53
35a8a8c5 54static int filter_wants(git_remote *remote, const git_fetch_options *opts)
d88d4311 55{
359dce72 56 git_remote_head **heads;
af613ecd 57 git_refspec tagspec, head;
359dce72
CMN
58 int error = 0;
59 git_odb *odb;
60 size_t i, heads_len;
35a8a8c5
CMN
61 git_remote_autotag_option_t tagopt = remote->download_tags;
62
c2418f46 63 if (opts && opts->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED)
35a8a8c5 64 tagopt = opts->download_tags;
d88d4311 65
359dce72
CMN
66 git_vector_clear(&remote->refs);
67 if ((error = git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true)) < 0)
68206c54 68 return error;
9462c471 69
4a3b18a6
CMN
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 */
af613ecd
CMN
76 if (remote->active_refspecs.length == 0) {
77 if ((error = git_refspec__parse(&head, "HEAD", true)) < 0)
78 goto cleanup;
79
1c967df3 80 error = git_refspec__dwim_one(&remote->active_refspecs, &head, &remote->refs);
ac3d33df 81 git_refspec__dispose(&head);
1c967df3
CMN
82
83 if (error < 0)
af613ecd
CMN
84 goto cleanup;
85 }
86
359dce72
CMN
87 if (git_repository_odb__weakptr(&odb, remote->repo) < 0)
88 goto cleanup;
e1f4a761 89
359dce72 90 if (git_remote_ls((const git_remote_head ***)&heads, &heads_len, remote) < 0)
68206c54 91 goto cleanup;
e1f4a761 92
359dce72 93 for (i = 0; i < heads_len; i++) {
35a8a8c5 94 if ((error = maybe_want(remote, heads[i], odb, &tagspec, tagopt)) < 0)
359dce72
CMN
95 break;
96 }
68206c54 97
98cleanup:
ac3d33df 99 git_refspec__dispose(&tagspec);
68206c54 100
101 return error;
e1f4a761 102}
65fbc48a 103
65fbc48a
CMN
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 */
35a8a8c5 109int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts)
65fbc48a 110{
b5a8aa94 111 git_transport *t = remote->transport;
25e0b157 112
35a8a8c5 113 remote->need_pack = 0;
31143b36 114
35a8a8c5 115 if (filter_wants(remote, opts) < 0) {
ac3d33df 116 git_error_set(GIT_ERROR_NET, "failed to filter the reference list for wants");
5eb8affb
CMN
117 return -1;
118 }
e1d88030 119
da290220 120 /* Don't try to negotiate when we don't want anything */
af613ecd 121 if (!remote->need_pack)
5eb8affb 122 return 0;
427ca3d3 123
7e1a94db 124 /*
64d01de8 125 * Now we have everything set up so we can start tell the
41fb1ca0 126 * server what we want and what we have.
64d01de8 127 */
41fb1ca0
PK
128 return t->negotiate_fetch(t,
129 remote->repo,
130 (const git_remote_head * const *)remote->refs.contents,
131 remote->refs.length);
65fbc48a
CMN
132}
133
8f0104ec 134int git_fetch_download_pack(git_remote *remote, const git_remote_callbacks *callbacks)
2c982daa 135{
41fb1ca0 136 git_transport *t = remote->transport;
8f0104ec
CMN
137 git_transfer_progress_cb progress = NULL;
138 void *payload = NULL;
2c982daa 139
25e0b157 140 if (!remote->need_pack)
e03e71da 141 return 0;
dee5515a 142
8f0104ec
CMN
143 if (callbacks) {
144 progress = callbacks->transfer_progress;
145 payload = callbacks->payload;
146 }
147
148 return t->download_pack(t, remote->repo, &remote->stats, progress, payload);
149}
150
151int git_fetch_init_options(git_fetch_options *opts, unsigned int version)
152{
153 GIT_INIT_STRUCTURE_FROM_TEMPLATE(
154 opts, version, git_fetch_options, GIT_FETCH_OPTIONS_INIT);
155 return 0;
dee5515a 156}