Skip to content

Commit

Permalink
sha1_file: when writing objects, skip the read_object_hook
Browse files Browse the repository at this point in the history
If we are going to write an object there is no use in calling
the read object hook to get an object from a potentially remote
source.  We would rather just write out the object and avoid the
potential round trip for an object that doesn't exist.

This change adds a flag to the check_and_freshen() and
freshen_loose_object() functions' signatures so that the hook
is bypassed when the functions are called before writing loose
objects. The check for a local object is still performed so we
don't overwrite something that has already been written to one
of the objects directories.

Based on a patch by Kevin Willford.

Signed-off-by: Johannes Schindelin <johasc@microsoft.com>
  • Loading branch information
dscho committed Aug 16, 2023
1 parent 8fad608 commit 6981fb9
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 8 deletions.
19 changes: 11 additions & 8 deletions object-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1121,15 +1121,17 @@ static int check_and_freshen_nonlocal(const struct object_id *oid, int freshen)
return 0;
}

static int check_and_freshen(const struct object_id *oid, int freshen)
static int check_and_freshen(const struct object_id *oid, int freshen,
int skip_virtualized_objects)
{
int ret;
int tried_hook = 0;

retry:
ret = check_and_freshen_local(oid, freshen) ||
check_and_freshen_nonlocal(oid, freshen);
if (!ret && core_virtualize_objects && !tried_hook) {
if (!ret && core_virtualize_objects && !skip_virtualized_objects &&
!tried_hook) {
tried_hook = 1;
if (!read_object_process(oid))
goto retry;
Expand All @@ -1145,7 +1147,7 @@ int has_loose_object_nonlocal(const struct object_id *oid)

int has_loose_object(const struct object_id *oid)
{
return check_and_freshen(oid, 0);
return check_and_freshen(oid, 0, 0);
}

static void mmap_limit_check(size_t length)
Expand Down Expand Up @@ -2217,9 +2219,10 @@ static int write_loose_object(const struct object_id *oid, char *hdr,
return finalize_object_file(tmp_file.buf, filename.buf);
}

static int freshen_loose_object(const struct object_id *oid)
static int freshen_loose_object(const struct object_id *oid,
int skip_virtualized_objects)
{
return check_and_freshen(oid, 1);
return check_and_freshen(oid, 1, skip_virtualized_objects);
}

static int freshen_packed_object(const struct object_id *oid)
Expand Down Expand Up @@ -2313,7 +2316,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,
die(_("deflateEnd on stream object failed (%d)"), ret);
close_loose_object(fd, tmp_file.buf);

if (freshen_packed_object(oid) || freshen_loose_object(oid)) {
if (freshen_packed_object(oid) || freshen_loose_object(oid, 1)) {
unlink_or_warn(tmp_file.buf);
goto cleanup;
}
Expand Down Expand Up @@ -2353,7 +2356,7 @@ int write_object_file_flags(const void *buf, size_t len,
*/
write_object_file_prepare(the_hash_algo, buf, len, type, oid, hdr,
&hdrlen);
if (freshen_packed_object(oid) || freshen_loose_object(oid))
if (freshen_packed_object(oid) || freshen_loose_object(oid, 1))
return 0;
return write_loose_object(oid, hdr, hdrlen, buf, len, 0, flags);
}
Expand All @@ -2374,7 +2377,7 @@ int write_object_file_literally(const void *buf, size_t len,

if (!(flags & HASH_WRITE_OBJECT))
goto cleanup;
if (freshen_packed_object(oid) || freshen_loose_object(oid))
if (freshen_packed_object(oid) || freshen_loose_object(oid, 1))
goto cleanup;
status = write_loose_object(oid, header, hdrlen, buf, len, 0, 0);

Expand Down
4 changes: 4 additions & 0 deletions t/t0410/read-object
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ while (1) {
system ('git --git-dir="' . $DIR . '" cat-file blob ' . $sha1 . ' | git -c core.virtualizeobjects=false hash-object -w --stdin >/dev/null 2>&1');
packet_txt_write(($?) ? "status=error" : "status=success");
packet_flush();

open my $log, '>>.git/read-object-hook.log';
print $log "Read object $sha1, exit code $?\n";
close $log;
} else {
die "bad command '$command'";
}
Expand Down
7 changes: 7 additions & 0 deletions t/t0411-read-object.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,12 @@ test_expect_success 'invalid blobs generate errors' '
test_must_fail git cat-file blob "invalid")
'

test_expect_success 'read-object-hook is bypassed when writing objects' '
(cd guest-repo &&
echo hello >hello.txt &&
git add hello.txt &&
hash="$(git rev-parse --verify :hello.txt)" &&
! grep "$hash" .git/read-object-hook.log)
'

test_done

0 comments on commit 6981fb9

Please sign in to comment.