Raw
1 /*
2 * GIT - The information manager from hell
3 *
4 * Copyright (C) Linus Torvalds, 2005
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 "convert.h"
13 #include "diff.h"
14 #include "environment.h"
15 #include "gettext.h"
16 #include "hex.h"
17 #include "ident.h"
18 #include "list-objects-filter-options.h"
19 #include "parse-options.h"
20 #include "userdiff.h"
21 #include "oid-array.h"
22 #include "packfile.h"
23 #include "object-file.h"
24 #include "object-name.h"
25 #include "odb.h"
26 #include "odb/streaming.h"
27 #include "replace-object.h"
28 #include "promisor-remote.h"
29 #include "mailmap.h"
30 #include "write-or-die.h"
31 #include "alias.h"
32 #include "remote.h"
33 #include "transport.h"
34 #include "fetch-object-info.h"
35
36 /*
37 * Maximum length for a remote URL. While no universal standard exists,
38 * 8K is assumed to be a reasonable limit.
39 */
40 #define MAX_REMOTE_URL_LEN (8 * 1024)
41
42 /* Maximum number of objects allowed in a single remote-object-info request. */
43 #define MAX_ALLOWED_OBJ_LIMIT 10000
44
45 /* Maximum input size permitted for the remote-object-info command. */
46 #define MAX_REMOTE_OBJ_INFO_LINE \
47 (MAX_REMOTE_URL_LEN + MAX_ALLOWED_OBJ_LIMIT * (GIT_MAX_HEXSZ + 1))
48
49 enum batch_mode {
50 BATCH_MODE_CONTENTS,
51 BATCH_MODE_INFO,
52 BATCH_MODE_QUEUE_AND_DISPATCH,
53 };
54
55 struct batch_options {
56 struct list_objects_filter_options objects_filter;
57 int enabled;
58 int follow_symlinks;
59 enum batch_mode batch_mode;
60 int buffer_output;
61 int all_objects;
62 int unordered;
63 int transform_mode; /* may be 'w' or 'c' for --filters or --textconv */
64 char input_delim;
65 char output_delim;
66 const char *format;
67 };
68
69 static const char *force_path;
70
71 static struct string_list mailmap = STRING_LIST_INIT_NODUP;
72 static int use_mailmap;
73
74 static char *replace_idents_using_mailmap(char *, size_t *);
75
76 /*
77 * The mailmap is initialized with .strdup_strings set to 0,
78 * but read_mailmap() sets the bit to 1 (this is true even when
79 * not a single mailmap entry is read), so it can be used for
80 * lazy loading.
81 */
82 static void load_mailmap(void)
83 {
84 if (mailmap.strdup_strings)
85 return;
86
87 read_mailmap(the_repository, &mailmap);
88 }
89
90 static char *replace_idents_using_mailmap(char *object_buf, size_t *size)
91 {
92 struct strbuf sb = STRBUF_INIT;
93 const char *headers[] = { "author ", "committer ", "tagger ", NULL };
94
95 strbuf_attach(&sb, object_buf, *size, *size + 1);
96 apply_mailmap_to_header(&sb, headers, &mailmap);
97 *size = sb.len;
98 return strbuf_detach(&sb, NULL);
99 }
100
101 static int filter_object(const char *path, unsigned mode,
102 const struct object_id *oid,
103 char **buf, size_t *size)
104 {
105 enum object_type type;
106
107 *buf = odb_read_object(the_repository->objects, oid, &type, size);
108 if (!*buf)
109 return error(_("cannot read object %s '%s'"),
110 oid_to_hex(oid), path);
111 if ((type == OBJ_BLOB) && S_ISREG(mode)) {
112 struct strbuf strbuf = STRBUF_INIT;
113 struct checkout_metadata meta;
114
115 init_checkout_metadata(&meta, NULL, NULL, oid);
116 if (convert_to_working_tree(the_repository->index, path, *buf, *size, &strbuf, &meta)) {
117 free(*buf);
118 *size = strbuf.len;
119 *buf = strbuf_detach(&strbuf, NULL);
120 }
121 }
122
123 return 0;
124 }
125
126 static int stream_blob(const struct object_id *oid)
127 {
128 if (odb_stream_blob_to_fd(the_repository->objects, 1, oid, NULL, 0))
129 die("unable to stream %s to stdout", oid_to_hex(oid));
130 return 0;
131 }
132
133 static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
134 {
135 int ret;
136 struct object_id oid;
137 enum object_type type;
138 char *buf;
139 size_t size;
140 struct object_context obj_context = {0};
141 struct object_info oi = OBJECT_INFO_INIT;
142 unsigned flags = OBJECT_INFO_LOOKUP_REPLACE;
143 unsigned get_oid_flags =
144 GET_OID_RECORD_PATH |
145 GET_OID_ONLY_TO_DIE |
146 GET_OID_HASH_ANY;
147 const char *path = force_path;
148 const int opt_cw = (opt == 'c' || opt == 'w');
149 if (!path && opt_cw)
150 get_oid_flags |= GET_OID_REQUIRE_PATH;
151
152 if (get_oid_with_context(the_repository, obj_name, get_oid_flags, &oid,
153 &obj_context))
154 die("Not a valid object name %s", obj_name);
155
156 if (!path)
157 path = obj_context.path;
158 if (obj_context.mode == S_IFINVALID)
159 obj_context.mode = 0100644;
160
161 buf = NULL;
162 switch (opt) {
163 case 't':
164 oi.typep = &type;
165 if (odb_read_object_info_extended(the_repository->objects, &oid, &oi, flags) < 0)
166 die("git cat-file: could not get object info");
167 printf("%s\n", type_name(type));
168 ret = 0;
169 goto cleanup;
170
171 case 's':
172 oi.sizep = &size;
173
174 if (use_mailmap) {
175 oi.typep = &type;
176 oi.contentp = (void**)&buf;
177 }
178
179 if (odb_read_object_info_extended(the_repository->objects, &oid, &oi, flags) < 0)
180 die("git cat-file: could not get object info");
181
182 if (use_mailmap && (type == OBJ_COMMIT || type == OBJ_TAG))
183 buf = replace_idents_using_mailmap(buf, &size);
184
185 printf("%"PRIuMAX"\n", (uintmax_t)size);
186 ret = 0;
187 goto cleanup;
188
189 case 'e':
190 ret = !odb_has_object(the_repository->objects, &oid,
191 ODB_HAS_OBJECT_RECHECK_PACKED | ODB_HAS_OBJECT_FETCH_PROMISOR);
192 goto cleanup;
193
194 case 'w':
195
196 if (filter_object(path, obj_context.mode,
197 &oid, &buf, &size)) {
198 ret = -1;
199 goto cleanup;
200 }
201 break;
202
203 case 'c':
204 {
205 unsigned long size_ul = 0;
206 int textconv_ret = textconv_object(the_repository, path,
207 obj_context.mode, &oid, 1,
208 &buf, &size_ul);
209 size = size_ul;
210 if (textconv_ret)
211 break;
212 }
213 /* else fallthrough */
214
215 case 'p':
216 type = odb_read_object_info(the_repository->objects, &oid, NULL);
217 if (type < 0)
218 die("Not a valid object name %s", obj_name);
219
220 /* custom pretty-print here */
221 if (type == OBJ_TREE) {
222 const char *ls_args[3] = { NULL };
223 ls_args[0] = "ls-tree";
224 ls_args[1] = obj_name;
225 ret = cmd_ls_tree(2, ls_args, NULL, the_repository);
226 goto cleanup;
227 }
228
229 if (type == OBJ_BLOB) {
230 ret = stream_blob(&oid);
231 goto cleanup;
232 }
233 buf = odb_read_object(the_repository->objects, &oid,
234 &type, &size);
235 if (!buf)
236 die("Cannot read object %s", obj_name);
237
238 if (use_mailmap)
239 buf = replace_idents_using_mailmap(buf, &size);
240
241 /* otherwise just spit out the data */
242 break;
243
244 case 0:
245 {
246 enum object_type exp_type_id = type_from_string(exp_type);
247
248 if (exp_type_id == OBJ_BLOB) {
249 struct object_id blob_oid;
250 if (odb_read_object_info(the_repository->objects,
251 &oid, NULL) == OBJ_TAG) {
252 char *buffer = odb_read_object(the_repository->objects,
253 &oid, &type, &size);
254 const char *target;
255
256 if (!buffer)
257 die(_("unable to read %s"), oid_to_hex(&oid));
258
259 if (!skip_prefix(buffer, "object ", &target) ||
260 get_oid_hex_algop(target, &blob_oid,
261 &hash_algos[oid.algo]))
262 die("%s not a valid tag", oid_to_hex(&oid));
263 free(buffer);
264 } else
265 oidcpy(&blob_oid, &oid);
266
267 if (odb_read_object_info(the_repository->objects,
268 &blob_oid, NULL) == OBJ_BLOB) {
269 ret = stream_blob(&blob_oid);
270 goto cleanup;
271 }
272 /*
273 * we attempted to dereference a tag to a blob
274 * and failed; there may be new dereference
275 * mechanisms this code is not aware of.
276 * fall-back to the usual case.
277 */
278 }
279 buf = odb_read_object_peeled(the_repository->objects, &oid,
280 exp_type_id, &size, NULL);
281
282 if (use_mailmap)
283 buf = replace_idents_using_mailmap(buf, &size);
284 break;
285 }
286 default:
287 die("git cat-file: unknown option: %s", exp_type);
288 }
289
290 if (!buf)
291 die("git cat-file %s: bad file", obj_name);
292
293 write_or_die(1, buf, size);
294 ret = 0;
295 cleanup:
296 free(buf);
297 object_context_release(&obj_context);
298 return ret;
299 }
300
301 struct expand_data {
302 struct object_id oid;
303 enum object_type type;
304 size_t size;
305 unsigned short mode;
306 off_t disk_size;
307 const char *rest;
308 struct object_id delta_base_oid;
309
310 /*
311 * If mark_query is true, we do not expand anything, but rather
312 * just mark the object_info with items we wish to query.
313 */
314 int mark_query;
315
316 /*
317 * Whether to split the input on whitespace before feeding it to
318 * get_sha1; this is decided during the mark_query phase based on
319 * whether we have a %(rest) token in our format.
320 */
321 int split_on_whitespace;
322
323 /*
324 * After a mark_query run, this object_info is set up to be
325 * passed to odb_read_object_info_extended. It will point to the data
326 * elements above, so you can retrieve the response from there.
327 */
328 struct object_info info;
329
330 /*
331 * This flag will be true if the requested batch format and options
332 * don't require us to call oid_object_info, which can then be
333 * optimized out.
334 */
335 unsigned skip_object_info : 1;
336
337 /*
338 * Flags about when an object info is being fetched from remote.
339 */
340 unsigned is_remote:1;
341
342 /*
343 * List of atoms (i.e. "objectsize") that the server supports. Built
344 * from the server's object-info advertised capabilities.
345 */
346 struct string_list remote_allowed_atoms;
347 };
348
349 #define EXPAND_DATA_INIT { \
350 .mode = S_IFINVALID, \
351 .type = OBJ_BAD, \
352 .remote_allowed_atoms = STRING_LIST_INIT_NODUP, \
353 }
354
355 static int is_atom(const char *atom, const char *s, int slen)
356 {
357 int alen = strlen(atom);
358 return alen == slen && !memcmp(atom, s, alen);
359 }
360
361 static int expand_atom(struct strbuf *sb, const char *atom, int len,
362 struct expand_data *data)
363 {
364 if (data->is_remote) {
365 size_t i;
366 for (i = 0; i < data->remote_allowed_atoms.nr; i++)
367 if (is_atom(data->remote_allowed_atoms.items[i].string,
368 atom, len))
369 break;
370 if (i == data->remote_allowed_atoms.nr)
371 return 1;
372 }
373
374 if (is_atom("objectname", atom, len)) {
375 if (!data->mark_query)
376 strbuf_add_oid_hex(sb, &data->oid);
377 } else if (is_atom("objecttype", atom, len)) {
378 if (data->mark_query) {
379 data->info.typep = &data->type;
380 } else {
381 const char *t = type_name(data->type);
382 strbuf_addstr(sb, t ? t : "");
383 }
384 } else if (is_atom("objectsize", atom, len)) {
385 if (data->mark_query)
386 data->info.sizep = &data->size;
387 else
388 strbuf_add_uint(sb, data->size);
389 } else if (is_atom("objectsize:disk", atom, len)) {
390 if (data->mark_query)
391 data->info.disk_sizep = &data->disk_size;
392 else
393 strbuf_add_uint(sb, data->disk_size);
394 } else if (is_atom("rest", atom, len)) {
395 if (data->mark_query)
396 data->split_on_whitespace = 1;
397 else if (data->rest)
398 strbuf_addstr(sb, data->rest);
399 } else if (is_atom("deltabase", atom, len)) {
400 if (data->mark_query)
401 data->info.delta_base_oid = &data->delta_base_oid;
402 else
403 strbuf_add_oid_hex(sb, &data->delta_base_oid);
404 } else if (is_atom("objectmode", atom, len)) {
405 if (!data->mark_query && !(S_IFINVALID == data->mode))
406 strbuf_addf(sb, "%06o", data->mode);
407 } else
408 return 0;
409 return 1;
410 }
411
412 static void expand_format(struct strbuf *sb, const char *start,
413 struct expand_data *data)
414 {
415 while (strbuf_expand_step(sb, &start)) {
416 const char *end;
417
418 if (skip_prefix(start, "%", &start) || *start != '(')
419 strbuf_addch(sb, '%');
420 else if ((end = strchr(start + 1, ')')) &&
421 expand_atom(sb, start + 1, end - start - 1, data))
422 start = end + 1;
423 else
424 strbuf_expand_bad_format(start, "cat-file");
425 }
426 }
427
428 static void batch_write(struct batch_options *opt, const void *data, int len)
429 {
430 if (opt->buffer_output) {
431 if (fwrite(data, 1, len, stdout) != len)
432 die_errno("unable to write to stdout");
433 } else
434 write_or_die(1, data, len);
435 }
436
437 static void print_object_or_die(struct batch_options *opt, struct expand_data *data)
438 {
439 const struct object_id *oid = &data->oid;
440
441 assert(data->info.typep);
442
443 if (data->type == OBJ_BLOB) {
444 if (opt->buffer_output)
445 fflush(stdout);
446 if (opt->transform_mode) {
447 char *contents;
448 size_t size;
449
450 if (!data->rest)
451 die("missing path for '%s'", oid_to_hex(oid));
452
453 if (opt->transform_mode == 'w') {
454 if (filter_object(data->rest, 0100644, oid,
455 &contents, &size))
456 die("could not convert '%s' %s",
457 oid_to_hex(oid), data->rest);
458 } else if (opt->transform_mode == 'c') {
459 enum object_type type;
460 unsigned long size_ul = 0;
461 if (textconv_object(the_repository,
462 data->rest, 0100644, oid,
463 1, &contents, &size_ul))
464 size = size_ul;
465 else
466 contents = odb_read_object(the_repository->objects,
467 oid, &type, &size);
468 if (!contents)
469 die("could not convert '%s' %s",
470 oid_to_hex(oid), data->rest);
471 } else
472 BUG("invalid transform_mode: %c", opt->transform_mode);
473 batch_write(opt, contents, size);
474 free(contents);
475 } else {
476 stream_blob(oid);
477 }
478 }
479 else {
480 enum object_type type;
481 size_t size;
482 void *contents;
483
484 contents = odb_read_object(the_repository->objects, oid,
485 &type, &size);
486 if (!contents)
487 die("object %s disappeared", oid_to_hex(oid));
488
489 if (use_mailmap)
490 contents = replace_idents_using_mailmap(contents, &size);
491
492 if (type != data->type)
493 die("object %s changed type!?", oid_to_hex(oid));
494 if (data->info.sizep && size != data->size && !use_mailmap)
495 die("object %s changed size!?", oid_to_hex(oid));
496
497 batch_write(opt, contents, size);
498 free(contents);
499 }
500 }
501
502 static void print_default_format(struct strbuf *scratch, struct expand_data *data,
503 struct batch_options *opt)
504 {
505 strbuf_add_oid_hex(scratch, &data->oid);
506 strbuf_addch(scratch, ' ');
507 strbuf_addstr(scratch, type_name(data->type));
508 strbuf_addch(scratch, ' ');
509 strbuf_add_uint(scratch, data->size);
510 strbuf_addch(scratch, opt->output_delim);
511 }
512
513 static void report_object_status(struct batch_options *opt,
514 const char *obj_name,
515 const struct object_id *oid,
516 const char *status)
517 {
518 printf("%s %s%c", obj_name ? obj_name : oid_to_hex(oid),
519 status, opt->output_delim);
520 fflush(stdout);
521 }
522
523 /*
524 * If "pack" is non-NULL, then "offset" is the byte offset within the pack from
525 * which the object may be accessed (though note that we may also rely on
526 * data->oid, too). If "pack" is NULL, then offset is ignored.
527 */
528 static void batch_object_write(const char *obj_name,
529 struct strbuf *scratch,
530 struct batch_options *opt,
531 struct expand_data *data,
532 struct packed_git *pack,
533 off_t offset)
534 {
535 if (!data->skip_object_info) {
536 int ret;
537
538 if (use_mailmap ||
539 opt->objects_filter.choice == LOFC_BLOB_NONE ||
540 opt->objects_filter.choice == LOFC_BLOB_LIMIT ||
541 opt->objects_filter.choice == LOFC_OBJECT_TYPE)
542 data->info.typep = &data->type;
543 if (opt->objects_filter.choice == LOFC_BLOB_LIMIT)
544 data->info.sizep = &data->size;
545
546 if (pack)
547 ret = packed_object_info(NULL, pack, offset, &data->info);
548 else
549 ret = odb_read_object_info_extended(the_repository->objects,
550 &data->oid, &data->info,
551 OBJECT_INFO_LOOKUP_REPLACE);
552 if (ret < 0) {
553 if (data->mode == S_IFGITLINK)
554 report_object_status(opt, NULL, &data->oid, "submodule");
555 else
556 report_object_status(opt, obj_name, &data->oid, "missing");
557 return;
558 }
559
560 switch (opt->objects_filter.choice) {
561 case LOFC_DISABLED:
562 break;
563 case LOFC_BLOB_NONE:
564 if (data->type == OBJ_BLOB) {
565 if (!opt->all_objects)
566 report_object_status(opt, obj_name,
567 &data->oid, "excluded");
568 return;
569 }
570 break;
571 case LOFC_BLOB_LIMIT:
572 if (data->type == OBJ_BLOB &&
573 data->size >= opt->objects_filter.blob_limit_value) {
574 if (!opt->all_objects)
575 report_object_status(opt, obj_name,
576 &data->oid, "excluded");
577 return;
578 }
579 break;
580 case LOFC_OBJECT_TYPE:
581 if (data->type != opt->objects_filter.object_type) {
582 if (!opt->all_objects)
583 report_object_status(opt, obj_name,
584 &data->oid, "excluded");
585 return;
586 }
587 break;
588 default:
589 BUG("unsupported objects filter");
590 }
591
592 if (use_mailmap && (data->type == OBJ_COMMIT || data->type == OBJ_TAG)) {
593 char *buf = NULL;
594
595 buf = odb_read_object(the_repository->objects, &data->oid,
596 &data->type, &data->size);
597 if (!buf)
598 die(_("unable to read %s"), oid_to_hex(&data->oid));
599 buf = replace_idents_using_mailmap(buf, &data->size);
600
601 free(buf);
602 }
603 }
604
605 strbuf_reset(scratch);
606
607 if (!opt->format) {
608 print_default_format(scratch, data, opt);
609 } else {
610 expand_format(scratch, opt->format, data);
611 strbuf_addch(scratch, opt->output_delim);
612 }
613
614 batch_write(opt, scratch->buf, scratch->len);
615
616 if (opt->batch_mode == BATCH_MODE_CONTENTS) {
617 print_object_or_die(opt, data);
618 batch_write(opt, &opt->output_delim, 1);
619 }
620 }
621
622 static void batch_one_object(const char *obj_name,
623 struct strbuf *scratch,
624 struct batch_options *opt,
625 struct expand_data *data)
626 {
627 struct object_context ctx = {0};
628 int flags =
629 GET_OID_HASH_ANY |
630 (opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0);
631 enum get_oid_result result;
632
633 result = get_oid_with_context(the_repository, obj_name,
634 flags, &data->oid, &ctx);
635 if (result != FOUND) {
636 switch (result) {
637 case MISSING_OBJECT:
638 report_object_status(opt, obj_name, &data->oid, "missing");
639 break;
640 case SHORT_NAME_AMBIGUOUS:
641 report_object_status(opt, obj_name, &data->oid, "ambiguous");
642 break;
643 case DANGLING_SYMLINK:
644 printf("dangling %"PRIuMAX"%c%s%c",
645 (uintmax_t)strlen(obj_name),
646 opt->output_delim, obj_name, opt->output_delim);
647 break;
648 case SYMLINK_LOOP:
649 printf("loop %"PRIuMAX"%c%s%c",
650 (uintmax_t)strlen(obj_name),
651 opt->output_delim, obj_name, opt->output_delim);
652 break;
653 case NOT_DIR:
654 printf("notdir %"PRIuMAX"%c%s%c",
655 (uintmax_t)strlen(obj_name),
656 opt->output_delim, obj_name, opt->output_delim);
657 break;
658 default:
659 BUG("unknown get_sha1_with_context result %d\n",
660 result);
661 break;
662 }
663 fflush(stdout);
664
665 goto out;
666 }
667
668 if (ctx.mode == 0) {
669 printf("symlink %"PRIuMAX"%c%s%c",
670 (uintmax_t)ctx.symlink_path.len,
671 opt->output_delim, ctx.symlink_path.buf, opt->output_delim);
672 fflush(stdout);
673 goto out;
674 }
675
676 data->mode = ctx.mode;
677 batch_object_write(obj_name, scratch, opt, data, NULL, 0);
678
679 out:
680 object_context_release(&ctx);
681 }
682
683 static int get_remote_info(int argc,
684 const char **argv,
685 struct fetch_object_info_results *results,
686 struct oid_array *object_info_oids)
687 {
688 int retval = 0;
689 struct remote *remote = NULL;
690 struct object_id oid;
691 struct transport *gtransport;
692
693 remote = remote_get(argv[0]);
694 if (!remote)
695 die(_("must supply valid remote when using remote-object-info"));
696
697 oid_array_clear(object_info_oids);
698 for (size_t i = 1; i < argc; i++) {
699 if (get_oid_hex(argv[i], &oid)) {
700 size_t len = strlen(argv[i]);
701
702 if (len < the_hash_algo->hexsz && len >= 4) {
703 size_t j;
704 for (j = 0; j < len; j++)
705 if (!isxdigit(argv[i][j]))
706 break;
707 if (j == len)
708 die(_("remote-object-info does not support "
709 "short oids, %d characters required"),
710 (int)the_hash_algo->hexsz);
711 }
712 die(_("not a valid object name '%s'"), argv[i]);
713 }
714 oid_array_append(object_info_oids, &oid);
715 }
716
717 if (!object_info_oids->nr)
718 die(_("remote-object-info requires objects"));
719
720 gtransport = transport_get(remote, NULL);
721
722 if (!gtransport->smart_options) {
723 retval = -1;
724 goto cleanup;
725 }
726
727 gtransport->smart_options->object_info_oids = object_info_oids;
728
729 gtransport->smart_options->object_info_results = results;
730 retval = transport_fetch_object_info(gtransport);
731 cleanup:
732 transport_disconnect(gtransport);
733 return retval;
734 }
735
736 struct object_cb_data {
737 struct batch_options *opt;
738 struct expand_data *expand;
739 struct oidset *seen;
740 struct strbuf *scratch;
741 };
742
743 static int batch_object_cb(const struct object_id *oid, void *vdata)
744 {
745 struct object_cb_data *data = vdata;
746 oidcpy(&data->expand->oid, oid);
747 batch_object_write(NULL, data->scratch, data->opt, data->expand,
748 NULL, 0);
749 return 0;
750 }
751
752 static int collect_object(const struct object_id *oid,
753 struct packed_git *pack UNUSED,
754 off_t offset UNUSED,
755 void *data)
756 {
757 oid_array_append(data, oid);
758 return 0;
759 }
760
761 static int batch_unordered_object(const struct object_id *oid,
762 struct packed_git *pack,
763 off_t offset,
764 void *vdata)
765 {
766 struct object_cb_data *data = vdata;
767
768 if (oidset_insert(data->seen, oid))
769 return 0;
770
771 oidcpy(&data->expand->oid, oid);
772 batch_object_write(NULL, data->scratch, data->opt, data->expand,
773 pack, offset);
774 return 0;
775 }
776
777 typedef void (*parse_cmd_fn_t)(struct batch_options *, const char *,
778 struct strbuf *, struct expand_data *);
779
780 struct queued_cmd {
781 parse_cmd_fn_t fn;
782 char *line;
783 };
784
785 static void parse_cmd_contents(struct batch_options *opt,
786 const char *line,
787 struct strbuf *output,
788 struct expand_data *data)
789 {
790 enum object_type *saved_typep = data->info.typep;
791 data->info.typep = &data->type;
792 opt->batch_mode = BATCH_MODE_CONTENTS;
793 batch_one_object(line, output, opt, data);
794 data->info.typep = saved_typep;
795 }
796
797 static void parse_cmd_info(struct batch_options *opt,
798 const char *line,
799 struct strbuf *output,
800 struct expand_data *data)
801 {
802 opt->batch_mode = BATCH_MODE_INFO;
803 batch_one_object(line, output, opt, data);
804 }
805
806 static void parse_cmd_mailmap(struct batch_options *opt UNUSED,
807 const char *line,
808 struct strbuf *output UNUSED,
809 struct expand_data *data UNUSED)
810 {
811 use_mailmap = git_parse_maybe_bool(line);
812
813 if (use_mailmap < 0)
814 die(_("mailmap: invalid boolean '%s'"), line);
815
816 if (use_mailmap)
817 load_mailmap();
818 }
819
820 static void parse_cmd_remote_object_info(struct batch_options *opt,
821 const char *line, struct strbuf *output,
822 struct expand_data *data)
823 {
824 int count;
825 const char **argv;
826 char *line_to_split;
827 struct fetch_object_info_results results = FETCH_OBJECT_INFO_RESULTS_INIT;
828 struct oid_array object_info_oids = OID_ARRAY_INIT;
829
830 if (strlen(line) >= MAX_REMOTE_OBJ_INFO_LINE)
831 die(_("remote-object-info command too long"));
832
833 line_to_split = xstrdup(line);
834 count = split_cmdline(line_to_split, &argv);
835 if (count < 0)
836 die(_("remote-object-info: failed to parse command line: %s"),
837 split_cmdline_strerror(count));
838 if (count - 1 > MAX_ALLOWED_OBJ_LIMIT)
839 die(_("remote-object-info supports at most %d objects"),
840 MAX_ALLOWED_OBJ_LIMIT);
841
842 if (data->info.sizep)
843 results.wants_size = 1;
844 if (data->info.typep)
845 results.wants_type = 1;
846
847 if (get_remote_info(count, argv, &results, &object_info_oids))
848 die(_("failed to get object info from the remote: %s"), argv[0]);
849
850 string_list_clear(&data->remote_allowed_atoms, 0);
851 string_list_append(&data->remote_allowed_atoms, "objectname");
852 if (results.sizes)
853 string_list_append(&data->remote_allowed_atoms, "objectsize");
854 if (results.types)
855 string_list_append(&data->remote_allowed_atoms, "objecttype");
856
857 data->skip_object_info = 1;
858 for (size_t i = 0; i < results.nr; i++) {
859 data->oid = object_info_oids.oid[i];
860
861 if (results.unrecognized[i]) {
862 report_object_status(opt, oid_to_hex(&data->oid),
863 &data->oid, "missing");
864 continue;
865 }
866
867 /*
868 * When reaching here, it means remote-object-info can retrieve
869 * information from server without downloading them.
870 */
871 if (results.sizes)
872 data->size = results.sizes[i];
873
874 if (results.types)
875 data->type = results.types[i];
876
877 opt->batch_mode = BATCH_MODE_INFO;
878 data->is_remote = 1;
879 batch_object_write(argv[i + 1], output, opt, data, NULL, 0);
880 data->is_remote = 0;
881 }
882 data->skip_object_info = 0;
883
884 free_fetch_object_info_results(&results);
885 free(line_to_split);
886 free(argv);
887 oid_array_clear(&object_info_oids);
888 }
889
890 static void dispatch_calls(struct batch_options *opt,
891 struct strbuf *output,
892 struct expand_data *data,
893 struct queued_cmd *cmd,
894 size_t nr)
895 {
896 if (!opt->buffer_output)
897 die(_("flush is only for --buffer mode"));
898
899 for (size_t i = 0; i < nr; i++)
900 cmd[i].fn(opt, cmd[i].line, output, data);
901
902 fflush(stdout);
903 }
904
905 static void free_cmds(struct queued_cmd *cmd, size_t *nr)
906 {
907 for (size_t i = 0; i < *nr; i++)
908 FREE_AND_NULL(cmd[i].line);
909
910 *nr = 0;
911 }
912
913
914 static const struct parse_cmd {
915 const char *name;
916 parse_cmd_fn_t fn;
917 unsigned takes_args;
918 } commands[] = {
919 { "contents", parse_cmd_contents, 1 },
920 { "flush", NULL, 0 },
921 { "info", parse_cmd_info, 1 },
922 { "mailmap", parse_cmd_mailmap, 1 },
923 { "remote-object-info", parse_cmd_remote_object_info, 1 },
924 };
925
926 static void batch_objects_command(struct batch_options *opt,
927 struct strbuf *output,
928 struct expand_data *data)
929 {
930 struct strbuf input = STRBUF_INIT;
931 struct queued_cmd *queued_cmd = NULL;
932 size_t alloc = 0, nr = 0;
933
934 while (strbuf_getdelim_strip_crlf(&input, stdin, opt->input_delim) != EOF) {
935 const struct parse_cmd *cmd = NULL;
936 const char *p = NULL, *cmd_end;
937 struct queued_cmd call = {0};
938
939 if (!input.len)
940 die(_("empty command in input"));
941 if (isspace(*input.buf))
942 die(_("whitespace before command: '%s'"), input.buf);
943
944 for (size_t i = 0; i < ARRAY_SIZE(commands); i++) {
945 if (!skip_prefix(input.buf, commands[i].name, &cmd_end))
946 continue;
947
948 cmd = &commands[i];
949 if (cmd->takes_args) {
950 if (*cmd_end != ' ')
951 die(_("%s requires arguments"),
952 commands[i].name);
953
954 p = cmd_end + 1;
955 } else if (*cmd_end) {
956 die(_("%s takes no arguments"),
957 commands[i].name);
958 }
959
960 break;
961 }
962
963 if (!cmd)
964 die(_("unknown command: '%s'"), input.buf);
965
966 if (!strcmp(cmd->name, "flush")) {
967 dispatch_calls(opt, output, data, queued_cmd, nr);
968 free_cmds(queued_cmd, &nr);
969 } else if (!opt->buffer_output) {
970 cmd->fn(opt, p, output, data);
971 } else {
972 ALLOC_GROW(queued_cmd, nr + 1, alloc);
973 call.fn = cmd->fn;
974 call.line = xstrdup_or_null(p);
975 queued_cmd[nr++] = call;
976 }
977 }
978
979 if (opt->buffer_output &&
980 nr &&
981 !git_env_bool("GIT_TEST_CAT_FILE_NO_FLUSH_ON_EXIT", 0)) {
982 dispatch_calls(opt, output, data, queued_cmd, nr);
983 free_cmds(queued_cmd, &nr);
984 }
985
986 free_cmds(queued_cmd, &nr);
987 free(queued_cmd);
988 strbuf_release(&input);
989 }
990
991 #define DEFAULT_FORMAT "%(objectname) %(objecttype) %(objectsize)"
992
993 typedef int (*for_each_object_fn)(const struct object_id *oid, struct packed_git *pack,
994 off_t offset, void *data);
995
996 struct for_each_object_payload {
997 for_each_object_fn callback;
998 void *payload;
999 };
1000
1001 static int batch_one_object_oi(const struct object_id *oid,
1002 struct object_info *oi,
1003 void *_payload)
1004 {
1005 struct for_each_object_payload *payload = _payload;
1006 if (oi && oi->source_infop->source->type == ODB_SOURCE_PACKED)
1007 return payload->callback(oid, oi->source_infop->u.packed.pack,
1008 oi->source_infop->u.packed.offset,
1009 payload->payload);
1010 return payload->callback(oid, NULL, 0, payload->payload);
1011 }
1012
1013 static void batch_each_object(struct batch_options *opt,
1014 for_each_object_fn callback,
1015 unsigned flags,
1016 void *_payload)
1017 {
1018 struct for_each_object_payload payload = {
1019 .callback = callback,
1020 .payload = _payload,
1021 };
1022 struct odb_source_info source_info;
1023 struct object_info oi = {
1024 .source_infop = &source_info,
1025 };
1026 struct odb_for_each_object_options opts = {
1027 .flags = flags,
1028 .filter = &opt->objects_filter,
1029 };
1030
1031 odb_for_each_object_ext(the_repository->objects, &oi,
1032 batch_one_object_oi, &payload, &opts);
1033 }
1034
1035 static int batch_objects(struct batch_options *opt)
1036 {
1037 struct strbuf input = STRBUF_INIT;
1038 struct strbuf output = STRBUF_INIT;
1039 struct expand_data data = EXPAND_DATA_INIT;
1040 struct repo_config_values *cfg = repo_config_values(the_repository);
1041 int save_warning;
1042 int retval = 0;
1043
1044 /*
1045 * Expand once with our special mark_query flag, which will prime the
1046 * object_info to be handed to odb_read_object_info_extended for each
1047 * object.
1048 */
1049 data.mark_query = 1;
1050 expand_format(&output,
1051 opt->format ? opt->format : DEFAULT_FORMAT,
1052 &data);
1053 data.mark_query = 0;
1054 strbuf_release(&output);
1055 if (opt->transform_mode)
1056 data.split_on_whitespace = 1;
1057
1058 if (opt->format && !strcmp(opt->format, DEFAULT_FORMAT))
1059 opt->format = NULL;
1060 /*
1061 * If we are printing out the object, then always fill in the type,
1062 * since we will want to decide whether or not to stream.
1063 */
1064 if (opt->batch_mode == BATCH_MODE_CONTENTS)
1065 data.info.typep = &data.type;
1066
1067 if (opt->all_objects) {
1068 struct object_cb_data cb;
1069 struct object_info empty = OBJECT_INFO_INIT;
1070
1071 if (!memcmp(&data.info, &empty, sizeof(empty)) &&
1072 opt->objects_filter.choice == LOFC_DISABLED)
1073 data.skip_object_info = 1;
1074
1075 if (repo_has_promisor_remote(the_repository))
1076 warning("This repository uses promisor remotes. Some objects may not be loaded.");
1077
1078 disable_replace_refs();
1079
1080 cb.opt = opt;
1081 cb.expand = &data;
1082 cb.scratch = &output;
1083
1084 if (opt->unordered) {
1085 struct oidset seen = OIDSET_INIT;
1086
1087 cb.seen = &seen;
1088
1089 batch_each_object(opt, batch_unordered_object,
1090 ODB_FOR_EACH_OBJECT_PACK_ORDER, &cb);
1091
1092 oidset_clear(&seen);
1093 } else {
1094 struct oid_array sa = OID_ARRAY_INIT;
1095
1096 batch_each_object(opt, collect_object, 0, &sa);
1097 oid_array_for_each_unique(&sa, batch_object_cb, &cb);
1098
1099 oid_array_clear(&sa);
1100 }
1101
1102 strbuf_release(&output);
1103 return 0;
1104 }
1105
1106 /*
1107 * We are going to call get_sha1 on a potentially very large number of
1108 * objects. In most large cases, these will be actual object sha1s. The
1109 * cost to double-check that each one is not also a ref (just so we can
1110 * warn) ends up dwarfing the actual cost of the object lookups
1111 * themselves. We can work around it by just turning off the warning.
1112 */
1113 save_warning = cfg->warn_on_object_refname_ambiguity;
1114 cfg->warn_on_object_refname_ambiguity = 0;
1115
1116 if (opt->batch_mode == BATCH_MODE_QUEUE_AND_DISPATCH) {
1117 batch_objects_command(opt, &output, &data);
1118 goto cleanup;
1119 }
1120
1121 while (strbuf_getdelim_strip_crlf(&input, stdin, opt->input_delim) != EOF) {
1122 if (data.split_on_whitespace) {
1123 /*
1124 * Split at first whitespace, tying off the beginning
1125 * of the string and saving the remainder (or NULL) in
1126 * data.rest.
1127 */
1128 char *p = strpbrk(input.buf, " \t");
1129 if (p) {
1130 while (*p && strchr(" \t", *p))
1131 *p++ = '\0';
1132 }
1133 data.rest = p;
1134 }
1135
1136 batch_one_object(input.buf, &output, opt, &data);
1137 }
1138
1139 cleanup:
1140 strbuf_release(&input);
1141 strbuf_release(&output);
1142 string_list_clear(&data.remote_allowed_atoms, 0);
1143 cfg->warn_on_object_refname_ambiguity = save_warning;
1144 return retval;
1145 }
1146
1147 static int git_cat_file_config(const char *var, const char *value,
1148 const struct config_context *ctx, void *cb)
1149 {
1150 if (userdiff_config(var, value) < 0)
1151 return -1;
1152
1153 return git_default_config(var, value, ctx, cb);
1154 }
1155
1156 static int batch_option_callback(const struct option *opt,
1157 const char *arg,
1158 int unset)
1159 {
1160 struct batch_options *bo = opt->value;
1161
1162 BUG_ON_OPT_NEG(unset);
1163
1164 if (bo->enabled) {
1165 return error(_("only one batch option may be specified"));
1166 }
1167
1168 bo->enabled = 1;
1169
1170 if (!strcmp(opt->long_name, "batch"))
1171 bo->batch_mode = BATCH_MODE_CONTENTS;
1172 else if (!strcmp(opt->long_name, "batch-check"))
1173 bo->batch_mode = BATCH_MODE_INFO;
1174 else if (!strcmp(opt->long_name, "batch-command"))
1175 bo->batch_mode = BATCH_MODE_QUEUE_AND_DISPATCH;
1176 else
1177 BUG("%s given to batch-option-callback", opt->long_name);
1178
1179 bo->format = arg;
1180
1181 return 0;
1182 }
1183
1184 int cmd_cat_file(int argc,
1185 const char **argv,
1186 const char *prefix,
1187 struct repository *repo UNUSED)
1188 {
1189 int opt = 0;
1190 int opt_cw = 0;
1191 int opt_epts = 0;
1192 const char *exp_type = NULL, *obj_name = NULL;
1193 struct batch_options batch = {
1194 .objects_filter = LIST_OBJECTS_FILTER_INIT,
1195 };
1196 int unknown_type = 0;
1197 int input_nul_terminated = 0;
1198 int nul_terminated = 0;
1199 int ret;
1200
1201 const char * const builtin_catfile_usage[] = {
1202 N_("git cat-file <type> <object>"),
1203 N_("git cat-file (-e | -p | -t | -s) <object>"),
1204 N_("git cat-file (--textconv | --filters)\n"
1205 " [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]"),
1206 N_("git cat-file (--batch | --batch-check | --batch-command) [--batch-all-objects]\n"
1207 " [--buffer] [--follow-symlinks] [--unordered]\n"
1208 " [--textconv | --filters] [-Z]"),
1209 NULL
1210 };
1211 const struct option options[] = {
1212 /* Simple queries */
1213 OPT_GROUP(N_("Check object existence or emit object contents")),
1214 OPT_CMDMODE('e', NULL, &opt,
1215 N_("check if <object> exists"), 'e'),
1216 OPT_CMDMODE('p', NULL, &opt, N_("pretty-print <object> content"), 'p'),
1217
1218 OPT_GROUP(N_("Emit [broken] object attributes")),
1219 OPT_CMDMODE('t', NULL, &opt, N_("show object type (one of 'blob', 'tree', 'commit', 'tag', ...)"), 't'),
1220 OPT_CMDMODE('s', NULL, &opt, N_("show object size"), 's'),
1221 OPT_HIDDEN_BOOL(0, "allow-unknown-type", &unknown_type,
1222 N_("historical option -- no-op")),
1223 OPT_BOOL(0, "use-mailmap", &use_mailmap, N_("use mail map file")),
1224 OPT_ALIAS(0, "mailmap", "use-mailmap"),
1225 /* Batch mode */
1226 OPT_GROUP(N_("Batch objects requested on stdin (or --batch-all-objects)")),
1227 OPT_CALLBACK_F(0, "batch", &batch, N_("format"),
1228 N_("show full <object> or <rev> contents"),
1229 PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
1230 batch_option_callback),
1231 OPT_CALLBACK_F(0, "batch-check", &batch, N_("format"),
1232 N_("like --batch, but don't emit <contents>"),
1233 PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
1234 batch_option_callback),
1235 OPT_BOOL_F('z', NULL, &input_nul_terminated, N_("stdin is NUL-terminated"),
1236 PARSE_OPT_HIDDEN),
1237 OPT_BOOL('Z', NULL, &nul_terminated, N_("stdin and stdout is NUL-terminated")),
1238 OPT_CALLBACK_F(0, "batch-command", &batch, N_("format"),
1239 N_("read commands from stdin"),
1240 PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
1241 batch_option_callback),
1242 OPT_CMDMODE(0, "batch-all-objects", &opt,
1243 N_("with --batch[-check]: ignores stdin, batches all known objects"), 'b'),
1244 /* Batch-specific options */
1245 OPT_GROUP(N_("Change or optimize batch output")),
1246 OPT_BOOL(0, "buffer", &batch.buffer_output, N_("buffer --batch output")),
1247 OPT_BOOL(0, "follow-symlinks", &batch.follow_symlinks,
1248 N_("follow in-tree symlinks")),
1249 OPT_BOOL(0, "unordered", &batch.unordered,
1250 N_("do not order objects before emitting them")),
1251 /* Textconv options, stand-ole*/
1252 OPT_GROUP(N_("Emit object (blob or tree) with conversion or filter (stand-alone, or with batch)")),
1253 OPT_CMDMODE(0, "textconv", &opt,
1254 N_("run textconv on object's content"), 'c'),
1255 OPT_CMDMODE(0, "filters", &opt,
1256 N_("run filters on object's content"), 'w'),
1257 OPT_STRING(0, "path", &force_path, N_("blob|tree"),
1258 N_("use a <path> for (--textconv | --filters); Not with 'batch'")),
1259 OPT_PARSE_LIST_OBJECTS_FILTER(&batch.objects_filter),
1260 OPT_END()
1261 };
1262
1263 repo_config(the_repository, git_cat_file_config, NULL);
1264
1265 batch.buffer_output = -1;
1266
1267 argc = parse_options(argc, argv, prefix, options, builtin_catfile_usage, 0);
1268 opt_cw = (opt == 'c' || opt == 'w');
1269 opt_epts = (opt == 'e' || opt == 'p' || opt == 't' || opt == 's');
1270
1271 if (use_mailmap)
1272 load_mailmap();
1273
1274 switch (batch.objects_filter.choice) {
1275 case LOFC_DISABLED:
1276 break;
1277 case LOFC_BLOB_NONE:
1278 case LOFC_BLOB_LIMIT:
1279 case LOFC_OBJECT_TYPE:
1280 if (!batch.enabled)
1281 usage(_("objects filter only supported in batch mode"));
1282 break;
1283 default:
1284 usagef(_("objects filter not supported: '%s'"),
1285 list_object_filter_config_name(batch.objects_filter.choice));
1286 }
1287
1288 /* --batch-all-objects? */
1289 if (opt == 'b')
1290 batch.all_objects = 1;
1291
1292 /* Option compatibility */
1293 if (force_path && !opt_cw)
1294 usage_msg_optf(_("'%s=<%s>' needs '%s' or '%s'"),
1295 builtin_catfile_usage, options,
1296 "--path", _("path|tree-ish"), "--filters",
1297 "--textconv");
1298
1299 /* Option compatibility with batch mode */
1300 if (batch.enabled)
1301 ;
1302 else if (batch.follow_symlinks)
1303 usage_msg_optf(_("'%s' requires a batch mode"), builtin_catfile_usage,
1304 options, "--follow-symlinks");
1305 else if (batch.buffer_output >= 0)
1306 usage_msg_optf(_("'%s' requires a batch mode"), builtin_catfile_usage,
1307 options, "--buffer");
1308 else if (batch.all_objects)
1309 usage_msg_optf(_("'%s' requires a batch mode"), builtin_catfile_usage,
1310 options, "--batch-all-objects");
1311 else if (input_nul_terminated)
1312 usage_msg_optf(_("'%s' requires a batch mode"), builtin_catfile_usage,
1313 options, "-z");
1314 else if (nul_terminated)
1315 usage_msg_optf(_("'%s' requires a batch mode"), builtin_catfile_usage,
1316 options, "-Z");
1317
1318 batch.input_delim = batch.output_delim = '\n';
1319 if (input_nul_terminated)
1320 batch.input_delim = '\0';
1321 if (nul_terminated)
1322 batch.input_delim = batch.output_delim = '\0';
1323
1324 /* Batch defaults */
1325 if (batch.buffer_output < 0)
1326 batch.buffer_output = batch.all_objects;
1327
1328 prepare_repo_settings(the_repository);
1329 the_repository->settings.command_requires_full_index = 0;
1330
1331 /* Return early if we're in batch mode? */
1332 if (batch.enabled) {
1333 if (opt_cw)
1334 batch.transform_mode = opt;
1335 else if (opt && opt != 'b')
1336 usage_msg_optf(_("'-%c' is incompatible with batch mode"),
1337 builtin_catfile_usage, options, opt);
1338 else if (argc)
1339 usage_msg_opt(_("batch modes take no arguments"),
1340 builtin_catfile_usage, options);
1341
1342 ret = batch_objects(&batch);
1343 goto out;
1344 }
1345
1346 if (opt) {
1347 if (!argc && opt == 'c')
1348 usage_msg_optf(_("<rev> required with '%s'"),
1349 builtin_catfile_usage, options,
1350 "--textconv");
1351 else if (!argc && opt == 'w')
1352 usage_msg_optf(_("<rev> required with '%s'"),
1353 builtin_catfile_usage, options,
1354 "--filters");
1355 else if (!argc && opt_epts)
1356 usage_msg_optf(_("<object> required with '-%c'"),
1357 builtin_catfile_usage, options, opt);
1358 else if (argc == 1)
1359 obj_name = argv[0];
1360 else
1361 usage_msg_opt(_("too many arguments"), builtin_catfile_usage,
1362 options);
1363 } else if (!argc) {
1364 usage_with_options(builtin_catfile_usage, options);
1365 } else if (argc != 2) {
1366 usage_msg_optf(_("only two arguments allowed in <type> <object> mode, not %d"),
1367 builtin_catfile_usage, options, argc);
1368 } else if (argc) {
1369 exp_type = argv[0];
1370 obj_name = argv[1];
1371 }
1372
1373 ret = cat_one_file(opt, exp_type, obj_name);
1374
1375 out:
1376 list_objects_filter_release(&batch.objects_filter);
1377 return ret;
1378 }