diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2013-10-08 13:54:50 +0400 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2013-10-08 13:54:50 +0400 |
commit | 7fb6eb278b350f9f4caab5a3f72bfb70353fc40d (patch) | |
tree | ca90ff797a5253045030b09e442e417de3c8fe95 /src/indexer.c | |
parent | b4342b116d98ba439d958c374eb4d49b06488f4c (diff) |
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.
Diffstat (limited to 'src/indexer.c')
-rw-r--r-- | src/indexer.c | 64 |
1 files changed, 37 insertions, 27 deletions
diff --git a/src/indexer.c b/src/indexer.c index 21b993a28..2cda1a629 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -683,50 +683,58 @@ cleanup: static int fix_thin_pack(git_indexer_stream *idx, git_transfer_progress *stats) { - int error; + int error, found_ref_delta = 0; unsigned int i; 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) { giterr_set(GITERR_INDEXER, "cannot fix a thin pack without an ODB"); return -1; } + /* Loop until we find the first REF delta */ git_vector_foreach(&idx->deltas, i, delta) { - size_t size; - 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; - + curpos = delta->delta_off; error = git_packfile_unpack_header(&size, &type, &idx->pack->mwf, &w, &curpos); git_mwindow_close(&w); if (error < 0) return error; - if (type != GIT_OBJ_REF_DELTA) { - giterr_set(GITERR_INDEXER, "delta with missing base is not REF_DELTA"); - return -1; + if (type == GIT_OBJ_REF_DELTA) { + found_ref_delta = 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; - } + if (!found_ref_delta) { + giterr_set(GITERR_INDEXER, "no REF_DELTA found, cannot inject object"); + return -1; + } - git_oid_fromraw(&base, base_info); - git_mwindow_close(&w); + /* 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; + } - if (inject_object(idx, &base) < 0) - return -1; + git_oid_fromraw(&base, base_info); + git_mwindow_close(&w); - stats->total_objects++; - stats->local_objects++; - } + if (inject_object(idx, &base) < 0) + return -1; + + stats->total_objects++; + stats->local_objects++; return 0; } @@ -764,8 +772,10 @@ static int resolve_deltas(git_indexer_stream *idx, git_transfer_progress *stats) i--; } - if (!progressed && (fix_thin_pack(idx, stats) < 0)) - return -1; + if (!progressed && (fix_thin_pack(idx, stats) < 0)) { + giterr_set(GITERR_INDEXER, "missing delta bases"); + return -1; + } } return 0; |