Skip to content

Commit 90191d3

Browse files
peffgitster
authored andcommitted
packed_object_info: hoist delta type resolution to helper
To calculate the type of a packed object, we must walk down its delta chain until we hit a true base object with a real type. Most of the code in packed_object_info is for handling this case. Let's hoist it out into a separate helper function, which will make it easier to make the type-lookup optional in the future (and keep our indentation level sane). Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 052fe5e commit 90191d3

File tree

1 file changed

+53
-40
lines changed

1 file changed

+53
-40
lines changed

sha1_file.c

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,52 +1710,21 @@ static int retry_bad_packed_offset(struct packed_git *p, off_t obj_offset)
17101710
return type;
17111711
}
17121712

1713-
17141713
#define POI_STACK_PREALLOC 64
17151714

1716-
static int packed_object_info(struct packed_git *p, off_t obj_offset,
1717-
unsigned long *sizep, int *rtype,
1718-
unsigned long *disk_sizep)
1715+
static enum object_type packed_to_object_type(struct packed_git *p,
1716+
off_t obj_offset,
1717+
enum object_type type,
1718+
struct pack_window **w_curs,
1719+
off_t curpos)
17191720
{
1720-
struct pack_window *w_curs = NULL;
1721-
unsigned long size;
1722-
off_t curpos = obj_offset;
1723-
enum object_type type;
17241721
off_t small_poi_stack[POI_STACK_PREALLOC];
17251722
off_t *poi_stack = small_poi_stack;
17261723
int poi_stack_nr = 0, poi_stack_alloc = POI_STACK_PREALLOC;
17271724

1728-
type = unpack_object_header(p, &w_curs, &curpos, &size);
1729-
1730-
if (rtype)
1731-
*rtype = type; /* representation type */
1732-
1733-
if (sizep) {
1734-
if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
1735-
off_t tmp_pos = curpos;
1736-
off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
1737-
type, obj_offset);
1738-
if (!base_offset) {
1739-
type = OBJ_BAD;
1740-
goto out;
1741-
}
1742-
*sizep = get_size_from_delta(p, &w_curs, tmp_pos);
1743-
if (*sizep == 0) {
1744-
type = OBJ_BAD;
1745-
goto out;
1746-
}
1747-
} else {
1748-
*sizep = size;
1749-
}
1750-
}
1751-
1752-
if (disk_sizep) {
1753-
struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
1754-
*disk_sizep = revidx[1].offset - obj_offset;
1755-
}
1756-
17571725
while (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
17581726
off_t base_offset;
1727+
unsigned long size;
17591728
/* Push the object we're going to leave behind */
17601729
if (poi_stack_nr >= poi_stack_alloc && poi_stack == small_poi_stack) {
17611730
poi_stack_alloc = alloc_nr(poi_stack_nr);
@@ -1766,11 +1735,11 @@ static int packed_object_info(struct packed_git *p, off_t obj_offset,
17661735
}
17671736
poi_stack[poi_stack_nr++] = obj_offset;
17681737
/* If parsing the base offset fails, just unwind */
1769-
base_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset);
1738+
base_offset = get_delta_base(p, w_curs, &curpos, type, obj_offset);
17701739
if (!base_offset)
17711740
goto unwind;
17721741
curpos = obj_offset = base_offset;
1773-
type = unpack_object_header(p, &w_curs, &curpos, &size);
1742+
type = unpack_object_header(p, w_curs, &curpos, &size);
17741743
if (type <= OBJ_NONE) {
17751744
/* If getting the base itself fails, we first
17761745
* retry the base, otherwise unwind */
@@ -1797,7 +1766,6 @@ static int packed_object_info(struct packed_git *p, off_t obj_offset,
17971766
out:
17981767
if (poi_stack != small_poi_stack)
17991768
free(poi_stack);
1800-
unuse_pack(&w_curs);
18011769
return type;
18021770

18031771
unwind:
@@ -1811,6 +1779,51 @@ static int packed_object_info(struct packed_git *p, off_t obj_offset,
18111779
goto out;
18121780
}
18131781

1782+
static int packed_object_info(struct packed_git *p, off_t obj_offset,
1783+
unsigned long *sizep, int *rtype,
1784+
unsigned long *disk_sizep)
1785+
{
1786+
struct pack_window *w_curs = NULL;
1787+
unsigned long size;
1788+
off_t curpos = obj_offset;
1789+
enum object_type type;
1790+
1791+
type = unpack_object_header(p, &w_curs, &curpos, &size);
1792+
1793+
if (rtype)
1794+
*rtype = type; /* representation type */
1795+
1796+
if (sizep) {
1797+
if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
1798+
off_t tmp_pos = curpos;
1799+
off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
1800+
type, obj_offset);
1801+
if (!base_offset) {
1802+
type = OBJ_BAD;
1803+
goto out;
1804+
}
1805+
*sizep = get_size_from_delta(p, &w_curs, tmp_pos);
1806+
if (*sizep == 0) {
1807+
type = OBJ_BAD;
1808+
goto out;
1809+
}
1810+
} else {
1811+
*sizep = size;
1812+
}
1813+
}
1814+
1815+
if (disk_sizep) {
1816+
struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
1817+
*disk_sizep = revidx[1].offset - obj_offset;
1818+
}
1819+
1820+
type = packed_to_object_type(p, obj_offset, type, &w_curs, curpos);
1821+
1822+
out:
1823+
unuse_pack(&w_curs);
1824+
return type;
1825+
}
1826+
18141827
static void *unpack_compressed_entry(struct packed_git *p,
18151828
struct pack_window **w_curs,
18161829
off_t curpos,

0 commit comments

Comments
 (0)