17
#include "sha1-array.h"
18
#include "sigchain.h"
19
20
-/* rsync support */
21
-
22
-/*
23
- * We copy packed-refs and refs/ into a temporary file, then read the
24
- * loose refs recursively (sorting whenever possible), and then inserting
25
- * those packed refs that are not yet in the list (not validating, but
26
- * assuming that the file is sorted).
27
- *
28
- * Appears refactoring this from refs.c is too cumbersome.
29
- */
30
-
31
-static int str_cmp(const void *a, const void *b)
32
-{
33
- const char *s1 = a;
34
- const char *s2 = b;
35
-
36
- return strcmp(s1, s2);
37
-}
38
-
39
-/* path->buf + name_offset is expected to point to "refs/" */
40
-
41
-static int read_loose_refs(struct strbuf *path, int name_offset,
42
- struct ref **tail)
43
-{
44
- DIR *dir = opendir(path->buf);
45
- struct dirent *de;
46
- struct {
47
- char **entries;
48
- int nr, alloc;
49
- } list;
50
- int i, pathlen;
51
-
52
- if (!dir)
53
- return -1;
54
-
55
- memset (&list, 0, sizeof(list));
56
-
57
- while ((de = readdir(dir))) {
58
- if (is_dot_or_dotdot(de->d_name))
59
- continue;
60
- ALLOC_GROW(list.entries, list.nr + 1, list.alloc);
61
- list.entries[list.nr++] = xstrdup(de->d_name);
62
- }
63
- closedir(dir);
64
-
65
- /* sort the list */
66
-
67
- qsort(list.entries, list.nr, sizeof(char *), str_cmp);
68
-
69
- pathlen = path->len;
70
- strbuf_addch(path, '/');
71
-
72
- for (i = 0; i < list.nr; i++, strbuf_setlen(path, pathlen + 1)) {
73
- strbuf_addstr(path, list.entries[i]);
74
- if (read_loose_refs(path, name_offset, tail)) {
75
- int fd = open(path->buf, O_RDONLY);
76
- char buffer[40];
77
- struct ref *next;
78
-
79
- if (fd < 0)
80
- continue;
81
- next = alloc_ref(path->buf + name_offset);
82
- if (read_in_full(fd, buffer, 40) != 40 ||
83
- get_oid_hex(buffer, &next->old_oid)) {
84
- close(fd);
85
- free(next);
86
- continue;
87
- }
88
- close(fd);
89
- (*tail)->next = next;
90
- *tail = next;
91
- }
92
- }
93
- strbuf_setlen(path, pathlen);
94
-
95
- for (i = 0; i < list.nr; i++)
96
- free(list.entries[i]);
97
- free(list.entries);
98
-
99
- return 0;
100
-}
101
-
102
-/* insert the packed refs for which no loose refs were found */
103
-
104
-static void insert_packed_refs(const char *packed_refs, struct ref **list)
105
-{
106
- FILE *f = fopen(packed_refs, "r");
107
- static char buffer[PATH_MAX];
108
-
109
- if (!f)
110
- return;
111
-
112
- for (;;) {
113
- int cmp = 0; /* assigned before used */
114
- int len;
115
-
116
- if (!fgets(buffer, sizeof(buffer), f)) {
117
- fclose(f);
118
- return;
119
- }
120
-
121
- if (!isxdigit(buffer[0]))
122
- continue;
123
- len = strlen(buffer);
124
- if (len && buffer[len - 1] == '\n')
125
- buffer[--len] = '\0';
126
- if (len < 41)
127
- continue;
128
- while ((*list)->next &&
129
- (cmp = strcmp(buffer + 41,
130
- (*list)->next->name)) > 0)
131
- list = &(*list)->next;
132
- if (!(*list)->next || cmp < 0) {
133
- struct ref *next = alloc_ref(buffer + 41);
134
- buffer[40] = '\0';
135
- if (get_oid_hex(buffer, &next->old_oid)) {
136
- warning ("invalid SHA-1: %s", buffer);
137
- free(next);
138
- continue;
139
- }
140
- next->next = (*list)->next;
141
- (*list)->next = next;
142
- list = &(*list)->next;
143
- }
144
- }
145
-}
146
-
20
static void set_upstreams(struct transport *transport, struct ref *refs,
21
int pretend)
22
{
65
}
66
}
67
195
-static const char *rsync_url(const char *url)
196
-{
197
- if (!starts_with(url, "rsync://"))
198
- skip_prefix(url, "rsync:", &url);
199
- return url;
200
-}
201
-
202
-static struct ref *get_refs_via_rsync(struct transport *transport, int for_push)
203
-{
204
- struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;
205
- struct ref dummy = {NULL}, *tail = &dummy;
206
- struct child_process rsync = CHILD_PROCESS_INIT;
207
- const char *args[5];
208
- int temp_dir_len;
209
-
210
- if (for_push)
211
- return NULL;
212
-
213
- /* copy the refs to the temporary directory */
214
-
215
- strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
216
- if (!mkdtemp(temp_dir.buf))
217
- die_errno ("Could not make temporary directory");
218
- temp_dir_len = temp_dir.len;
219
-
220
- strbuf_addstr(&buf, rsync_url(transport->url));
221
- strbuf_addstr(&buf, "/refs");
222
-
223
- rsync.argv = args;
224
- rsync.stdout_to_stderr = 1;
225
- args[0] = "rsync";
226
- args[1] = (transport->verbose > 1) ? "-rv" : "-r";
227
- args[2] = buf.buf;
228
- args[3] = temp_dir.buf;
229
- args[4] = NULL;
230
-
231
- if (run_command(&rsync))
232
- die ("Could not run rsync to get refs");
233
-
234
- strbuf_reset(&buf);
235
- strbuf_addstr(&buf, rsync_url(transport->url));
236
- strbuf_addstr(&buf, "/packed-refs");
237
-
238
- args[2] = buf.buf;
239
-
240
- if (run_command(&rsync))
241
- die ("Could not run rsync to get refs");
242
-
243
- /* read the copied refs */
244
-
245
- strbuf_addstr(&temp_dir, "/refs");
246
- read_loose_refs(&temp_dir, temp_dir_len + 1, &tail);
247
- strbuf_setlen(&temp_dir, temp_dir_len);
248
-
249
- tail = &dummy;
250
- strbuf_addstr(&temp_dir, "/packed-refs");
251
- insert_packed_refs(temp_dir.buf, &tail);
252
- strbuf_setlen(&temp_dir, temp_dir_len);
253
-
254
- if (remove_dir_recursively(&temp_dir, 0))
255
- warning ("Error removing temporary directory %s.",
256
- temp_dir.buf);
257
-
258
- strbuf_release(&buf);
259
- strbuf_release(&temp_dir);
260
-
261
- return dummy.next;
262
-}
263
-
264
-static int fetch_objs_via_rsync(struct transport *transport,
265
- int nr_objs, struct ref **to_fetch)
266
-{
267
- struct child_process rsync = CHILD_PROCESS_INIT;
268
-
269
- rsync.stdout_to_stderr = 1;
270
- argv_array_push(&rsync.args, "rsync");
271
- argv_array_push(&rsync.args, (transport->verbose > 1) ? "-rv" : "-r");
272
- argv_array_push(&rsync.args, "--ignore-existing");
273
- argv_array_push(&rsync.args, "--exclude");
274
- argv_array_push(&rsync.args, "info");
275
- argv_array_pushf(&rsync.args, "%s/objects/", rsync_url(transport->url));
276
- argv_array_push(&rsync.args, get_object_directory());
277
-
278
- /* NEEDSWORK: handle one level of alternates */
279
- return run_command(&rsync);
280
-}
281
-
282
-static int write_one_ref(const char *name, const struct object_id *oid,
283
- int flags, void *data)
284
-{
285
- struct strbuf *buf = data;
286
- int len = buf->len;
287
-
288
- /* when called via for_each_ref(), flags is non-zero */
289
- if (flags && !starts_with(name, "refs/heads/") &&
290
- !starts_with(name, "refs/tags/"))
291
- return 0;
292
-
293
- strbuf_addstr(buf, name);
294
- if (safe_create_leading_directories(buf->buf) ||
295
- write_file_gently(buf->buf, "%s", oid_to_hex(oid)))
296
- return error("problems writing temporary file %s: %s",
297
- buf->buf, strerror(errno));
298
- strbuf_setlen(buf, len);
299
- return 0;
300
-}
301
-
302
-static int write_refs_to_temp_dir(struct strbuf *temp_dir,
303
- int refspec_nr, const char **refspec)
304
-{
305
- int i;
306
-
307
- for (i = 0; i < refspec_nr; i++) {
308
- struct object_id oid;
309
- char *ref;
310
-
311
- if (dwim_ref(refspec[i], strlen(refspec[i]), oid.hash, &ref) != 1)
312
- return error("Could not get ref %s", refspec[i]);
313
-
314
- if (write_one_ref(ref, &oid, 0, temp_dir)) {
315
- free(ref);
316
- return -1;
317
- }
318
- free(ref);
319
- }
320
- return 0;
321
-}
322
-
323
-static int rsync_transport_push(struct transport *transport,
324
- int refspec_nr, const char **refspec, int flags)
325
-{
326
- struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;
327
- int result = 0, i;
328
- struct child_process rsync = CHILD_PROCESS_INIT;
329
- const char *args[10];
330
-
331
- if (flags & TRANSPORT_PUSH_MIRROR)
332
- return error("rsync transport does not support mirror mode");
333
-
334
- /* first push the objects */
335
-
336
- strbuf_addstr(&buf, rsync_url(transport->url));
337
- strbuf_addch(&buf, '/');
338
-
339
- rsync.argv = args;
340
- rsync.stdout_to_stderr = 1;
341
- i = 0;
342
- args[i++] = "rsync";
343
- args[i++] = "-a";
344
- if (flags & TRANSPORT_PUSH_DRY_RUN)
345
- args[i++] = "--dry-run";
346
- if (transport->verbose > 1)
347
- args[i++] = "-v";
348
- args[i++] = "--ignore-existing";
349
- args[i++] = "--exclude";
350
- args[i++] = "info";
351
- args[i++] = get_object_directory();
352
- args[i++] = buf.buf;
353
- args[i++] = NULL;
354
-
355
- if (run_command(&rsync))
356
- return error("Could not push objects to %s",
357
- rsync_url(transport->url));
358
-
359
- /* copy the refs to the temporary directory; they could be packed. */
360
-
361
- strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
362
- if (!mkdtemp(temp_dir.buf))
363
- die_errno ("Could not make temporary directory");
364
- strbuf_addch(&temp_dir, '/');
365
-
366
- if (flags & TRANSPORT_PUSH_ALL) {
367
- if (for_each_ref(write_one_ref, &temp_dir))
368
- return -1;
369
- } else if (write_refs_to_temp_dir(&temp_dir, refspec_nr, refspec))
370
- return -1;
371
-
372
- i = 2;
373
- if (flags & TRANSPORT_PUSH_DRY_RUN)
374
- args[i++] = "--dry-run";
375
- if (!(flags & TRANSPORT_PUSH_FORCE))
376
- args[i++] = "--ignore-existing";
377
- args[i++] = temp_dir.buf;
378
- args[i++] = rsync_url(transport->url);
379
- args[i++] = NULL;
380
- if (run_command(&rsync))
381
- result = error("Could not push to %s",
382
- rsync_url(transport->url));
383
-
384
- if (remove_dir_recursively(&temp_dir, 0))
385
- warning ("Could not remove temporary directory %s.",
386
- temp_dir.buf);
387
-
388
- strbuf_release(&buf);
389
- strbuf_release(&temp_dir);
390
-
391
- return result;
392
-}
393
-
68
struct bundle_transport_data {
69
int fd;
70
struct bundle_header header;
658
if (helper) {
659
transport_helper_init(ret, helper);
660
} else if (starts_with(url, "rsync:")) {
987
- transport_check_allowed("rsync");
988
- ret->get_refs_list = get_refs_via_rsync;
989
- ret->fetch = fetch_objs_via_rsync;
990
- ret->push = rsync_transport_push;
991
- ret->smart_options = NULL;
661
+ die("git-over-rsync is no longer supported");
662
} else if (url_is_local_not_ssh(url) && is_file(url) && is_bundle(url, 1)) {
663
struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
664
transport_check_allowed("file");