Merge branch 'sg/httpd-test-unflake'
[git] / bundle.c
1 #include "cache.h"
2 #include "lockfile.h"
3 #include "bundle.h"
4 #include "object-store.h"
5 #include "object.h"
6 #include "commit.h"
7 #include "diff.h"
8 #include "revision.h"
9 #include "list-objects.h"
10 #include "run-command.h"
11 #include "refs.h"
12 #include "argv-array.h"
13
14 static const char bundle_signature[] = "# v2 git bundle\n";
15
16 static void add_to_ref_list(const struct object_id *oid, const char *name,
17                 struct ref_list *list)
18 {
19         ALLOC_GROW(list->list, list->nr + 1, list->alloc);
20         oidcpy(&list->list[list->nr].oid, oid);
21         list->list[list->nr].name = xstrdup(name);
22         list->nr++;
23 }
24
25 static int parse_bundle_header(int fd, struct bundle_header *header,
26                                const char *report_path)
27 {
28         struct strbuf buf = STRBUF_INIT;
29         int status = 0;
30
31         /* The bundle header begins with the signature */
32         if (strbuf_getwholeline_fd(&buf, fd, '\n') ||
33             strcmp(buf.buf, bundle_signature)) {
34                 if (report_path)
35                         error(_("'%s' does not look like a v2 bundle file"),
36                               report_path);
37                 status = -1;
38                 goto abort;
39         }
40
41         /* The bundle header ends with an empty line */
42         while (!strbuf_getwholeline_fd(&buf, fd, '\n') &&
43                buf.len && buf.buf[0] != '\n') {
44                 struct object_id oid;
45                 int is_prereq = 0;
46                 const char *p;
47
48                 if (*buf.buf == '-') {
49                         is_prereq = 1;
50                         strbuf_remove(&buf, 0, 1);
51                 }
52                 strbuf_rtrim(&buf);
53
54                 /*
55                  * Tip lines have object name, SP, and refname.
56                  * Prerequisites have object name that is optionally
57                  * followed by SP and subject line.
58                  */
59                 if (parse_oid_hex(buf.buf, &oid, &p) ||
60                     (*p && !isspace(*p)) ||
61                     (!is_prereq && !*p)) {
62                         if (report_path)
63                                 error(_("unrecognized header: %s%s (%d)"),
64                                       (is_prereq ? "-" : ""), buf.buf, (int)buf.len);
65                         status = -1;
66                         break;
67                 } else {
68                         if (is_prereq)
69                                 add_to_ref_list(&oid, "", &header->prerequisites);
70                         else
71                                 add_to_ref_list(&oid, p + 1, &header->references);
72                 }
73         }
74
75  abort:
76         if (status) {
77                 close(fd);
78                 fd = -1;
79         }
80         strbuf_release(&buf);
81         return fd;
82 }
83
84 int read_bundle_header(const char *path, struct bundle_header *header)
85 {
86         int fd = open(path, O_RDONLY);
87
88         if (fd < 0)
89                 return error(_("could not open '%s'"), path);
90         return parse_bundle_header(fd, header, path);
91 }
92
93 int is_bundle(const char *path, int quiet)
94 {
95         struct bundle_header header;
96         int fd = open(path, O_RDONLY);
97
98         if (fd < 0)
99                 return 0;
100         memset(&header, 0, sizeof(header));
101         fd = parse_bundle_header(fd, &header, quiet ? NULL : path);
102         if (fd >= 0)
103                 close(fd);
104         return (fd >= 0);
105 }
106
107 static int list_refs(struct ref_list *r, int argc, const char **argv)
108 {
109         int i;
110
111         for (i = 0; i < r->nr; i++) {
112                 if (argc > 1) {
113                         int j;
114                         for (j = 1; j < argc; j++)
115                                 if (!strcmp(r->list[i].name, argv[j]))
116                                         break;
117                         if (j == argc)
118                                 continue;
119                 }
120                 printf("%s %s\n", oid_to_hex(&r->list[i].oid),
121                                 r->list[i].name);
122         }
123         return 0;
124 }
125
126 /* Remember to update object flag allocation in object.h */
127 #define PREREQ_MARK (1u<<16)
128
129 int verify_bundle(struct bundle_header *header, int verbose)
130 {
131         /*
132          * Do fast check, then if any prereqs are missing then go line by line
133          * to be verbose about the errors
134          */
135         struct ref_list *p = &header->prerequisites;
136         struct rev_info revs;
137         const char *argv[] = {NULL, "--all", NULL};
138         struct commit *commit;
139         int i, ret = 0, req_nr;
140         const char *message = _("Repository lacks these prerequisite commits:");
141
142         init_revisions(&revs, NULL);
143         for (i = 0; i < p->nr; i++) {
144                 struct ref_list_entry *e = p->list + i;
145                 struct object *o = parse_object(&e->oid);
146                 if (o) {
147                         o->flags |= PREREQ_MARK;
148                         add_pending_object(&revs, o, e->name);
149                         continue;
150                 }
151                 if (++ret == 1)
152                         error("%s", message);
153                 error("%s %s", oid_to_hex(&e->oid), e->name);
154         }
155         if (revs.pending.nr != p->nr)
156                 return ret;
157         req_nr = revs.pending.nr;
158         setup_revisions(2, argv, &revs, NULL);
159
160         if (prepare_revision_walk(&revs))
161                 die(_("revision walk setup failed"));
162
163         i = req_nr;
164         while (i && (commit = get_revision(&revs)))
165                 if (commit->object.flags & PREREQ_MARK)
166                         i--;
167
168         for (i = 0; i < p->nr; i++) {
169                 struct ref_list_entry *e = p->list + i;
170                 struct object *o = parse_object(&e->oid);
171                 assert(o); /* otherwise we'd have returned early */
172                 if (o->flags & SHOWN)
173                         continue;
174                 if (++ret == 1)
175                         error("%s", message);
176                 error("%s %s", oid_to_hex(&e->oid), e->name);
177         }
178
179         /* Clean up objects used, as they will be reused. */
180         for (i = 0; i < p->nr; i++) {
181                 struct ref_list_entry *e = p->list + i;
182                 commit = lookup_commit_reference_gently(&e->oid, 1);
183                 if (commit)
184                         clear_commit_marks(commit, ALL_REV_FLAGS);
185         }
186
187         if (verbose) {
188                 struct ref_list *r;
189
190                 r = &header->references;
191                 printf_ln(Q_("The bundle contains this ref:",
192                              "The bundle contains these %d refs:",
193                              r->nr),
194                           r->nr);
195                 list_refs(r, 0, NULL);
196                 r = &header->prerequisites;
197                 if (!r->nr) {
198                         printf_ln(_("The bundle records a complete history."));
199                 } else {
200                         printf_ln(Q_("The bundle requires this ref:",
201                                      "The bundle requires these %d refs:",
202                                      r->nr),
203                                   r->nr);
204                         list_refs(r, 0, NULL);
205                 }
206         }
207         return ret;
208 }
209
210 int list_bundle_refs(struct bundle_header *header, int argc, const char **argv)
211 {
212         return list_refs(&header->references, argc, argv);
213 }
214
215 static int is_tag_in_date_range(struct object *tag, struct rev_info *revs)
216 {
217         unsigned long size;
218         enum object_type type;
219         char *buf = NULL, *line, *lineend;
220         timestamp_t date;
221         int result = 1;
222
223         if (revs->max_age == -1 && revs->min_age == -1)
224                 goto out;
225
226         buf = read_object_file(&tag->oid, &type, &size);
227         if (!buf)
228                 goto out;
229         line = memmem(buf, size, "\ntagger ", 8);
230         if (!line++)
231                 goto out;
232         lineend = memchr(line, '\n', buf + size - line);
233         line = memchr(line, '>', lineend ? lineend - line : buf + size - line);
234         if (!line++)
235                 goto out;
236         date = parse_timestamp(line, NULL, 10);
237         result = (revs->max_age == -1 || revs->max_age < date) &&
238                 (revs->min_age == -1 || revs->min_age > date);
239 out:
240         free(buf);
241         return result;
242 }
243
244
245 /* Write the pack data to bundle_fd, then close it if it is > 1. */
246 static int write_pack_data(int bundle_fd, struct rev_info *revs)
247 {
248         struct child_process pack_objects = CHILD_PROCESS_INIT;
249         int i;
250
251         argv_array_pushl(&pack_objects.args,
252                          "pack-objects", "--all-progress-implied",
253                          "--stdout", "--thin", "--delta-base-offset",
254                          NULL);
255         pack_objects.in = -1;
256         pack_objects.out = bundle_fd;
257         pack_objects.git_cmd = 1;
258         if (start_command(&pack_objects))
259                 return error(_("Could not spawn pack-objects"));
260
261         for (i = 0; i < revs->pending.nr; i++) {
262                 struct object *object = revs->pending.objects[i].item;
263                 if (object->flags & UNINTERESTING)
264                         write_or_die(pack_objects.in, "^", 1);
265                 write_or_die(pack_objects.in, oid_to_hex(&object->oid), GIT_SHA1_HEXSZ);
266                 write_or_die(pack_objects.in, "\n", 1);
267         }
268         close(pack_objects.in);
269         if (finish_command(&pack_objects))
270                 return error(_("pack-objects died"));
271         return 0;
272 }
273
274 static int compute_and_write_prerequisites(int bundle_fd,
275                                            struct rev_info *revs,
276                                            int argc, const char **argv)
277 {
278         struct child_process rls = CHILD_PROCESS_INIT;
279         struct strbuf buf = STRBUF_INIT;
280         FILE *rls_fout;
281         int i;
282
283         argv_array_pushl(&rls.args,
284                          "rev-list", "--boundary", "--pretty=oneline",
285                          NULL);
286         for (i = 1; i < argc; i++)
287                 argv_array_push(&rls.args, argv[i]);
288         rls.out = -1;
289         rls.git_cmd = 1;
290         if (start_command(&rls))
291                 return -1;
292         rls_fout = xfdopen(rls.out, "r");
293         while (strbuf_getwholeline(&buf, rls_fout, '\n') != EOF) {
294                 struct object_id oid;
295                 if (buf.len > 0 && buf.buf[0] == '-') {
296                         write_or_die(bundle_fd, buf.buf, buf.len);
297                         if (!get_oid_hex(buf.buf + 1, &oid)) {
298                                 struct object *object = parse_object_or_die(&oid,
299                                                                             buf.buf);
300                                 object->flags |= UNINTERESTING;
301                                 add_pending_object(revs, object, buf.buf);
302                         }
303                 } else if (!get_oid_hex(buf.buf, &oid)) {
304                         struct object *object = parse_object_or_die(&oid,
305                                                                     buf.buf);
306                         object->flags |= SHOWN;
307                 }
308         }
309         strbuf_release(&buf);
310         fclose(rls_fout);
311         if (finish_command(&rls))
312                 return error(_("rev-list died"));
313         return 0;
314 }
315
316 /*
317  * Write out bundle refs based on the tips already
318  * parsed into revs.pending. As a side effect, may
319  * manipulate revs.pending to include additional
320  * necessary objects (like tags).
321  *
322  * Returns the number of refs written, or negative
323  * on error.
324  */
325 static int write_bundle_refs(int bundle_fd, struct rev_info *revs)
326 {
327         int i;
328         int ref_count = 0;
329
330         for (i = 0; i < revs->pending.nr; i++) {
331                 struct object_array_entry *e = revs->pending.objects + i;
332                 struct object_id oid;
333                 char *ref;
334                 const char *display_ref;
335                 int flag;
336
337                 if (e->item->flags & UNINTERESTING)
338                         continue;
339                 if (dwim_ref(e->name, strlen(e->name), &oid, &ref) != 1)
340                         goto skip_write_ref;
341                 if (read_ref_full(e->name, RESOLVE_REF_READING, &oid, &flag))
342                         flag = 0;
343                 display_ref = (flag & REF_ISSYMREF) ? e->name : ref;
344
345                 if (e->item->type == OBJ_TAG &&
346                                 !is_tag_in_date_range(e->item, revs)) {
347                         e->item->flags |= UNINTERESTING;
348                         goto skip_write_ref;
349                 }
350
351                 /*
352                  * Make sure the refs we wrote out is correct; --max-count and
353                  * other limiting options could have prevented all the tips
354                  * from getting output.
355                  *
356                  * Non commit objects such as tags and blobs do not have
357                  * this issue as they are not affected by those extra
358                  * constraints.
359                  */
360                 if (!(e->item->flags & SHOWN) && e->item->type == OBJ_COMMIT) {
361                         warning(_("ref '%s' is excluded by the rev-list options"),
362                                 e->name);
363                         goto skip_write_ref;
364                 }
365                 /*
366                  * If you run "git bundle create bndl v1.0..v2.0", the
367                  * name of the positive ref is "v2.0" but that is the
368                  * commit that is referenced by the tag, and not the tag
369                  * itself.
370                  */
371                 if (oidcmp(&oid, &e->item->oid)) {
372                         /*
373                          * Is this the positive end of a range expressed
374                          * in terms of a tag (e.g. v2.0 from the range
375                          * "v1.0..v2.0")?
376                          */
377                         struct commit *one = lookup_commit_reference(&oid);
378                         struct object *obj;
379
380                         if (e->item == &(one->object)) {
381                                 /*
382                                  * Need to include e->name as an
383                                  * independent ref to the pack-objects
384                                  * input, so that the tag is included
385                                  * in the output; otherwise we would
386                                  * end up triggering "empty bundle"
387                                  * error.
388                                  */
389                                 obj = parse_object_or_die(&oid, e->name);
390                                 obj->flags |= SHOWN;
391                                 add_pending_object(revs, obj, e->name);
392                         }
393                         goto skip_write_ref;
394                 }
395
396                 ref_count++;
397                 write_or_die(bundle_fd, oid_to_hex(&e->item->oid), 40);
398                 write_or_die(bundle_fd, " ", 1);
399                 write_or_die(bundle_fd, display_ref, strlen(display_ref));
400                 write_or_die(bundle_fd, "\n", 1);
401  skip_write_ref:
402                 free(ref);
403         }
404
405         /* end header */
406         write_or_die(bundle_fd, "\n", 1);
407         return ref_count;
408 }
409
410 int create_bundle(struct bundle_header *header, const char *path,
411                   int argc, const char **argv)
412 {
413         struct lock_file lock = LOCK_INIT;
414         int bundle_fd = -1;
415         int bundle_to_stdout;
416         int ref_count = 0;
417         struct rev_info revs;
418
419         bundle_to_stdout = !strcmp(path, "-");
420         if (bundle_to_stdout)
421                 bundle_fd = 1;
422         else {
423                 bundle_fd = hold_lock_file_for_update(&lock, path,
424                                                       LOCK_DIE_ON_ERROR);
425
426                 /*
427                  * write_pack_data() will close the fd passed to it,
428                  * but commit_lock_file() will also try to close the
429                  * lockfile's fd. So make a copy of the file
430                  * descriptor to avoid trying to close it twice.
431                  */
432                 bundle_fd = dup(bundle_fd);
433                 if (bundle_fd < 0)
434                         die_errno("unable to dup file descriptor");
435         }
436
437         /* write signature */
438         write_or_die(bundle_fd, bundle_signature, strlen(bundle_signature));
439
440         /* init revs to list objects for pack-objects later */
441         save_commit_buffer = 0;
442         init_revisions(&revs, NULL);
443
444         /* write prerequisites */
445         if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv))
446                 goto err;
447
448         argc = setup_revisions(argc, argv, &revs, NULL);
449
450         if (argc > 1) {
451                 error(_("unrecognized argument: %s"), argv[1]);
452                 goto err;
453         }
454
455         object_array_remove_duplicates(&revs.pending);
456
457         ref_count = write_bundle_refs(bundle_fd, &revs);
458         if (!ref_count)
459                 die(_("Refusing to create empty bundle."));
460         else if (ref_count < 0)
461                 goto err;
462
463         /* write pack */
464         if (write_pack_data(bundle_fd, &revs)) {
465                 bundle_fd = -1; /* already closed by the above call */
466                 goto err;
467         }
468
469         if (!bundle_to_stdout) {
470                 if (commit_lock_file(&lock))
471                         die_errno(_("cannot create '%s'"), path);
472         }
473         return 0;
474 err:
475         if (!bundle_to_stdout) {
476                 if (0 <= bundle_fd)
477                         close(bundle_fd);
478                 rollback_lock_file(&lock);
479         }
480         return -1;
481 }
482
483 int unbundle(struct bundle_header *header, int bundle_fd, int flags)
484 {
485         const char *argv_index_pack[] = {"index-pack",
486                                          "--fix-thin", "--stdin", NULL, NULL};
487         struct child_process ip = CHILD_PROCESS_INIT;
488
489         if (flags & BUNDLE_VERBOSE)
490                 argv_index_pack[3] = "-v";
491
492         if (verify_bundle(header, 0))
493                 return -1;
494         ip.argv = argv_index_pack;
495         ip.in = bundle_fd;
496         ip.no_stdout = 1;
497         ip.git_cmd = 1;
498         if (run_command(&ip))
499                 return error(_("index-pack died"));
500         return 0;
501 }