commit 088a1c3b8187114bdc9d9f4ee98c2c8dceb97172 from: Omar Polo date: Tue Aug 13 23:11:58 2024 UTC got/cvg info: print work tree version This exends got_worktree_path_info() to resemble the "transaction"-like interface we have for rebase, patch etc. There's a prepare() routine that returns the fileindex, and locks the worktree, and a complete() function to free the fileinedx and release the lock. This way, we can open only once the fileindex in cmd_info() and have the chance to ask for its version. ok stsp@ commit - 4775b069530ea249dcfbc877685bf55700ca6423 commit + 088a1c3b8187114bdc9d9f4ee98c2c8dceb97172 blob - 938a41dbea74cf93fa15f11168f273f6f1b3b594 blob + 0c373141b94712c86b5183baed684811237bfdc0 --- cvg/cvg.c +++ cvg/cvg.c @@ -9023,6 +9023,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; @@ -9087,6 +9088,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) @@ -9103,6 +9108,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) { @@ -9116,7 +9123,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; @@ -9131,8 +9138,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 - 8cf938cd11b24a93a1118ddaed1d6725dbe666e2 blob + 2affb7860e6b084436d9adf95c331abd8fcfc8f6 --- got/got.c +++ got/got.c @@ -14620,6 +14620,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; @@ -14684,6 +14685,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) @@ -14700,6 +14705,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) { @@ -14713,7 +14720,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; @@ -14728,8 +14735,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 - 25b4a291714dfe97961ac61b9f0ac9b1954c8d05 blob + c5f4e9675da942e0ff7a4d547735205fbd74cca4 --- lib/fileindex.c +++ lib/fileindex.c @@ -53,6 +53,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; @@ -341,6 +342,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; @@ -776,6 +778,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, @@ -799,6 +802,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 - fd153d0cb67184bad0ac6b9dbd7ac36cf9866fe9 blob + 952bcd8c0a6e345b6480c5ab5354064b59b538d2 --- lib/worktree.c +++ lib/worktree.c @@ -10010,43 +10010,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 *