mirror of
https://github.com/git/git.git
synced 2025-12-12 20:36:24 +01:00
object-file: refactor freshening of objects
When writing an object that already exists in our object database we skip the write and instead only update mtimes of the object, either in its packed or loose object format. This logic is wholly contained in "object-file.c", but that file is really only concerned with loose objects. So it does not really make sense that it also contains the logic to freshen a packed object. Introduce a new `odb_freshen_object()` function that sits on the object database level and two functions `packfile_store_freshen_object()` and `odb_source_loose_freshen_object()`. Like this, the format-specific functions can be part of their respective subsystems, while the backend agnostic function to freshen an object sits at the object database layer. Note that this change also moves the logic that iterates through object sources from the object source layer into the object database layer. This change is intentional: object sources should ideally only have to worry about themselves, and coordination of different sources should be handled on the object database level. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
05130c6c9e
commit
f2bd88a308
@@ -968,30 +968,10 @@ static int write_loose_object(struct odb_source *source,
|
||||
FOF_SKIP_COLLISION_CHECK);
|
||||
}
|
||||
|
||||
static int freshen_loose_object(struct object_database *odb,
|
||||
const struct object_id *oid)
|
||||
int odb_source_loose_freshen_object(struct odb_source *source,
|
||||
const struct object_id *oid)
|
||||
{
|
||||
odb_prepare_alternates(odb);
|
||||
for (struct odb_source *source = odb->sources; source; source = source->next)
|
||||
if (check_and_freshen_source(source, oid, 1))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int freshen_packed_object(struct object_database *odb,
|
||||
const struct object_id *oid)
|
||||
{
|
||||
struct pack_entry e;
|
||||
if (!find_pack_entry(odb->repo, oid, &e))
|
||||
return 0;
|
||||
if (e.p->is_cruft)
|
||||
return 0;
|
||||
if (e.p->freshened)
|
||||
return 1;
|
||||
if (!freshen_file(e.p->pack_name))
|
||||
return 0;
|
||||
e.p->freshened = 1;
|
||||
return 1;
|
||||
return !!check_and_freshen_source(source, oid, 1);
|
||||
}
|
||||
|
||||
int stream_loose_object(struct odb_source *source,
|
||||
@@ -1073,12 +1053,10 @@ int stream_loose_object(struct odb_source *source,
|
||||
die(_("deflateEnd on stream object failed (%d)"), ret);
|
||||
close_loose_object(source, fd, tmp_file.buf);
|
||||
|
||||
if (freshen_packed_object(source->odb, oid) ||
|
||||
freshen_loose_object(source->odb, oid)) {
|
||||
if (odb_freshen_object(source->odb, oid)) {
|
||||
unlink_or_warn(tmp_file.buf);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
odb_loose_path(source, &filename, oid);
|
||||
|
||||
/* We finally know the object path, and create the missing dir. */
|
||||
@@ -1137,8 +1115,7 @@ int write_object_file(struct odb_source *source,
|
||||
* it out into .git/objects/??/?{38} file.
|
||||
*/
|
||||
write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
|
||||
if (freshen_packed_object(source->odb, oid) ||
|
||||
freshen_loose_object(source->odb, oid))
|
||||
if (odb_freshen_object(source->odb, oid))
|
||||
return 0;
|
||||
if (write_loose_object(source, oid, hdr, hdrlen, buf, len, 0, flags))
|
||||
return -1;
|
||||
|
||||
@@ -59,6 +59,9 @@ void *odb_source_loose_map_object(struct odb_source *source,
|
||||
int odb_source_loose_has_object(struct odb_source *source,
|
||||
const struct object_id *oid);
|
||||
|
||||
int odb_source_loose_freshen_object(struct odb_source *source,
|
||||
const struct object_id *oid);
|
||||
|
||||
/*
|
||||
* Populate and return the loose object cache array corresponding to the
|
||||
* given object ID.
|
||||
|
||||
16
odb.c
16
odb.c
@@ -987,6 +987,22 @@ int odb_has_object(struct object_database *odb, const struct object_id *oid,
|
||||
return odb_read_object_info_extended(odb, oid, NULL, object_info_flags) >= 0;
|
||||
}
|
||||
|
||||
int odb_freshen_object(struct object_database *odb,
|
||||
const struct object_id *oid)
|
||||
{
|
||||
struct odb_source *source;
|
||||
|
||||
if (packfile_store_freshen_object(odb->packfiles, oid))
|
||||
return 1;
|
||||
|
||||
odb_prepare_alternates(odb);
|
||||
for (source = odb->sources; source; source = source->next)
|
||||
if (odb_source_loose_freshen_object(source, oid))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void odb_assert_oid_type(struct object_database *odb,
|
||||
const struct object_id *oid, enum object_type expect)
|
||||
{
|
||||
|
||||
3
odb.h
3
odb.h
@@ -396,6 +396,9 @@ int odb_has_object(struct object_database *odb,
|
||||
const struct object_id *oid,
|
||||
unsigned flags);
|
||||
|
||||
int odb_freshen_object(struct object_database *odb,
|
||||
const struct object_id *oid);
|
||||
|
||||
void odb_assert_oid_type(struct object_database *odb,
|
||||
const struct object_id *oid, enum object_type expect);
|
||||
|
||||
|
||||
16
packfile.c
16
packfile.c
@@ -819,6 +819,22 @@ struct packed_git *packfile_store_load_pack(struct packfile_store *store,
|
||||
return p;
|
||||
}
|
||||
|
||||
int packfile_store_freshen_object(struct packfile_store *store,
|
||||
const struct object_id *oid)
|
||||
{
|
||||
struct pack_entry e;
|
||||
if (!find_pack_entry(store->odb->repo, oid, &e))
|
||||
return 0;
|
||||
if (e.p->is_cruft)
|
||||
return 0;
|
||||
if (e.p->freshened)
|
||||
return 1;
|
||||
if (utime(e.p->pack_name, NULL))
|
||||
return 0;
|
||||
e.p->freshened = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void (*report_garbage)(unsigned seen_bits, const char *path);
|
||||
|
||||
static void report_helper(const struct string_list *list,
|
||||
|
||||
@@ -163,6 +163,9 @@ struct list_head *packfile_store_get_packs_mru(struct packfile_store *store);
|
||||
struct packed_git *packfile_store_load_pack(struct packfile_store *store,
|
||||
const char *idx_path, int local);
|
||||
|
||||
int packfile_store_freshen_object(struct packfile_store *store,
|
||||
const struct object_id *oid);
|
||||
|
||||
struct pack_window {
|
||||
struct pack_window *next;
|
||||
unsigned char *base;
|
||||
|
||||
Reference in New Issue
Block a user