Skip to content

Commit 20dc547

Browse files
committed
sha1_file: when writing objects, skip the read_object_hook
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 <johannes.schindelin@gmx.de>
1 parent b53f484 commit 20dc547

6 files changed

Lines changed: 27 additions & 11 deletions

File tree

‎object-file.c‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,16 @@ int check_and_freshen_file(const char *fn, int freshen)
9393

9494
static int check_and_freshen_source(struct odb_source *source,
9595
const struct object_id *oid,
96-
int freshen)
96+
int freshen, int skip_virtualized_objects)
9797
{
9898
static struct strbuf path = STRBUF_INIT;
9999
int ret, tried_hook = 0;
100100

101101
odb_loose_path(source, &path, oid);
102102
retry:
103103
ret = check_and_freshen_file(path.buf, freshen);
104-
if (!ret && gvfs_virtualize_objects(source->odb->repo) && !tried_hook) {
104+
if (!ret && gvfs_virtualize_objects(source->odb->repo) &&
105+
!skip_virtualized_objects && !tried_hook) {
105106
tried_hook = 1;
106107
if (!read_object_process(source->odb->repo, oid))
107108
goto retry;
@@ -112,7 +113,7 @@ static int check_and_freshen_source(struct odb_source *source,
112113
int odb_source_loose_has_object(struct odb_source *source,
113114
const struct object_id *oid)
114115
{
115-
return check_and_freshen_source(source, oid, 0);
116+
return check_and_freshen_source(source, oid, 0, 0);
116117
}
117118

118119
int format_object_header(char *str, size_t size, enum object_type type,
@@ -1002,9 +1003,10 @@ static int write_loose_object(struct odb_source *source,
10021003
}
10031004

10041005
int odb_source_loose_freshen_object(struct odb_source *source,
1005-
const struct object_id *oid)
1006+
const struct object_id *oid,
1007+
int skip_virtualized_objects)
10061008
{
1007-
return !!check_and_freshen_source(source, oid, 1);
1009+
return !!check_and_freshen_source(source, oid, 1, skip_virtualized_objects);
10081010
}
10091011

10101012
int odb_source_loose_write_stream(struct odb_source *source,
@@ -1086,7 +1088,7 @@ int odb_source_loose_write_stream(struct odb_source *source,
10861088
die(_("deflateEnd on stream object failed (%d)"), ret);
10871089
close_loose_object(source, fd, tmp_file.buf);
10881090

1089-
if (odb_freshen_object(source->odb, oid)) {
1091+
if (odb_freshen_object(source->odb, oid, 1)) {
10901092
unlink_or_warn(tmp_file.buf);
10911093
goto cleanup;
10921094
}
@@ -1148,7 +1150,7 @@ int odb_source_loose_write_object(struct odb_source *source,
11481150
* it out into .git/objects/??/?{38} file.
11491151
*/
11501152
write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
1151-
if (odb_freshen_object(source->odb, oid))
1153+
if (odb_freshen_object(source->odb, oid, 1))
11521154
return 0;
11531155
if (write_loose_object(source, oid, hdr, hdrlen, buf, len, 0, flags))
11541156
return -1;

‎object-file.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ int odb_source_loose_has_object(struct odb_source *source,
6262
const struct object_id *oid);
6363

6464
int odb_source_loose_freshen_object(struct odb_source *source,
65-
const struct object_id *oid);
65+
const struct object_id *oid,
66+
int skip_virtualized_objects);
6667

6768
int odb_source_loose_write_object(struct odb_source *source,
6869
const void *buf, size_t len,

‎odb.c‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,8 @@ int odb_has_object(struct object_database *odb, const struct object_id *oid,
11031103
}
11041104

11051105
int odb_freshen_object(struct object_database *odb,
1106-
const struct object_id *oid)
1106+
const struct object_id *oid,
1107+
int skip_virtualized_objects)
11071108
{
11081109
struct odb_source *source;
11091110

@@ -1112,7 +1113,7 @@ int odb_freshen_object(struct object_database *odb,
11121113

11131114
odb_prepare_alternates(odb);
11141115
for (source = odb->sources; source; source = source->next)
1115-
if (odb_source_loose_freshen_object(source, oid))
1116+
if (odb_source_loose_freshen_object(source, oid, skip_virtualized_objects))
11161117
return 1;
11171118

11181119
return 0;

‎odb.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,8 @@ int odb_has_object(struct object_database *odb,
408408
unsigned flags);
409409

410410
int odb_freshen_object(struct object_database *odb,
411-
const struct object_id *oid);
411+
const struct object_id *oid,
412+
int skip_virtualized_objects);
412413

413414
void odb_assert_oid_type(struct object_database *odb,
414415
const struct object_id *oid, enum object_type expect);

‎t/t0410/read-object‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ while (1) {
108108
system ('git --git-dir="' . $DIR . '" cat-file blob ' . $sha1 . ' | git -c core.virtualizeobjects=false hash-object -w --stdin >/dev/null 2>&1');
109109
packet_txt_write(($?) ? "status=error" : "status=success");
110110
packet_flush();
111+
112+
open my $log, '>>.git/read-object-hook.log';
113+
print $log "Read object $sha1, exit code $?\n";
114+
close $log;
111115
} else {
112116
die "bad command '$command'";
113117
}

‎t/t0499-read-object.sh‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,12 @@ test_expect_success 'invalid blobs generate errors' '
2626
test_must_fail git cat-file blob "invalid")
2727
'
2828

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

3037
test_done

0 commit comments

Comments
 (0)