From: Tracey Emery Subject: Re: Move got_opentempfd out of got_repo_open To: gameoftrees@openbsd.org Date: Tue, 7 Jun 2022 10:22:10 -0600 On Mon, Jun 06, 2022 at 04:20:11PM -0600, Tracey Emery wrote: > On Mon, Jun 06, 2022 at 03:28:16PM -0600, Tracey Emery wrote: > > Let's give this one a look over. This passes all regress and tog works. > > This should be tested thoroughly before going in. Comments? Suggestions? > > > > -- > > > > Tracey Emery > > > > Ok, please disregard this for now. I realized that the tests cannot be > trusted here. This diff needs every test run on packed repositories to > be accurate. I need to update tests as well before this can proceed. > > -- > > Tracey Emery > Ok, here we go. Please look this over. We now pass packed regress testing (thanks stsp for pointing out GOT_TEST_PACK=1). Comments? Ok? -- Tracey Emery diff 9f4f302a43f7e186910d59f9dbe0f839b6f2d565 1cffdd60b856f3a96a719dcd69be20f57036b0b3 blob - d88f23ce5b63a9d80862b5fac05c212d054a0b74 blob + d1f9d2af6460b1ef39239ce66df3e219af7d5875 --- got/got.c +++ got/got.c @@ -715,6 +715,7 @@ cmd_import(int argc, char *argv[]) struct got_pathlist_head ignores; struct got_pathlist_entry *pe; int preserve_logmsg = 0; + int *pack_fds = NULL; TAILQ_INIT(&ignores); @@ -773,10 +774,12 @@ cmd_import(int argc, char *argv[]) error = get_gitconfig_path(&gitconfig_path); if (error) goto done; - error = got_repo_open(&repo, repo_path, gitconfig_path); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + error = got_repo_open(&repo, repo_path, gitconfig_path, pack_fds); if (error) goto done; - error = get_author(&author, repo, NULL); if (error) return error; @@ -900,6 +903,12 @@ cmd_import(int argc, char *argv[]) printf("Created branch %s with commit %s\n", got_ref_get_name(branch_ref), id_str); done: + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (preserve_logmsg) { fprintf(stderr, "%s: log message preserved in %s\n", getprogname(), logmsg_path); @@ -1484,6 +1493,7 @@ cmd_clone(int argc, char *argv[]) char *git_url = NULL; int verbosity = 0, fetch_all_branches = 0, mirror_references = 0; int list_refs_only = 0; + int *pack_fds = NULL; TAILQ_INIT(&refs); TAILQ_INIT(&symrefs); @@ -1628,7 +1638,10 @@ cmd_clone(int argc, char *argv[]) error = got_repo_init(repo_path); if (error) goto done; - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error) goto done; } @@ -1806,6 +1819,12 @@ cmd_clone(int argc, char *argv[]) printf("Created %s repository '%s'\n", mirror_references ? "mirrored" : "cloned", repo_path); done: + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (fetchpid > 0) { if (kill(fetchpid, SIGTERM) == -1) error = got_error_from_errno("kill"); @@ -2212,6 +2231,7 @@ cmd_fetch(int argc, char *argv[]) struct got_fetch_progress_arg fpa; int verbosity = 0, fetch_all_branches = 0, list_refs_only = 0; int delete_refs = 0, replace_tags = 0, delete_remote = 0; + int *pack_fds = NULL; TAILQ_INIT(&refs); TAILQ_INIT(&symrefs); @@ -2311,8 +2331,12 @@ cmd_fetch(int argc, char *argv[]) goto done; } + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; else @@ -2333,7 +2357,7 @@ cmd_fetch(int argc, char *argv[]) } } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error) goto done; @@ -2606,6 +2630,12 @@ cmd_fetch(int argc, char *argv[]) } } done: + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (fetchpid > 0) { if (kill(fetchpid, SIGTERM) == -1) error = got_error_from_errno("kill"); @@ -2848,6 +2878,7 @@ cmd_checkout(int argc, char *argv[]) int ch, same_path_prefix, allow_nonempty = 0, verbosity = 0; struct got_pathlist_head paths; struct got_checkout_progress_arg cpa; + int *pack_fds = NULL; TAILQ_INIT(&paths); @@ -2936,10 +2967,14 @@ cmd_checkout(int argc, char *argv[]) got_path_strip_trailing_slashes(repo_path); got_path_strip_trailing_slashes(worktree_path); - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_pack_fds_open(&pack_fds); if (error != NULL) goto done; + error = got_repo_open(&repo, repo_path, NULL, pack_fds); + if (error != NULL) + goto done; + /* Pre-create work tree path for unveil(2) */ error = got_path_mkdir(worktree_path); if (error) { @@ -2966,7 +3001,7 @@ cmd_checkout(int argc, char *argv[]) if (error != NULL && !(error->code == GOT_ERR_ERRNO && errno == EEXIST)) goto done; - error = got_worktree_open(&worktree, worktree_path); + error = got_worktree_open(&worktree, worktree_path, pack_fds); if (error != NULL) goto done; @@ -3052,6 +3087,12 @@ cmd_checkout(int argc, char *argv[]) if (cpa.had_base_commit_ref_error) show_worktree_base_ref_warning(); done: + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (head_ref) got_ref_close(head_ref); if (ref) @@ -3281,9 +3322,14 @@ wrap_not_worktree_error(const struct got_error *orig_e const struct got_error *err; struct got_repository *repo; static char msg[512]; + int *pack_fds = NULL; - err = got_repo_open(&repo, path, NULL); + err = got_repo_pack_fds_open(&pack_fds); if (err) + return err; + + err = got_repo_open(&repo, path, NULL, pack_fds); + if (err) return orig_err; snprintf(msg, sizeof(msg), @@ -3293,6 +3339,12 @@ wrap_not_worktree_error(const struct got_error *orig_e "The got(1) manual page contains more information.", cmdname); err = got_error_msg(GOT_ERR_NOT_WORKTREE, msg); got_repo_close(repo); + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (err == NULL) + err = pack_err; + } return err; } @@ -3311,6 +3363,7 @@ cmd_update(int argc, char *argv[]) struct got_pathlist_entry *pe; int ch, verbosity = 0; struct got_update_progress_arg upa; + int *pack_fds = NULL; TAILQ_INIT(&paths); @@ -3346,7 +3399,12 @@ cmd_update(int argc, char *argv[]) error = got_error_from_errno("getcwd"); goto done; } - error = got_worktree_open(&worktree, worktree_path); + + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, worktree_path, pack_fds); if (error) { if (error->code == GOT_ERR_NOT_WORKTREE) error = wrap_not_worktree_error(error, "update", @@ -3359,7 +3417,7 @@ cmd_update(int argc, char *argv[]) goto done; error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), - NULL); + NULL, pack_fds); if (error != NULL) goto done; @@ -3463,8 +3521,15 @@ cmd_update(int argc, char *argv[]) got_worktree_get_head_ref_name(worktree), commit_id_str); } else printf("Already up-to-date\n"); + print_update_progress_stats(&upa); done: + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } free(worktree_path); TAILQ_FOREACH(pe, &paths, entry) free((char *)pe->path); @@ -4120,6 +4185,7 @@ cmd_log(int argc, char *argv[]) const char *errstr; struct got_reflist_head refs; struct got_reflist_object_id_map *refs_idmap = NULL; + int *pack_fds = NULL; TAILQ_INIT(&refs); @@ -4195,8 +4261,12 @@ cmd_log(int argc, char *argv[]) goto done; } + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; error = NULL; @@ -4227,7 +4297,7 @@ cmd_log(int argc, char *argv[]) goto done; } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error != NULL) goto done; @@ -4309,6 +4379,12 @@ cmd_log(int argc, char *argv[]) show_changed_paths, show_patch, search_pattern, diff_context, limit, log_branches, reverse_display_order, refs_idmap); done: + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } free(path); free(repo_path); free(cwd); @@ -4579,6 +4655,7 @@ cmd_diff(int argc, char *argv[]) struct got_pathlist_head paths; struct got_pathlist_entry *pe; FILE *f1 = NULL, *f2 = NULL; + int *pack_fds = NULL; TAILQ_INIT(&refs); TAILQ_INIT(&paths); @@ -4638,8 +4715,12 @@ cmd_diff(int argc, char *argv[]) goto done; } + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; else @@ -4660,7 +4741,7 @@ cmd_diff(int argc, char *argv[]) } } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); free(repo_path); if (error != NULL) goto done; @@ -4915,6 +4996,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } TAILQ_FOREACH(pe, &paths, entry) free((char *)pe->path); got_pathlist_free(&paths); @@ -5061,6 +5148,7 @@ cmd_blame(int argc, char *argv[]) struct blame_cb_args bca; int ch, obj_type, i; off_t filesize; + int *pack_fds = NULL; memset(&bca, 0, sizeof(bca)); @@ -5101,8 +5189,13 @@ cmd_blame(int argc, char *argv[]) error = got_error_from_errno("getcwd"); goto done; } + + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; else @@ -5124,7 +5217,7 @@ cmd_blame(int argc, char *argv[]) } } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error != NULL) goto done; @@ -5258,6 +5351,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (bca.lines) { for (i = 0; i < bca.nlines; i++) { struct blame_line *bline = &bca.lines[i]; @@ -5402,6 +5501,7 @@ cmd_tree(int argc, char *argv[]) char *commit_id_str = NULL; int show_ids = 0, recurse = 0; int ch; + int *pack_fds = NULL; #ifndef PROFILE if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil", @@ -5448,8 +5548,13 @@ cmd_tree(int argc, char *argv[]) error = got_error_from_errno("getcwd"); goto done; } + + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; else @@ -5470,7 +5575,7 @@ cmd_tree(int argc, char *argv[]) } } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error != NULL) goto done; @@ -5558,6 +5663,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } return error; } @@ -5624,6 +5735,7 @@ cmd_status(int argc, char *argv[]) struct got_pathlist_head paths; struct got_pathlist_entry *pe; int ch, i, no_ignores = 0; + int *pack_fds = NULL; TAILQ_INIT(&paths); @@ -5683,7 +5795,11 @@ cmd_status(int argc, char *argv[]) goto done; } - error = got_worktree_open(&worktree, cwd); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (error->code == GOT_ERR_NOT_WORKTREE) error = wrap_not_worktree_error(error, "status", cwd); @@ -5691,7 +5807,7 @@ cmd_status(int argc, char *argv[]) } error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), - NULL); + NULL, pack_fds); if (error != NULL) goto done; @@ -5707,6 +5823,13 @@ cmd_status(int argc, char *argv[]) error = got_worktree_status(worktree, &paths, repo, no_ignores, print_status, &st, check_cancelled, NULL); done: + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } + TAILQ_FOREACH(pe, &paths, entry) free((char *)pe->path); got_pathlist_free(&paths); @@ -5848,6 +5971,7 @@ cmd_ref(int argc, char *argv[]) int ch, do_list = 0, do_delete = 0, sort_by_time = 0; const char *obj_arg = NULL, *symref_target= NULL; char *refname = NULL; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "c:dr:ls:t")) != -1) { switch (ch) { @@ -5931,8 +6055,12 @@ cmd_ref(int argc, char *argv[]) goto done; } + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; else @@ -5953,7 +6081,7 @@ cmd_ref(int argc, char *argv[]) } } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error != NULL) goto done; @@ -5989,6 +6117,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (worktree) got_worktree_close(worktree); free(cwd); @@ -6238,6 +6372,7 @@ cmd_branch(int argc, char *argv[]) struct got_pathlist_entry *pe; struct got_object_id *commit_id = NULL; char *commit_id_str = NULL; + int *pack_fds = NULL; TAILQ_INIT(&paths); @@ -6302,8 +6437,12 @@ cmd_branch(int argc, char *argv[]) goto done; } + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; else @@ -6324,7 +6463,7 @@ cmd_branch(int argc, char *argv[]) } } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error != NULL) goto done; @@ -6417,6 +6556,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (worktree) got_worktree_close(worktree); free(cwd); @@ -6796,6 +6941,7 @@ cmd_tag(int argc, char *argv[]) char *gitconfig_path = NULL, *tagger = NULL; const char *tag_name, *commit_id_arg = NULL, *tagmsg = NULL; int ch, do_list = 0; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "c:m:r:l")) != -1) { switch (ch) { @@ -6848,8 +6994,12 @@ cmd_tag(int argc, char *argv[]) goto done; } + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; else @@ -6876,9 +7026,10 @@ cmd_tag(int argc, char *argv[]) got_worktree_close(worktree); worktree = NULL; } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error != NULL) goto done; + #ifndef PROFILE /* Remove "cpath" promise. */ if (pledge("stdio rpath wpath flock proc exec sendfd unveil", @@ -6893,7 +7044,8 @@ cmd_tag(int argc, char *argv[]) error = get_gitconfig_path(&gitconfig_path); if (error) goto done; - error = got_repo_open(&repo, repo_path, gitconfig_path); + error = got_repo_open(&repo, repo_path, gitconfig_path, + pack_fds); if (error != NULL) goto done; @@ -6939,6 +7091,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (worktree) got_worktree_close(worktree); free(cwd); @@ -6976,6 +7134,7 @@ cmd_add(int argc, char *argv[]) struct got_pathlist_head paths; struct got_pathlist_entry *pe; int ch, can_recurse = 0, no_ignores = 0; + int *pack_fds = NULL; TAILQ_INIT(&paths); @@ -7010,7 +7169,11 @@ cmd_add(int argc, char *argv[]) goto done; } - error = got_worktree_open(&worktree, cwd); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (error->code == GOT_ERR_NOT_WORKTREE) error = wrap_not_worktree_error(error, "add", cwd); @@ -7018,7 +7181,7 @@ cmd_add(int argc, char *argv[]) } error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), - NULL); + NULL, pack_fds); if (error != NULL) goto done; @@ -7068,6 +7231,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (worktree) got_worktree_close(worktree); TAILQ_FOREACH(pe, &paths, entry) @@ -7111,6 +7280,7 @@ cmd_remove(int argc, char *argv[]) struct got_pathlist_entry *pe; int ch, delete_local_mods = 0, can_recurse = 0, keep_on_disk = 0, i; int ignore_missing_paths = 0; + int *pack_fds = NULL; TAILQ_INIT(&paths); @@ -7164,7 +7334,12 @@ cmd_remove(int argc, char *argv[]) error = got_error_from_errno("getcwd"); goto done; } - error = got_worktree_open(&worktree, cwd); + + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (error->code == GOT_ERR_NOT_WORKTREE) error = wrap_not_worktree_error(error, "remove", cwd); @@ -7172,7 +7347,7 @@ cmd_remove(int argc, char *argv[]) } error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), - NULL); + NULL, pack_fds); if (error) goto done; @@ -7223,6 +7398,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (worktree) got_worktree_close(worktree); TAILQ_FOREACH(pe, &paths, entry) @@ -7327,6 +7508,7 @@ cmd_patch(int argc, char *argv[]) char *cwd = NULL; int ch, nop = 0, strip = -1, reverse = 0; int patchfd; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "np:R")) != -1) { switch (ch) { @@ -7369,12 +7551,16 @@ cmd_patch(int argc, char *argv[]) goto done; } - error = got_worktree_open(&worktree, cwd); + error = got_repo_pack_fds_open(&pack_fds); if (error != NULL) goto done; + error = got_worktree_open(&worktree, cwd, pack_fds); + if (error != NULL) + goto done; + const char *repo_path = got_worktree_get_repo_path(worktree); - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error != NULL) goto done; @@ -7398,6 +7584,12 @@ done: if (error == NULL) error = close_error; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (worktree != NULL) { close_error = got_worktree_close(worktree); if (error == NULL) @@ -7552,6 +7744,7 @@ cmd_revert(int argc, char *argv[]) FILE *patch_script_file = NULL; const char *patch_script_path = NULL; struct choose_patch_arg cpa; + int *pack_fds = NULL; TAILQ_INIT(&paths); @@ -7590,7 +7783,12 @@ cmd_revert(int argc, char *argv[]) error = got_error_from_errno("getcwd"); goto done; } - error = got_worktree_open(&worktree, cwd); + + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (error->code == GOT_ERR_NOT_WORKTREE) error = wrap_not_worktree_error(error, "revert", cwd); @@ -7598,7 +7796,7 @@ cmd_revert(int argc, char *argv[]) } error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), - NULL); + NULL, pack_fds); if (error != NULL) goto done; @@ -7661,6 +7859,13 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } + if (worktree) got_worktree_close(worktree); free(path); @@ -7836,6 +8041,7 @@ cmd_commit(int argc, char *argv[]) int ch, rebase_in_progress, histedit_in_progress, preserve_logmsg = 0; int allow_bad_symlinks = 0, non_interactive = 0, merge_in_progress = 0; struct got_pathlist_head paths; + int *pack_fds = NULL; TAILQ_INIT(&paths); cl_arg.logmsg_path = NULL; @@ -7880,7 +8086,12 @@ cmd_commit(int argc, char *argv[]) error = got_error_from_errno("getcwd"); goto done; } - error = got_worktree_open(&worktree, cwd); + + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (error->code == GOT_ERR_NOT_WORKTREE) error = wrap_not_worktree_error(error, "commit", cwd); @@ -7904,7 +8115,7 @@ cmd_commit(int argc, char *argv[]) if (error) goto done; error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), - gitconfig_path); + gitconfig_path, pack_fds); if (error != NULL) goto done; @@ -7977,6 +8188,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (worktree) got_worktree_close(worktree); free(cwd); @@ -8215,6 +8432,7 @@ cmd_send(int argc, char *argv[]) int verbosity = 0, overwrite_refs = 0; int send_all_branches = 0, send_all_tags = 0; struct got_reference *ref = NULL; + int *pack_fds = NULL; TAILQ_INIT(&branches); TAILQ_INIT(&tags); @@ -8294,8 +8512,12 @@ cmd_send(int argc, char *argv[]) goto done; } + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; else @@ -8316,7 +8538,7 @@ cmd_send(int argc, char *argv[]) } } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error) goto done; @@ -8520,6 +8742,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (worktree) got_worktree_close(worktree); if (ref) @@ -8561,6 +8789,7 @@ cmd_cherrypick(int argc, char *argv[]) struct got_object_qid *pid; int ch; struct got_update_progress_arg upa; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "")) != -1) { switch (ch) { @@ -8586,7 +8815,12 @@ cmd_cherrypick(int argc, char *argv[]) error = got_error_from_errno("getcwd"); goto done; } - error = got_worktree_open(&worktree, cwd); + + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (error->code == GOT_ERR_NOT_WORKTREE) error = wrap_not_worktree_error(error, "cherrypick", @@ -8595,7 +8829,7 @@ cmd_cherrypick(int argc, char *argv[]) } error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), - NULL); + NULL, pack_fds); if (error != NULL) goto done; @@ -8637,6 +8871,13 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } + return error; } @@ -8659,6 +8900,7 @@ cmd_backout(int argc, char *argv[]) struct got_object_qid *pid; int ch; struct got_update_progress_arg upa; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "")) != -1) { switch (ch) { @@ -8684,7 +8926,12 @@ cmd_backout(int argc, char *argv[]) error = got_error_from_errno("getcwd"); goto done; } - error = got_worktree_open(&worktree, cwd); + + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (error->code == GOT_ERR_NOT_WORKTREE) error = wrap_not_worktree_error(error, "backout", cwd); @@ -8692,7 +8939,7 @@ cmd_backout(int argc, char *argv[]) } error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), - NULL); + NULL, pack_fds); if (error != NULL) goto done; @@ -8738,6 +8985,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } return error; } @@ -9322,6 +9575,7 @@ cmd_rebase(int argc, char *argv[]) const struct got_object_id_queue *parent_ids; struct got_object_qid *qid, *pid; struct got_update_progress_arg upa; + int *pack_fds = NULL; STAILQ_INIT(&commits); TAILQ_INIT(&merged_paths); @@ -9388,7 +9642,12 @@ cmd_rebase(int argc, char *argv[]) error = got_error_from_errno("getcwd"); goto done; } - error = got_worktree_open(&worktree, cwd); + + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (list_backups || delete_backups) { if (error->code != GOT_ERR_NOT_WORKTREE) @@ -9402,7 +9661,8 @@ cmd_rebase(int argc, char *argv[]) } error = got_repo_open(&repo, - worktree ? got_worktree_get_repo_path(worktree) : cwd, NULL); + worktree ? got_worktree_get_repo_path(worktree) : cwd, NULL, + pack_fds); if (error != NULL) goto done; @@ -9687,6 +9947,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } return error; } @@ -10541,6 +10807,7 @@ cmd_histedit(int argc, char *argv[]) struct got_object_qid *pid; struct got_histedit_list histedit_cmds; struct got_histedit_list_entry *hle; + int *pack_fds = NULL; STAILQ_INIT(&commits); TAILQ_INIT(&histedit_cmds); @@ -10662,7 +10929,12 @@ cmd_histedit(int argc, char *argv[]) error = got_error_from_errno("getcwd"); goto done; } - error = got_worktree_open(&worktree, cwd); + + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (list_backups || delete_backups) { if (error->code != GOT_ERR_NOT_WORKTREE) @@ -10678,7 +10950,7 @@ cmd_histedit(int argc, char *argv[]) if (list_backups || delete_backups) { error = got_repo_open(&repo, worktree ? got_worktree_get_repo_path(worktree) : cwd, - NULL); + NULL, pack_fds); if (error != NULL) goto done; error = apply_unveil(got_repo_get_path(repo), 0, @@ -10692,7 +10964,7 @@ cmd_histedit(int argc, char *argv[]) } error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), - NULL); + NULL, pack_fds); if (error != NULL) goto done; @@ -11062,6 +11334,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } return error; } @@ -11085,6 +11363,7 @@ cmd_integrate(int argc, char *argv[]) struct got_object_id *commit_id = NULL, *base_commit_id = NULL; int ch; struct got_update_progress_arg upa; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "")) != -1) { switch (ch) { @@ -11111,7 +11390,11 @@ cmd_integrate(int argc, char *argv[]) goto done; } - error = got_worktree_open(&worktree, cwd); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (error->code == GOT_ERR_NOT_WORKTREE) error = wrap_not_worktree_error(error, "integrate", @@ -11124,7 +11407,7 @@ cmd_integrate(int argc, char *argv[]) goto done; error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), - NULL); + NULL, pack_fds); if (error != NULL) goto done; @@ -11202,6 +11485,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (worktree) got_worktree_close(worktree); free(cwd); @@ -11236,6 +11525,7 @@ cmd_merge(int argc, char *argv[]) struct got_update_progress_arg upa; struct got_object_id *merge_commit_id = NULL; char *branch_name = NULL; + int *pack_fds = NULL; memset(&upa, 0, sizeof(upa)); @@ -11279,7 +11569,11 @@ cmd_merge(int argc, char *argv[]) goto done; } - error = got_worktree_open(&worktree, cwd); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (error->code == GOT_ERR_NOT_WORKTREE) error = wrap_not_worktree_error(error, @@ -11288,7 +11582,8 @@ cmd_merge(int argc, char *argv[]) } error = got_repo_open(&repo, - worktree ? got_worktree_get_repo_path(worktree) : cwd, NULL); + worktree ? got_worktree_get_repo_path(worktree) : cwd, NULL, + pack_fds); if (error != NULL) goto done; @@ -11474,6 +11769,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } return error; } @@ -11526,6 +11827,7 @@ cmd_stage(int argc, char *argv[]) FILE *patch_script_file = NULL; const char *patch_script_path = NULL; struct choose_patch_arg cpa; + int *pack_fds = NULL; TAILQ_INIT(&paths); @@ -11568,7 +11870,11 @@ cmd_stage(int argc, char *argv[]) goto done; } - error = got_worktree_open(&worktree, cwd); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (error->code == GOT_ERR_NOT_WORKTREE) error = wrap_not_worktree_error(error, "stage", cwd); @@ -11576,7 +11882,7 @@ cmd_stage(int argc, char *argv[]) } error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), - NULL); + NULL, pack_fds); if (error != NULL) goto done; @@ -11621,6 +11927,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (worktree) got_worktree_close(worktree); TAILQ_FOREACH(pe, &paths, entry) @@ -11654,6 +11966,7 @@ cmd_unstage(int argc, char *argv[]) FILE *patch_script_file = NULL; const char *patch_script_path = NULL; struct choose_patch_arg cpa; + int *pack_fds = NULL; TAILQ_INIT(&paths); @@ -11688,7 +12001,11 @@ cmd_unstage(int argc, char *argv[]) goto done; } - error = got_worktree_open(&worktree, cwd); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (error->code == GOT_ERR_NOT_WORKTREE) error = wrap_not_worktree_error(error, "unstage", cwd); @@ -11696,7 +12013,7 @@ cmd_unstage(int argc, char *argv[]) } error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), - NULL); + NULL, pack_fds); if (error != NULL) goto done; @@ -11734,6 +12051,12 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } if (worktree) got_worktree_close(worktree); TAILQ_FOREACH(pe, &paths, entry) @@ -11938,6 +12261,7 @@ cmd_cat(int argc, char *argv[]) struct got_commit_object *commit = NULL; int ch, obj_type, i, force_path = 0; struct got_reflist_head refs; + int *pack_fds = NULL; TAILQ_INIT(&refs); @@ -11977,8 +12301,12 @@ cmd_cat(int argc, char *argv[]) goto done; } + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; if (worktree) { @@ -12001,7 +12329,7 @@ cmd_cat(int argc, char *argv[]) return got_error_from_errno("strdup"); } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); free(repo_path); if (error != NULL) goto done; @@ -12087,6 +12415,13 @@ done: if (error == NULL) error = close_err; } + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } + got_ref_list_free(&refs); return error; } @@ -12177,6 +12512,7 @@ cmd_info(int argc, char *argv[]) struct got_pathlist_entry *pe; char *uuidstr = NULL; int ch, show_files = 0; + int *pack_fds = NULL; TAILQ_INIT(&paths); @@ -12202,7 +12538,11 @@ cmd_info(int argc, char *argv[]) goto done; } - error = got_worktree_open(&worktree, cwd); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error) { if (error->code == GOT_ERR_NOT_WORKTREE) error = wrap_not_worktree_error(error, "info", cwd); @@ -12269,6 +12609,12 @@ cmd_info(int argc, char *argv[]) } } done: + if (pack_fds) { + const struct got_error *pack_err = + got_repo_pack_fds_close(pack_fds); + if (error == NULL) + error = pack_err; + } TAILQ_FOREACH(pe, &paths, entry) free((char *)pe->path); got_pathlist_free(&paths); blob - 59c11d1ab01684d8a2f16d934fb1d6870d7ac871 blob + 94aa122da416f31dd52c4f9839a25313a0da9cc2 --- gotadmin/gotadmin.c +++ gotadmin/gotadmin.c @@ -238,6 +238,7 @@ get_repo_path(char **repo_path) const struct got_error *err = NULL; struct got_worktree *worktree = NULL; char *cwd; + int *pack_fds = NULL; *repo_path = NULL; @@ -245,7 +246,11 @@ get_repo_path(char **repo_path) if (cwd == NULL) return got_error_from_errno("getcwd"); - err = got_worktree_open(&worktree, cwd); + err = got_repo_pack_fds_open(&pack_fds); + if (err != NULL) + goto done; + + err = got_worktree_open(&worktree, cwd, pack_fds); if (err) { if (err->code != GOT_ERR_NOT_WORKTREE) goto done; @@ -262,6 +267,7 @@ done: if (worktree) got_worktree_close(worktree); free(cwd); + err = got_repo_pack_fds_close(pack_fds); return err; } @@ -275,6 +281,7 @@ cmd_info(int argc, char *argv[]) int ch, npackfiles, npackedobj, nobj; off_t packsize, loose_size; char scaled[FMT_SCALED_STRSIZE]; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "r:")) != -1) { switch (ch) { @@ -304,7 +311,10 @@ cmd_info(int argc, char *argv[]) if (error) goto done; } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error) goto done; #ifndef PROFILE @@ -371,6 +381,7 @@ cmd_info(int argc, char *argv[]) done: if (repo) got_repo_close(repo); + error = got_repo_pack_fds_close(pack_fds); free(repo_path); return error; } @@ -629,6 +640,7 @@ cmd_pack(int argc, char *argv[]) struct got_reflist_head exclude_refs; struct got_reflist_head include_refs; struct got_reflist_entry *re, *new; + int *pack_fds = NULL; TAILQ_INIT(&exclude_args); TAILQ_INIT(&exclude_refs); @@ -675,7 +687,10 @@ cmd_pack(int argc, char *argv[]) if (error) goto done; } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error) goto done; @@ -731,6 +746,9 @@ cmd_pack(int argc, char *argv[]) printf("\n"); goto done; } + error = got_repo_pack_fds_close(pack_fds); + if (error) + goto done; error = got_object_id_str(&id_str, pack_hash); if (error) @@ -775,6 +793,7 @@ cmd_indexpack(int argc, char *argv[]) char *id_str = NULL; struct got_pack_progress_arg ppa; FILE *packfile = NULL; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "")) != -1) { switch (ch) { @@ -800,9 +819,15 @@ cmd_indexpack(int argc, char *argv[]) err(1, "pledge"); #endif - error = got_repo_open(&repo, packfile_path, NULL); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + error = got_repo_open(&repo, packfile_path, NULL, pack_fds); if (error) goto done; + error = got_repo_pack_fds_close(pack_fds); + if (error) + goto done; error = apply_unveil(got_repo_get_path_git_dir(repo), 0); if (error) @@ -943,6 +968,7 @@ cmd_listpack(int argc, char *argv[]) struct gotadmin_list_pack_cb_args lpa; FILE *packfile = NULL; int show_stats = 0, human_readable = 0; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "hs")) != -1) { switch (ch) { @@ -972,9 +998,15 @@ cmd_listpack(int argc, char *argv[]) NULL) == -1) err(1, "pledge"); #endif - error = got_repo_open(&repo, packfile_path, NULL); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + error = got_repo_open(&repo, packfile_path, NULL, pack_fds); if (error) goto done; + error = got_repo_pack_fds_close(pack_fds); + if (error) + goto done; #ifndef PROFILE /* Remove "cpath" promise. */ if (pledge("stdio rpath wpath flock proc exec sendfd unveil", @@ -1120,6 +1152,7 @@ cmd_cleanup(int argc, char *argv[]) char scaled_diff[FMT_SCALED_STRSIZE]; char **extensions; int nextensions, i; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "apr:nq")) != -1) { switch (ch) { @@ -1161,9 +1194,15 @@ cmd_cleanup(int argc, char *argv[]) if (error) goto done; } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error) goto done; + error = got_repo_pack_fds_close(pack_fds); + if (error) + goto done; error = apply_unveil(got_repo_get_path_git_dir(repo), 0); if (error) blob - 613976ee0e8a3f55e862ceb0aa730fd85f3e46e3 blob + e36610bb8f42b4e466bde3c7d20d2138169f08df --- gotweb/gotweb.c +++ gotweb/gotweb.c @@ -2784,6 +2784,7 @@ gw_get_repo_age(char **repo_age, struct gw_trans *gw_t struct got_reflist_head refs; struct got_reflist_entry *re; time_t committer_time = 0, cmp_time = 0; + int *pack_fds = NULL; *repo_age = NULL; TAILQ_INIT(&refs); @@ -2794,9 +2795,15 @@ gw_get_repo_age(char **repo_age, struct gw_trans *gw_t if (gw_trans->repo) repo = gw_trans->repo; else { - error = got_repo_open(&repo, dir, NULL); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + error = got_repo_open(&repo, dir, NULL, pack_fds); if (error) return error; + error = got_repo_pack_fds_close(pack_fds); + if (error) + return error; } error = got_ref_list(&refs, repo, "refs/heads", @@ -2955,15 +2962,23 @@ gw_get_repo_owner(char **owner, struct gw_trans *gw_tr const struct got_error *error = NULL, *close_err; struct got_repository *repo; const char *gitconfig_owner; + int *pack_fds = NULL; *owner = NULL; if (gw_trans->gw_conf->got_show_repo_owner == 0) return NULL; - error = got_repo_open(&repo, dir, NULL); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + return error; + error = got_repo_open(&repo, dir, NULL, pack_fds); if (error) return error; + error = got_repo_pack_fds_close(pack_fds); + if (error) + return error; + gitconfig_owner = got_repo_get_gitconfig_owner(repo); if (gitconfig_owner) { *owner = strdup(gitconfig_owner); @@ -3772,10 +3787,18 @@ gw_get_header(struct gw_trans *gw_trans, struct gw_hea char *in_repo_path = NULL; struct got_object_id *id = NULL; struct got_reference *ref; + int *pack_fds = NULL; - error = got_repo_open(&gw_trans->repo, gw_trans->repo_path, NULL); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + error = got_repo_open(&gw_trans->repo, gw_trans->repo_path, NULL, + pack_fds); if (error) return error; + error = got_repo_pack_fds_close(pack_fds); + if (error) + return error; if (gw_trans->commit_id == NULL || gw_trans->action == GW_COMMITS || gw_trans->action == GW_BRIEFS || gw_trans->action == GW_SUMMARY || blob - b6e44e8b40b8476a471c53fd10cffd4a7ff3b32d blob + c6c3ae86c927f406085a265e15638706ec7fed6f --- include/got_repository.h +++ include/got_repository.h @@ -20,7 +20,7 @@ struct got_tag_object; /* Open and close repositories. */ const struct got_error *got_repo_open(struct got_repository**, const char *, - const char *); + const char *, int *); const struct got_error *got_repo_close(struct got_repository*); /* Obtain the on-disk path to the repository. */ @@ -177,3 +177,12 @@ const struct got_error *got_repo_get_loose_object_info /* Obtain the number and size of packed objects in the repository. */ const struct got_error *got_repo_get_packfile_info(int *npackfiles, int *nobjects, off_t *total_packsize, struct got_repository *); + +/* Create an array of file descriptors to hand over to got_repo_open for pack */ +const struct got_error *got_repo_pack_fds_open(int **); + +/* Copy our pack file descriptors */ +const struct got_error *got_repo_pack_fds_copy(int **, struct got_repository *); + +/* Close the array of file descriptors handed over to got_repo_open for pack */ +const struct got_error *got_repo_pack_fds_close(int *); blob - 610e03aa8788afbfcdcdc782c96c1c1965707674 blob + e193a6a07c0f85bab692aa00733a0b15e305e345 --- include/got_worktree.h +++ include/got_worktree.h @@ -54,7 +54,8 @@ const struct got_error *got_worktree_init(const char * * Attempt to open a worktree at or above the specified path. * The caller must dispose of it with got_worktree_close(). */ -const struct got_error *got_worktree_open(struct got_worktree **, const char *); +const struct got_error *got_worktree_open(struct got_worktree **, const char *, + int *); /* Dispose of an open work tree. */ const struct got_error *got_worktree_close(struct got_worktree *); blob - a35884552cf66d678f0db623e1dd92d976a7014e blob + 414cf45f495487020f948b4b0c3e6a45ef730da9 --- lib/got_lib_worktree.h +++ lib/got_lib_worktree.h @@ -22,6 +22,7 @@ struct got_worktree { struct got_object_id *base_commit_id; char *head_ref_name; uuid_t uuid; + int *pack_fds; /* * File descriptor for the lock file, open while a work tree is open. blob - 5be66db732b6a51d032ae835a233ef3cbcd3733b blob + 16e1536fb8cda2f6a65839a25fc2cedb0b06a14c --- lib/repository.c +++ lib/repository.c @@ -68,6 +68,8 @@ #define nitems(_a) (sizeof(_a) / sizeof((_a)[0])) #endif +#define GOT_PACK_NUM_TEMPFILES GOT_PACK_CACHE_SIZE * 2 + RB_PROTOTYPE(got_packidx_bloom_filter_tree, got_packidx_bloom_filter, entry, got_packidx_bloom_filter_cmp); @@ -247,6 +249,67 @@ done: } const struct got_error * +got_repo_pack_fds_open(int **pack_fds) +{ + const struct got_error *err = NULL; + int i, pack_fds_tmp[GOT_PACK_NUM_TEMPFILES]; + + *pack_fds = calloc(GOT_PACK_NUM_TEMPFILES, sizeof(**pack_fds)); + if (*pack_fds == NULL) + return got_error_from_errno("calloc"); + + for (i = 0; i < GOT_PACK_NUM_TEMPFILES; i++) { + pack_fds_tmp[i] = got_opentempfd(); + if (pack_fds_tmp[i] == -1) + return got_error_from_errno("got_opentempfd"); + } + memcpy(*pack_fds, pack_fds_tmp, sizeof(pack_fds_tmp)); + return err; +} + +const struct got_error * +got_repo_pack_fds_copy(int **pack_fds, struct got_repository *repo) +{ + const struct got_error *err = NULL; + int i, pack_fds_tmp[GOT_PACK_NUM_TEMPFILES]; + + *pack_fds = calloc(GOT_PACK_NUM_TEMPFILES, sizeof(**pack_fds)); + if (*pack_fds == NULL) + return got_error_from_errno("calloc"); + + for (i = 0; i < GOT_PACK_NUM_TEMPFILES / 2; i++) { + pack_fds_tmp[i] = repo->packs[i].accumfd; + if (pack_fds_tmp[i] == -1) + return got_error_from_errno("got_repo_pack_fds_copy"); + } + for (i = GOT_PACK_NUM_TEMPFILES / 2; i < GOT_PACK_NUM_TEMPFILES; i++) { + pack_fds_tmp[i] = repo->packs[i - + (GOT_PACK_NUM_TEMPFILES / 2)].basefd; + if (pack_fds_tmp[i] == -1) + return got_error_from_errno("got_repo_pack_fds_copy"); + } + memcpy(*pack_fds, pack_fds_tmp, sizeof(pack_fds_tmp)); + return err; +} + +const struct got_error * +got_repo_pack_fds_close(int *pack_fds) +{ + const struct got_error *err = NULL; + int i; + + for (i = 0; i < GOT_PACK_NUM_TEMPFILES; i++) { + if (close(pack_fds[i]) == -1) { + err = got_error_from_errno("close"); + break; + } + } + free(pack_fds); + pack_fds = NULL; + return err; +} + +const struct got_error * got_repo_cache_object(struct got_repository *repo, struct got_object_id *id, struct got_object *obj) { @@ -651,12 +714,12 @@ static const char *const repo_extensions[] = { const struct got_error * got_repo_open(struct got_repository **repop, const char *path, - const char *global_gitconfig_path) + const char *global_gitconfig_path, int *pack_fds) { struct got_repository *repo = NULL; const struct got_error *err = NULL; char *repo_path = NULL; - size_t i; + size_t i, j = 0; struct rlimit rl; *repop = NULL; @@ -703,12 +766,8 @@ got_repo_open(struct got_repository **repop, const cha repo->pack_cache_size = rl.rlim_cur / 8; for (i = 0; i < nitems(repo->packs); i++) { if (i < repo->pack_cache_size) { - repo->packs[i].basefd = got_opentempfd(); - if (repo->packs[i].basefd == -1) - return got_error_from_errno("got_opentempfd"); - repo->packs[i].accumfd = got_opentempfd(); - if (repo->packs[i].accumfd == -1) - return got_error_from_errno("got_opentempfd"); + repo->packs[i].basefd = pack_fds[j++]; + repo->packs[i].accumfd = pack_fds[j++]; } else { repo->packs[i].basefd = -1; repo->packs[i].accumfd = -1; @@ -796,20 +855,10 @@ got_repo_close(struct got_repository *repo) free(bf); } - for (i = 0; i < repo->pack_cache_size; i++) { + for (i = 0; i < repo->pack_cache_size; i++) if (repo->packs[i].path_packfile) - got_pack_close(&repo->packs[i]); - if (repo->packs[i].basefd != -1) { - if (close(repo->packs[i].basefd) == -1 && err == NULL) - err = got_error_from_errno("close"); - repo->packs[i].basefd = -1; - } - if (repo->packs[i].accumfd != -1) { - if (close(repo->packs[i].accumfd) == -1 && err == NULL) - err = got_error_from_errno("close"); - repo->packs[i].accumfd = -1; - } - } + if (repo->packs[i].path_packfile) + got_pack_close(&repo->packs[i]); free(repo->path); free(repo->path_git_dir); blob - 673cbeb89c705904097774881d38ef9d51751939 blob + b2c501c93b5b911eda66bb0c017747c3e1297121 --- lib/worktree_open.c +++ lib/worktree_open.c @@ -105,7 +105,7 @@ done: } static const struct got_error * -open_worktree(struct got_worktree **worktree, const char *path) +open_worktree(struct got_worktree **worktree, const char *path, int *pack_fds) { const struct got_error *err = NULL; char *path_got; @@ -190,7 +190,7 @@ open_worktree(struct got_worktree **worktree, const ch goto done; } - err = got_repo_open(&repo, (*worktree)->repo_path, NULL); + err = got_repo_open(&repo, (*worktree)->repo_path, NULL, pack_fds); if (err) goto done; @@ -244,7 +244,8 @@ done: } const struct got_error * -got_worktree_open(struct got_worktree **worktree, const char *path) +got_worktree_open(struct got_worktree **worktree, const char *path, + int *pack_fds) { const struct got_error *err = NULL; char *worktree_path; @@ -256,7 +257,7 @@ got_worktree_open(struct got_worktree **worktree, cons for (;;) { char *parent_path; - err = open_worktree(worktree, worktree_path); + err = open_worktree(worktree, worktree_path, pack_fds); if (err && !(err->code == GOT_ERR_ERRNO && errno == ENOENT)) { free(worktree_path); return err; blob - b4efe82ad2000b743da8b7312623bf0fe3708969 blob + b496b13bf344f95e51f313a226f6e665bd72ce23 --- tog/tog.c +++ tog/tog.c @@ -503,6 +503,7 @@ struct tog_view { int dying; struct tog_view *parent; struct tog_view *child; + struct got_repository *repo; /* * This flag is initially set on parent views when a new child view @@ -1125,7 +1126,7 @@ view_loop(struct tog_view *view) } TAILQ_INSERT_TAIL(&views, new_view, entry); view = new_view; - } + } if (view) { if (view_is_parent_view(view)) { if (view->child && view->child->focussed) @@ -2317,6 +2318,7 @@ open_log_view(struct tog_view *view, struct got_object struct got_repository *thread_repo = NULL; struct got_commit_graph *thread_graph = NULL; int errcode; + int *pack_fds = NULL; if (in_repo_path != s->in_repo_path) { free(s->in_repo_path); @@ -2370,9 +2372,16 @@ open_log_view(struct tog_view *view, struct got_object view->search_start = search_start_log_view; view->search_next = search_next_log_view; - err = got_repo_open(&thread_repo, got_repo_get_path(repo), NULL); + err = got_repo_pack_fds_open(&pack_fds); if (err) goto done; + err = got_repo_open(&thread_repo, got_repo_get_path(repo), NULL, + pack_fds); + if (err) + goto done; + err = got_repo_pack_fds_close(pack_fds); + if (err) + goto done; err = got_commit_graph_open(&thread_graph, s->in_repo_path, !s->log_branches); if (err) @@ -2442,6 +2451,7 @@ input_log_view(struct tog_view **new_view, struct tog_ struct tog_view *ref_view = NULL; struct commit_queue_entry *entry; int begin_x = 0, n; + int *pack_fds = NULL; if (s->thread_args.load_all) { if (ch == KEY_BACKSPACE) @@ -2634,10 +2644,16 @@ input_log_view(struct tog_view **new_view, struct tog_ } else /* 'B' */ s->log_branches = !s->log_branches; + err = got_repo_pack_fds_open(&pack_fds); + if (err) + return err; err = got_repo_open(&s->thread_args.repo, - got_repo_get_path(s->repo), NULL); + got_repo_get_path(s->repo), NULL, pack_fds); if (err) return err; + err = got_repo_pack_fds_close(pack_fds); + if (err) + return err; tog_free_refs(); err = tog_load_refs(s->repo, 0); if (err) @@ -2791,6 +2807,7 @@ cmd_log(int argc, char *argv[]) const char *head_ref_name = NULL; int ch, log_branches = 0; struct tog_view *view; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "bc:r:")) != -1) { switch (ch) { @@ -2818,11 +2835,15 @@ cmd_log(int argc, char *argv[]) if (argc > 1) usage_log(); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { cwd = getcwd(NULL, 0); if (cwd == NULL) return got_error_from_errno("getcwd"); - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; if (worktree) @@ -2836,7 +2857,7 @@ cmd_log(int argc, char *argv[]) } } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error != NULL) goto done; @@ -2893,6 +2914,9 @@ cmd_log(int argc, char *argv[]) worktree = NULL; } error = view_loop(view); + if (error != NULL) + goto done; + error = got_repo_pack_fds_close(pack_fds); done: free(in_repo_path); free(repo_path); @@ -3911,6 +3935,7 @@ cmd_diff(int argc, char *argv[]) int ch, force_text_diff = 0; const char *errstr; struct tog_view *view; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "aC:r:w")) != -1) { switch (ch) { @@ -3951,11 +3976,15 @@ cmd_diff(int argc, char *argv[]) } else usage_diff(); + error = got_repo_pack_fds_open(&pack_fds); + if (error) + goto done; + if (repo_path == NULL) { cwd = getcwd(NULL, 0); if (cwd == NULL) return got_error_from_errno("getcwd"); - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; if (worktree) @@ -3969,7 +3998,7 @@ cmd_diff(int argc, char *argv[]) } } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error) goto done; @@ -4003,6 +4032,9 @@ cmd_diff(int argc, char *argv[]) if (error) goto done; error = view_loop(view); + if (error) + return error; + error = got_repo_pack_fds_close(pack_fds); done: free(label1); free(label2); @@ -4162,7 +4194,7 @@ draw_blame(struct tog_view *view) width = 9; wline = wcsdup(L""); if (wline == NULL) { - err = got_error_from_errno("wcsdup"); + err = got_error_from_errno("wcsup"); free(line); return err; } @@ -4372,6 +4404,7 @@ run_blame(struct tog_view *view) struct got_repository *thread_repo = NULL; struct got_object_id *obj_id = NULL; int obj_type; + int *pack_fds = NULL; err = got_object_open_as_commit(&commit, s->repo, &s->blamed_commit->id); @@ -4418,9 +4451,13 @@ run_blame(struct tog_view *view) goto done; } - err = got_repo_open(&thread_repo, got_repo_get_path(s->repo), NULL); + err = got_repo_pack_fds_copy(&pack_fds, view->repo); if (err) goto done; + err = got_repo_open(&thread_repo, got_repo_get_path(s->repo), NULL, + pack_fds); + if (err) + goto done; blame->cb_args.view = view; blame->cb_args.lines = blame->lines; @@ -4494,6 +4531,7 @@ open_blame_view(struct tog_view *view, char *path, return err; } + view->repo = repo; view->show = show_blame_view; view->input = input_blame_view; view->close = close_blame_view; @@ -4861,6 +4899,7 @@ cmd_blame(int argc, char *argv[]) char *commit_id_str = NULL; int ch; struct tog_view *view; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "c:r:")) != -1) { switch (ch) { @@ -4885,11 +4924,15 @@ cmd_blame(int argc, char *argv[]) if (argc != 1) usage_blame(); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { cwd = getcwd(NULL, 0); if (cwd == NULL) return got_error_from_errno("getcwd"); - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; if (worktree) @@ -4903,7 +4946,7 @@ cmd_blame(int argc, char *argv[]) } } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error != NULL) goto done; @@ -4962,6 +5005,9 @@ cmd_blame(int argc, char *argv[]) worktree = NULL; } error = view_loop(view); + if (error) + goto done; + error = got_repo_pack_fds_close(pack_fds); done: free(repo_path); free(in_repo_path); @@ -5723,6 +5769,7 @@ cmd_tree(int argc, char *argv[]) const char *head_ref_name = NULL; int ch; struct tog_view *view; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "c:r:")) != -1) { switch (ch) { @@ -5747,11 +5794,15 @@ cmd_tree(int argc, char *argv[]) if (argc > 1) usage_tree(); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { cwd = getcwd(NULL, 0); if (cwd == NULL) return got_error_from_errno("getcwd"); - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; if (worktree) @@ -5765,7 +5816,7 @@ cmd_tree(int argc, char *argv[]) } } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error != NULL) goto done; @@ -5828,6 +5879,9 @@ cmd_tree(int argc, char *argv[]) worktree = NULL; } error = view_loop(view); + if (error) + goto done; + error = got_repo_pack_fds_close(pack_fds); done: free(repo_path); free(cwd); @@ -6476,6 +6530,7 @@ cmd_ref(int argc, char *argv[]) char *cwd = NULL, *repo_path = NULL; int ch; struct tog_view *view; + int *pack_fds = NULL; while ((ch = getopt(argc, argv, "r:")) != -1) { switch (ch) { @@ -6497,11 +6552,15 @@ cmd_ref(int argc, char *argv[]) if (argc > 1) usage_ref(); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + if (repo_path == NULL) { cwd = getcwd(NULL, 0); if (cwd == NULL) return got_error_from_errno("getcwd"); - error = got_worktree_open(&worktree, cwd); + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; if (worktree) @@ -6515,7 +6574,7 @@ cmd_ref(int argc, char *argv[]) } } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error != NULL) goto done; @@ -6545,6 +6604,9 @@ cmd_ref(int argc, char *argv[]) worktree = NULL; } error = view_loop(view); + if (error) + goto done; + error = got_repo_pack_fds_close(pack_fds); done: free(repo_path); free(cwd); @@ -6624,12 +6686,17 @@ tog_log_with_path(int argc, char *argv[]) struct got_commit_object *commit = NULL; char *cwd = NULL, *repo_path = NULL, *in_repo_path = NULL; char *commit_id_str = NULL, **cmd_argv = NULL; + int *pack_fds = NULL; cwd = getcwd(NULL, 0); if (cwd == NULL) return got_error_from_errno("getcwd"); - error = got_worktree_open(&worktree, cwd); + error = got_repo_pack_fds_open(&pack_fds); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, cwd, pack_fds); if (error && error->code != GOT_ERR_NOT_WORKTREE) goto done; @@ -6642,9 +6709,12 @@ tog_log_with_path(int argc, char *argv[]) goto done; } - error = got_repo_open(&repo, repo_path, NULL); + error = got_repo_open(&repo, repo_path, NULL, pack_fds); if (error != NULL) goto done; + error = got_repo_pack_fds_close(pack_fds); + if (error) + goto done; error = get_in_repo_path_from_argv0(&in_repo_path, argc, argv, repo, worktree); @@ -6806,4 +6876,5 @@ main(int argc, char *argv[]) if (error && error->code != GOT_ERR_CANCELLED) fprintf(stderr, "%s: %s\n", getprogname(), error->msg); return 0; + }