Raw
1 /*
2 * "git fast-export" builtin command
3 *
4 * Copyright (C) 2007 Johannes E. Schindelin
5 */
6
7 #define USE_THE_REPOSITORY_VARIABLE
8 #define DISABLE_SIGN_COMPARE_WARNINGS
9
10 #include "builtin.h"
11 #include "config.h"
12 #include "environment.h"
13 #include "gettext.h"
14 #include "hex.h"
15 #include "refs.h"
16 #include "refspec.h"
17 #include "object-file.h"
18 #include "odb.h"
19 #include "commit.h"
20 #include "object.h"
21 #include "tag.h"
22 #include "diff.h"
23 #include "diffcore.h"
24 #include "log-tree.h"
25 #include "revision.h"
26 #include "decorate.h"
27 #include "string-list.h"
28 #include "utf8.h"
29 #include "parse-options.h"
30 #include "quote.h"
31 #include "remote.h"
32 #include "blob.h"
33 #include "gpg-interface.h"
34
35 static const char *const fast_export_usage[] = {
36 N_("git fast-export [<options>] [<revision-range>] [[--] <path>...]"),
37 NULL
38 };
39
40 static int progress;
41 static enum sign_mode signed_tag_mode = SIGN_ABORT;
42 static enum sign_mode signed_commit_mode = SIGN_STRIP;
43 static enum tag_of_filtered_mode { TAG_FILTERING_ABORT, DROP, REWRITE } tag_of_filtered_mode = TAG_FILTERING_ABORT;
44 static enum reencode_mode { REENCODE_ABORT, REENCODE_YES, REENCODE_NO } reencode_mode = REENCODE_ABORT;
45 static int fake_missing_tagger;
46 static int use_done_feature;
47 static int no_data;
48 static int full_tree;
49 static int reference_excluded_commits;
50 static int show_original_ids;
51 static int mark_tags;
52 static struct string_list extra_refs = STRING_LIST_INIT_DUP;
53 static struct string_list tag_refs = STRING_LIST_INIT_DUP;
54 static struct refspec refspecs;
55 static int anonymize;
56 static struct hashmap anonymized_seeds;
57 static struct revision_sources revision_sources;
58
59 static int parse_opt_sign_mode(const struct option *opt,
60 const char *arg, int unset)
61 {
62 enum sign_mode *val = opt->value;
63
64 if (unset)
65 return 0;
66
67 if (parse_sign_mode(arg, val, NULL) || (*val == SIGN_STRIP_IF_INVALID) ||
68 (*val == SIGN_SIGN_IF_INVALID) || (*val == SIGN_ABORT_IF_INVALID))
69 return error(_("unknown %s mode: %s"), opt->long_name, arg);
70
71 return 0;
72 }
73
74 static int parse_opt_tag_of_filtered_mode(const struct option *opt,
75 const char *arg, int unset)
76 {
77 enum tag_of_filtered_mode *val = opt->value;
78
79 if (unset || !strcmp(arg, "abort"))
80 *val = TAG_FILTERING_ABORT;
81 else if (!strcmp(arg, "drop"))
82 *val = DROP;
83 else if (!strcmp(arg, "rewrite"))
84 *val = REWRITE;
85 else
86 return error(_("unknown tag-of-filtered mode: %s"), arg);
87 return 0;
88 }
89
90 static int parse_opt_reencode_mode(const struct option *opt,
91 const char *arg, int unset)
92 {
93 enum reencode_mode *val = opt->value;
94
95 if (unset) {
96 *val = REENCODE_ABORT;
97 return 0;
98 }
99
100 switch (git_parse_maybe_bool(arg)) {
101 case 0:
102 *val = REENCODE_NO;
103 break;
104 case 1:
105 *val = REENCODE_YES;
106 break;
107 default:
108 if (!strcasecmp(arg, "abort"))
109 *val = REENCODE_ABORT;
110 else
111 return error(_("unknown reencoding mode: %s"), arg);
112 }
113
114 return 0;
115 }
116
117 static struct decoration idnums;
118 static uint32_t last_idnum;
119 struct anonymized_entry {
120 struct hashmap_entry hash;
121 char *anon;
122 const char orig[FLEX_ARRAY];
123 };
124
125 struct anonymized_entry_key {
126 struct hashmap_entry hash;
127 const char *orig;
128 size_t orig_len;
129 };
130
131 static int anonymized_entry_cmp(const void *cmp_data UNUSED,
132 const struct hashmap_entry *eptr,
133 const struct hashmap_entry *entry_or_key,
134 const void *keydata)
135 {
136 const struct anonymized_entry *a, *b;
137
138 a = container_of(eptr, const struct anonymized_entry, hash);
139 if (keydata) {
140 const struct anonymized_entry_key *key = keydata;
141 int equal = !xstrncmpz(a->orig, key->orig, key->orig_len);
142 return !equal;
143 }
144
145 b = container_of(entry_or_key, const struct anonymized_entry, hash);
146 return strcmp(a->orig, b->orig);
147 }
148
149 static struct anonymized_entry *add_anonymized_entry(struct hashmap *map,
150 unsigned hash,
151 const char *orig, size_t len,
152 char *anon)
153 {
154 struct anonymized_entry *ret, *old;
155
156 if (!map->cmpfn)
157 hashmap_init(map, anonymized_entry_cmp, NULL, 0);
158
159 FLEX_ALLOC_MEM(ret, orig, orig, len);
160 hashmap_entry_init(&ret->hash, hash);
161 ret->anon = anon;
162 old = hashmap_put_entry(map, ret, hash);
163
164 if (old) {
165 free(old->anon);
166 free(old);
167 }
168
169 return ret;
170 }
171
172 /*
173 * Basically keep a cache of X->Y so that we can repeatedly replace
174 * the same anonymized string with another. The actual generation
175 * is farmed out to the generate function.
176 */
177 static const char *anonymize_str(struct hashmap *map,
178 char *(*generate)(void),
179 const char *orig, size_t len)
180 {
181 struct anonymized_entry_key key;
182 struct anonymized_entry *ret;
183
184 hashmap_entry_init(&key.hash, memhash(orig, len));
185 key.orig = orig;
186 key.orig_len = len;
187
188 /* First check if it's a token the user configured manually... */
189 ret = hashmap_get_entry(&anonymized_seeds, &key, hash, &key);
190
191 /* ...otherwise check if we've already seen it in this context... */
192 if (!ret)
193 ret = hashmap_get_entry(map, &key, hash, &key);
194
195 /* ...and finally generate a new mapping if necessary */
196 if (!ret)
197 ret = add_anonymized_entry(map, key.hash.hash,
198 orig, len, generate());
199
200 return ret->anon;
201 }
202
203 /*
204 * We anonymize each component of a path individually,
205 * so that paths a/b and a/c will share a common root.
206 * The paths are cached via anonymize_mem so that repeated
207 * lookups for "a" will yield the same value.
208 */
209 static void anonymize_path(struct strbuf *out, const char *path,
210 struct hashmap *map,
211 char *(*generate)(void))
212 {
213 while (*path) {
214 const char *end_of_component = strchrnul(path, '/');
215 size_t len = end_of_component - path;
216 const char *c = anonymize_str(map, generate, path, len);
217 strbuf_addstr(out, c);
218 path = end_of_component;
219 if (*path)
220 strbuf_addch(out, *path++);
221 }
222 }
223
224 static inline void *mark_to_ptr(uint32_t mark)
225 {
226 return (void *)(uintptr_t)mark;
227 }
228
229 static inline uint32_t ptr_to_mark(void * mark)
230 {
231 return (uint32_t)(uintptr_t)mark;
232 }
233
234 static inline void mark_object(struct object *object, uint32_t mark)
235 {
236 add_decoration(&idnums, object, mark_to_ptr(mark));
237 }
238
239 static inline void mark_next_object(struct object *object)
240 {
241 mark_object(object, ++last_idnum);
242 }
243
244 static int get_object_mark(struct object *object)
245 {
246 void *decoration = lookup_decoration(&idnums, object);
247 if (!decoration)
248 return 0;
249 return ptr_to_mark(decoration);
250 }
251
252 static struct commit *rewrite_commit(struct commit *p)
253 {
254 for (;;) {
255 if (p->parents && p->parents->next)
256 break;
257 if (p->object.flags & UNINTERESTING)
258 break;
259 if (!(p->object.flags & TREESAME))
260 break;
261 if (!p->parents)
262 return NULL;
263 p = p->parents->item;
264 }
265 return p;
266 }
267
268 static void show_progress(void)
269 {
270 static int counter = 0;
271 if (!progress)
272 return;
273 if ((++counter % progress) == 0)
274 printf("progress %d objects\n", counter);
275 }
276
277 /*
278 * Ideally we would want some transformation of the blob data here
279 * that is unreversible, but would still be the same size and have
280 * the same data relationship to other blobs (so that we get the same
281 * delta and packing behavior as the original). But the first and last
282 * requirements there are probably mutually exclusive, so let's take
283 * the easy way out for now, and just generate arbitrary content.
284 *
285 * There's no need to cache this result with anonymize_mem, since
286 * we already handle blob content caching with marks.
287 */
288 static char *anonymize_blob(unsigned long *size)
289 {
290 static int counter;
291 struct strbuf out = STRBUF_INIT;
292 strbuf_addf(&out, "anonymous blob %d", counter++);
293 *size = out.len;
294 return strbuf_detach(&out, NULL);
295 }
296
297 static void export_blob(const struct object_id *oid)
298 {
299 unsigned long size;
300 enum object_type type;
301 char *buf;
302 struct object *object;
303 int eaten;
304
305 if (no_data)
306 return;
307
308 if (is_null_oid(oid))
309 return;
310
311 object = lookup_object(the_repository, oid);
312 if (object && object->flags & SHOWN)
313 return;
314
315 if (anonymize) {
316 buf = anonymize_blob(&size);
317 object = (struct object *)lookup_blob(the_repository, oid);
318 eaten = 0;
319 } else {
320 size_t size_st = 0;
321 buf = odb_read_object(the_repository->objects, oid, &type,
322 &size_st);
323 size = cast_size_t_to_ulong(size_st);
324 if (!buf)
325 die(_("could not read blob %s"), oid_to_hex(oid));
326 if (check_object_signature(the_repository, oid, buf, size,
327 type) < 0)
328 die(_("oid mismatch in blob %s"), oid_to_hex(oid));
329 object = parse_object_buffer(the_repository, oid, type,
330 size, buf, &eaten);
331 }
332
333 if (!object)
334 die(_("could not read blob %s"), oid_to_hex(oid));
335
336 mark_next_object(object);
337
338 printf("blob\nmark :%"PRIu32"\n", last_idnum);
339 if (show_original_ids)
340 printf("original-oid %s\n", oid_to_hex(oid));
341 printf("data %"PRIuMAX"\n", (uintmax_t)size);
342 if (size && fwrite(buf, size, 1, stdout) != 1)
343 die_errno(_("could not write blob '%s'"), oid_to_hex(oid));
344 printf("\n");
345
346 show_progress();
347
348 object->flags |= SHOWN;
349 if (!eaten)
350 free(buf);
351 }
352
353 static int depth_first(const void *a_, const void *b_)
354 {
355 const struct diff_filepair *a = *((const struct diff_filepair **)a_);
356 const struct diff_filepair *b = *((const struct diff_filepair **)b_);
357 const char *name_a, *name_b;
358 int len_a, len_b, len;
359 int cmp;
360
361 name_a = a->one ? a->one->path : a->two->path;
362 name_b = b->one ? b->one->path : b->two->path;
363
364 len_a = strlen(name_a);
365 len_b = strlen(name_b);
366 len = (len_a < len_b) ? len_a : len_b;
367
368 /* strcmp will sort 'd' before 'd/e', we want 'd/e' before 'd' */
369 cmp = memcmp(name_a, name_b, len);
370 if (cmp)
371 return cmp;
372 cmp = len_b - len_a;
373 if (cmp)
374 return cmp;
375 /*
376 * Move 'R'ename entries last so that all references of the file
377 * appear in the output before it is renamed (e.g., when a file
378 * was copied and renamed in the same commit).
379 */
380 return (a->status == 'R') - (b->status == 'R');
381 }
382
383 static void print_path_1(const char *path)
384 {
385 int need_quote = quote_c_style(path, NULL, NULL, 0);
386 if (need_quote)
387 quote_c_style(path, NULL, stdout, 0);
388 else if (strchr(path, ' '))
389 printf("\"%s\"", path);
390 else
391 printf("%s", path);
392 }
393
394 static char *anonymize_path_component(void)
395 {
396 static int counter;
397 struct strbuf out = STRBUF_INIT;
398 strbuf_addf(&out, "path%d", counter++);
399 return strbuf_detach(&out, NULL);
400 }
401
402 static void print_path(const char *path)
403 {
404 if (!anonymize)
405 print_path_1(path);
406 else {
407 static struct hashmap paths;
408 static struct strbuf anon = STRBUF_INIT;
409
410 anonymize_path(&anon, path, &paths, anonymize_path_component);
411 print_path_1(anon.buf);
412 strbuf_reset(&anon);
413 }
414 }
415
416 static char *generate_fake_oid(void)
417 {
418 static uint32_t counter = 1; /* avoid null oid */
419 const unsigned hashsz = the_hash_algo->rawsz;
420 struct object_id oid;
421 char *hex = xmallocz(GIT_MAX_HEXSZ);
422
423 oidclr(&oid, the_repository->hash_algo);
424 put_be32(oid.hash + hashsz - 4, counter++);
425 return oid_to_hex_r(hex, &oid);
426 }
427
428 static const char *anonymize_oid(const char *oid_hex)
429 {
430 static struct hashmap objs;
431 size_t len = strlen(oid_hex);
432 return anonymize_str(&objs, generate_fake_oid, oid_hex, len);
433 }
434
435 static void show_filemodify(struct diff_queue_struct *q,
436 struct diff_options *options UNUSED, void *data)
437 {
438 int i;
439 struct string_list *changed = data;
440
441 /*
442 * Handle files below a directory first, in case they are all deleted
443 * and the directory changes to a file or symlink.
444 */
445 QSORT(q->queue, q->nr, depth_first);
446
447 for (i = 0; i < q->nr; i++) {
448 struct diff_filespec *ospec = q->queue[i]->one;
449 struct diff_filespec *spec = q->queue[i]->two;
450
451 switch (q->queue[i]->status) {
452 case DIFF_STATUS_DELETED:
453 printf("D ");
454 print_path(spec->path);
455 string_list_insert(changed, spec->path);
456 putchar('\n');
457 break;
458
459 case DIFF_STATUS_COPIED:
460 case DIFF_STATUS_RENAMED:
461 /*
462 * If a change in the file corresponding to ospec->path
463 * has been observed, we cannot trust its contents
464 * because the diff is calculated based on the prior
465 * contents, not the current contents. So, declare a
466 * copy or rename only if there was no change observed.
467 */
468 if (!string_list_has_string(changed, ospec->path)) {
469 printf("%c ", q->queue[i]->status);
470 print_path(ospec->path);
471 putchar(' ');
472 print_path(spec->path);
473 string_list_insert(changed, spec->path);
474 putchar('\n');
475
476 if (oideq(&ospec->oid, &spec->oid) &&
477 ospec->mode == spec->mode)
478 break;
479 }
480 /* fallthrough */
481
482 case DIFF_STATUS_TYPE_CHANGED:
483 case DIFF_STATUS_MODIFIED:
484 case DIFF_STATUS_ADDED:
485 /*
486 * Links refer to objects in another repositories;
487 * output the SHA-1 verbatim.
488 */
489 if (no_data || S_ISGITLINK(spec->mode))
490 printf("M %06o %s ", spec->mode,
491 anonymize ?
492 anonymize_oid(oid_to_hex(&spec->oid)) :
493 oid_to_hex(&spec->oid));
494 else {
495 struct object *object = lookup_object(the_repository,
496 &spec->oid);
497 printf("M %06o :%d ", spec->mode,
498 get_object_mark(object));
499 }
500 print_path(spec->path);
501 string_list_insert(changed, spec->path);
502 putchar('\n');
503 break;
504
505 default:
506 die(_("unexpected comparison status '%c' for %s, %s"),
507 q->queue[i]->status,
508 ospec->path ? ospec->path : _("none"),
509 spec->path ? spec->path : _("none"));
510 }
511 }
512 }
513
514 static char *anonymize_ref_component(void)
515 {
516 static int counter;
517 struct strbuf out = STRBUF_INIT;
518 strbuf_addf(&out, "ref%d", counter++);
519 return strbuf_detach(&out, NULL);
520 }
521
522 static const char *anonymize_refname(const char *refname)
523 {
524 /*
525 * If any of these prefixes is found, we will leave it intact
526 * so that tags remain tags and so forth.
527 */
528 static const char *prefixes[] = {
529 "refs/heads/",
530 "refs/tags/",
531 "refs/remotes/",
532 "refs/"
533 };
534 static struct hashmap refs;
535 static struct strbuf anon = STRBUF_INIT;
536 int i;
537
538 strbuf_reset(&anon);
539 for (i = 0; i < ARRAY_SIZE(prefixes); i++) {
540 if (skip_prefix(refname, prefixes[i], &refname)) {
541 strbuf_addstr(&anon, prefixes[i]);
542 break;
543 }
544 }
545
546 anonymize_path(&anon, refname, &refs, anonymize_ref_component);
547 return anon.buf;
548 }
549
550 /*
551 * We do not even bother to cache commit messages, as they are unlikely
552 * to be repeated verbatim, and it is not that interesting when they are.
553 */
554 static char *anonymize_commit_message(void)
555 {
556 static int counter;
557 return xstrfmt("subject %d\n\nbody\n", counter++);
558 }
559
560 static char *anonymize_ident(void)
561 {
562 static int counter;
563 struct strbuf out = STRBUF_INIT;
564 strbuf_addf(&out, "User %d <user%d@example.com>", counter, counter);
565 counter++;
566 return strbuf_detach(&out, NULL);
567 }
568
569 /*
570 * Our strategy here is to anonymize the names and email addresses,
571 * but keep timestamps intact, as they influence things like traversal
572 * order (and by themselves should not be too revealing).
573 */
574 static void anonymize_ident_line(const char **beg, const char **end)
575 {
576 static struct hashmap idents;
577 static struct strbuf buffers[] = { STRBUF_INIT, STRBUF_INIT };
578 static unsigned which_buffer;
579
580 struct strbuf *out;
581 struct ident_split split;
582 const char *end_of_header;
583
584 out = &buffers[which_buffer++];
585 which_buffer %= ARRAY_SIZE(buffers);
586 strbuf_reset(out);
587
588 /* skip "committer", "author", "tagger", etc */
589 end_of_header = strchr(*beg, ' ');
590 if (!end_of_header)
591 BUG("malformed line fed to anonymize_ident_line: %.*s",
592 (int)(*end - *beg), *beg);
593 end_of_header++;
594 strbuf_add(out, *beg, end_of_header - *beg);
595
596 if (!split_ident_line(&split, end_of_header, *end - end_of_header) &&
597 split.date_begin) {
598 const char *ident;
599 size_t len;
600
601 len = split.mail_end - split.name_begin;
602 ident = anonymize_str(&idents, anonymize_ident,
603 split.name_begin, len);
604 strbuf_addstr(out, ident);
605 strbuf_addch(out, ' ');
606 strbuf_add(out, split.date_begin, split.tz_end - split.date_begin);
607 } else {
608 strbuf_addstr(out, "Malformed Ident <malformed@example.com> 0 -0000");
609 }
610
611 *beg = out->buf;
612 *end = out->buf + out->len;
613 }
614
615 /*
616 * find_commit_multiline_header is similar to find_commit_header,
617 * except that it handles multi-line headers, rather than simply
618 * returning the first line of the header.
619 *
620 * The returned string has had the ' ' line continuation markers
621 * removed, and points to allocated memory that must be free()d (not
622 * to memory within 'msg').
623 *
624 * If the header is found, then *end is set to point at the '\n' in
625 * msg that immediately follows the header value.
626 */
627 static const char *find_commit_multiline_header(const char *msg,
628 const char *key,
629 const char **end)
630 {
631 struct strbuf val = STRBUF_INIT;
632 const char *bol, *eol;
633 size_t len;
634
635 bol = find_commit_header(msg, key, &len);
636 if (!bol)
637 return NULL;
638 eol = bol + len;
639 strbuf_add(&val, bol, len);
640
641 while (eol[0] == '\n' && eol[1] == ' ') {
642 bol = eol + 2;
643 eol = strchrnul(bol, '\n');
644 strbuf_addch(&val, '\n');
645 strbuf_add(&val, bol, eol - bol);
646 }
647
648 *end = eol;
649 return strbuf_detach(&val, NULL);
650 }
651
652 static void print_signature(const char *signature, const char *object_hash)
653 {
654 if (!signature)
655 return;
656
657 printf("gpgsig %s %s\ndata %u\n%s\n",
658 object_hash,
659 get_signature_format(signature),
660 (unsigned)strlen(signature),
661 signature);
662 }
663
664 static const char *append_signatures_for_header(struct string_list *signatures,
665 const char *pos,
666 const char *header,
667 const char *object_hash)
668 {
669 const char *signature;
670 const char *start = pos;
671 const char *end = pos;
672
673 while ((signature = find_commit_multiline_header(start + 1,
674 header,
675 &end))) {
676 string_list_append(signatures, signature)->util = (void *)object_hash;
677 free((char *)signature);
678 start = end;
679 }
680
681 return end;
682 }
683
684 static void handle_commit(struct commit *commit, struct rev_info *rev,
685 struct string_list *paths_of_changed_objects)
686 {
687 int saved_output_format = rev->diffopt.output_format;
688 const char *commit_buffer, *commit_buffer_cursor;
689 const char *author, *author_end, *committer, *committer_end;
690 const char *encoding = NULL;
691 size_t encoding_len;
692 struct string_list signatures = STRING_LIST_INIT_DUP;
693 const char *message;
694 char *reencoded = NULL;
695 struct commit_list *p;
696 const char *refname;
697 int i;
698
699 rev->diffopt.output_format = DIFF_FORMAT_CALLBACK;
700
701 parse_commit_or_die(commit);
702 commit_buffer_cursor = commit_buffer = repo_get_commit_buffer(the_repository, commit, NULL);
703
704 author = strstr(commit_buffer_cursor, "\nauthor ");
705 if (!author)
706 die(_("could not find author in commit %s"),
707 oid_to_hex(&commit->object.oid));
708 author++;
709 commit_buffer_cursor = author_end = strchrnul(author, '\n');
710
711 committer = strstr(commit_buffer_cursor, "\ncommitter ");
712 if (!committer)
713 die(_("could not find committer in commit %s"),
714 oid_to_hex(&commit->object.oid));
715 committer++;
716 commit_buffer_cursor = committer_end = strchrnul(committer, '\n');
717
718 /*
719 * find_commit_header() and find_commit_multiline_header() get
720 * a `+ 1` because commit_buffer_cursor points at the trailing
721 * "\n" at the end of the previous line, but they want a
722 * pointer to the beginning of the next line.
723 */
724
725 if (*commit_buffer_cursor == '\n') {
726 encoding = find_commit_header(commit_buffer_cursor + 1, "encoding", &encoding_len);
727 if (encoding)
728 commit_buffer_cursor = encoding + encoding_len;
729 }
730
731 if (*commit_buffer_cursor == '\n') {
732 const char *after_sha1 = append_signatures_for_header(&signatures, commit_buffer_cursor,
733 "gpgsig", "sha1");
734 const char *after_sha256 = append_signatures_for_header(&signatures, commit_buffer_cursor,
735 "gpgsig-sha256", "sha256");
736 commit_buffer_cursor = (after_sha1 > after_sha256) ? after_sha1 : after_sha256;
737 }
738
739 message = strstr(commit_buffer_cursor, "\n\n");
740 if (message)
741 message += 2;
742
743 if (commit->parents &&
744 (get_object_mark(&commit->parents->item->object) != 0 ||
745 reference_excluded_commits) &&
746 !full_tree) {
747 parse_commit_or_die(commit->parents->item);
748 diff_tree_oid(get_commit_tree_oid(commit->parents->item),
749 get_commit_tree_oid(commit), "", &rev->diffopt);
750 }
751 else
752 diff_root_tree_oid(get_commit_tree_oid(commit),
753 "", &rev->diffopt);
754
755 /* Export the referenced blobs, and remember the marks. */
756 for (i = 0; i < diff_queued_diff.nr; i++)
757 if (!S_ISGITLINK(diff_queued_diff.queue[i]->two->mode))
758 export_blob(&diff_queued_diff.queue[i]->two->oid);
759
760 refname = *revision_sources_at(&revision_sources, commit);
761 /*
762 * FIXME: string_list_remove() below for each ref is overall
763 * O(N^2). Compared to a history walk and diffing trees, this is
764 * just lost in the noise in practice. However, theoretically a
765 * repo may have enough refs for this to become slow.
766 */
767 string_list_remove(&extra_refs, refname, 0);
768 if (anonymize) {
769 refname = anonymize_refname(refname);
770 anonymize_ident_line(&committer, &committer_end);
771 anonymize_ident_line(&author, &author_end);
772 }
773
774 mark_next_object(&commit->object);
775 if (anonymize) {
776 reencoded = anonymize_commit_message();
777 } else if (encoding) {
778 char *buf;
779 switch (reencode_mode) {
780 case REENCODE_YES:
781 buf = xstrfmt("%.*s", (int)encoding_len, encoding);
782 reencoded = reencode_string(message, "UTF-8", buf);
783 free(buf);
784 break;
785 case REENCODE_NO:
786 break;
787 case REENCODE_ABORT:
788 die(_("encountered commit-specific encoding %.*s in commit "
789 "%s; use --reencode=[yes|no] to handle it"),
790 (int)encoding_len, encoding,
791 oid_to_hex(&commit->object.oid));
792 }
793 }
794 if (!commit->parents)
795 printf("reset %s\n", refname);
796 printf("commit %s\nmark :%"PRIu32"\n", refname, last_idnum);
797 if (show_original_ids)
798 printf("original-oid %s\n", oid_to_hex(&commit->object.oid));
799 printf("%.*s\n%.*s\n",
800 (int)(author_end - author), author,
801 (int)(committer_end - committer), committer);
802 if (signatures.nr) {
803 switch (signed_commit_mode) {
804 /* Exporting modes */
805 case SIGN_WARN_VERBATIM:
806 warning(_("exporting %"PRIuMAX" signature(s) for commit %s"),
807 (uintmax_t)signatures.nr, oid_to_hex(&commit->object.oid));
808 /* fallthru */
809 case SIGN_VERBATIM:
810 for (size_t i = 0; i < signatures.nr; i++) {
811 struct string_list_item *item = &signatures.items[i];
812 print_signature(item->string, item->util);
813 }
814 break;
815
816 /* Stripping modes */
817 case SIGN_WARN_STRIP:
818 warning(_("stripping signature(s) from commit %s"),
819 oid_to_hex(&commit->object.oid));
820 /* fallthru */
821 case SIGN_STRIP:
822 break;
823
824 /* Aborting modes */
825 case SIGN_ABORT:
826 die(_("encountered signed commit %s; use "
827 "--signed-commits=<mode> to handle it"),
828 oid_to_hex(&commit->object.oid));
829 default:
830 BUG("invalid signed_commit_mode value %d", signed_commit_mode);
831 }
832 string_list_clear(&signatures, 0);
833 }
834 if (!reencoded && encoding)
835 printf("encoding %.*s\n", (int)encoding_len, encoding);
836 printf("data %u\n%s",
837 (unsigned)(reencoded
838 ? strlen(reencoded) : message
839 ? strlen(message) : 0),
840 reencoded ? reencoded : message ? message : "");
841 free(reencoded);
842 repo_unuse_commit_buffer(the_repository, commit, commit_buffer);
843
844 for (i = 0, p = commit->parents; p; p = p->next) {
845 struct object *obj = &p->item->object;
846 int mark = get_object_mark(obj);
847
848 if (!mark && !reference_excluded_commits)
849 continue;
850 if (i == 0)
851 printf("from ");
852 else
853 printf("merge ");
854 if (mark)
855 printf(":%d\n", mark);
856 else
857 printf("%s\n",
858 anonymize ?
859 anonymize_oid(oid_to_hex(&obj->oid)) :
860 oid_to_hex(&obj->oid));
861 i++;
862 }
863
864 if (full_tree)
865 printf("deleteall\n");
866 log_tree_diff_flush(rev);
867 string_list_clear(paths_of_changed_objects, 0);
868 rev->diffopt.output_format = saved_output_format;
869
870 printf("\n");
871
872 show_progress();
873 }
874
875 static char *anonymize_tag(void)
876 {
877 static int counter;
878 struct strbuf out = STRBUF_INIT;
879 strbuf_addf(&out, "tag message %d", counter++);
880 return strbuf_detach(&out, NULL);
881 }
882
883
884 static void handle_tag(const char *name, struct tag *tag)
885 {
886 size_t size;
887 enum object_type type;
888 char *buf;
889 const char *tagger, *tagger_end, *message;
890 size_t message_size = 0;
891 struct object *tagged;
892 int tagged_mark;
893 struct commit *p;
894
895 /* Trees have no identifier in fast-export output, thus we have no way
896 * to output tags of trees, tags of tags of trees, etc. Simply omit
897 * such tags.
898 */
899 tagged = tag->tagged;
900 while (tagged->type == OBJ_TAG) {
901 tagged = ((struct tag *)tagged)->tagged;
902 }
903 if (tagged->type == OBJ_TREE) {
904 warning(_("omitting tag %s,\nsince tags of trees (or tags "
905 "of tags of trees, etc.) are not supported."),
906 oid_to_hex(&tag->object.oid));
907 return;
908 }
909
910 buf = odb_read_object(the_repository->objects, &tag->object.oid,
911 &type, &size);
912 if (!buf)
913 die(_("could not read tag %s"), oid_to_hex(&tag->object.oid));
914 message = memmem(buf, size, "\n\n", 2);
915 if (message) {
916 message += 2;
917 message_size = strlen(message);
918 }
919 tagger = memmem(buf, message ? message - buf : size, "\ntagger ", 8);
920 if (!tagger) {
921 if (fake_missing_tagger)
922 tagger = "tagger Unspecified Tagger "
923 "<unspecified-tagger> 0 +0000";
924 else
925 tagger = "";
926 tagger_end = tagger + strlen(tagger);
927 } else {
928 tagger++;
929 tagger_end = strchrnul(tagger, '\n');
930 if (anonymize)
931 anonymize_ident_line(&tagger, &tagger_end);
932 }
933
934 if (anonymize) {
935 name = anonymize_refname(name);
936 if (message) {
937 static struct hashmap tags;
938 message = anonymize_str(&tags, anonymize_tag,
939 message, message_size);
940 message_size = strlen(message);
941 }
942 }
943
944 /* handle signed tags */
945 if (message) {
946 size_t sig_offset = parse_signed_buffer(message, message_size);
947 if (sig_offset < message_size)
948 switch (signed_tag_mode) {
949 /* Exporting modes */
950 case SIGN_WARN_VERBATIM:
951 warning(_("exporting signed tag %s"),
952 oid_to_hex(&tag->object.oid));
953 /* fallthru */
954 case SIGN_VERBATIM:
955 break;
956
957 /* Stripping modes */
958 case SIGN_WARN_STRIP:
959 warning(_("stripping signature from tag %s"),
960 oid_to_hex(&tag->object.oid));
961 /* fallthru */
962 case SIGN_STRIP:
963 message_size = sig_offset;
964 break;
965
966 /* Aborting modes */
967 case SIGN_ABORT:
968 die(_("encountered signed tag %s; use "
969 "--signed-tags=<mode> to handle it"),
970 oid_to_hex(&tag->object.oid));
971 default:
972 BUG("invalid signed_commit_mode value %d", signed_commit_mode);
973 }
974 }
975
976 /* handle tag->tagged having been filtered out due to paths specified */
977 tagged = tag->tagged;
978 tagged_mark = get_object_mark(tagged);
979 if (!tagged_mark) {
980 switch (tag_of_filtered_mode) {
981 case TAG_FILTERING_ABORT:
982 die(_("tag %s tags unexported object; use "
983 "--tag-of-filtered-object=<mode> to handle it"),
984 oid_to_hex(&tag->object.oid));
985 case DROP:
986 /* Ignore this tag altogether */
987 free(buf);
988 return;
989 case REWRITE:
990 if (tagged->type == OBJ_TAG && !mark_tags) {
991 die(_("cannot export nested tags unless --mark-tags is specified."));
992 } else if (tagged->type == OBJ_COMMIT) {
993 p = rewrite_commit((struct commit *)tagged);
994 if (!p) {
995 printf("reset %s\nfrom %s\n\n",
996 name, oid_to_hex(null_oid(the_hash_algo)));
997 free(buf);
998 return;
999 }
1000 tagged_mark = get_object_mark(&p->object);
1001 } else {
1002 /* tagged->type is either OBJ_BLOB or OBJ_TAG */
1003 tagged_mark = get_object_mark(tagged);
1004 }
1005 }
1006 }
1007
1008 if (tagged->type == OBJ_TAG) {
1009 printf("reset %s\nfrom %s\n\n",
1010 name, oid_to_hex(null_oid(the_hash_algo)));
1011 }
1012 skip_prefix(name, "refs/tags/", &name);
1013 printf("tag %s\n", name);
1014 if (mark_tags) {
1015 mark_next_object(&tag->object);
1016 printf("mark :%"PRIu32"\n", last_idnum);
1017 }
1018 if (tagged_mark)
1019 printf("from :%d\n", tagged_mark);
1020 else
1021 printf("from %s\n", oid_to_hex(&tagged->oid));
1022
1023 if (show_original_ids)
1024 printf("original-oid %s\n", oid_to_hex(&tag->object.oid));
1025 printf("%.*s%sdata %d\n%.*s\n",
1026 (int)(tagger_end - tagger), tagger,
1027 tagger == tagger_end ? "" : "\n",
1028 (int)message_size, (int)message_size, message ? message : "");
1029 free(buf);
1030 }
1031
1032 static struct commit *get_commit(struct rev_cmdline_entry *e, const char *full_name)
1033 {
1034 switch (e->item->type) {
1035 case OBJ_COMMIT:
1036 return (struct commit *)e->item;
1037 case OBJ_TAG: {
1038 struct tag *tag = (struct tag *)e->item;
1039
1040 /* handle nested tags */
1041 while (tag && tag->object.type == OBJ_TAG) {
1042 parse_object(the_repository, &tag->object.oid);
1043 string_list_append(&tag_refs, full_name)->util = tag;
1044 tag = (struct tag *)tag->tagged;
1045 }
1046 if (!tag)
1047 die(_("tag %s points nowhere?"), e->name);
1048 return (struct commit *)tag;
1049 }
1050 default:
1051 return NULL;
1052 }
1053 }
1054
1055 static void get_tags_and_duplicates(struct rev_cmdline_info *info)
1056 {
1057 int i;
1058
1059 for (i = 0; i < info->nr; i++) {
1060 struct rev_cmdline_entry *e = info->rev + i;
1061 struct object_id oid;
1062 struct commit *commit;
1063 char *full_name = NULL;
1064
1065 if (e->flags & UNINTERESTING)
1066 continue;
1067
1068 if (repo_dwim_ref(the_repository, e->name, strlen(e->name),
1069 &oid, &full_name, 0) != 1) {
1070 free(full_name);
1071 continue;
1072 }
1073
1074 if (refspecs.nr) {
1075 char *private;
1076 private = apply_refspecs(&refspecs, full_name);
1077 if (private) {
1078 free(full_name);
1079 full_name = private;
1080 }
1081 }
1082
1083 commit = get_commit(e, full_name);
1084 if (!commit) {
1085 warning(_("%s: unexpected object of type %s, skipping."),
1086 e->name,
1087 type_name(e->item->type));
1088 free(full_name);
1089 continue;
1090 }
1091
1092 switch (commit->object.type) {
1093 case OBJ_COMMIT:
1094 break;
1095 case OBJ_BLOB:
1096 export_blob(&commit->object.oid);
1097 free(full_name);
1098 continue;
1099 default: /* OBJ_TAG (nested tags) is already handled */
1100 warning(_("tag points to object of unexpected type %s, skipping."),
1101 type_name(commit->object.type));
1102 free(full_name);
1103 continue;
1104 }
1105
1106 /*
1107 * Make sure this ref gets properly updated eventually, whether
1108 * through a commit or manually at the end.
1109 */
1110 if (e->item->type != OBJ_TAG)
1111 string_list_append(&extra_refs, full_name)->util = commit;
1112
1113 if (!*revision_sources_at(&revision_sources, commit))
1114 *revision_sources_at(&revision_sources, commit) = full_name;
1115 else
1116 free(full_name);
1117 }
1118
1119 string_list_sort_u(&extra_refs, 0);
1120 }
1121
1122 static void handle_tags_and_duplicates(struct string_list *extras)
1123 {
1124 struct commit *commit;
1125 int i;
1126
1127 for (i = extras->nr - 1; i >= 0; i--) {
1128 const char *name = extras->items[i].string;
1129 struct object *object = extras->items[i].util;
1130 int mark;
1131
1132 switch (object->type) {
1133 case OBJ_TAG:
1134 handle_tag(name, (struct tag *)object);
1135 break;
1136 case OBJ_COMMIT:
1137 if (anonymize)
1138 name = anonymize_refname(name);
1139 /* create refs pointing to already seen commits */
1140 commit = rewrite_commit((struct commit *)object);
1141 if (!commit) {
1142 /*
1143 * Neither this object nor any of its
1144 * ancestors touch any relevant paths, so
1145 * it has been filtered to nothing. Delete
1146 * it.
1147 */
1148 printf("reset %s\nfrom %s\n\n",
1149 name, oid_to_hex(null_oid(the_hash_algo)));
1150 continue;
1151 }
1152
1153 mark = get_object_mark(&commit->object);
1154 if (!mark) {
1155 /*
1156 * Getting here means we have a commit which
1157 * was excluded by a negative refspec (e.g.
1158 * fast-export ^HEAD HEAD). If we are
1159 * referencing excluded commits, set the ref
1160 * to the exact commit. Otherwise, the user
1161 * wants the branch exported but every commit
1162 * in its history to be deleted, which basically
1163 * just means deletion of the ref.
1164 */
1165 if (!reference_excluded_commits) {
1166 /* delete the ref */
1167 printf("reset %s\nfrom %s\n\n",
1168 name, oid_to_hex(null_oid(the_hash_algo)));
1169 continue;
1170 }
1171 /* set ref to commit using oid, not mark */
1172 printf("reset %s\nfrom %s\n\n", name,
1173 oid_to_hex(&commit->object.oid));
1174 continue;
1175 }
1176
1177 printf("reset %s\nfrom :%d\n\n", name, mark
1178 );
1179 show_progress();
1180 break;
1181 }
1182 }
1183 }
1184
1185 static void export_marks(char *file)
1186 {
1187 unsigned int i;
1188 uint32_t mark;
1189 struct decoration_entry *deco = idnums.entries;
1190 FILE *f;
1191 int e = 0;
1192
1193 f = fopen_for_writing(file);
1194 if (!f)
1195 die_errno(_("unable to open marks file %s for writing."), file);
1196
1197 for (i = 0; i < idnums.size; i++) {
1198 if (deco->base && deco->base->type == 1) {
1199 mark = ptr_to_mark(deco->decoration);
1200 if (fprintf(f, ":%"PRIu32" %s\n", mark,
1201 oid_to_hex(&deco->base->oid)) < 0) {
1202 e = 1;
1203 break;
1204 }
1205 }
1206 deco++;
1207 }
1208
1209 e |= ferror(f);
1210 e |= fclose(f);
1211 if (e)
1212 error(_("unable to write marks file %s."), file);
1213 }
1214
1215 static void import_marks(char *input_file, int check_exists)
1216 {
1217 char line[512];
1218 FILE *f;
1219 struct stat sb;
1220
1221 if (check_exists && stat(input_file, &sb))
1222 return;
1223
1224 f = xfopen(input_file, "r");
1225 while (fgets(line, sizeof(line), f)) {
1226 uint32_t mark;
1227 char *line_end, *mark_end;
1228 struct object_id oid;
1229 struct object *object;
1230 struct commit *commit;
1231 enum object_type type;
1232
1233 line_end = strchr(line, '\n');
1234 if (line[0] != ':' || !line_end)
1235 die(_("corrupt mark line: %s"), line);
1236 *line_end = '\0';
1237
1238 mark = strtoumax(line + 1, &mark_end, 10);
1239 if (!mark || mark_end == line + 1
1240 || *mark_end != ' ' || get_oid_hex(mark_end + 1, &oid))
1241 die(_("corrupt mark line: %s"), line);
1242
1243 if (last_idnum < mark)
1244 last_idnum = mark;
1245
1246 type = odb_read_object_info(the_repository->objects, &oid, NULL);
1247 if (type < 0)
1248 die(_("object not found: %s"), oid_to_hex(&oid));
1249
1250 if (type != OBJ_COMMIT)
1251 /* only commits */
1252 continue;
1253
1254 commit = lookup_commit(the_repository, &oid);
1255 if (!commit)
1256 die(_("not a commit? can't happen: %s"), oid_to_hex(&oid));
1257
1258 object = &commit->object;
1259
1260 if (object->flags & SHOWN)
1261 error(_("object %s already has a mark"), oid_to_hex(&oid));
1262
1263 mark_object(object, mark);
1264
1265 object->flags |= SHOWN;
1266 }
1267 fclose(f);
1268 }
1269
1270 static void handle_deletes(void)
1271 {
1272 int i;
1273 for (i = 0; i < refspecs.nr; i++) {
1274 struct refspec_item *refspec = &refspecs.items[i];
1275 if (*refspec->src)
1276 continue;
1277
1278 printf("reset %s\nfrom %s\n\n",
1279 refspec->dst, oid_to_hex(null_oid(the_hash_algo)));
1280 }
1281 }
1282
1283 static int parse_opt_anonymize_map(const struct option *opt,
1284 const char *arg, int unset)
1285 {
1286 struct hashmap *map = opt->value;
1287 const char *delim, *value;
1288 size_t keylen;
1289
1290 BUG_ON_OPT_NEG(unset);
1291
1292 delim = strchr(arg, ':');
1293 if (delim) {
1294 keylen = delim - arg;
1295 value = delim + 1;
1296 } else {
1297 keylen = strlen(arg);
1298 value = arg;
1299 }
1300
1301 if (!keylen || !*value)
1302 return error(_("--anonymize-map token cannot be empty"));
1303
1304 add_anonymized_entry(map, memhash(arg, keylen), arg, keylen,
1305 xstrdup(value));
1306
1307 return 0;
1308 }
1309
1310 int cmd_fast_export(int argc,
1311 const char **argv,
1312 const char *prefix,
1313 struct repository *repo UNUSED)
1314 {
1315 struct rev_info revs;
1316 struct commit *commit;
1317 char *export_filename = NULL,
1318 *import_filename = NULL,
1319 *import_filename_if_exists = NULL;
1320 uint32_t lastimportid;
1321 struct string_list refspecs_list = STRING_LIST_INIT_NODUP;
1322 struct string_list paths_of_changed_objects = STRING_LIST_INIT_DUP;
1323 struct option options[] = {
1324 OPT_INTEGER(0, "progress", &progress,
1325 N_("show progress after <n> objects")),
1326 OPT_CALLBACK(0, "signed-tags", &signed_tag_mode, N_("mode"),
1327 N_("select handling of signed tags"),
1328 parse_opt_sign_mode),
1329 OPT_CALLBACK(0, "signed-commits", &signed_commit_mode, N_("mode"),
1330 N_("select handling of signed commits"),
1331 parse_opt_sign_mode),
1332 OPT_CALLBACK(0, "tag-of-filtered-object", &tag_of_filtered_mode, N_("mode"),
1333 N_("select handling of tags that tag filtered objects"),
1334 parse_opt_tag_of_filtered_mode),
1335 OPT_CALLBACK(0, "reencode", &reencode_mode, N_("mode"),
1336 N_("select handling of commit messages in an alternate encoding"),
1337 parse_opt_reencode_mode),
1338 OPT_STRING(0, "export-marks", &export_filename, N_("file"),
1339 N_("dump marks to this file")),
1340 OPT_STRING(0, "import-marks", &import_filename, N_("file"),
1341 N_("import marks from this file")),
1342 OPT_STRING(0, "import-marks-if-exists",
1343 &import_filename_if_exists,
1344 N_("file"),
1345 N_("import marks from this file if it exists")),
1346 OPT_BOOL(0, "fake-missing-tagger", &fake_missing_tagger,
1347 N_("fake a tagger when tags lack one")),
1348 OPT_BOOL(0, "full-tree", &full_tree,
1349 N_("output full tree for each commit")),
1350 OPT_BOOL(0, "use-done-feature", &use_done_feature,
1351 N_("use the done feature to terminate the stream")),
1352 OPT_BOOL(0, "no-data", &no_data, N_("skip output of blob data")),
1353 OPT_STRING_LIST(0, "refspec", &refspecs_list, N_("refspec"),
1354 N_("apply refspec to exported refs")),
1355 OPT_BOOL(0, "anonymize", &anonymize, N_("anonymize output")),
1356 OPT_CALLBACK_F(0, "anonymize-map", &anonymized_seeds, N_("from:to"),
1357 N_("convert <from> to <to> in anonymized output"),
1358 PARSE_OPT_NONEG, parse_opt_anonymize_map),
1359 OPT_BOOL(0, "reference-excluded-parents",
1360 &reference_excluded_commits, N_("reference parents which are not in fast-export stream by object id")),
1361 OPT_BOOL(0, "show-original-ids", &show_original_ids,
1362 N_("show original object ids of blobs/commits")),
1363 OPT_BOOL(0, "mark-tags", &mark_tags,
1364 N_("label tags with mark ids")),
1365
1366 OPT_END()
1367 };
1368
1369 if (argc == 1)
1370 usage_with_options (fast_export_usage, options);
1371
1372 /* we handle encodings */
1373 repo_config(the_repository, git_default_config, NULL);
1374
1375 refspec_init_fetch(&refspecs, the_hash_algo);
1376
1377 repo_init_revisions(the_repository, &revs, prefix);
1378 init_revision_sources(&revision_sources);
1379 revs.topo_order = 1;
1380 revs.sources = &revision_sources;
1381 revs.rewrite_parents = 1;
1382 argc = parse_options(argc, argv, prefix, options, fast_export_usage,
1383 PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT);
1384 argc = setup_revisions(argc, argv, &revs, NULL);
1385 if (argc > 1)
1386 usage_with_options (fast_export_usage, options);
1387
1388 if (anonymized_seeds.cmpfn && !anonymize)
1389 die(_("the option '%s' requires '%s'"), "--anonymize-map", "--anonymize");
1390
1391 if (refspecs_list.nr) {
1392 int i;
1393
1394 for (i = 0; i < refspecs_list.nr; i++)
1395 refspec_append(&refspecs, refspecs_list.items[i].string);
1396
1397 string_list_clear(&refspecs_list, 1);
1398 }
1399
1400 if (use_done_feature)
1401 printf("feature done\n");
1402
1403 if (import_filename && import_filename_if_exists)
1404 die(_("options '%s' and '%s' cannot be used together"), "--import-marks", "--import-marks-if-exists");
1405 if (import_filename)
1406 import_marks(import_filename, 0);
1407 else if (import_filename_if_exists)
1408 import_marks(import_filename_if_exists, 1);
1409 lastimportid = last_idnum;
1410
1411 if (import_filename && revs.prune_data.nr)
1412 full_tree = 1;
1413
1414 get_tags_and_duplicates(&revs.cmdline);
1415
1416 if (prepare_revision_walk(&revs))
1417 die(_("revision walk setup failed"));
1418
1419 revs.reverse = 1;
1420 revs.diffopt.format_callback = show_filemodify;
1421 revs.diffopt.format_callback_data = &paths_of_changed_objects;
1422 revs.diffopt.flags.recursive = 1;
1423
1424 revs.diffopt.no_free = 1;
1425 while ((commit = get_revision(&revs)))
1426 handle_commit(commit, &revs, &paths_of_changed_objects);
1427 revs.diffopt.no_free = 0;
1428
1429 handle_tags_and_duplicates(&extra_refs);
1430 handle_tags_and_duplicates(&tag_refs);
1431 handle_deletes();
1432
1433 if (export_filename && lastimportid != last_idnum)
1434 export_marks(export_filename);
1435
1436 if (use_done_feature)
1437 printf("done\n");
1438
1439 refspec_clear(&refspecs);
1440 release_revisions(&revs);
1441
1442 return 0;
1443 }