Commit Diff


commit - 625e5896fc9ecf87ccfc92ad2a65cd3be58f73c0
commit + b8a4401b8e46c0a32b824433c648ea749898616b
blob - 02b998107e294bc2eca6ffb21a128c5973771755
blob + fadbfad45e1c86893452d04c192e3bf35883bebf
--- lib/got_lib_repository.h
+++ lib/got_lib_repository.h
@@ -52,6 +52,7 @@ struct got_repository {
 	int gitdir_fd;
 
 	struct got_pathlist_head packidx_paths;
+	time_t pack_path_mtime;
 
 	/* The pack index cache speeds up search for packed objects. */
 	struct got_packidx *packidx_cache[GOT_PACK_CACHE_SIZE];
blob - 237c796775a73f7eac4b6b6b463b2caefc13b720
blob + 87c7abb573744c7b7f9b38f35d7550229267b418
--- lib/repository.c
+++ lib/repository.c
@@ -1282,6 +1282,7 @@ got_repo_list_packidx(struct got_pathlist_head *packid
 	struct dirent *dent;
 	char *path_packidx = NULL;
 	int packdir_fd;
+	struct stat sb;
 
 	packdir_fd = openat(got_repo_get_fd(repo),
 	    GOT_OBJECTS_PACK_DIR, O_DIRECTORY | O_CLOEXEC);
@@ -1294,8 +1295,14 @@ got_repo_list_packidx(struct got_pathlist_head *packid
 	packdir = fdopendir(packdir_fd);
 	if (packdir == NULL) {
 		err = got_error_from_errno("fdopendir");
+		goto done;
+	}
+
+	if (fstat(packdir_fd, &sb) == -1) {
+		err = got_error_from_errno("fstat");
 		goto done;
 	}
+	repo->pack_path_mtime = sb.st_mtime;
 
 	while ((dent = readdir(packdir)) != NULL) {
 		if (!got_repo_is_packidx_filename(dent->d_name, dent->d_namlen))
@@ -1606,6 +1613,19 @@ got_repo_init(const char *repo_path)
 		return err;
 
 	return NULL;
+}
+
+static void
+purge_packidx_paths(struct got_pathlist_head *packidx_paths)
+{
+	struct got_pathlist_entry *pe;
+
+	while (!TAILQ_EMPTY(packidx_paths)) {
+		pe = TAILQ_FIRST(packidx_paths);
+		TAILQ_REMOVE(packidx_paths, pe, entry);
+		free((char *)pe->path);
+		free(pe);
+	}
 }
 
 static const struct got_error *
@@ -1615,9 +1635,21 @@ match_packed_object(struct got_object_id **unique_id,
 	const struct got_error *err = NULL;
 	struct got_object_id_queue matched_ids;
 	struct got_pathlist_entry *pe;
+	struct stat sb;
 
 	STAILQ_INIT(&matched_ids);
 
+	if (stat(got_repo_get_path_objects_pack(repo), &sb) == -1) {
+		if (errno != ENOENT)
+			return got_error_from_errno2("stat",
+			    got_repo_get_path_objects_pack(repo));
+	} else if (sb.st_mtime != repo->pack_path_mtime) {
+		purge_packidx_paths(&repo->packidx_paths);
+		err = got_repo_list_packidx(&repo->packidx_paths, repo);
+		if (err)
+			return err;
+	}
+
 	TAILQ_FOREACH(pe, &repo->packidx_paths, entry) {
 		const char *path_packidx = pe->path;
 		struct got_packidx *packidx;