static int fix_thin_pack(git_indexer *idx, git_transfer_progress *stats) { 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 = 0; 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, delta_info*) { if (!delta) continue; 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) { found_ref_delta = 1; break; } } 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->local_objects++; return 0; }
void test_checkout_conflict__report_progress(void) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_vector paths = GIT_VECTOR_INIT; char *path; size_t i; struct checkout_index_entry checkout_index_entries[] = { { 0100644, CONFLICTING_ANCESTOR_OID, 1, "conflicting-1.txt" }, { 0100644, CONFLICTING_OURS_OID, 2, "conflicting-1.txt" }, { 0100644, CONFLICTING_THEIRS_OID, 3, "conflicting-1.txt" }, { 0100644, CONFLICTING_ANCESTOR_OID, 1, "conflicting-2.txt" }, { 0100644, CONFLICTING_OURS_OID, 2, "conflicting-2.txt" }, { 0100644, CONFLICTING_THEIRS_OID, 3, "conflicting-2.txt" }, { 0100644, AUTOMERGEABLE_ANCESTOR_OID, 1, "conflicting-3.txt" }, { 0100644, AUTOMERGEABLE_OURS_OID, 2, "conflicting-3.txt" }, { 0100644, AUTOMERGEABLE_THEIRS_OID, 3, "conflicting-3.txt" }, { 0100644, AUTOMERGEABLE_ANCESTOR_OID, 1, "conflicting-4.txt" }, { 0100644, AUTOMERGEABLE_OURS_OID, 2, "conflicting-4.txt" }, { 0100644, AUTOMERGEABLE_THEIRS_OID, 3, "conflicting-4.txt" }, }; opts.progress_cb = collect_progress; opts.progress_payload = &paths; create_index(checkout_index_entries, 12); git_index_write(g_index); cl_git_pass(git_checkout_index(g_repo, g_index, &opts)); cl_assert_equal_i(4, git_vector_length(&paths)); cl_assert_equal_s("conflicting-1.txt", git_vector_get(&paths, 0)); cl_assert_equal_s("conflicting-2.txt", git_vector_get(&paths, 1)); cl_assert_equal_s("conflicting-3.txt", git_vector_get(&paths, 2)); cl_assert_equal_s("conflicting-4.txt", git_vector_get(&paths, 3)); git_vector_foreach(&paths, i, path) git__free(path); git_vector_free(&paths); }
int git_diff_from_buffer( git_diff **out, const char *content, size_t content_len) { git_diff_parsed *diff; git_patch *patch; git_patch_parse_ctx *ctx = NULL; int error = 0; *out = NULL; diff = diff_parsed_alloc(); GITERR_CHECK_ALLOC(diff); ctx = git_patch_parse_ctx_init(content, content_len, NULL); GITERR_CHECK_ALLOC(ctx); while (ctx->remain_len) { if ((error = git_patch_parse(&patch, ctx)) < 0) break; git_vector_insert(&diff->patches, patch); git_vector_insert(&diff->base.deltas, patch->delta); } if (error == GIT_ENOTFOUND && git_vector_length(&diff->patches) > 0) { giterr_clear(); error = 0; } git_patch_parse_ctx_free(ctx); if (error < 0) git_diff_free(&diff->base); else *out = &diff->base; return error; }