worktree: pass repository to public functions

Refactor remaining public functions that still depend on `the_repository` to instead receive a repository as parameter. This allows us to get rid of `USE_THE_REPOSITORY_VARIABLE`. Adapt callers accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jul 16, 2026 at 07:33 UTC e2533e0915ab1e40cf058669c4e8755d693366a6
19 files changed +120 -97
branch.c
+2 -2
@@ -394,7 +394,7 @@ static void prepare_checked_out_branches(void)
394 return;
395 initialized_checked_out_branches = 1;
396
397 - worktrees = get_worktrees();
397 + worktrees = get_worktrees(the_repository);
398
399 while (worktrees[i]) {
400 char *old, *wt_gitdir;
@@ -846,7 +846,7 @@ void remove_branch_state(struct repository *r, int verbose)
846
847 void die_if_checked_out(const char *branch, int ignore_current_worktree)
848 {
849 - struct worktree **worktrees = get_worktrees();
849 + struct worktree **worktrees = get_worktrees(the_repository);
850
851 for (int i = 0; worktrees[i]; i++) {
852 if (worktrees[i]->is_current && ignore_current_worktree)
builtin/branch.c
+1 -1
@@ -579,7 +579,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
579 const char *interpreted_oldname = NULL;
580 const char *interpreted_newname = NULL;
581 int recovery = 0, oldref_usage = 0;
582 - struct worktree **worktrees = get_worktrees();
582 + struct worktree **worktrees = get_worktrees(the_repository);
583
584 if (check_branch_ref(&oldref, oldname)) {
585 /*
builtin/config.c
+1 -1
@@ -974,7 +974,7 @@ static void location_options_init(struct config_location_options *opts,
974 opts->source.file = opts->file_to_free = repo_git_path(the_repository, "config");
975 opts->source.scope = CONFIG_SCOPE_LOCAL;
976 } else if (opts->use_worktree_config) {
977 - struct worktree **worktrees = get_worktrees();
977 + struct worktree **worktrees = get_worktrees(the_repository);
978 if (the_repository->repository_format_worktree_config)
979 opts->source.file = opts->file_to_free =
980 repo_git_path(the_repository, "config.worktree");
builtin/fsck.c
+3 -3
@@ -632,7 +632,7 @@ static void snapshot_refs(struct repository *repo,
632 refs_for_each_ref_ext(get_main_ref_store(repo),
633 snapshot_ref, &data, &opts);
634
635 - worktrees = get_worktrees();
635 + worktrees = get_worktrees(repo);
636 for (p = worktrees; *p; p++) {
637 struct worktree *wt = *p;
638 struct strbuf refname = STRBUF_INIT;
@@ -685,7 +685,7 @@ static void process_refs(struct repository *repo, struct snapshot *snap)
685 }
686
687 if (include_reflogs) {
688 - worktrees = get_worktrees();
688 + worktrees = get_worktrees(repo);
689 for (p = worktrees; *p; p++) {
690 struct worktree *wt = *p;
691
@@ -1121,7 +1121,7 @@ int cmd_fsck(int argc,
1121 verify_index_checksum = 1;
1122 verify_ce_order = 1;
1123
1124 - worktrees = get_worktrees();
1124 + worktrees = get_worktrees(repo);
1125 for (p = worktrees; *p; p++) {
1126 struct worktree *wt = *p;
1127 struct index_state istate =
builtin/gc.c
+1 -1
@@ -412,7 +412,7 @@ static int worktree_prune_condition(struct gc_config *cfg)
412 while (limit && (d = readdir_skip_dot_and_dotdot(dir))) {
413 char *wtpath;
414 strbuf_reset(&buf);
415 - if (should_prune_worktree(d->d_name, &buf, &wtpath, expiry_date))
415 + if (should_prune_worktree(the_repository, d->d_name, &buf, &wtpath, expiry_date))
416 limit--;
417 free(wtpath);
418 }
builtin/notes.c
+1 -1
@@ -989,7 +989,7 @@ static int merge(int argc, const char **argv, const char *prefix,
989 "NOTES_MERGE_PARTIAL", &result_oid, NULL,
990 0, UPDATE_REFS_DIE_ON_ERR);
991 /* Store ref-to-be-updated into .git/NOTES_MERGE_REF */
992 - worktrees = get_worktrees();
992 + worktrees = get_worktrees(the_repository);
993 wt = find_shared_symref(worktrees, "NOTES_MERGE_REF",
994 notes_ref);
995 if (wt)
builtin/receive-pack.c
+1 -1
@@ -1503,7 +1503,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
1503 struct object_id *old_oid = &cmd->old_oid;
1504 struct object_id *new_oid = &cmd->new_oid;
1505 int do_update_worktree = 0;
1506 - struct worktree **worktrees = get_worktrees();
1506 + struct worktree **worktrees = get_worktrees(the_repository);
1507 const struct worktree *worktree =
1508 find_shared_symref(worktrees, "HEAD", name);
1509
builtin/reflog.c
+2 -2
@@ -250,7 +250,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix,
250 struct string_list_item *item;
251 struct worktree **worktrees, **p;
252
253 - worktrees = get_worktrees();
253 + worktrees = get_worktrees(the_repository);
254 for (p = worktrees; *p; p++) {
255 if (single_worktree && !(*p)->is_current)
256 continue;
@@ -374,7 +374,7 @@ static int cmd_reflog_drop(int argc, const char **argv, const char *prefix,
374 struct string_list_item *item;
375 struct worktree **worktrees, **p;
376
377 - worktrees = get_worktrees();
377 + worktrees = get_worktrees(the_repository);
378 for (p = worktrees; *p; p++) {
379 if (single_worktree && !(*p)->is_current)
380 continue;
builtin/refs.c
+1 -1
@@ -113,7 +113,7 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix,
113 repo_config(repo, git_fsck_config, &fsck_refs_options);
114 prepare_repo_settings(repo);
115
116 - worktrees = get_worktrees_without_reading_head();
116 + worktrees = get_worktrees_without_reading_head(repo);
117 for (size_t i = 0; worktrees[i]; i++)
118 ret |= refs_fsck(get_worktree_ref_store(worktrees[i]),
119 &fsck_refs_options, worktrees[i]);
builtin/worktree.c
+13 -11
@@ -226,7 +226,7 @@ static void prune_worktrees(void)
226 while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) {
227 char *path;
228 strbuf_reset(&reason);
229 - if (should_prune_worktree(d->d_name, &reason, &path, expire))
229 + if (should_prune_worktree(the_repository, d->d_name, &reason, &path, expire))
230 prune_worktree(d->d_name, reason.buf);
231 else if (path)
232 string_list_append_nodup(&kept, path)->util = xstrdup(d->d_name);
@@ -475,7 +475,7 @@ static int add_worktree(const char *path, const char *refname,
475 struct ref_store *wt_refs;
476 struct repo_config_values *cfg = repo_config_values(the_repository);
477
478 - worktrees = get_worktrees();
478 + worktrees = get_worktrees(the_repository);
479 check_candidate_path(path, opts->force, worktrees, "add");
480 free_worktrees(worktrees);
481 worktrees = NULL;
@@ -539,7 +539,8 @@ static int add_worktree(const char *path, const char *refname,
539
540 strbuf_reset(&sb);
541 strbuf_addf(&sb, "%s/gitdir", sb_repo.buf);
542 - write_worktree_linking_files(sb_git.buf, sb.buf, opts->relative_paths);
542 + write_worktree_linking_files(the_repository, sb_git.buf,
543 + sb.buf, opts->relative_paths);
544 strbuf_reset(&sb);
545 strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
546 write_file(sb.buf, "../..");
@@ -547,7 +548,7 @@ static int add_worktree(const char *path, const char *refname,
548 /*
549 * Set up the ref store of the worktree and create the HEAD reference.
550 */
550 - wt = get_linked_worktree(name, 1);
551 + wt = get_linked_worktree(the_repository, name, 1);
552 if (!wt) {
553 ret = error(_("could not find created worktree '%s'"), name);
554 goto done;
@@ -1103,7 +1104,7 @@ static int list(int ac, const char **av, const char *prefix,
1104 else if (!line_terminator && !porcelain)
1105 die(_("the option '%s' requires '%s'"), "-z", "--porcelain");
1106 else {
1106 - struct worktree **worktrees = get_worktrees();
1107 + struct worktree **worktrees = get_worktrees(the_repository);
1108 int path_maxwidth = 0, abbrev = DEFAULT_ABBREV, i;
1109 struct worktree_display *display = NULL;
1110
@@ -1146,7 +1147,7 @@ static int lock_worktree(int ac, const char **av, const char *prefix,
1147 if (ac != 1)
1148 usage_with_options(git_worktree_lock_usage, options);
1149
1149 - worktrees = get_worktrees();
1150 + worktrees = get_worktrees(the_repository);
1151 wt = find_worktree(worktrees, prefix, av[0]);
1152 if (!wt)
1153 die(_("'%s' is not a working tree"), av[0]);
@@ -1183,7 +1184,7 @@ static int unlock_worktree(int ac, const char **av, const char *prefix,
1184 if (ac != 1)
1185 usage_with_options(git_worktree_unlock_usage, options);
1186
1186 - worktrees = get_worktrees();
1187 + worktrees = get_worktrees(the_repository);
1188 wt = find_worktree(worktrees, prefix, av[0]);
1189 if (!wt)
1190 die(_("'%s' is not a working tree"), av[0]);
@@ -1269,7 +1270,7 @@ static int move_worktree(int ac, const char **av, const char *prefix,
1270 strbuf_addstr(&dst, path);
1271 free(path);
1272
1272 - worktrees = get_worktrees();
1273 + worktrees = get_worktrees(the_repository);
1274 wt = find_worktree(worktrees, prefix, av[0]);
1275 if (!wt)
1276 die(_("'%s' is not a working tree"), av[0]);
@@ -1394,7 +1395,7 @@ static int remove_worktree(int ac, const char **av, const char *prefix,
1395 if (ac != 1)
1396 usage_with_options(git_worktree_remove_usage, options);
1397
1397 - worktrees = get_worktrees();
1398 + worktrees = get_worktrees(the_repository);
1399 wt = find_worktree(worktrees, prefix, av[0]);
1400 if (!wt)
1401 die(_("'%s' is not a working tree"), av[0]);
@@ -1456,8 +1457,9 @@ static int repair(int ac, const char **av, const char *prefix,
1457 ac = parse_options(ac, av, prefix, options, git_worktree_repair_usage, 0);
1458 p = ac > 0 ? av : self;
1459 for (; *p; p++)
1459 - repair_worktree_at_path(*p, report_repair, &rc, use_relative_paths);
1460 - repair_worktrees(report_repair, &rc, use_relative_paths);
1460 + repair_worktree_at_path(the_repository, *p, report_repair,
1461 + &rc, use_relative_paths);
1462 + repair_worktrees(the_repository, report_repair, &rc, use_relative_paths);
1463 return rc;
1464 }
1465
reachable.c
+2 -2
@@ -62,7 +62,7 @@ static void add_rebase_files(struct rev_info *revs)
62 "rebase-merge/autostash",
63 "rebase-merge/orig-head",
64 };
65 - struct worktree **worktrees = get_worktrees();
65 + struct worktree **worktrees = get_worktrees(the_repository);
66
67 for (struct worktree **wt = worktrees; *wt; wt++) {
68 char *wt_gitdir = get_worktree_git_dir(*wt);
@@ -319,7 +319,7 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
319
320 /* detached HEAD is not included in the list above */
321 refs_head_ref(get_main_ref_store(the_repository), add_one_ref, revs);
322 - other_head_refs(add_one_ref, revs);
322 + other_head_refs(the_repository, add_one_ref, revs);
323
324 /* rebase autostash and orig-head */
325 add_rebase_files(revs);
ref-filter.c
+1 -1
@@ -2402,7 +2402,7 @@ static void lazy_init_worktree_map(void)
2402 if (ref_to_worktree_map.worktrees)
2403 return;
2404
2405 - ref_to_worktree_map.worktrees = get_worktrees();
2405 + ref_to_worktree_map.worktrees = get_worktrees(the_repository);
2406 hashmap_init(&(ref_to_worktree_map.map), ref_to_worktree_map_cmpfnc, NULL, 0);
2407 populate_worktree_map(&(ref_to_worktree_map.map), ref_to_worktree_map.worktrees);
2408 }
refs.c
+1 -1
@@ -3328,7 +3328,7 @@ done:
3328
3329 static int has_worktrees(void)
3330 {
3331 - struct worktree **worktrees = get_worktrees();
3331 + struct worktree **worktrees = get_worktrees(the_repository);
3332 int ret = 0;
3333 size_t i;
3334
revision.c
+3 -3
@@ -1711,7 +1711,7 @@ static void add_other_reflogs_to_pending(struct all_refs_cb *cb)
1711 {
1712 struct worktree **worktrees, **p;
1713
1714 - worktrees = get_worktrees();
1714 + worktrees = get_worktrees(the_repository);
1715 for (p = worktrees; *p; p++) {
1716 struct worktree *wt = *p;
1717
@@ -1837,7 +1837,7 @@ void add_index_objects_to_pending(struct rev_info *revs, unsigned int flags)
1837 if (revs->single_worktree)
1838 return;
1839
1840 - worktrees = get_worktrees();
1840 + worktrees = get_worktrees(the_repository);
1841 for (p = worktrees; *p; p++) {
1842 struct worktree *wt = *p;
1843 struct index_state istate = INDEX_STATE_INIT(revs->repo);
@@ -2813,7 +2813,7 @@ static int handle_revision_pseudo_opt(struct rev_info *revs,
2813 struct all_refs_cb cb;
2814
2815 init_all_refs_cb(&cb, revs, *flags);
2816 - other_head_refs(handle_one_ref, &cb);
2816 + other_head_refs(the_repository, handle_one_ref, &cb);
2817 }
2818 clear_ref_exclusions(&revs->ref_excludes);
2819 } else if (!strcmp(arg, "--branches")) {
setup.c
+4 -3
@@ -2650,7 +2650,8 @@ static void create_object_directory(struct repository *repo)
2650 strbuf_release(&path);
2651 }
2652
2653 -static void separate_git_dir(const char *git_dir, const char *git_link)
2653 +static void separate_git_dir(struct repository *repo,
2654 + const char *git_dir, const char *git_link)
2655 {
2656 struct stat st;
2657
@@ -2666,7 +2667,7 @@ static void separate_git_dir(const char *git_dir, const char *git_link)
2667
2668 if (rename(src, git_dir))
2669 die_errno(_("unable to move %s to %s"), src, git_dir);
2669 - repair_worktrees_after_gitdir_move(src);
2670 + repair_worktrees_after_gitdir_move(repo, src);
2671 }
2672
2673 write_file(git_link, "gitdir: %s", git_dir);
@@ -2823,7 +2824,7 @@ int init_db(struct repository *repo,
2824
2825 set_git_dir(repo, real_git_dir, 1);
2826 git_dir = repo_get_git_dir(repo);
2826 - separate_git_dir(git_dir, original_git_dir);
2827 + separate_git_dir(repo, git_dir, original_git_dir);
2828 }
2829 else {
2830 set_git_dir(repo, git_dir, 1);
submodule.c
+1 -1
@@ -2494,7 +2494,7 @@ static void relocate_single_git_dir_into_superproject(const char *path,
2494 if (validate_submodule_path(path) < 0)
2495 exit(128);
2496
2497 - if (submodule_uses_worktrees(path))
2497 + if (submodule_uses_worktrees(the_repository, path))
2498 die(_("relocate_gitdir for submodule '%s' with "
2499 "more than one worktree not supported"), path);
2500
t/helper/test-ref-store.c
+1 -1
@@ -84,7 +84,7 @@ static const char **get_store(const char **argv, struct ref_store **refs)
84
85 *refs = repo_get_submodule_ref_store(the_repository, gitdir);
86 } else if (skip_prefix(argv[0], "worktree:", &gitdir)) {
87 - struct worktree **p, **worktrees = get_worktrees();
87 + struct worktree **p, **worktrees = get_worktrees(the_repository);
88
89 for (p = worktrees; *p; p++) {
90 struct worktree *wt = *p;
worktree.c
+64 -51
@@ -1,4 +1,3 @@
1 -#define USE_THE_REPOSITORY_VARIABLE
1 #define DISABLE_SIGN_COMPARE_WARNINGS
2
3 #include "git-compat-util.h"
@@ -139,7 +138,8 @@ static struct worktree *get_main_worktree(struct repository *repo,
138 return worktree;
139 }
140
142 -struct worktree *get_linked_worktree(const char *id,
141 +struct worktree *get_linked_worktree(struct repository *repo,
142 + const char *id,
143 int skip_reading_head)
144 {
145 struct worktree *worktree = NULL;
@@ -149,7 +149,7 @@ struct worktree *get_linked_worktree(const char *id,
149 if (!id)
150 die("Missing linked worktree name");
151
152 - repo_common_path_append(the_repository, &path, "worktrees/%s/gitdir", id);
152 + repo_common_path_append(repo, &path, "worktrees/%s/gitdir", id);
153 if (strbuf_read_file(&worktree_path, path.buf, 0) <= 0)
154 /* invalid gitdir file */
155 goto done;
@@ -163,7 +163,7 @@ struct worktree *get_linked_worktree(const char *id,
163 }
164
165 CALLOC_ARRAY(worktree, 1);
166 - worktree->repo = the_repository;
166 + worktree->repo = repo;
167 worktree->path = strbuf_detach(&worktree_path, NULL);
168 worktree->id = xstrdup(id);
169 worktree->is_current = is_current_worktree(worktree);
@@ -203,7 +203,7 @@ static struct worktree **get_worktrees_internal(struct repository *repo,
203 while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) {
204 struct worktree *linked = NULL;
205
206 - if ((linked = get_linked_worktree(d->d_name, skip_reading_head))) {
206 + if ((linked = get_linked_worktree(repo, d->d_name, skip_reading_head))) {
207 ALLOC_GROW(list, counter + 1, alloc);
208 list[counter++] = linked;
209 }
@@ -216,14 +216,14 @@ static struct worktree **get_worktrees_internal(struct repository *repo,
216 return list;
217 }
218
219 -struct worktree **get_worktrees(void)
219 +struct worktree **get_worktrees(struct repository *repo)
220 {
221 - return get_worktrees_internal(the_repository, 0);
221 + return get_worktrees_internal(repo, 0);
222 }
223
224 -struct worktree **get_worktrees_without_reading_head(void)
224 +struct worktree **get_worktrees_without_reading_head(struct repository *repo)
225 {
226 - return get_worktrees_internal(the_repository, 1);
226 + return get_worktrees_internal(repo, 1);
227 }
228
229 char *get_worktree_git_dir(const struct worktree *wt)
@@ -336,7 +336,7 @@ const char *worktree_prune_reason(struct worktree *wt, timestamp_t expire)
336 if (wt->prune_reason_valid)
337 return wt->prune_reason;
338
339 - if (should_prune_worktree(wt->id, &reason, &path, expire))
339 + if (should_prune_worktree(wt->repo, wt->id, &reason, &path, expire))
340 wt->prune_reason = strbuf_detach(&reason, NULL);
341 wt->prune_reason_valid = 1;
342
@@ -447,7 +447,8 @@ void update_worktree_location(struct worktree *wt, const char *path_,
447 strbuf_realpath(&path, path_, 1);
448 strbuf_addf(&dotgit, "%s/.git", path.buf);
449 if (fspathcmp(wt->path, path.buf)) {
450 - write_worktree_linking_files(dotgit.buf, gitdir.buf, use_relative_paths);
450 + write_worktree_linking_files(wt->repo, dotgit.buf,
451 + gitdir.buf, use_relative_paths);
452
453 free(wt->path);
454 wt->path = strbuf_detach(&path, NULL);
@@ -535,7 +536,8 @@ const struct worktree *find_shared_symref(struct worktree **worktrees,
536 return NULL;
537 }
538
538 -int submodule_uses_worktrees(const char *path)
539 +int submodule_uses_worktrees(struct repository *repo,
540 + const char *path)
541 {
542 char *submodule_gitdir;
543 struct strbuf sb = STRBUF_INIT, err = STRBUF_INIT;
@@ -544,7 +546,7 @@ int submodule_uses_worktrees(const char *path)
546 int ret = 0;
547 struct repository_format format = REPOSITORY_FORMAT_INIT;
548
547 - submodule_gitdir = repo_submodule_path(the_repository,
549 + submodule_gitdir = repo_submodule_path(repo,
550 path, "%s", "");
551 if (!submodule_gitdir)
552 return 0;
@@ -597,13 +599,14 @@ void strbuf_worktree_ref(const struct worktree *wt,
599 strbuf_addstr(sb, refname);
600 }
601
600 -int other_head_refs(refs_for_each_cb fn, void *cb_data)
602 +int other_head_refs(struct repository *repo,
603 + refs_for_each_cb fn, void *cb_data)
604 {
605 struct worktree **worktrees, **p;
606 struct strbuf refname = STRBUF_INIT;
607 int ret = 0;
608
606 - worktrees = get_worktrees();
609 + worktrees = get_worktrees(repo);
610 for (p = worktrees; *p; p++) {
611 struct worktree *wt = *p;
612 struct object_id oid;
@@ -614,7 +617,7 @@ int other_head_refs(refs_for_each_cb fn, void *cb_data)
617
618 strbuf_reset(&refname);
619 strbuf_worktree_ref(wt, &refname, "HEAD");
617 - if (refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
620 + if (refs_resolve_ref_unsafe(get_main_ref_store(repo),
621 refname.buf,
622 RESOLVE_REF_READING,
623 &oid, &flag)) {
@@ -687,7 +690,8 @@ static void repair_gitfile(struct worktree *wt,
690
691 if (repair) {
692 fn(0, wt->path, repair, cb_data);
690 - write_worktree_linking_files(dotgit.buf, gitdir.buf, use_relative_paths);
693 + write_worktree_linking_files(wt->repo, dotgit.buf,
694 + gitdir.buf, use_relative_paths);
695 }
696
697 done:
@@ -707,9 +711,10 @@ static void repair_noop(int iserr UNUSED,
711 /* nothing */
712 }
713
710 -void repair_worktrees(worktree_repair_fn fn, void *cb_data, int use_relative_paths)
714 +void repair_worktrees(struct repository *repo, worktree_repair_fn fn,
715 + void *cb_data, int use_relative_paths)
716 {
712 - struct worktree **worktrees = get_worktrees_internal(the_repository, 1);
717 + struct worktree **worktrees = get_worktrees_internal(repo, 1);
718 struct worktree **wt = worktrees + 1; /* +1 skips main worktree */
719
720 if (!fn)
@@ -745,16 +750,17 @@ void repair_worktree_after_gitdir_move(struct worktree *wt, const char *old_path
750 if (!file_exists(dotgit.buf))
751 goto done;
752
748 - write_worktree_linking_files(dotgit.buf, gitdir.buf, is_relative_path);
753 + write_worktree_linking_files(wt->repo, dotgit.buf,
754 + gitdir.buf, is_relative_path);
755 done:
756 strbuf_release(&gitdir);
757 strbuf_release(&dotgit);
758 free(path);
759 }
760
755 -void repair_worktrees_after_gitdir_move(const char *old_path)
761 +void repair_worktrees_after_gitdir_move(struct repository *repo, const char *old_path)
762 {
757 - struct worktree **worktrees = get_worktrees_internal(the_repository, 1);
763 + struct worktree **worktrees = get_worktrees_internal(repo, 1);
764 struct worktree **wt = worktrees + 1; /* +1 skips main worktree */
765
766 for (; *wt; wt++)
@@ -762,7 +768,7 @@ void repair_worktrees_after_gitdir_move(const char *old_path)
768 free_worktrees(worktrees);
769 }
770
765 -static int is_main_worktree_path(const char *path)
771 +static int is_main_worktree_path(struct repository *repo, const char *path)
772 {
773 struct strbuf target = STRBUF_INIT;
774 struct strbuf maindir = STRBUF_INIT;
@@ -770,7 +776,7 @@ static int is_main_worktree_path(const char *path)
776
777 strbuf_add_real_path(&target, path);
778 strbuf_strip_suffix(&target, "/.git");
773 - strbuf_add_real_path(&maindir, repo_get_common_dir(the_repository));
779 + strbuf_add_real_path(&maindir, repo_get_common_dir(repo));
780 strbuf_strip_suffix(&maindir, "/.git");
781 cmp = fspathcmp(maindir.buf, target.buf);
782
@@ -821,7 +827,8 @@ error:
827 * Repair <repo>/worktrees/<id>/gitdir if missing, corrupt, or not pointing at
828 * the worktree's path.
829 */
824 -void repair_worktree_at_path(const char *path,
830 +void repair_worktree_at_path(struct repository *repo,
831 + const char *path,
832 worktree_repair_fn fn, void *cb_data,
833 int use_relative_paths)
834 {
@@ -837,7 +844,7 @@ void repair_worktree_at_path(const char *path,
844 if (!fn)
845 fn = repair_noop;
846
840 - if (is_main_worktree_path(path))
847 + if (is_main_worktree_path(repo, path))
848 goto done;
849
850 strbuf_addf(&dotgit, "%s/.git", path);
@@ -846,7 +853,7 @@ void repair_worktree_at_path(const char *path,
853 goto done;
854 }
855
849 - infer_backlink(the_repository, dotgit.buf, &inferred_backlink);
856 + infer_backlink(repo, dotgit.buf, &inferred_backlink);
857 strbuf_realpath_forgiving(&inferred_backlink, inferred_backlink.buf, 0);
858 dotgit_contents = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err));
859 if (dotgit_contents) {
@@ -919,7 +926,8 @@ void repair_worktree_at_path(const char *path,
926
927 if (repair) {
928 fn(0, gitdir.buf, repair, cb_data);
922 - write_worktree_linking_files(dotgit.buf, gitdir.buf, use_relative_paths);
929 + write_worktree_linking_files(repo, dotgit.buf,
930 + gitdir.buf, use_relative_paths);
931 }
932 done:
933 free(dotgit_contents);
@@ -930,12 +938,16 @@ done:
938 strbuf_release(&dotgit);
939 }
940
933 -int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath, timestamp_t expire)
941 +int should_prune_worktree(struct repository *repo,
942 + const char *id,
943 + struct strbuf *reason,
944 + char **wtpath,
945 + timestamp_t expire)
946 {
947 struct stat st;
948 struct strbuf dotgit = STRBUF_INIT;
949 struct strbuf gitdir = STRBUF_INIT;
938 - struct strbuf repo = STRBUF_INIT;
950 + struct strbuf repo_path = STRBUF_INIT;
951 struct strbuf file = STRBUF_INIT;
952 char *path = NULL;
953 int rc = 0;
@@ -945,17 +957,17 @@ int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath,
957
958 *wtpath = NULL;
959
948 - path = repo_common_path(the_repository, "worktrees/%s", id);
949 - strbuf_realpath(&repo, path, 1);
960 + path = repo_common_path(repo, "worktrees/%s", id);
961 + strbuf_realpath(&repo_path, path, 1);
962 FREE_AND_NULL(path);
963
952 - strbuf_addf(&gitdir, "%s/gitdir", repo.buf);
953 - if (!is_directory(repo.buf)) {
964 + strbuf_addf(&gitdir, "%s/gitdir", repo_path.buf);
965 + if (!is_directory(repo_path.buf)) {
966 strbuf_addstr(reason, _("not a valid directory"));
967 rc = 1;
968 goto done;
969 }
958 - strbuf_addf(&file, "%s/locked", repo.buf);
970 + strbuf_addf(&file, "%s/locked", repo_path.buf);
971 if (file_exists(file.buf)) {
972 goto done;
973 }
@@ -999,12 +1011,12 @@ int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath,
1011 if (is_absolute_path(path)) {
1012 strbuf_addstr(&dotgit, path);
1013 } else {
1002 - strbuf_addf(&dotgit, "%s/%s", repo.buf, path);
1014 + strbuf_addf(&dotgit, "%s/%s", repo_path.buf, path);
1015 strbuf_realpath_forgiving(&dotgit, dotgit.buf, 0);
1016 }
1017 if (!file_exists(dotgit.buf)) {
1018 strbuf_reset(&file);
1007 - strbuf_addf(&file, "%s/index", repo.buf);
1019 + strbuf_addf(&file, "%s/index", repo_path.buf);
1020 if (stat(file.buf, &st) || st.st_mtime <= expire) {
1021 strbuf_addstr(reason, _("gitdir file points to non-existent location"));
1022 rc = 1;
@@ -1016,7 +1028,7 @@ done:
1028 free(path);
1029 strbuf_release(&dotgit);
1030 strbuf_release(&gitdir);
1019 - strbuf_release(&repo);
1031 + strbuf_release(&repo_path);
1032 strbuf_release(&file);
1033 return rc;
1034 }
@@ -1094,37 +1106,38 @@ cleanup:
1106 return res;
1107 }
1108
1097 -void write_worktree_linking_files(const char *dotgit, const char *gitdir,
1109 +void write_worktree_linking_files(struct repository *repo,
1110 + const char *dotgit, const char *gitdir,
1111 int use_relative_paths)
1112 {
1113 struct strbuf path = STRBUF_INIT;
1101 - struct strbuf repo = STRBUF_INIT;
1114 + struct strbuf repo_path = STRBUF_INIT;
1115 struct strbuf tmp = STRBUF_INIT;
1116
1117 strbuf_addstr(&path, dotgit);
1118 strbuf_strip_suffix(&path, "/.git");
1119 strbuf_realpath(&path, path.buf, 1);
1107 - strbuf_addstr(&repo, gitdir);
1108 - strbuf_strip_suffix(&repo, "/gitdir");
1109 - strbuf_realpath(&repo, repo.buf, 1);
1120 + strbuf_addstr(&repo_path, gitdir);
1121 + strbuf_strip_suffix(&repo_path, "/gitdir");
1122 + strbuf_realpath(&repo_path, repo_path.buf, 1);
1123
1111 - if (use_relative_paths && !the_repository->repository_format_relative_worktrees) {
1112 - if (upgrade_repository_format(the_repository, 1) < 0)
1124 + if (use_relative_paths && !repo->repository_format_relative_worktrees) {
1125 + if (upgrade_repository_format(repo, 1) < 0)
1126 die(_("unable to upgrade repository format to support relative worktrees"));
1114 - if (repo_config_set_gently(the_repository, "extensions.relativeWorktrees", "true"))
1127 + if (repo_config_set_gently(repo, "extensions.relativeWorktrees", "true"))
1128 die(_("unable to set extensions.relativeWorktrees setting"));
1116 - the_repository->repository_format_relative_worktrees = 1;
1129 + repo->repository_format_relative_worktrees = 1;
1130 }
1131
1132 if (use_relative_paths) {
1120 - write_file(gitdir, "%s/.git", relative_path(path.buf, repo.buf, &tmp));
1121 - write_file(dotgit, "gitdir: %s", relative_path(repo.buf, path.buf, &tmp));
1133 + write_file(gitdir, "%s/.git", relative_path(path.buf, repo_path.buf, &tmp));
1134 + write_file(dotgit, "gitdir: %s", relative_path(repo_path.buf, path.buf, &tmp));
1135 } else {
1136 write_file(gitdir, "%s/.git", path.buf);
1124 - write_file(dotgit, "gitdir: %s", repo.buf);
1137 + write_file(dotgit, "gitdir: %s", repo_path.buf);
1138 }
1139
1140 strbuf_release(&path);
1128 - strbuf_release(&repo);
1141 + strbuf_release(&repo_path);
1142 strbuf_release(&tmp);
1143 }
worktree.h
+17 -10
@@ -28,7 +28,7 @@ struct worktree {
28 * The caller is responsible for freeing the memory from the returned
29 * worktrees by calling free_worktrees().
30 */
31 -struct worktree **get_worktrees(void);
31 +struct worktree **get_worktrees(struct repository *repo);
32
33 /*
34 * Like `get_worktrees`, but does not read HEAD. Skip reading HEAD allows to
@@ -36,7 +36,7 @@ struct worktree **get_worktrees(void);
36 * the HEAD ref. This is useful in contexts where it is assumed that the
37 * refdb may not be in a consistent state.
38 */
39 -struct worktree **get_worktrees_without_reading_head(void);
39 +struct worktree **get_worktrees_without_reading_head(struct repository *repo);
40
41 /*
42 * Construct a struct worktree corresponding to repo->gitdir and
@@ -47,7 +47,7 @@ struct worktree *get_current_worktree(struct repository *repo);
47 /*
48 * Returns 1 if linked worktrees exist, 0 otherwise.
49 */
50 -int submodule_uses_worktrees(const char *path);
50 +int submodule_uses_worktrees(struct repository *repo, const char *path);
51
52 /*
53 * Return git dir of the worktree. Note that the path may be relative.
@@ -76,7 +76,8 @@ struct worktree *find_worktree(struct worktree **list,
76 * Look up the worktree corresponding to `id`, or NULL of no such worktree
77 * exists.
78 */
79 -struct worktree *get_linked_worktree(const char *id,
79 +struct worktree *get_linked_worktree(struct repository *repo,
80 + const char *id,
81 int skip_reading_head);
82
83 /*
@@ -112,7 +113,8 @@ const char *worktree_prune_reason(struct worktree *wt, timestamp_t expire);
113 * `expire` defines a grace period to prune the worktree when its path
114 * does not exist.
115 */
115 -int should_prune_worktree(const char *id,
116 +int should_prune_worktree(struct repository *repo,
117 + const char *id,
118 struct strbuf *reason,
119 char **wtpath,
120 timestamp_t expire);
@@ -142,12 +144,14 @@ typedef void (* worktree_repair_fn)(int iserr, const char *path,
144 * function, if non-NULL, is called with the path of the worktree and a
145 * description of the repair or error, along with the callback user-data.
146 */
145 -void repair_worktrees(worktree_repair_fn, void *cb_data, int use_relative_paths);
147 +void repair_worktrees(struct repository *repo, worktree_repair_fn,
148 + void *cb_data, int use_relative_paths);
149
150 /*
151 * Repair the linked worktrees after the gitdir has been moved.
152 */
150 -void repair_worktrees_after_gitdir_move(const char *old_path);
153 +void repair_worktrees_after_gitdir_move(struct repository *repo,
154 + const char *old_path);
155
156 /*
157 * Repair the linked worktree after the gitdir has been moved.
@@ -164,7 +168,9 @@ void repair_worktree_after_gitdir_move(struct worktree *wt, const char *old_path
168 * worktree and a description of the repair or error, along with the callback
169 * user-data.
170 */
167 -void repair_worktree_at_path(const char *, worktree_repair_fn,
171 +void repair_worktree_at_path(struct repository *repo,
172 + const char *path,
173 + worktree_repair_fn fn,
174 void *cb_data, int use_relative_paths);
175
176 /*
@@ -196,7 +202,7 @@ int is_shared_symref(const struct worktree *wt,
202 * Similar to head_ref() for all HEADs _except_ one from the current
203 * worktree, which is covered by head_ref().
204 */
199 -int other_head_refs(refs_for_each_cb fn, void *cb_data);
205 +int other_head_refs(struct repository *repo, refs_for_each_cb fn, void *cb_data);
206
207 int is_worktree_being_rebased(const struct worktree *wt, const char *target);
208 int is_worktree_being_bisected(const struct worktree *wt, const char *target);
@@ -239,7 +245,8 @@ int init_worktree_config(struct repository *r);
245 * dotgit: "/path/to/foo/.git"
246 * gitdir: "/path/to/repo/worktrees/foo/gitdir"
247 */
242 -void write_worktree_linking_files(const char *dotgit, const char *gitdir,
248 +void write_worktree_linking_files(struct repository *repo,
249 + const char *dotgit, const char *gitdir,
250 int use_relative_paths);
251
252 #endif