commit 088ea0a1b34b1a9d038a2d0d0e48bb70cd9bcc04 from: Omar Polo via: Thomas Adam date: Wed Aug 14 21:51:02 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 - 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 *