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;