vendor/libgit2/src/odb_pack.c in rugged-0.17.0.b6 vs vendor/libgit2/src/odb_pack.c in rugged-0.17.0.b7

- old
+ new

@@ -22,11 +22,10 @@ struct pack_backend { git_odb_backend parent; git_vector packs; struct git_pack_file *last_found; char *pack_folder; - time_t pack_folder_mtime; }; /** * The wonderful tale of a Packed Object lookup query * =================================================== @@ -235,90 +234,104 @@ static int packfile_refresh_all(struct pack_backend *backend) { int error; struct stat st; + git_buf path = GIT_BUF_INIT; if (backend->pack_folder == NULL) return 0; if (p_stat(backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode)) return git_odb__error_notfound("failed to refresh packfiles", NULL); - if (st.st_mtime != backend->pack_folder_mtime) { - git_buf path = GIT_BUF_INIT; - git_buf_sets(&path, backend->pack_folder); + git_buf_sets(&path, backend->pack_folder); - /* reload all packs */ - error = git_path_direach(&path, packfile_load__cb, (void *)backend); + /* reload all packs */ + error = git_path_direach(&path, packfile_load__cb, (void *)backend); - git_buf_free(&path); + git_buf_free(&path); - if (error < 0) - return error; + if (error < 0) + return error; - git_vector_sort(&backend->packs); - backend->pack_folder_mtime = st.st_mtime; - } + git_vector_sort(&backend->packs); return 0; } -static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid) +static int pack_entry_find_inner( + struct git_pack_entry *e, + struct pack_backend *backend, + const git_oid *oid, + struct git_pack_file *last_found) { - int error; unsigned int i; - if ((error = packfile_refresh_all(backend)) < 0) - return error; - - if (backend->last_found && - git_pack_entry_find(e, backend->last_found, oid, GIT_OID_HEXSZ) == 0) + if (last_found && + git_pack_entry_find(e, last_found, oid, GIT_OID_HEXSZ) == 0) return 0; for (i = 0; i < backend->packs.length; ++i) { struct git_pack_file *p; p = git_vector_get(&backend->packs, i); - if (p == backend->last_found) + if (p == last_found) continue; if (git_pack_entry_find(e, p, oid, GIT_OID_HEXSZ) == 0) { backend->last_found = p; return 0; } } - return git_odb__error_notfound("failed to find pack entry", oid); + return -1; } -static int pack_entry_find_prefix( - struct git_pack_entry *e, - struct pack_backend *backend, - const git_oid *short_oid, - size_t len) +static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid) { int error; - unsigned int i; - unsigned found = 0; + struct git_pack_file *last_found = backend->last_found; + if (backend->last_found && + git_pack_entry_find(e, backend->last_found, oid, GIT_OID_HEXSZ) == 0) + return 0; + + if (!pack_entry_find_inner(e, backend, oid, last_found)) + return 0; if ((error = packfile_refresh_all(backend)) < 0) return error; + if (!pack_entry_find_inner(e, backend, oid, last_found)) + return 0; - if (backend->last_found) { - error = git_pack_entry_find(e, backend->last_found, short_oid, len); + return git_odb__error_notfound("failed to find pack entry", oid); +} + +static unsigned pack_entry_find_prefix_inner( + struct git_pack_entry *e, + struct pack_backend *backend, + const git_oid *short_oid, + size_t len, + struct git_pack_file *last_found) +{ + int error; + unsigned int i; + unsigned found = 0; + + if (last_found) { + error = git_pack_entry_find(e, last_found, short_oid, len); if (error == GIT_EAMBIGUOUS) return error; if (!error) found = 1; } for (i = 0; i < backend->packs.length; ++i) { struct git_pack_file *p; p = git_vector_get(&backend->packs, i); - if (p == backend->last_found) + if (p == last_found) continue; error = git_pack_entry_find(e, p, short_oid, len); if (error == GIT_EAMBIGUOUS) return error; @@ -327,10 +340,30 @@ break; backend->last_found = p; } } + return found; +} + +static int pack_entry_find_prefix( + struct git_pack_entry *e, + struct pack_backend *backend, + const git_oid *short_oid, + size_t len) +{ + unsigned found = 0; + int error; + struct git_pack_file *last_found = backend->last_found; + + if ((found = pack_entry_find_prefix_inner(e, backend, short_oid, len, last_found)) > 0) + goto cleanup; + if ((error = packfile_refresh_all(backend)) < 0) + return error; + found = pack_entry_find_prefix_inner(e, backend, short_oid, len, last_found); + +cleanup: if (!found) return git_odb__error_notfound("no matching pack entry for prefix", short_oid); else if (found > 1) return git_odb__error_ambiguous("found multiple pack entries"); else @@ -433,11 +466,11 @@ /* Make sure we know about the packfiles */ if ((error = packfile_refresh_all(backend)) < 0) return error; git_vector_foreach(&backend->packs, i, p) { - if ((error = git_pack_foreach_entry(p, cb, &data)) < 0) + if ((error = git_pack_foreach_entry(p, cb, data)) < 0) return error; } return 0; } @@ -511,10 +544,9 @@ return -1; } if (git_path_isdir(git_buf_cstr(&path)) == true) { backend->pack_folder = git_buf_detach(&path); - backend->pack_folder_mtime = 0; } backend->parent.read = &pack_backend__read; backend->parent.read_prefix = &pack_backend__read_prefix; backend->parent.read_header = NULL;