summaryrefslogtreecommitdiff
path: root/builtin/cat-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/cat-file.c')
-rw-r--r--builtin/cat-file.c361
1 files changed, 239 insertions, 122 deletions
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index bfdfb51c7c..5ca2ca3852 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -3,7 +3,10 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "convert.h"
@@ -12,14 +15,16 @@
#include "gettext.h"
#include "hex.h"
#include "ident.h"
+#include "list-objects-filter-options.h"
#include "parse-options.h"
#include "userdiff.h"
#include "streaming.h"
#include "oid-array.h"
#include "packfile.h"
+#include "pack-bitmap.h"
#include "object-file.h"
#include "object-name.h"
-#include "object-store-ll.h"
+#include "odb.h"
#include "replace-object.h"
#include "promisor-remote.h"
#include "mailmap.h"
@@ -32,6 +37,7 @@ enum batch_mode {
};
struct batch_options {
+ struct list_objects_filter_options objects_filter;
int enabled;
int follow_symlinks;
enum batch_mode batch_mode;
@@ -68,7 +74,7 @@ static int filter_object(const char *path, unsigned mode,
{
enum object_type type;
- *buf = repo_read_object_file(the_repository, oid, &type, size);
+ *buf = odb_read_object(the_repository->objects, oid, &type, size);
if (!*buf)
return error(_("cannot read object %s '%s'"),
oid_to_hex(oid), path);
@@ -94,8 +100,7 @@ static int stream_blob(const struct object_id *oid)
return 0;
}
-static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
- int unknown_type)
+static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
{
int ret;
struct object_id oid;
@@ -104,7 +109,6 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
unsigned long size;
struct object_context obj_context = {0};
struct object_info oi = OBJECT_INFO_INIT;
- struct strbuf sb = STRBUF_INIT;
unsigned flags = OBJECT_INFO_LOOKUP_REPLACE;
unsigned get_oid_flags =
GET_OID_RECORD_PATH |
@@ -115,9 +119,6 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
if (!path && opt_cw)
get_oid_flags |= GET_OID_REQUIRE_PATH;
- if (unknown_type)
- flags |= OBJECT_INFO_ALLOW_UNKNOWN_TYPE;
-
if (get_oid_with_context(the_repository, obj_name, get_oid_flags, &oid,
&obj_context))
die("Not a valid object name %s", obj_name);
@@ -130,16 +131,12 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
buf = NULL;
switch (opt) {
case 't':
- oi.type_name = &sb;
- if (oid_object_info_extended(the_repository, &oid, &oi, flags) < 0)
+ oi.typep = &type;
+ if (odb_read_object_info_extended(the_repository->objects, &oid, &oi, flags) < 0)
die("git cat-file: could not get object info");
- if (sb.len) {
- printf("%s\n", sb.buf);
- strbuf_release(&sb);
- ret = 0;
- goto cleanup;
- }
- break;
+ printf("%s\n", type_name(type));
+ ret = 0;
+ goto cleanup;
case 's':
oi.sizep = &size;
@@ -149,7 +146,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
oi.contentp = (void**)&buf;
}
- if (oid_object_info_extended(the_repository, &oid, &oi, flags) < 0)
+ if (odb_read_object_info_extended(the_repository->objects, &oid, &oi, flags) < 0)
die("git cat-file: could not get object info");
if (use_mailmap && (type == OBJ_COMMIT || type == OBJ_TAG)) {
@@ -163,7 +160,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
goto cleanup;
case 'e':
- ret = !repo_has_object_file(the_repository, &oid);
+ ret = !odb_has_object(the_repository->objects, &oid,
+ HAS_OBJECT_RECHECK_PACKED | HAS_OBJECT_FETCH_PROMISOR);
goto cleanup;
case 'w':
@@ -182,7 +180,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
/* else fallthrough */
case 'p':
- type = oid_object_info(the_repository, &oid, NULL);
+ type = odb_read_object_info(the_repository->objects, &oid, NULL);
if (type < 0)
die("Not a valid object name %s", obj_name);
@@ -199,8 +197,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
ret = stream_blob(&oid);
goto cleanup;
}
- buf = repo_read_object_file(the_repository, &oid, &type,
- &size);
+ buf = odb_read_object(the_repository->objects, &oid,
+ &type, &size);
if (!buf)
die("Cannot read object %s", obj_name);
@@ -219,11 +217,10 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
if (exp_type_id == OBJ_BLOB) {
struct object_id blob_oid;
- if (oid_object_info(the_repository, &oid, NULL) == OBJ_TAG) {
- char *buffer = repo_read_object_file(the_repository,
- &oid,
- &type,
- &size);
+ if (odb_read_object_info(the_repository->objects,
+ &oid, NULL) == OBJ_TAG) {
+ char *buffer = odb_read_object(the_repository->objects,
+ &oid, &type, &size);
const char *target;
if (!buffer)
@@ -237,7 +234,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
} else
oidcpy(&blob_oid, &oid);
- if (oid_object_info(the_repository, &blob_oid, NULL) == OBJ_BLOB) {
+ if (odb_read_object_info(the_repository->objects,
+ &blob_oid, NULL) == OBJ_BLOB) {
ret = stream_blob(&blob_oid);
goto cleanup;
}
@@ -248,8 +246,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
* fall-back to the usual case.
*/
}
- buf = read_object_with_reference(the_repository, &oid,
- exp_type_id, &size, NULL);
+ buf = odb_read_object_peeled(the_repository->objects, &oid,
+ exp_type_id, &size, NULL);
if (use_mailmap) {
size_t s = size;
@@ -277,6 +275,7 @@ struct expand_data {
struct object_id oid;
enum object_type type;
unsigned long size;
+ unsigned short mode;
off_t disk_size;
const char *rest;
struct object_id delta_base_oid;
@@ -296,7 +295,7 @@ struct expand_data {
/*
* After a mark_query run, this object_info is set up to be
- * passed to oid_object_info_extended. It will point to the data
+ * passed to odb_read_object_info_extended. It will point to the data
* elements above, so you can retrieve the response from there.
*/
struct object_info info;
@@ -308,6 +307,7 @@ struct expand_data {
*/
unsigned skip_object_info : 1;
};
+#define EXPAND_DATA_INIT { .mode = S_IFINVALID }
static int is_atom(const char *atom, const char *s, int slen)
{
@@ -347,6 +347,9 @@ static int expand_atom(struct strbuf *sb, const char *atom, int len,
else
strbuf_addstr(sb,
oid_to_hex(&data->delta_base_oid));
+ } else if (is_atom("objectmode", atom, len)) {
+ if (!data->mark_query && !(S_IFINVALID == data->mode))
+ strbuf_addf(sb, "%06o", data->mode);
} else
return 0;
return 1;
@@ -403,10 +406,8 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
if (!textconv_object(the_repository,
data->rest, 0100644, oid,
1, &contents, &size))
- contents = repo_read_object_file(the_repository,
- oid,
- &type,
- &size);
+ contents = odb_read_object(the_repository->objects,
+ oid, &type, &size);
if (!contents)
die("could not convert '%s' %s",
oid_to_hex(oid), data->rest);
@@ -423,8 +424,8 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
unsigned long size;
void *contents;
- contents = repo_read_object_file(the_repository, oid, &type,
- &size);
+ contents = odb_read_object(the_repository->objects, oid,
+ &type, &size);
if (!contents)
die("object %s disappeared", oid_to_hex(oid));
@@ -452,6 +453,16 @@ static void print_default_format(struct strbuf *scratch, struct expand_data *dat
(uintmax_t)data->size, opt->output_delim);
}
+static void report_object_status(struct batch_options *opt,
+ const char *obj_name,
+ const struct object_id *oid,
+ const char *status)
+{
+ printf("%s %s%c", obj_name ? obj_name : oid_to_hex(oid),
+ status, opt->output_delim);
+ fflush(stdout);
+}
+
/*
* If "pack" is non-NULL, then "offset" is the byte offset within the pack from
* which the object may be accessed (though note that we may also rely on
@@ -467,29 +478,67 @@ static void batch_object_write(const char *obj_name,
if (!data->skip_object_info) {
int ret;
- if (use_mailmap)
+ if (use_mailmap ||
+ opt->objects_filter.choice == LOFC_BLOB_NONE ||
+ opt->objects_filter.choice == LOFC_BLOB_LIMIT ||
+ opt->objects_filter.choice == LOFC_OBJECT_TYPE)
data->info.typep = &data->type;
+ if (opt->objects_filter.choice == LOFC_BLOB_LIMIT)
+ data->info.sizep = &data->size;
if (pack)
- ret = packed_object_info(the_repository, pack, offset,
- &data->info);
+ ret = packed_object_info(the_repository, pack,
+ offset, &data->info);
else
- ret = oid_object_info_extended(the_repository,
- &data->oid, &data->info,
- OBJECT_INFO_LOOKUP_REPLACE);
+ ret = odb_read_object_info_extended(the_repository->objects,
+ &data->oid, &data->info,
+ OBJECT_INFO_LOOKUP_REPLACE);
if (ret < 0) {
- printf("%s missing%c",
- obj_name ? obj_name : oid_to_hex(&data->oid), opt->output_delim);
- fflush(stdout);
+ if (data->mode == S_IFGITLINK)
+ report_object_status(opt, NULL, &data->oid, "submodule");
+ else
+ report_object_status(opt, obj_name, &data->oid, "missing");
return;
}
+ switch (opt->objects_filter.choice) {
+ case LOFC_DISABLED:
+ break;
+ case LOFC_BLOB_NONE:
+ if (data->type == OBJ_BLOB) {
+ if (!opt->all_objects)
+ report_object_status(opt, obj_name,
+ &data->oid, "excluded");
+ return;
+ }
+ break;
+ case LOFC_BLOB_LIMIT:
+ if (data->type == OBJ_BLOB &&
+ data->size >= opt->objects_filter.blob_limit_value) {
+ if (!opt->all_objects)
+ report_object_status(opt, obj_name,
+ &data->oid, "excluded");
+ return;
+ }
+ break;
+ case LOFC_OBJECT_TYPE:
+ if (data->type != opt->objects_filter.object_type) {
+ if (!opt->all_objects)
+ report_object_status(opt, obj_name,
+ &data->oid, "excluded");
+ return;
+ }
+ break;
+ default:
+ BUG("unsupported objects filter");
+ }
+
if (use_mailmap && (data->type == OBJ_COMMIT || data->type == OBJ_TAG)) {
size_t s = data->size;
char *buf = NULL;
- buf = repo_read_object_file(the_repository, &data->oid, &data->type,
- &data->size);
+ buf = odb_read_object(the_repository->objects, &data->oid,
+ &data->type, &data->size);
if (!buf)
die(_("unable to read %s"), oid_to_hex(&data->oid));
buf = replace_idents_using_mailmap(buf, &s);
@@ -532,10 +581,10 @@ static void batch_one_object(const char *obj_name,
if (result != FOUND) {
switch (result) {
case MISSING_OBJECT:
- printf("%s missing%c", obj_name, opt->output_delim);
+ report_object_status(opt, obj_name, &data->oid, "missing");
break;
case SHORT_NAME_AMBIGUOUS:
- printf("%s ambiguous%c", obj_name, opt->output_delim);
+ report_object_status(opt, obj_name, &data->oid, "ambiguous");
break;
case DANGLING_SYMLINK:
printf("dangling %"PRIuMAX"%c%s%c",
@@ -570,6 +619,7 @@ static void batch_one_object(const char *obj_name,
goto out;
}
+ data->mode = ctx.mode;
batch_object_write(obj_name, scratch, opt, data, NULL, 0);
out:
@@ -592,25 +642,18 @@ static int batch_object_cb(const struct object_id *oid, void *vdata)
return 0;
}
-static int collect_loose_object(const struct object_id *oid,
- const char *path UNUSED,
- void *data)
-{
- oid_array_append(data, oid);
- return 0;
-}
-
-static int collect_packed_object(const struct object_id *oid,
- struct packed_git *pack UNUSED,
- uint32_t pos UNUSED,
- void *data)
+static int collect_object(const struct object_id *oid,
+ struct packed_git *pack UNUSED,
+ off_t offset UNUSED,
+ void *data)
{
oid_array_append(data, oid);
return 0;
}
static int batch_unordered_object(const struct object_id *oid,
- struct packed_git *pack, off_t offset,
+ struct packed_git *pack,
+ off_t offset,
void *vdata)
{
struct object_cb_data *data = vdata;
@@ -624,23 +667,6 @@ static int batch_unordered_object(const struct object_id *oid,
return 0;
}
-static int batch_unordered_loose(const struct object_id *oid,
- const char *path UNUSED,
- void *data)
-{
- return batch_unordered_object(oid, NULL, 0, data);
-}
-
-static int batch_unordered_packed(const struct object_id *oid,
- struct packed_git *pack,
- uint32_t pos,
- void *data)
-{
- return batch_unordered_object(oid, pack,
- nth_packed_object_offset(pack, pos),
- data);
-}
-
typedef void (*parse_cmd_fn_t)(struct batch_options *, const char *,
struct strbuf *, struct expand_data *);
@@ -773,20 +799,90 @@ static void batch_objects_command(struct batch_options *opt,
#define DEFAULT_FORMAT "%(objectname) %(objecttype) %(objectsize)"
+typedef int (*for_each_object_fn)(const struct object_id *oid, struct packed_git *pack,
+ off_t offset, void *data);
+
+struct for_each_object_payload {
+ for_each_object_fn callback;
+ void *payload;
+};
+
+static int batch_one_object_loose(const struct object_id *oid,
+ const char *path UNUSED,
+ void *_payload)
+{
+ struct for_each_object_payload *payload = _payload;
+ return payload->callback(oid, NULL, 0, payload->payload);
+}
+
+static int batch_one_object_packed(const struct object_id *oid,
+ struct packed_git *pack,
+ uint32_t pos,
+ void *_payload)
+{
+ struct for_each_object_payload *payload = _payload;
+ return payload->callback(oid, pack, nth_packed_object_offset(pack, pos),
+ payload->payload);
+}
+
+static int batch_one_object_bitmapped(const struct object_id *oid,
+ enum object_type type UNUSED,
+ int flags UNUSED,
+ uint32_t hash UNUSED,
+ struct packed_git *pack,
+ off_t offset,
+ void *_payload)
+{
+ struct for_each_object_payload *payload = _payload;
+ return payload->callback(oid, pack, offset, payload->payload);
+}
+
+static void batch_each_object(struct batch_options *opt,
+ for_each_object_fn callback,
+ unsigned flags,
+ void *_payload)
+{
+ struct for_each_object_payload payload = {
+ .callback = callback,
+ .payload = _payload,
+ };
+ struct bitmap_index *bitmap = prepare_bitmap_git(the_repository);
+
+ for_each_loose_object(the_repository->objects, batch_one_object_loose, &payload, 0);
+
+ if (bitmap && !for_each_bitmapped_object(bitmap, &opt->objects_filter,
+ batch_one_object_bitmapped, &payload)) {
+ struct packfile_store *packs = the_repository->objects->packfiles;
+ struct packed_git *pack;
+
+ for (pack = packfile_store_get_all_packs(packs); pack; pack = pack->next) {
+ if (bitmap_index_contains_pack(bitmap, pack) ||
+ open_pack_index(pack))
+ continue;
+ for_each_object_in_pack(pack, batch_one_object_packed,
+ &payload, flags);
+ }
+ } else {
+ for_each_packed_object(the_repository, batch_one_object_packed,
+ &payload, flags);
+ }
+
+ free_bitmap_index(bitmap);
+}
+
static int batch_objects(struct batch_options *opt)
{
struct strbuf input = STRBUF_INIT;
struct strbuf output = STRBUF_INIT;
- struct expand_data data;
+ struct expand_data data = EXPAND_DATA_INIT;
int save_warning;
int retval = 0;
/*
* Expand once with our special mark_query flag, which will prime the
- * object_info to be handed to oid_object_info_extended for each
+ * object_info to be handed to odb_read_object_info_extended for each
* object.
*/
- memset(&data, 0, sizeof(data));
data.mark_query = 1;
expand_format(&output,
opt->format ? opt->format : DEFAULT_FORMAT,
@@ -809,7 +905,8 @@ static int batch_objects(struct batch_options *opt)
struct object_cb_data cb;
struct object_info empty = OBJECT_INFO_INIT;
- if (!memcmp(&data.info, &empty, sizeof(empty)))
+ if (!memcmp(&data.info, &empty, sizeof(empty)) &&
+ opt->objects_filter.choice == LOFC_DISABLED)
data.skip_object_info = 1;
if (repo_has_promisor_remote(the_repository))
@@ -826,17 +923,14 @@ static int batch_objects(struct batch_options *opt)
cb.seen = &seen;
- for_each_loose_object(batch_unordered_loose, &cb, 0);
- for_each_packed_object(batch_unordered_packed, &cb,
- FOR_EACH_OBJECT_PACK_ORDER);
+ batch_each_object(opt, batch_unordered_object,
+ FOR_EACH_OBJECT_PACK_ORDER, &cb);
oidset_clear(&seen);
} else {
struct oid_array sa = OID_ARRAY_INIT;
- for_each_loose_object(collect_loose_object, &sa, 0);
- for_each_packed_object(collect_packed_object, &sa, 0);
-
+ batch_each_object(opt, collect_object, 0, &sa);
oid_array_for_each_unique(&sa, batch_object_cb, &cb);
oid_array_clear(&sa);
@@ -932,15 +1026,17 @@ int cmd_cat_file(int argc,
int opt_cw = 0;
int opt_epts = 0;
const char *exp_type = NULL, *obj_name = NULL;
- struct batch_options batch = {0};
+ struct batch_options batch = {
+ .objects_filter = LIST_OBJECTS_FILTER_INIT,
+ };
int unknown_type = 0;
int input_nul_terminated = 0;
int nul_terminated = 0;
+ int ret;
- const char * const usage[] = {
+ const char * const builtin_catfile_usage[] = {
N_("git cat-file <type> <object>"),
- N_("git cat-file (-e | -p) <object>"),
- N_("git cat-file (-t | -s) [--allow-unknown-type] <object>"),
+ N_("git cat-file (-e | -p | -t | -s) <object>"),
N_("git cat-file (--textconv | --filters)\n"
" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]"),
N_("git cat-file (--batch | --batch-check | --batch-command) [--batch-all-objects]\n"
@@ -958,8 +1054,8 @@ int cmd_cat_file(int argc,
OPT_GROUP(N_("Emit [broken] object attributes")),
OPT_CMDMODE('t', NULL, &opt, N_("show object type (one of 'blob', 'tree', 'commit', 'tag', ...)"), 't'),
OPT_CMDMODE('s', NULL, &opt, N_("show object size"), 's'),
- OPT_BOOL(0, "allow-unknown-type", &unknown_type,
- N_("allow -s and -t to work with broken/corrupt objects")),
+ OPT_HIDDEN_BOOL(0, "allow-unknown-type", &unknown_type,
+ N_("historical option -- no-op")),
OPT_BOOL(0, "use-mailmap", &use_mailmap, N_("use mail map file")),
OPT_ALIAS(0, "mailmap", "use-mailmap"),
/* Batch mode */
@@ -996,20 +1092,35 @@ int cmd_cat_file(int argc,
N_("run filters on object's content"), 'w'),
OPT_STRING(0, "path", &force_path, N_("blob|tree"),
N_("use a <path> for (--textconv | --filters); Not with 'batch'")),
+ OPT_PARSE_LIST_OBJECTS_FILTER(&batch.objects_filter),
OPT_END()
};
- git_config(git_cat_file_config, NULL);
+ repo_config(the_repository, git_cat_file_config, NULL);
batch.buffer_output = -1;
- argc = parse_options(argc, argv, prefix, options, usage, 0);
+ argc = parse_options(argc, argv, prefix, options, builtin_catfile_usage, 0);
opt_cw = (opt == 'c' || opt == 'w');
opt_epts = (opt == 'e' || opt == 'p' || opt == 't' || opt == 's');
if (use_mailmap)
read_mailmap(&mailmap);
+ switch (batch.objects_filter.choice) {
+ case LOFC_DISABLED:
+ break;
+ case LOFC_BLOB_NONE:
+ case LOFC_BLOB_LIMIT:
+ case LOFC_OBJECT_TYPE:
+ if (!batch.enabled)
+ usage(_("objects filter only supported in batch mode"));
+ break;
+ default:
+ usagef(_("objects filter not supported: '%s'"),
+ list_object_filter_config_name(batch.objects_filter.choice));
+ }
+
/* --batch-all-objects? */
if (opt == 'b')
batch.all_objects = 1;
@@ -1017,7 +1128,7 @@ int cmd_cat_file(int argc,
/* Option compatibility */
if (force_path && !opt_cw)
usage_msg_optf(_("'%s=<%s>' needs '%s' or '%s'"),
- usage, options,
+ builtin_catfile_usage, options,
"--path", _("path|tree-ish"), "--filters",
"--textconv");
@@ -1025,20 +1136,20 @@ int cmd_cat_file(int argc,
if (batch.enabled)
;
else if (batch.follow_symlinks)
- usage_msg_optf(_("'%s' requires a batch mode"), usage, options,
- "--follow-symlinks");
+ usage_msg_optf(_("'%s' requires a batch mode"), builtin_catfile_usage,
+ options, "--follow-symlinks");
else if (batch.buffer_output >= 0)
- usage_msg_optf(_("'%s' requires a batch mode"), usage, options,
- "--buffer");
+ usage_msg_optf(_("'%s' requires a batch mode"), builtin_catfile_usage,
+ options, "--buffer");
else if (batch.all_objects)
- usage_msg_optf(_("'%s' requires a batch mode"), usage, options,
- "--batch-all-objects");
+ usage_msg_optf(_("'%s' requires a batch mode"), builtin_catfile_usage,
+ options, "--batch-all-objects");
else if (input_nul_terminated)
- usage_msg_optf(_("'%s' requires a batch mode"), usage, options,
- "-z");
+ usage_msg_optf(_("'%s' requires a batch mode"), builtin_catfile_usage,
+ options, "-z");
else if (nul_terminated)
- usage_msg_optf(_("'%s' requires a batch mode"), usage, options,
- "-Z");
+ usage_msg_optf(_("'%s' requires a batch mode"), builtin_catfile_usage,
+ options, "-Z");
batch.input_delim = batch.output_delim = '\n';
if (input_nul_terminated)
@@ -1059,39 +1170,45 @@ int cmd_cat_file(int argc,
batch.transform_mode = opt;
else if (opt && opt != 'b')
usage_msg_optf(_("'-%c' is incompatible with batch mode"),
- usage, options, opt);
+ builtin_catfile_usage, options, opt);
else if (argc)
- usage_msg_opt(_("batch modes take no arguments"), usage,
- options);
+ usage_msg_opt(_("batch modes take no arguments"),
+ builtin_catfile_usage, options);
- return batch_objects(&batch);
+ ret = batch_objects(&batch);
+ goto out;
}
if (opt) {
if (!argc && opt == 'c')
usage_msg_optf(_("<rev> required with '%s'"),
- usage, options, "--textconv");
+ builtin_catfile_usage, options,
+ "--textconv");
else if (!argc && opt == 'w')
usage_msg_optf(_("<rev> required with '%s'"),
- usage, options, "--filters");
+ builtin_catfile_usage, options,
+ "--filters");
else if (!argc && opt_epts)
usage_msg_optf(_("<object> required with '-%c'"),
- usage, options, opt);
+ builtin_catfile_usage, options, opt);
else if (argc == 1)
obj_name = argv[0];
else
- usage_msg_opt(_("too many arguments"), usage, options);
+ usage_msg_opt(_("too many arguments"), builtin_catfile_usage,
+ options);
} else if (!argc) {
- usage_with_options(usage, options);
+ usage_with_options(builtin_catfile_usage, options);
} else if (argc != 2) {
usage_msg_optf(_("only two arguments allowed in <type> <object> mode, not %d"),
- usage, options, argc);
+ builtin_catfile_usage, options, argc);
} else if (argc) {
exp_type = argv[0];
obj_name = argv[1];
}
- if (unknown_type && opt != 't' && opt != 's')
- die("git cat-file --allow-unknown-type: use with -s or -t");
- return cat_one_file(opt, exp_type, obj_name, unknown_type);
+ ret = cat_one_file(opt, exp_type, obj_name);
+
+out:
+ list_objects_filter_release(&batch.objects_filter);
+ return ret;
}