Skip to content

Commit 9d98354

Browse files
stefanbellergitster
authored andcommitted
cache.h: allow oid_object_info to handle arbitrary repositories
This involves also adapting oid_object_info_extended and a some internal functions that are used to implement these. It all has to happen in one patch, because of a single recursive chain of calls visits all these functions. oid_object_info_extended is also used in partial clones, which allow fetching missing objects. As this series will not add the repository struct to the transport code and fetch_object(), add a TODO note and omit fetching if a user tries to use a partial clone in a repository other than the_repository. Among the functions modified to handle arbitrary repositories, unpack_entry() is one of them. Note that it still references the globals "delta_base_cache" and "delta_base_cached", but those are safe to be referenced (the former is indexed partly by "struct packed_git *", which is repo-specific, and the latter is only used to limit the size of the former as an optimization). Helped-by: Brandon Williams <[email protected]> Helped-by: Jonathan Tan <[email protected]> Signed-off-by: Jonathan Nieder <[email protected]> Signed-off-by: Stefan Beller <[email protected]> Reviewed-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 589de91 commit 9d98354

File tree

4 files changed

+54
-52
lines changed

4 files changed

+54
-52
lines changed

cache.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,8 +1192,7 @@ static inline void *read_object_file(const struct object_id *oid, enum object_ty
11921192
}
11931193

11941194
/* Read and unpack an object file into memory, write memory to an object file */
1195-
#define oid_object_info(r, o, f) oid_object_info_##r(o, f)
1196-
int oid_object_info_the_repository(const struct object_id *, unsigned long *);
1195+
int oid_object_info(struct repository *r, const struct object_id *, unsigned long *);
11971196

11981197
extern int hash_object_file(const void *buf, unsigned long len,
11991198
const char *type, struct object_id *oid);
@@ -1675,9 +1674,9 @@ struct object_info {
16751674
/* Do not check loose object */
16761675
#define OBJECT_INFO_IGNORE_LOOSE 16
16771676

1678-
#define oid_object_info_extended(r, oid, oi, flags) \
1679-
oid_object_info_extended_##r(oid, oi, flags)
1680-
int oid_object_info_extended_the_repository(const struct object_id *, struct object_info *, unsigned flags);
1677+
int oid_object_info_extended(struct repository *r,
1678+
const struct object_id *,
1679+
struct object_info *, unsigned flags);
16811680

16821681
/*
16831682
* Set this to 0 to prevent sha1_object_info_extended() from fetching missing

packfile.c

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,9 +1104,9 @@ static const unsigned char *get_delta_base_sha1(struct packed_git *p,
11041104
return NULL;
11051105
}
11061106

1107-
#define retry_bad_packed_offset(r, p, o) \
1108-
retry_bad_packed_offset_##r(p, o)
1109-
static int retry_bad_packed_offset_the_repository(struct packed_git *p, off_t obj_offset)
1107+
static int retry_bad_packed_offset(struct repository *r,
1108+
struct packed_git *p,
1109+
off_t obj_offset)
11101110
{
11111111
int type;
11121112
struct revindex_entry *revidx;
@@ -1116,21 +1116,20 @@ static int retry_bad_packed_offset_the_repository(struct packed_git *p, off_t ob
11161116
return OBJ_BAD;
11171117
nth_packed_object_oid(&oid, p, revidx->nr);
11181118
mark_bad_packed_object(p, oid.hash);
1119-
type = oid_object_info(the_repository, &oid, NULL);
1119+
type = oid_object_info(r, &oid, NULL);
11201120
if (type <= OBJ_NONE)
11211121
return OBJ_BAD;
11221122
return type;
11231123
}
11241124

11251125
#define POI_STACK_PREALLOC 64
11261126

1127-
#define packed_to_object_type(r, p, o, t, w, c) \
1128-
packed_to_object_type_##r(p, o, t, w, c)
1129-
static enum object_type packed_to_object_type_the_repository(struct packed_git *p,
1130-
off_t obj_offset,
1131-
enum object_type type,
1132-
struct pack_window **w_curs,
1133-
off_t curpos)
1127+
static enum object_type packed_to_object_type(struct repository *r,
1128+
struct packed_git *p,
1129+
off_t obj_offset,
1130+
enum object_type type,
1131+
struct pack_window **w_curs,
1132+
off_t curpos)
11341133
{
11351134
off_t small_poi_stack[POI_STACK_PREALLOC];
11361135
off_t *poi_stack = small_poi_stack;
@@ -1157,7 +1156,7 @@ static enum object_type packed_to_object_type_the_repository(struct packed_git *
11571156
if (type <= OBJ_NONE) {
11581157
/* If getting the base itself fails, we first
11591158
* retry the base, otherwise unwind */
1160-
type = retry_bad_packed_offset(the_repository, p, base_offset);
1159+
type = retry_bad_packed_offset(r, p, base_offset);
11611160
if (type > OBJ_NONE)
11621161
goto out;
11631162
goto unwind;
@@ -1185,7 +1184,7 @@ static enum object_type packed_to_object_type_the_repository(struct packed_git *
11851184
unwind:
11861185
while (poi_stack_nr) {
11871186
obj_offset = poi_stack[--poi_stack_nr];
1188-
type = retry_bad_packed_offset(the_repository, p, obj_offset);
1187+
type = retry_bad_packed_offset(r, p, obj_offset);
11891188
if (type > OBJ_NONE)
11901189
goto out;
11911190
}
@@ -1272,15 +1271,15 @@ static void detach_delta_base_cache_entry(struct delta_base_cache_entry *ent)
12721271
free(ent);
12731272
}
12741273

1275-
#define cache_or_unpack_entry(r, p, bo, bs, t) cache_or_unpack_entry_##r(p, bo, bs, t)
1276-
static void *cache_or_unpack_entry_the_repository(struct packed_git *p, off_t base_offset,
1277-
unsigned long *base_size, enum object_type *type)
1274+
static void *cache_or_unpack_entry(struct repository *r, struct packed_git *p,
1275+
off_t base_offset, unsigned long *base_size,
1276+
enum object_type *type)
12781277
{
12791278
struct delta_base_cache_entry *ent;
12801279

12811280
ent = get_delta_base_cache_entry(p, base_offset);
12821281
if (!ent)
1283-
return unpack_entry(the_repository, p, base_offset, type, base_size);
1282+
return unpack_entry(r, p, base_offset, type, base_size);
12841283

12851284
if (type)
12861285
*type = ent->type;
@@ -1334,8 +1333,8 @@ static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
13341333
hashmap_add(&delta_base_cache, ent);
13351334
}
13361335

1337-
int packed_object_info_the_repository(struct packed_git *p, off_t obj_offset,
1338-
struct object_info *oi)
1336+
int packed_object_info(struct repository *r, struct packed_git *p,
1337+
off_t obj_offset, struct object_info *oi)
13391338
{
13401339
struct pack_window *w_curs = NULL;
13411340
unsigned long size;
@@ -1347,7 +1346,7 @@ int packed_object_info_the_repository(struct packed_git *p, off_t obj_offset,
13471346
* a "real" type later if the caller is interested.
13481347
*/
13491348
if (oi->contentp) {
1350-
*oi->contentp = cache_or_unpack_entry(the_repository, p, obj_offset, oi->sizep,
1349+
*oi->contentp = cache_or_unpack_entry(r, p, obj_offset, oi->sizep,
13511350
&type);
13521351
if (!*oi->contentp)
13531352
type = OBJ_BAD;
@@ -1381,7 +1380,7 @@ int packed_object_info_the_repository(struct packed_git *p, off_t obj_offset,
13811380

13821381
if (oi->typep || oi->type_name) {
13831382
enum object_type ptot;
1384-
ptot = packed_to_object_type(the_repository, p, obj_offset,
1383+
ptot = packed_to_object_type(r, p, obj_offset,
13851384
type, &w_curs, curpos);
13861385
if (oi->typep)
13871386
*oi->typep = ptot;
@@ -1470,25 +1469,24 @@ struct unpack_entry_stack_ent {
14701469
unsigned long size;
14711470
};
14721471

1473-
#define read_object(r, o, t, s) read_object_##r(o, t, s)
1474-
static void *read_object_the_repository(const struct object_id *oid,
1475-
enum object_type *type,
1476-
unsigned long *size)
1472+
static void *read_object(struct repository *r,
1473+
const struct object_id *oid,
1474+
enum object_type *type,
1475+
unsigned long *size)
14771476
{
14781477
struct object_info oi = OBJECT_INFO_INIT;
14791478
void *content;
14801479
oi.typep = type;
14811480
oi.sizep = size;
14821481
oi.contentp = &content;
14831482

1484-
if (oid_object_info_extended(the_repository, oid, &oi, 0) < 0)
1483+
if (oid_object_info_extended(r, oid, &oi, 0) < 0)
14851484
return NULL;
14861485
return content;
14871486
}
14881487

1489-
void *unpack_entry_the_repository(struct packed_git *p, off_t obj_offset,
1490-
enum object_type *final_type,
1491-
unsigned long *final_size)
1488+
void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset,
1489+
enum object_type *final_type, unsigned long *final_size)
14921490
{
14931491
struct pack_window *w_curs = NULL;
14941492
off_t curpos = obj_offset;
@@ -1618,7 +1616,7 @@ void *unpack_entry_the_repository(struct packed_git *p, off_t obj_offset,
16181616
oid_to_hex(&base_oid), (uintmax_t)obj_offset,
16191617
p->pack_name);
16201618
mark_bad_packed_object(p, base_oid.hash);
1621-
base = read_object(the_repository, &base_oid, &type, &base_size);
1619+
base = read_object(r, &base_oid, &type, &base_size);
16221620
external_base = base;
16231621
}
16241622
}

packfile.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,7 @@ extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t n);
115115
extern off_t find_pack_entry_one(const unsigned char *sha1, struct packed_git *);
116116

117117
extern int is_pack_valid(struct packed_git *);
118-
#define unpack_entry(r, p, of, ot, s) unpack_entry_##r(p, of, ot, s)
119-
extern void *unpack_entry_the_repository(struct packed_git *, off_t, enum object_type *, unsigned long *);
118+
extern void *unpack_entry(struct repository *r, struct packed_git *, off_t, enum object_type *, unsigned long *);
120119
extern unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
121120
extern unsigned long get_size_from_delta(struct packed_git *, struct pack_window **, off_t);
122121
extern int unpack_object_header(struct packed_git *, struct pack_window **, off_t *, unsigned long *);
@@ -126,8 +125,9 @@ extern void release_pack_memory(size_t);
126125
/* global flag to enable extra checks when accessing packed objects */
127126
extern int do_check_packed_object_crc;
128127

129-
#define packed_object_info(r, p, o, oi) packed_object_info_##r(p, o, oi)
130-
extern int packed_object_info_the_repository(struct packed_git *pack, off_t offset, struct object_info *);
128+
extern int packed_object_info(struct repository *r,
129+
struct packed_git *pack,
130+
off_t offset, struct object_info *);
131131

132132
extern void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1);
133133
extern const struct packed_git *has_packed_and_bad(const unsigned char *sha1);

sha1_file.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,7 +1231,8 @@ static int sha1_loose_object_info(struct repository *r,
12311231

12321232
int fetch_if_missing = 1;
12331233

1234-
int oid_object_info_extended_the_repository(const struct object_id *oid, struct object_info *oi, unsigned flags)
1234+
int oid_object_info_extended(struct repository *r, const struct object_id *oid,
1235+
struct object_info *oi, unsigned flags)
12351236
{
12361237
static struct object_info blank_oi = OBJECT_INFO_INIT;
12371238
struct pack_entry e;
@@ -1240,7 +1241,7 @@ int oid_object_info_extended_the_repository(const struct object_id *oid, struct
12401241
int already_retried = 0;
12411242

12421243
if (flags & OBJECT_INFO_LOOKUP_REPLACE)
1243-
real = lookup_replace_object(the_repository, oid);
1244+
real = lookup_replace_object(r, oid);
12441245

12451246
if (is_null_oid(real))
12461247
return -1;
@@ -1269,29 +1270,31 @@ int oid_object_info_extended_the_repository(const struct object_id *oid, struct
12691270
}
12701271

12711272
while (1) {
1272-
if (find_pack_entry(the_repository, real->hash, &e))
1273+
if (find_pack_entry(r, real->hash, &e))
12731274
break;
12741275

12751276
if (flags & OBJECT_INFO_IGNORE_LOOSE)
12761277
return -1;
12771278

12781279
/* Most likely it's a loose object. */
1279-
if (!sha1_loose_object_info(the_repository, real->hash, oi, flags))
1280+
if (!sha1_loose_object_info(r, real->hash, oi, flags))
12801281
return 0;
12811282

12821283
/* Not a loose object; someone else may have just packed it. */
12831284
if (!(flags & OBJECT_INFO_QUICK)) {
1284-
reprepare_packed_git(the_repository);
1285-
if (find_pack_entry(the_repository, real->hash, &e))
1285+
reprepare_packed_git(r);
1286+
if (find_pack_entry(r, real->hash, &e))
12861287
break;
12871288
}
12881289

12891290
/* Check if it is a missing object */
12901291
if (fetch_if_missing && repository_format_partial_clone &&
1291-
!already_retried) {
1292+
!already_retried && r == the_repository) {
12921293
/*
1293-
* TODO Investigate haveing fetch_object() return
1294+
* TODO Investigate having fetch_object() return
12941295
* TODO error/success and stopping the music here.
1296+
* TODO Pass a repository struct through fetch_object,
1297+
* such that arbitrary repositories work.
12951298
*/
12961299
fetch_object(repository_format_partial_clone, real->hash);
12971300
already_retried = 1;
@@ -1307,10 +1310,10 @@ int oid_object_info_extended_the_repository(const struct object_id *oid, struct
13071310
* information below, so return early.
13081311
*/
13091312
return 0;
1310-
rtype = packed_object_info(the_repository, e.p, e.offset, oi);
1313+
rtype = packed_object_info(r, e.p, e.offset, oi);
13111314
if (rtype < 0) {
13121315
mark_bad_packed_object(e.p, real->hash);
1313-
return oid_object_info_extended(the_repository, real, oi, 0);
1316+
return oid_object_info_extended(r, real, oi, 0);
13141317
} else if (oi->whence == OI_PACKED) {
13151318
oi->u.packed.offset = e.offset;
13161319
oi->u.packed.pack = e.p;
@@ -1322,15 +1325,17 @@ int oid_object_info_extended_the_repository(const struct object_id *oid, struct
13221325
}
13231326

13241327
/* returns enum object_type or negative */
1325-
int oid_object_info_the_repository(const struct object_id *oid, unsigned long *sizep)
1328+
int oid_object_info(struct repository *r,
1329+
const struct object_id *oid,
1330+
unsigned long *sizep)
13261331
{
13271332
enum object_type type;
13281333
struct object_info oi = OBJECT_INFO_INIT;
13291334

13301335
oi.typep = &type;
13311336
oi.sizep = sizep;
1332-
if (oid_object_info_extended(the_repository, oid, &oi,
1333-
OBJECT_INFO_LOOKUP_REPLACE) < 0)
1337+
if (oid_object_info_extended(r, oid, &oi,
1338+
OBJECT_INFO_LOOKUP_REPLACE) < 0)
13341339
return -1;
13351340
return type;
13361341
}

0 commit comments

Comments
 (0)