object_info: content_limit only applies to blobs

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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Eric Wong 2024-08-23 22:46:27 +00:00 committed by Junio C Hamano
parent 28402bcedd
commit 7d4e4d5dc8
4 changed files with 42 additions and 9 deletions

View File

@ -385,7 +385,24 @@ 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 (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:
/*
@ -395,7 +412,7 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
BUG("TODO OI_CACHED support not done");
case OI_LOOSE:
case OI_PACKED:
FREE_AND_NULL(data->content);
free(content);
break;
case OI_DBCACHED:
unlock_delta_base_cache();

View File

@ -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;

View File

@ -1546,7 +1546,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 {
@ -1583,10 +1583,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 {

View File

@ -622,20 +622,33 @@ test_expect_success 'confirm that neither loose blob is a delta' '
test_cmp expect actual
'
test_expect_success 'setup delta base tests' '
foo="$(git rev-parse HEAD:foo)" &&
foo_plus="$(git rev-parse HEAD:foo-plus)" &&
git repack -ad
'
# To avoid relying too much on the current delta heuristics,
# we will check only that one of the two objects is a delta
# against the other, but not the order. We can do so by just
# asking for the base of both, and checking whether either
# oid appears in the output.
test_expect_success '%(deltabase) reports packed delta bases' '
git repack -ad &&
git cat-file --batch-check="%(deltabase)" <blobs >actual &&
{
grep "$(git rev-parse HEAD:foo)" actual ||
grep "$(git rev-parse HEAD:foo-plus)" actual
grep "$foo" actual || grep "$foo_plus" actual
}
'
test_expect_success 'delta base direct cache use succeeds w/o asserting' '
commands="info $foo
info $foo_plus
contents $foo_plus
contents $foo" &&
echo "$commands" >in &&
git cat-file --batch-command <in >out
'
test_expect_success 'setup bogus data' '
bogus_short_type="bogus" &&
bogus_short_content="bogus" &&