Skip to content

Commit 785108f

Browse files
committed
odb: add write_packfile, for_each_unique_abbrev, convert_object_id
Add three vtable methods to odb_source that were not part of the recent ps/odb-sources and ps/object-counting series: - write_packfile: ingest a pack from a file descriptor. The files backend chooses between index-pack (large packs) and unpack-objects (small packs below fetch.unpackLimit). Options cover thin-pack fixing, promisor marking, fsck, lockfile capture, and shallow file passing. - for_each_unique_abbrev: iterate objects matching a hex prefix for disambiguation. Searches loose objects via oidtree, then multi-pack indices, then non-MIDX packs. - convert_object_id: translate between hash algorithms using the loose object map. Used during SHA-1 to SHA-256 migration. Also add ODB_SOURCE_HELPER to the source type enum, preparing for the helper backend in the next commit. The write_packfile vtable method replaces the pattern where callers spawn index-pack/unpack-objects directly. fast-import already uses odb_write_packfile() and this allows non-files backends to handle pack ingestion through their own mechanism. Signed-off-by: Aaron Paterson <apaterson@pm.me>
1 parent 41688c1 commit 785108f

File tree

5 files changed

+458
-12
lines changed

5 files changed

+458
-12
lines changed

object-name.c

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "packfile.h"
2121
#include "pretty.h"
2222
#include "object-file.h"
23+
#include "odb/source.h"
2324
#include "read-cache-ll.h"
2425
#include "repo-settings.h"
2526
#include "repository.h"
@@ -115,9 +116,12 @@ static void find_short_object_filename(struct disambiguate_state *ds)
115116
{
116117
struct odb_source *source;
117118

118-
for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next)
119+
for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next) {
120+
if (source->type != ODB_SOURCE_FILES)
121+
continue;
119122
oidtree_each(odb_source_loose_cache(source, &ds->bin_pfx),
120123
&ds->bin_pfx, ds->len, match_prefix, ds);
124+
}
121125
}
122126

123127
static int match_hash(unsigned len, const unsigned char *a, const unsigned char *b)
@@ -208,9 +212,13 @@ static void find_short_packed_object(struct disambiguate_state *ds)
208212

209213
odb_prepare_alternates(ds->repo->objects);
210214
for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next) {
211-
struct multi_pack_index *m = get_multi_pack_index(source);
212-
if (m)
213-
unique_in_midx(m, ds);
215+
if (source->type != ODB_SOURCE_FILES)
216+
continue;
217+
{
218+
struct multi_pack_index *m = get_multi_pack_index(source);
219+
if (m)
220+
unique_in_midx(m, ds);
221+
}
214222
}
215223

216224
repo_for_each_pack(ds->repo, p) {
@@ -796,19 +804,38 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
796804
mad->init_len = mad->cur_len;
797805
}
798806

799-
static void find_abbrev_len_packed(struct min_abbrev_data *mad)
807+
static int abbrev_len_cb(const struct object_id *oid,
808+
struct object_info *oi UNUSED, void *data)
800809
{
801-
struct packed_git *p;
810+
struct min_abbrev_data *mad = data;
811+
extend_abbrev_len(oid, mad);
812+
return 0;
813+
}
802814

815+
static void find_abbrev_len_packed(struct min_abbrev_data *mad)
816+
{
803817
odb_prepare_alternates(mad->repo->objects);
804-
for (struct odb_source *source = mad->repo->objects->sources; source; source = source->next) {
805-
struct multi_pack_index *m = get_multi_pack_index(source);
806-
if (m)
807-
find_abbrev_len_for_midx(m, mad);
818+
819+
for (struct odb_source *source = mad->repo->objects->sources;
820+
source; source = source->next) {
821+
if (source->for_each_unique_abbrev) {
822+
mad->init_len = 0;
823+
odb_source_for_each_unique_abbrev(
824+
source, mad->oid, mad->cur_len,
825+
abbrev_len_cb, mad);
826+
mad->init_len = mad->cur_len;
827+
} else {
828+
struct multi_pack_index *m = get_multi_pack_index(source);
829+
if (m)
830+
find_abbrev_len_for_midx(m, mad);
831+
}
808832
}
809833

810-
repo_for_each_pack(mad->repo, p)
811-
find_abbrev_len_for_pack(p, mad);
834+
if (!mad->repo->objects->sources->for_each_unique_abbrev) {
835+
struct packed_git *p;
836+
repo_for_each_pack(mad->repo, p)
837+
find_abbrev_len_for_pack(p, mad);
838+
}
812839
}
813840

814841
void strbuf_repo_add_unique_abbrev(struct strbuf *sb, struct repository *repo,

odb.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,32 @@ int odb_write_object_stream(struct object_database *odb,
981981
return odb_source_write_object_stream(odb->sources, stream, len, oid);
982982
}
983983

984+
int odb_write_packfile(struct object_database *odb,
985+
int pack_fd,
986+
struct odb_write_packfile_options *opts)
987+
{
988+
return odb_source_write_packfile(odb->sources, pack_fd, opts);
989+
}
990+
991+
int odb_for_each_unique_abbrev(struct object_database *odb,
992+
const struct object_id *oid_prefix,
993+
unsigned int prefix_len,
994+
odb_for_each_object_cb cb,
995+
void *cb_data)
996+
{
997+
int ret;
998+
999+
odb_prepare_alternates(odb);
1000+
for (struct odb_source *source = odb->sources; source; source = source->next) {
1001+
ret = odb_source_for_each_unique_abbrev(source, oid_prefix,
1002+
prefix_len, cb, cb_data);
1003+
if (ret)
1004+
return ret;
1005+
}
1006+
1007+
return 0;
1008+
}
1009+
9841010
struct object_database *odb_new(struct repository *repo,
9851011
const char *primary_source,
9861012
const char *secondary_sources)

odb.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,13 @@ enum object_info_flags {
374374
* clone. Implies OBJECT_INFO_SKIP_FETCH_OBJECT and OBJECT_INFO_QUICK.
375375
*/
376376
OBJECT_INFO_FOR_PREFETCH = (OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK),
377+
378+
/*
379+
* Only consider objects marked as "kept" (surviving GC). Used by
380+
* helper backends that track kept status per object. Backends that
381+
* do not support kept tracking should return -1 (not found).
382+
*/
383+
OBJECT_INFO_KEPT_ONLY = (1 << 5),
377384
};
378385

379386
/*
@@ -570,6 +577,25 @@ int odb_write_object_stream(struct object_database *odb,
570577
struct odb_write_stream *stream, size_t len,
571578
struct object_id *oid);
572579

580+
/*
581+
* Ingest a pack from a file descriptor into the primary source.
582+
* Returns 0 on success, a negative error code otherwise.
583+
*/
584+
struct odb_write_packfile_options;
585+
int odb_write_packfile(struct object_database *odb,
586+
int pack_fd,
587+
struct odb_write_packfile_options *opts);
588+
589+
/*
590+
* Iterate over all objects across all sources whose ID starts with
591+
* the given prefix. Used for object name disambiguation.
592+
*/
593+
int odb_for_each_unique_abbrev(struct object_database *odb,
594+
const struct object_id *oid_prefix,
595+
unsigned int prefix_len,
596+
odb_for_each_object_cb cb,
597+
void *cb_data);
598+
573599
void parse_alternates(const char *string,
574600
int sep,
575601
const char *relative_base,

0 commit comments

Comments
 (0)