mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-11 18:17:54 +00:00
indexer: inject one base at a time
There may be multiple deltas referencing the same base as well as OFS deltas which rely on a thin delta. Deal with both at the same time by injecting a single object and going back up to the main delta-resolving loop.
This commit is contained in:
parent
b4342b116d
commit
7fb6eb278b
@ -683,51 +683,59 @@ cleanup:
|
|||||||
|
|
||||||
static int fix_thin_pack(git_indexer_stream *idx, git_transfer_progress *stats)
|
static int fix_thin_pack(git_indexer_stream *idx, git_transfer_progress *stats)
|
||||||
{
|
{
|
||||||
int error;
|
int error, found_ref_delta = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct delta_info *delta;
|
struct delta_info *delta;
|
||||||
|
size_t size;
|
||||||
|
git_otype type;
|
||||||
|
git_mwindow *w = NULL;
|
||||||
|
git_off_t curpos;
|
||||||
|
unsigned char *base_info;
|
||||||
|
unsigned int left = 0;
|
||||||
|
git_oid base;
|
||||||
|
|
||||||
|
assert(git_vector_length(&idx->deltas) > 0);
|
||||||
|
|
||||||
if (idx->odb == NULL) {
|
if (idx->odb == NULL) {
|
||||||
giterr_set(GITERR_INDEXER, "cannot fix a thin pack without an ODB");
|
giterr_set(GITERR_INDEXER, "cannot fix a thin pack without an ODB");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Loop until we find the first REF delta */
|
||||||
git_vector_foreach(&idx->deltas, i, delta) {
|
git_vector_foreach(&idx->deltas, i, delta) {
|
||||||
size_t size;
|
curpos = delta->delta_off;
|
||||||
git_otype type;
|
|
||||||
git_mwindow *w = NULL;
|
|
||||||
git_off_t curpos = delta->delta_off;
|
|
||||||
unsigned char *base_info;
|
|
||||||
unsigned int left = 0;
|
|
||||||
git_oid base;
|
|
||||||
|
|
||||||
error = git_packfile_unpack_header(&size, &type, &idx->pack->mwf, &w, &curpos);
|
error = git_packfile_unpack_header(&size, &type, &idx->pack->mwf, &w, &curpos);
|
||||||
git_mwindow_close(&w);
|
git_mwindow_close(&w);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
if (type != GIT_OBJ_REF_DELTA) {
|
if (type == GIT_OBJ_REF_DELTA) {
|
||||||
giterr_set(GITERR_INDEXER, "delta with missing base is not REF_DELTA");
|
found_ref_delta = 1;
|
||||||
return -1;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* curpos now points to the base information, which is an OID */
|
|
||||||
base_info = git_mwindow_open(&idx->pack->mwf, &w, curpos, GIT_OID_RAWSZ, &left);
|
|
||||||
if (base_info == NULL) {
|
|
||||||
giterr_set(GITERR_INDEXER, "failed to map delta information");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
git_oid_fromraw(&base, base_info);
|
|
||||||
git_mwindow_close(&w);
|
|
||||||
|
|
||||||
if (inject_object(idx, &base) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
stats->total_objects++;
|
|
||||||
stats->local_objects++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!found_ref_delta) {
|
||||||
|
giterr_set(GITERR_INDEXER, "no REF_DELTA found, cannot inject object");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* curpos now points to the base information, which is an OID */
|
||||||
|
base_info = git_mwindow_open(&idx->pack->mwf, &w, curpos, GIT_OID_RAWSZ, &left);
|
||||||
|
if (base_info == NULL) {
|
||||||
|
giterr_set(GITERR_INDEXER, "failed to map delta information");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
git_oid_fromraw(&base, base_info);
|
||||||
|
git_mwindow_close(&w);
|
||||||
|
|
||||||
|
if (inject_object(idx, &base) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
stats->total_objects++;
|
||||||
|
stats->local_objects++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -764,8 +772,10 @@ static int resolve_deltas(git_indexer_stream *idx, git_transfer_progress *stats)
|
|||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!progressed && (fix_thin_pack(idx, stats) < 0))
|
if (!progressed && (fix_thin_pack(idx, stats) < 0)) {
|
||||||
return -1;
|
giterr_set(GITERR_INDEXER, "missing delta bases");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user