9
#include "userdiff.h"
10
#include "streaming.h"
11
12
-static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
12
+static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
13
+ int unknown_type)
14
{
15
unsigned char sha1[20];
16
enum object_type type;
17
char *buf;
18
unsigned long size;
19
struct object_context obj_context;
20
+ struct object_info oi = {NULL};
21
+ struct strbuf sb = STRBUF_INIT;
22
+ unsigned flags = LOOKUP_REPLACE_OBJECT;
23
+
24
+ if (unknown_type)
25
+ flags |= LOOKUP_UNKNOWN_OBJECT;
26
27
if (get_sha1_with_context(obj_name, 0, sha1, &obj_context))
28
die("Not a valid object name %s", obj_name);
30
buf = NULL;
31
switch (opt) {
32
case 't':
26
- type = sha1_object_info(sha1, NULL);
27
- if (type > 0) {
28
- printf("%s\n", typename(type));
33
+ oi.typename = &sb;
34
+ if (sha1_object_info_extended(sha1, &oi, flags) < 0)
35
+ die("git cat-file: could not get object info");
36
+ if (sb.len) {
37
+ printf("%s\n", sb.buf);
38
+ strbuf_release(&sb);
39
return 0;
40
}
41
break;
42
43
case 's':
34
- type = sha1_object_info(sha1, &size);
35
- if (type > 0) {
36
- printf("%lu\n", size);
37
- return 0;
38
- }
39
- break;
44
+ oi.sizep = &size;
45
+ if (sha1_object_info_extended(sha1, &oi, flags) < 0)
46
+ die("git cat-file: could not get object info");
47
+ printf("%lu\n", size);
48
+ return 0;
49
50
case 'e':
51
return !has_sha1_file(sha1);
332
}
333
334
static const char * const cat_file_usage[] = {
326
- N_("git cat-file (-t | -s | -e | -p | <type> | --textconv) <object>"),
335
+ N_("git cat-file (-t [--allow-unknown-type]|-s [--allow-unknown-type]|-e|-p|<type>|--textconv) <object>"),
336
N_("git cat-file (--batch | --batch-check) < <list-of-objects>"),
337
NULL
338
};
368
int opt = 0;
369
const char *exp_type = NULL, *obj_name = NULL;
370
struct batch_options batch = {0};
371
+ int unknown_type = 0;
372
373
const struct option options[] = {
374
OPT_GROUP(N_("<type> can be one of: blob, tree, commit, tag")),
379
OPT_CMDMODE('p', NULL, &opt, N_("pretty-print object's content"), 'p'),
380
OPT_CMDMODE(0, "textconv", &opt,
381
N_("for blob objects, run textconv on object's content"), 'c'),
382
+ OPT_BOOL( 0, "allow-unknown-type", &unknown_type,
383
+ N_("allow -s and -t to work with broken/corrupt objects")),
384
{ OPTION_CALLBACK, 0, "batch", &batch, "format",
385
N_("show info and content of objects fed from the standard input"),
386
PARSE_OPT_OPTARG, batch_option_callback },
414
if (batch.enabled)
415
return batch_objects(&batch);
416
405
- return cat_one_file(opt, exp_type, obj_name);
417
+ if (unknown_type && opt != 't' && opt != 's')
418
+ die("git cat-file --allow-unknown-type: use with -s or -t");
419
+ return cat_one_file(opt, exp_type, obj_name, unknown_type);
420
}