@@ -386,20 +386,39 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
assert(data->info.typep);
if (data->content) {
- batch_write(opt, data->content, data->size);
+ void *content = data->content;
+ unsigned long size = data->size;
+
+ data->content = NULL;
+ if (use_mailmap && (data->type == OBJ_COMMIT ||
+ data->type == OBJ_TAG)) {
+ size_t s = size;
+
+ if (USE_DIRECT_CACHE &&
+ data->info.whence == OI_DBCACHED) {
+ content = xmemdupz(content, s);
+ data->info.whence = OI_PACKED;
+ }
+
+ content = replace_idents_using_mailmap(content, &s);
+ size = cast_size_t_to_ulong(s);
+ }
+
+ batch_write(opt, content, size);
switch (data->info.whence) {
case OI_CACHED: BUG("FIXME OI_CACHED support not done");
case OI_LOOSE:
case OI_PACKED:
- FREE_AND_NULL(data->content);
+ free(content);
break;
case OI_DBCACHED:
if (USE_DIRECT_CACHE)
unlock_delta_base_cache();
else
- FREE_AND_NULL(data->content);
+ free(content);
}
- } else if (data->type == OBJ_BLOB) {
+ } else {
+ assert(data->type == OBJ_BLOB);
if (opt->buffer_output)
fflush(stdout);
if (opt->transform_mode) {
@@ -434,30 +453,6 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
stream_blob(oid);
}
}
- else {
- enum object_type type;
- unsigned long size;
- void *contents;
-
- contents = repo_read_object_file(the_repository, oid, &type,
- &size);
- if (!contents)
- die("object %s disappeared", oid_to_hex(oid));
-
- if (use_mailmap) {
- size_t s = size;
- contents = replace_idents_using_mailmap(contents, &s);
- size = cast_size_t_to_ulong(s);
- }
-
- if (type != data->type)
- die("object %s changed type!?", oid_to_hex(oid));
- if (data->info.sizep && size != data->size && !use_mailmap)
- die("object %s changed size!?", oid_to_hex(oid));
-
- batch_write(opt, contents, size);
- free(contents);
- }
}
static void print_default_format(struct strbuf *scratch, struct expand_data *data,
@@ -1492,7 +1492,8 @@ static int loose_object_info(struct repository *r,
if (!oi->contentp)
break;
- if (oi->content_limit && *oi->sizep > oi->content_limit) {
+ if (oi->content_limit && *oi->typep == OBJ_BLOB &&
+ *oi->sizep > oi->content_limit) {
git_inflate_end(&stream);
oi->contentp = NULL;
goto cleanup;
@@ -1542,7 +1542,7 @@ int packed_object_info(struct repository *r, struct packed_git *p,
if (oi->direct_cache) {
lock_delta_base_cache();
*oi->contentp = ent->data;
- } else if (!oi->content_limit ||
+ } else if (type != OBJ_BLOB || !oi->content_limit ||
ent->size <= oi->content_limit) {
*oi->contentp = xmemdupz(ent->data, ent->size);
} else {
@@ -1579,10 +1579,12 @@ int packed_object_info(struct repository *r, struct packed_git *p,
}
if (oi->contentp) {
- if (oi->sizep && *oi->sizep <= oi->content_limit) {
+ final_type = packed_to_object_type(r, p, obj_offset,
+ type, &w_curs, curpos);
+ if (final_type != OBJ_BLOB || (oi->sizep &&
+ *oi->sizep <= oi->content_limit)) {
*oi->contentp = unpack_entry(r, p, obj_offset,
&type, oi->sizep);
- final_type = type;
if (!*oi->contentp)
type = OBJ_BAD;
} else {
Streaming is only supported for blobs, so we'd end up having to slurp all the other object types into memory regardless. So slurp all the non-blob types up front when requesting content since we always handle them in-core, anyways. Signed-off-by: Eric Wong <e@80x24.org> --- builtin/cat-file.c | 51 +++++++++++++++++++++------------------------- object-file.c | 3 ++- packfile.c | 8 +++++--- 3 files changed, 30 insertions(+), 32 deletions(-)