Commit Diff


commit - 021918ff7717955820540e4a6b6433bebbcbe9b2
commit + 088ea0a1b34b1a9d038a2d0d0e48bb70cd9bcc04
blob - 047727d268daa152be8a8f1c06bda1b42aa1abb0
blob + 5924258df05176135368876cf7f2787c9264c9da
--- cvg/cvg.c
+++ cvg/cvg.c
@@ -9021,6 +9021,7 @@ cmd_info(int argc, char *argv[])
 	const struct got_error *error = NULL;
 	struct got_repository *repo = NULL;
 	struct got_worktree *worktree = NULL;
+	struct got_fileindex *fileindex = NULL;
 	char *cwd = NULL, *id_str = NULL;
 	struct got_pathlist_head paths;
 	char *uuidstr = NULL;
@@ -9085,6 +9086,10 @@ cmd_info(int argc, char *argv[])
 		show_files = 1;
 	}
 
+	error = got_worktree_prepare_path_info(&fileindex, worktree, repo);
+	if (error)
+		goto done;
+
 	error = got_object_id_str(&id_str,
 	    got_worktree_get_base_commit_id(worktree));
 	if (error)
@@ -9101,6 +9106,8 @@ cmd_info(int argc, char *argv[])
 	printf("work tree branch reference: %s\n",
 	    got_worktree_get_head_ref_name(worktree));
 	printf("work tree UUID: %s\n", uuidstr);
+	printf("file index version: %u\n",
+	    got_worktree_fileindex_version(fileindex));
 	printf("repository: %s\n", got_worktree_get_repo_path(worktree));
 
 	if (show_files) {
@@ -9114,7 +9121,7 @@ cmd_info(int argc, char *argv[])
 			 */
 			pe->data = (void *)got_error(GOT_ERR_BAD_PATH);
 		}
-		error = got_worktree_path_info(worktree, repo, &paths,
+		error = got_worktree_path_info(worktree, fileindex, &paths,
 		    print_path_info, &paths, check_cancelled, NULL);
 		if (error)
 			goto done;
@@ -9129,8 +9136,14 @@ cmd_info(int argc, char *argv[])
 		}
 	}
 done:
-	if (worktree)
+	if (worktree) {
+		const struct got_error *cerr;
+
+		cerr = got_worktree_path_info_complete(fileindex, worktree);
+		if (error == NULL)
+			error = cerr;
 		got_worktree_close(worktree);
+	}
 	if (repo) {
 		const struct got_error *close_err = got_repo_close(repo);
 		if (error == NULL)
blob - 038355ca9ebddac3137d594a30e2f9015876e2f1
blob + b335b04da4d3f018da9b53453f1b3c7c82e5bfb1
--- got/got.c
+++ got/got.c
@@ -14619,6 +14619,7 @@ cmd_info(int argc, char *argv[])
 	const struct got_error *error = NULL;
 	struct got_repository *repo = NULL;
 	struct got_worktree *worktree = NULL;
+	struct got_fileindex *fileindex = NULL;
 	char *cwd = NULL, *id_str = NULL;
 	struct got_pathlist_head paths;
 	char *uuidstr = NULL;
@@ -14683,6 +14684,10 @@ cmd_info(int argc, char *argv[])
 		show_files = 1;
 	}
 
+	error = got_worktree_prepare_path_info(&fileindex, worktree, repo);
+	if (error)
+		goto done;
+
 	error = got_object_id_str(&id_str,
 	    got_worktree_get_base_commit_id(worktree));
 	if (error)
@@ -14699,6 +14704,8 @@ cmd_info(int argc, char *argv[])
 	printf("work tree branch reference: %s\n",
 	    got_worktree_get_head_ref_name(worktree));
 	printf("work tree UUID: %s\n", uuidstr);
+	printf("file index version: %u\n",
+	    got_worktree_fileindex_version(fileindex));
 	printf("repository: %s\n", got_worktree_get_repo_path(worktree));
 
 	if (show_files) {
@@ -14712,7 +14719,7 @@ cmd_info(int argc, char *argv[])
 			 */
 			pe->data = (void *)got_error(GOT_ERR_BAD_PATH);
 		}
-		error = got_worktree_path_info(worktree, repo, &paths,
+		error = got_worktree_path_info(worktree, fileindex, &paths,
 		    print_path_info, &paths, check_cancelled, NULL);
 		if (error)
 			goto done;
@@ -14727,8 +14734,14 @@ cmd_info(int argc, char *argv[])
 		}
 	}
 done:
-	if (worktree)
+	if (worktree) {
+		const struct got_error *cerr;
+
+		cerr = got_worktree_path_info_complete(fileindex, worktree);
+		if (error == NULL)
+			error = cerr;
 		got_worktree_close(worktree);
+	}
 	if (repo) {
 		const struct got_error *close_err = got_repo_close(repo);
 		if (error == NULL)
blob - 4ad750063163bd75fcdbccf958d5b7b7a72278fb
blob + 2ffc0c695b85896305072307f75db7799c0e05a6
--- include/got_worktree.h
+++ include/got_worktree.h
@@ -578,6 +578,21 @@ const struct got_error *got_worktree_unstage(struct go
     struct got_pathlist_head *, got_worktree_checkout_cb, void *,
     got_worktree_patch_cb, void *, struct got_repository *);
 
+/*
+ * Prepare for getting meta data for paths in the work tree.  This
+ * function also returns a poniter to a fileindex wihch must be passed
+ * back to other path_info-related functions and *_version() functions.
+ */
+const struct got_error *
+got_worktree_prepare_path_info(struct got_fileindex **,
+    struct got_worktree *, struct got_repository *);
+
+/*
+ * Get the file-index version.
+ */
+uint32_t
+got_worktree_fileindex_version(struct got_fileindex *);
+
 /* A callback function which is invoked with per-path info. */
 typedef const struct got_error *(*got_worktree_path_info_cb)(void *,
     const char *path, mode_t mode, time_t mtime,
@@ -590,10 +605,16 @@ typedef const struct got_error *(*got_worktree_path_in
  * a path, and meta-data arguments (see got_worktree_path_info_cb).
  */
 const struct got_error *
-got_worktree_path_info(struct got_worktree *, struct got_repository *,
+got_worktree_path_info(struct got_worktree *, struct got_fileindex *,
     struct got_pathlist_head *, got_worktree_path_info_cb, void *,
     got_cancel_cb , void *);
 
+/*
+ * Complete the current path_info operation.
+ */
+const struct got_error *
+got_worktree_path_info_complete(struct got_fileindex *, struct got_worktree *);
+
 /* References pointing at pre-rebase commit backups. */
 #define GOT_WORKTREE_REBASE_BACKUP_REF_PREFIX "refs/got/backup/rebase"
 
blob - d3b5bfa3ce7e946a5af80cf2d4182deceedbefa2
blob + 058e10a319018b29fa2724b3c6f07bf265e960f1
--- lib/fileindex.c
+++ lib/fileindex.c
@@ -50,6 +50,7 @@
 
 struct got_fileindex {
 	struct got_fileindex_tree entries;
+	uint32_t version;
 	int nentries; /* Does not include entries marked for removal. */
 #define GOT_FILEIDX_MAX_ENTRIES INT32_MAX
 	enum got_hash_algorithm algo;
@@ -338,6 +339,7 @@ got_fileindex_alloc(enum got_hash_algorithm algo)
 	if (fileindex == NULL)
 		return NULL;
 
+	fileindex->version = GOT_FILE_INDEX_VERSION;
 	fileindex->algo = algo;
 	RB_INIT(&fileindex->entries);
 	return fileindex;
@@ -773,6 +775,7 @@ got_fileindex_read(struct got_fileindex *fileindex, FI
 	if (hdr.version > GOT_FILE_INDEX_VERSION)
 		return got_error(GOT_ERR_FILEIDX_VER);
 
+	fileindex->version = version;
 	fileindex->algo = algo;
 	for (i = 0; i < hdr.nentries; i++) {
 		err = read_fileindex_entry(&ie, &ctx, infile,
@@ -796,6 +799,12 @@ got_fileindex_read(struct got_fileindex *fileindex, FI
 	return NULL;
 }
 
+uint32_t
+got_fileindex_version(struct got_fileindex *fileindex)
+{
+	return fileindex->version;
+}
+
 static struct got_fileindex_entry *
 walk_fileindex(struct got_fileindex *fileindex, struct got_fileindex_entry *ie)
 {
blob - 7c7b47e3dc574a93a12fc50b094d200ba5622572
blob + 03397220fbdeebff0123f0ca228af8b8bc164f3f
--- lib/got_lib_fileindex.h
+++ lib/got_lib_fileindex.h
@@ -137,6 +137,7 @@ struct got_fileindex_entry *got_fileindex_entry_get(st
     const char *, size_t);
 const struct got_error *got_fileindex_read(struct got_fileindex *, FILE *,
 	enum got_hash_algorithm);
+uint32_t got_fileindex_version(struct got_fileindex *);
 typedef const struct got_error *(*got_fileindex_cb)(void *,
     struct got_fileindex_entry *);
 const struct got_error *got_fileindex_for_each_entry_safe(
blob - 1ad2b60f26831b7defb0210497d220571e42969f
blob + 365a4ae75b7427f458e4bdb251ae298fca1254b4
--- lib/worktree.c
+++ lib/worktree.c
@@ -10007,43 +10007,55 @@ report_file_info(void *arg, struct got_fileindex_entry
 }
 
 const struct got_error *
-got_worktree_path_info(struct got_worktree *worktree,
-    struct got_repository *repo,
-    struct got_pathlist_head *paths,
-    got_worktree_path_info_cb info_cb, void *info_arg,
-    got_cancel_cb cancel_cb, void *cancel_arg)
-
+got_worktree_prepare_path_info(struct got_fileindex **fileindex,
+    struct got_worktree *worktree, struct got_repository *repo)
 {
-	const struct got_error *err = NULL, *unlockerr;
-	struct got_fileindex *fileindex = NULL;
-	char *fileindex_path = NULL;
-	struct report_file_info_arg arg;
+	const struct got_error *err;
+	char *fileindex_path;
 
 	err = lock_worktree(worktree, LOCK_SH);
 	if (err)
 		return err;
 
-	err = open_fileindex(&fileindex, &fileindex_path, worktree,
+	err = open_fileindex(fileindex, &fileindex_path, worktree,
 	    got_repo_get_object_format(repo));
-	if (err)
-		goto done;
+	free(fileindex_path);
+	return err;
+}
+
+uint32_t
+got_worktree_fileindex_version(struct got_fileindex *fileindex)
+{
+	return got_fileindex_version(fileindex);
+}
+
+const struct got_error *
+got_worktree_path_info(struct got_worktree *worktree,
+    struct got_fileindex *fileindex,
+    struct got_pathlist_head *paths,
+    got_worktree_path_info_cb info_cb, void *info_arg,
+    got_cancel_cb cancel_cb, void *cancel_arg)
 
+{
+	struct report_file_info_arg arg;
+
 	arg.worktree = worktree;
 	arg.info_cb = info_cb;
 	arg.info_arg = info_arg;
 	arg.paths = paths;
 	arg.cancel_cb = cancel_cb;
 	arg.cancel_arg = cancel_arg;
-	err = got_fileindex_for_each_entry_safe(fileindex, report_file_info,
+	return got_fileindex_for_each_entry_safe(fileindex, report_file_info,
 	    &arg);
-done:
-	free(fileindex_path);
+}
+
+const struct got_error *
+got_worktree_path_info_complete(struct got_fileindex *fileindex,
+    struct got_worktree *worktree)
+{
 	if (fileindex)
 		got_fileindex_free(fileindex);
-	unlockerr = lock_worktree(worktree, LOCK_UN);
-	if (unlockerr && err == NULL)
-		err = unlockerr;
-	return err;
+	return lock_worktree(worktree, LOCK_UN);
 }
 
 static const struct got_error *