]> git.ipfire.org Git - thirdparty/git.git/blob - http-fetch.c
treewide: be explicit about dependence on gettext.h
[thirdparty/git.git] / http-fetch.c
1 #include "cache.h"
2 #include "config.h"
3 #include "exec-cmd.h"
4 #include "gettext.h"
5 #include "hex.h"
6 #include "http.h"
7 #include "walker.h"
8 #include "strvec.h"
9 #include "urlmatch.h"
10 #include "trace2.h"
11
12 static const char http_fetch_usage[] = "git http-fetch "
13 "[-c] [-t] [-a] [-v] [--recover] [-w ref] [--stdin | --packfile=hash | commit-id] url";
14
15 static int fetch_using_walker(const char *raw_url, int get_verbosely,
16 int get_recover, int commits, char **commit_id,
17 const char **write_ref, int commits_on_stdin)
18 {
19 char *url = NULL;
20 struct walker *walker;
21 int rc;
22
23 str_end_url_with_slash(raw_url, &url);
24
25 http_init(NULL, url, 0);
26
27 walker = get_http_walker(url);
28 walker->get_verbosely = get_verbosely;
29 walker->get_recover = get_recover;
30 walker->get_progress = 0;
31
32 rc = walker_fetch(walker, commits, commit_id, write_ref, url);
33
34 if (commits_on_stdin)
35 walker_targets_free(commits, commit_id, write_ref);
36
37 if (walker->corrupt_object_found) {
38 fprintf(stderr,
39 "Some loose object were found to be corrupt, but they might be just\n"
40 "a false '404 Not Found' error message sent with incorrect HTTP\n"
41 "status code. Suggest running 'git fsck'.\n");
42 }
43
44 walker_free(walker);
45 http_cleanup();
46 free(url);
47
48 return rc;
49 }
50
51 static void fetch_single_packfile(struct object_id *packfile_hash,
52 const char *url,
53 const char **index_pack_args) {
54 struct http_pack_request *preq;
55 struct slot_results results;
56 int ret;
57
58 http_init(NULL, url, 0);
59
60 preq = new_direct_http_pack_request(packfile_hash->hash, xstrdup(url));
61 if (!preq)
62 die("couldn't create http pack request");
63 preq->slot->results = &results;
64 preq->index_pack_args = index_pack_args;
65 preq->preserve_index_pack_stdout = 1;
66
67 if (start_active_slot(preq->slot)) {
68 run_active_slot(preq->slot);
69 if (results.curl_result != CURLE_OK) {
70 struct url_info url;
71 char *nurl = url_normalize(preq->url, &url);
72 if (!nurl || !git_env_bool("GIT_TRACE_REDACT", 1)) {
73 die("unable to get pack file '%s'\n%s", preq->url,
74 curl_errorstr);
75 } else {
76 die("failed to get '%.*s' url from '%.*s' "
77 "(full URL redacted due to GIT_TRACE_REDACT setting)\n%s",
78 (int)url.scheme_len, url.url,
79 (int)url.host_len, &url.url[url.host_off], curl_errorstr);
80 }
81 }
82 } else {
83 die("Unable to start request");
84 }
85
86 if ((ret = finish_http_pack_request(preq)))
87 die("finish_http_pack_request gave result %d", ret);
88
89 release_http_pack_request(preq);
90 http_cleanup();
91 }
92
93 int cmd_main(int argc, const char **argv)
94 {
95 int commits_on_stdin = 0;
96 int commits;
97 const char **write_ref = NULL;
98 char **commit_id;
99 int arg = 1;
100 int get_verbosely = 0;
101 int get_recover = 0;
102 int packfile = 0;
103 int nongit;
104 struct object_id packfile_hash;
105 struct strvec index_pack_args = STRVEC_INIT;
106
107 setup_git_directory_gently(&nongit);
108
109 while (arg < argc && argv[arg][0] == '-') {
110 const char *p;
111
112 if (argv[arg][1] == 't') {
113 } else if (argv[arg][1] == 'c') {
114 } else if (argv[arg][1] == 'a') {
115 } else if (argv[arg][1] == 'v') {
116 get_verbosely = 1;
117 } else if (argv[arg][1] == 'w') {
118 write_ref = &argv[arg + 1];
119 arg++;
120 } else if (argv[arg][1] == 'h') {
121 usage(http_fetch_usage);
122 } else if (!strcmp(argv[arg], "--recover")) {
123 get_recover = 1;
124 } else if (!strcmp(argv[arg], "--stdin")) {
125 commits_on_stdin = 1;
126 } else if (skip_prefix(argv[arg], "--packfile=", &p)) {
127 const char *end;
128
129 packfile = 1;
130 if (parse_oid_hex(p, &packfile_hash, &end) || *end)
131 die(_("argument to --packfile must be a valid hash (got '%s')"), p);
132 } else if (skip_prefix(argv[arg], "--index-pack-arg=", &p)) {
133 strvec_push(&index_pack_args, p);
134 }
135 arg++;
136 }
137 if (argc != arg + 2 - (commits_on_stdin || packfile))
138 usage(http_fetch_usage);
139
140 if (nongit)
141 die(_("not a git repository"));
142
143 trace2_cmd_name("http-fetch");
144
145 git_config(git_default_config, NULL);
146
147 if (packfile) {
148 if (!index_pack_args.nr)
149 die(_("the option '%s' requires '%s'"), "--packfile", "--index-pack-args");
150
151 fetch_single_packfile(&packfile_hash, argv[arg],
152 index_pack_args.v);
153
154 return 0;
155 }
156
157 if (index_pack_args.nr)
158 die(_("the option '%s' requires '%s'"), "--index-pack-args", "--packfile");
159
160 if (commits_on_stdin) {
161 commits = walker_targets_stdin(&commit_id, &write_ref);
162 } else {
163 commit_id = (char **) &argv[arg++];
164 commits = 1;
165 }
166 return fetch_using_walker(argv[arg], get_verbosely, get_recover,
167 commits, commit_id, write_ref,
168 commits_on_stdin);
169 }