Skip to content

Commit 39e4ae3

Browse files
KarthikNayakgitster
authored andcommitted
cat-file: teach cat-file a '--allow-unknown-type' option
'git cat-file' throws an error while trying to print the type or size of a broken/corrupt object. This is because these objects are usually of unknown types. Teach git cat-file a '--allow-unknown-type' option where it prints the type or size of a broken/corrupt object without throwing an error. Modify '-t' and '-s' options to call sha1_object_info_extended() directly to support the '--allow-unknown-type' option. Add documentation for 'cat-file --allow-unknown-type'. Helped-by: Junio C Hamano <[email protected]> Helped-by: Eric Sunshine <[email protected]> Signed-off-by: Karthik Nayak <[email protected]> cat-file: add documentation for '--allow-unknown-type' option. Signed-off-by: Karthik Nayak <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b48158a commit 39e4ae3

File tree

2 files changed

+30
-13
lines changed

2 files changed

+30
-13
lines changed

Documentation/git-cat-file.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ git-cat-file - Provide content or type and size information for repository objec
99
SYNOPSIS
1010
--------
1111
[verse]
12-
'git cat-file' (-t | -s | -e | -p | <type> | --textconv ) <object>
12+
'git cat-file' (-t [--allow-unknown-type]| -s [--allow-unknown-type]| -e | -p | <type> | --textconv ) <object>
1313
'git cat-file' (--batch | --batch-check) < <list-of-objects>
1414

1515
DESCRIPTION
@@ -69,6 +69,9 @@ OPTIONS
6969
not be combined with any other options or arguments. See the
7070
section `BATCH OUTPUT` below for details.
7171

72+
--allow-unknown-type::
73+
Allow -s or -t to query broken/corrupt objects of unknown type.
74+
7275
OUTPUT
7376
------
7477
If '-t' is specified, one of the <type>.

builtin/cat-file.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,43 @@
99
#include "userdiff.h"
1010
#include "streaming.h"
1111

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)
1314
{
1415
unsigned char sha1[20];
1516
enum object_type type;
1617
char *buf;
1718
unsigned long size;
1819
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;
1926

2027
if (get_sha1_with_context(obj_name, 0, sha1, &obj_context))
2128
die("Not a valid object name %s", obj_name);
2229

2330
buf = NULL;
2431
switch (opt) {
2532
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);
2939
return 0;
3040
}
3141
break;
3242

3343
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;
4049

4150
case 'e':
4251
return !has_sha1_file(sha1);
@@ -323,7 +332,7 @@ static int batch_objects(struct batch_options *opt)
323332
}
324333

325334
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>"),
327336
N_("git cat-file (--batch | --batch-check) < <list-of-objects>"),
328337
NULL
329338
};
@@ -359,6 +368,7 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
359368
int opt = 0;
360369
const char *exp_type = NULL, *obj_name = NULL;
361370
struct batch_options batch = {0};
371+
int unknown_type = 0;
362372

363373
const struct option options[] = {
364374
OPT_GROUP(N_("<type> can be one of: blob, tree, commit, tag")),
@@ -369,6 +379,8 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
369379
OPT_CMDMODE('p', NULL, &opt, N_("pretty-print object's content"), 'p'),
370380
OPT_CMDMODE(0, "textconv", &opt,
371381
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")),
372384
{ OPTION_CALLBACK, 0, "batch", &batch, "format",
373385
N_("show info and content of objects fed from the standard input"),
374386
PARSE_OPT_OPTARG, batch_option_callback },
@@ -402,5 +414,7 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
402414
if (batch.enabled)
403415
return batch_objects(&batch);
404416

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);
406420
}

0 commit comments

Comments
 (0)