* [PATCH 0/7] refs: remove use of `the_repository`
@ 2026-07-09 8:29 Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 1/7] refs/packed: de-globalize handling of "core.packedRefsTimeout" Patrick Steinhardt
` (7 more replies)
0 siblings, 8 replies; 16+ messages in thread
From: Patrick Steinhardt @ 2026-07-09 8:29 UTC (permalink / raw)
To: git
Hi,
this patch series refactors the ref subsystem to drop uses of
`the_repository`. These patches were part of a discarded attempt to
make the initialization of the refdb eager. I guess they make sense by
themselves though, so here we go.
Note that these patches contain a slight tangent to also adapt
"worktree.c". This is one of the subsystems that caused problems with
eager refdb initialization because of `has_worktrees()`, so I refactored
this subsystem while at it.
The series is built on top of f85a7e6620 (Start Git 2.56 cycle,
2026-07-06) with ps/refs-writing-subcommands at 002fe677ca
(builtin/refs: add "rename" subcommand, 2026-07-06) merged into it.
Despite that, there's a small set of conflicts with "seen" that can be
merged like this:
diff --cc lib/setup.c
index 505e8d7bf2,d31808130b..0000000000
--- a/lib/setup.c
+++ b/lib/setup.c
@@@ -2822,15 -2847,16 +2848,16 @@@ int init_db(struct repository *repo
if (!exist_ok && !stat(real_git_dir, &st))
die(_("%s already exists"), real_git_dir);
- set_git_dir(repo, real_git_dir, 1);
+ apply_and_export_relative_gitdir(repo, real_git_dir, 1);
git_dir = repo_get_git_dir(repo);
- separate_git_dir(git_dir, original_git_dir);
+ separate_git_dir(repo, git_dir, original_git_dir);
- }
- else {
- set_git_dir(repo, git_dir, 1);
+ } else {
+ apply_and_export_relative_gitdir(repo, git_dir, 1);
git_dir = repo_get_git_dir(repo);
}
- startup_info->have_repository = 1;
+
+ if (worktree)
+ set_git_work_tree(repo, worktree);
/*
* Check to see if the repository version is right.
diff --git a/lib/refs/files-backend.c b/lib/refs/files-backend.c
index f672059333..3ba1b4eac4 100644
--- a/lib/refs/files-backend.c
+++ b/lib/refs/files-backend.c
@@ -859,7 +859,7 @@ static enum ref_transaction_error lock_raw_ref(struct files_ref_store *refs,
} else {
unable_to_lock_message(ref_file.buf, myerr, err);
if (myerr == EEXIST) {
- if (repo_ignore_case(the_repository) &&
+ if (repo_ignore_case(refs->base.repo) &&
transaction_has_case_conflicting_update(transaction, update)) {
/*
* In case-insensitive filesystems, ensure that conflicts within a
@@ -973,7 +973,7 @@ static enum ref_transaction_error lock_raw_ref(struct files_ref_store *refs,
* conflicts between 'foo' and 'Foo/bar'. So let's lowercase
* the refname.
*/
- if (repo_ignore_case(the_repository)) {
+ if (repo_ignore_case(refs->base.repo)) {
struct strbuf lower = STRBUF_INIT;
strbuf_addstr(&lower, refname);
Thanks!
Patrick
---
Patrick Steinhardt (7):
refs/packed: de-globalize handling of "core.packedRefsTimeout"
refs/packed: drop `USE_THE_REPOSITORY_VARIABLE`
refs/files: drop `USE_THE_REPOSITORY_VARIABLE`
worktree: refactor code to use available repositories
worktree: pass repository to file-local functions
worktree: pass repository to public functions
refs: remove remaining uses of `the_repository`
branch.c | 6 +-
builtin/branch.c | 16 +++--
builtin/check-ref-format.c | 2 +-
builtin/checkout.c | 2 +-
builtin/config.c | 2 +-
builtin/fsck.c | 6 +-
builtin/gc.c | 2 +-
builtin/merge.c | 2 +-
builtin/notes.c | 2 +-
builtin/receive-pack.c | 2 +-
builtin/reflog.c | 4 +-
builtin/refs.c | 2 +-
builtin/worktree.c | 32 +++++----
reachable.c | 4 +-
ref-filter.c | 2 +-
refs.c | 23 +++----
refs.h | 5 +-
refs/files-backend.c | 31 +++++----
refs/packed-backend.c | 18 +++--
revision.c | 6 +-
setup.c | 7 +-
submodule.c | 2 +-
t/helper/test-ref-store.c | 2 +-
worktree.c | 166 +++++++++++++++++++++++++--------------------
worktree.h | 27 +++++---
25 files changed, 204 insertions(+), 169 deletions(-)
---
base-commit: f035246f779167db3506394141b59472d544af65
change-id: 20260618-pks-refs-wo-the-repository-7e43e29371ac
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 1/7] refs/packed: de-globalize handling of "core.packedRefsTimeout"
2026-07-09 8:29 [PATCH 0/7] refs: remove use of `the_repository` Patrick Steinhardt
@ 2026-07-09 8:29 ` Patrick Steinhardt
2026-07-09 18:52 ` Junio C Hamano
2026-07-09 8:29 ` [PATCH 2/7] refs/packed: drop `USE_THE_REPOSITORY_VARIABLE` Patrick Steinhardt
` (6 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Patrick Steinhardt @ 2026-07-09 8:29 UTC (permalink / raw)
To: git
When locking the "packed-refs" file we allow the user to configure a
timeout for how long we try taking the lock. This is configurable via
"core.packedRefsTimeout", which we parse in `packed_refs_lock()`.
The parsed value is stored in function-static variables though, which of
course has the effect that we'll only ever use the timeout configured in
the first packed reference store that we see. Consequently, if we ever
were to handle stores from different repositories, then we'd use the
same configuration for both stores even if they diverge.
This is of course a somewhat theoretical concern -- we don't typically
handle multiple packed stores, and even if we did it's very unlikely
that the user has configured different timeout values for each of them.
But still, this is a code smell, and an unnecessary one, too.
Fix the issue by moving the value into `struct packed_ref_store` so that
it can be parsed per store.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
refs/packed-backend.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index 499cb55dfa..5c49c06493 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -162,6 +162,13 @@ struct packed_ref_store {
* `packed_ref_store`) must not be freed.
*/
struct tempfile *tempfile;
+
+ /*
+ * Timeout when taking the "packed-refs.lock" file. configurable via
+ * "core.packedRefsTimeout".
+ */
+ bool timeout_configured;
+ int timeout_value;
};
/*
@@ -1233,12 +1240,10 @@ int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err)
struct packed_ref_store *refs =
packed_downcast(ref_store, REF_STORE_WRITE | REF_STORE_MAIN,
"packed_refs_lock");
- static int timeout_configured = 0;
- static int timeout_value = 1000;
- if (!timeout_configured) {
- repo_config_get_int(the_repository, "core.packedrefstimeout", &timeout_value);
- timeout_configured = 1;
+ if (!refs->timeout_configured) {
+ repo_config_get_int(ref_store->repo, "core.packedrefstimeout", &refs->timeout_value);
+ refs->timeout_configured = true;
}
/*
@@ -1249,7 +1254,7 @@ int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err)
if (hold_lock_file_for_update_timeout(
&refs->lock,
refs->path,
- flags, timeout_value) < 0) {
+ flags, refs->timeout_value) < 0) {
unable_to_lock_message(refs->path, errno, err);
return -1;
}
--
2.55.0.175.ge4962bd3d5.dirty
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/7] refs/packed: drop `USE_THE_REPOSITORY_VARIABLE`
2026-07-09 8:29 [PATCH 0/7] refs: remove use of `the_repository` Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 1/7] refs/packed: de-globalize handling of "core.packedRefsTimeout" Patrick Steinhardt
@ 2026-07-09 8:29 ` Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 3/7] refs/files: " Patrick Steinhardt
` (5 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Patrick Steinhardt @ 2026-07-09 8:29 UTC (permalink / raw)
To: git
There's a single user of `the_repository` in the "packed" reference
backend. Convert it to instead use the backend's repository and drop
`USE_THE_REPOSITORY_VARIABLE`.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
refs/packed-backend.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index 5c49c06493..7d0a4811fe 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -1,4 +1,3 @@
-#define USE_THE_REPOSITORY_VARIABLE
#define DISABLE_SIGN_COMPARE_WARNINGS
#include "../git-compat-util.h"
--
2.55.0.175.ge4962bd3d5.dirty
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/7] refs/files: drop `USE_THE_REPOSITORY_VARIABLE`
2026-07-09 8:29 [PATCH 0/7] refs: remove use of `the_repository` Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 1/7] refs/packed: de-globalize handling of "core.packedRefsTimeout" Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 2/7] refs/packed: drop `USE_THE_REPOSITORY_VARIABLE` Patrick Steinhardt
@ 2026-07-09 8:29 ` Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 4/7] worktree: refactor code to use available repositories Patrick Steinhardt
` (4 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Patrick Steinhardt @ 2026-07-09 8:29 UTC (permalink / raw)
To: git
We have a bunch of users of `the_repository` in the "files" backend, all
of which are trivial to convert to instead use the backend's own repo.
Do so.
There is one more dependency on global state though via `ignore_case`,
and thus we can't trivially remove `USE_THE_REPOSITORY_VARIABLE`. But
this is the only use of global state, and we want to ensure that we
don't unwittingly reintroduce a dependency on `the_repository` going
forward.
Add an extern declaration for `ignore_case` so that it becomes
accessible even without `USE_THE_REPOSITORY_VARIABLE` and drop the
define itself.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
refs/files-backend.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 3df56c25c8..09e1be838a 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1,4 +1,3 @@
-#define USE_THE_REPOSITORY_VARIABLE
#define DISABLE_SIGN_COMPARE_WARNINGS
#include "../git-compat-util.h"
@@ -29,6 +28,9 @@
#include "../revision.h"
#include <wildmatch.h>
+/* So that we can drop `USE_THE_REPOSITORY_VARIABLE`. */
+extern int ignore_case;
+
/*
* This backend uses the following flags in `ref_update::flags` for
* internal bookkeeping purposes. Their numerical values must not
@@ -788,7 +790,7 @@ static enum ref_transaction_error lock_raw_ref(struct files_ref_store *refs,
files_ref_path(refs, &ref_file, refname);
retry:
- switch (safe_create_leading_directories(the_repository, ref_file.buf)) {
+ switch (safe_create_leading_directories(refs->base.repo, ref_file.buf)) {
case SCLD_OK:
break; /* success */
case SCLD_EXISTS:
@@ -1164,7 +1166,8 @@ typedef int create_file_fn(const char *path, void *cb);
* recent call of fn. fn is always called at least once, and will be
* called more than once if it returns ENOENT or EISDIR.
*/
-static int raceproof_create_file(const char *path, create_file_fn fn, void *cb)
+static int raceproof_create_file(struct files_ref_store *refs,
+ const char *path, create_file_fn fn, void *cb)
{
/*
* The number of times we will try to remove empty directories
@@ -1220,7 +1223,7 @@ static int raceproof_create_file(const char *path, create_file_fn fn, void *cb)
strbuf_addstr(&path_copy, path);
do {
- scld_result = safe_create_leading_directories(the_repository, path_copy.buf);
+ scld_result = safe_create_leading_directories(refs->base.repo, path_copy.buf);
if (scld_result == SCLD_OK)
goto retry_fn;
} while (scld_result == SCLD_VANISHED && create_directories_remaining-- > 0);
@@ -1289,7 +1292,7 @@ static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs,
cb_data.lk = &lock->lk;
cb_data.repo = refs->base.repo;
- if (raceproof_create_file(ref_file.buf, create_reflock, &cb_data)) {
+ if (raceproof_create_file(refs, ref_file.buf, create_reflock, &cb_data)) {
unable_to_lock_message(ref_file.buf, errno, err);
goto error_return;
}
@@ -1383,7 +1386,7 @@ static void prune_ref(struct files_ref_store *refs, struct ref_to_prune *r)
ref_transaction_add_update(
transaction, r->name,
REF_NO_DEREF | REF_HAVE_NEW | REF_HAVE_OLD | REF_IS_PRUNING,
- null_oid(the_hash_algo), &r->oid, NULL, NULL, NULL,
+ null_oid(refs->base.repo->hash_algo), &r->oid, NULL, NULL, NULL,
NULL, NULL);
if (ref_transaction_commit(transaction, &err))
goto cleanup;
@@ -1629,7 +1632,7 @@ static int rename_tmp_log(struct files_ref_store *refs, const char *newrefname)
files_reflog_path(refs, &path, newrefname);
files_reflog_path(refs, &tmp, TMP_RENAMED_LOG);
cb.tmp_renamed_log = tmp.buf;
- ret = raceproof_create_file(path.buf, rename_tmp_log_callback, &cb);
+ ret = raceproof_create_file(refs, path.buf, rename_tmp_log_callback, &cb);
if (ret) {
if (errno == EISDIR)
error("directory not empty: %s", path.buf);
@@ -1916,13 +1919,13 @@ static int log_ref_setup(struct files_ref_store *refs,
char *logfile;
if (log_refs_cfg == LOG_REFS_UNSET)
- log_refs_cfg = is_bare_repository(the_repository) ? LOG_REFS_NONE : LOG_REFS_NORMAL;
+ log_refs_cfg = is_bare_repository(refs->base.repo) ? LOG_REFS_NONE : LOG_REFS_NORMAL;
files_reflog_path(refs, &logfile_sb, refname);
logfile = strbuf_detach(&logfile_sb, NULL);
if (force_create || should_autocreate_reflog(log_refs_cfg, refname)) {
- if (raceproof_create_file(logfile, open_or_create_logfile, logfd)) {
+ if (raceproof_create_file(refs, logfile, open_or_create_logfile, logfd)) {
if (errno == ENOENT)
strbuf_addf(err, "unable to create directory for '%s': "
"%s", logfile, strerror(errno));
@@ -1955,7 +1958,7 @@ static int log_ref_setup(struct files_ref_store *refs,
}
if (*logfd >= 0)
- adjust_shared_perm(the_repository, logfile);
+ adjust_shared_perm(refs->base.repo, logfile);
free(logfile);
return 0;
@@ -3672,8 +3675,8 @@ static int files_ref_store_create_on_disk(struct ref_store *ref_store,
* they do not understand the reference format extension.
*/
strbuf_addf(&sb, "%s/refs", ref_store->gitdir);
- safe_create_dir(the_repository, sb.buf, 1);
- adjust_shared_perm(the_repository, sb.buf);
+ safe_create_dir(refs->base.repo, sb.buf, 1);
+ adjust_shared_perm(refs->base.repo, sb.buf);
/*
* There is no need to create directories for common refs when creating
@@ -3685,11 +3688,11 @@ static int files_ref_store_create_on_disk(struct ref_store *ref_store,
*/
strbuf_reset(&sb);
files_ref_path(refs, &sb, "refs/heads");
- safe_create_dir(the_repository, sb.buf, 1);
+ safe_create_dir(refs->base.repo, sb.buf, 1);
strbuf_reset(&sb);
files_ref_path(refs, &sb, "refs/tags");
- safe_create_dir(the_repository, sb.buf, 1);
+ safe_create_dir(refs->base.repo, sb.buf, 1);
}
strbuf_release(&sb);
--
2.55.0.175.ge4962bd3d5.dirty
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 4/7] worktree: refactor code to use available repositories
2026-07-09 8:29 [PATCH 0/7] refs: remove use of `the_repository` Patrick Steinhardt
` (2 preceding siblings ...)
2026-07-09 8:29 ` [PATCH 3/7] refs/files: " Patrick Steinhardt
@ 2026-07-09 8:29 ` Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 5/7] worktree: pass repository to file-local functions Patrick Steinhardt
` (3 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Patrick Steinhardt @ 2026-07-09 8:29 UTC (permalink / raw)
To: git
In "worktree.c" we have lots of users of `the_repository` that already
have a repository available to them. Convert all of them to use that
repository instead.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
worktree.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/worktree.c b/worktree.c
index 30125827fd..8b10dea179 100644
--- a/worktree.c
+++ b/worktree.c
@@ -392,7 +392,7 @@ int validate_worktree(const struct worktree *wt, struct strbuf *errmsg,
if (!is_absolute_path(wt->path)) {
strbuf_addf_gently(errmsg,
_("'%s' file does not contain absolute path to the working tree location"),
- repo_common_path_replace(the_repository, &buf, "worktrees/%s/gitdir", wt->id));
+ repo_common_path_replace(wt->repo, &buf, "worktrees/%s/gitdir", wt->id));
goto done;
}
@@ -414,12 +414,12 @@ int validate_worktree(const struct worktree *wt, struct strbuf *errmsg,
goto done;
}
- strbuf_realpath(&realpath, repo_common_path_replace(the_repository, &buf, "worktrees/%s", wt->id), 1);
+ strbuf_realpath(&realpath, repo_common_path_replace(wt->repo, &buf, "worktrees/%s", wt->id), 1);
ret = fspathcmp(path, realpath.buf);
if (ret)
strbuf_addf_gently(errmsg, _("'%s' does not point back to '%s'"),
- wt->path, repo_common_path_replace(the_repository, &buf,
+ wt->path, repo_common_path_replace(wt->repo, &buf,
"worktrees/%s", wt->id));
done:
free(path);
@@ -440,7 +440,7 @@ void update_worktree_location(struct worktree *wt, const char *path_,
if (is_main_worktree(wt))
BUG("can't relocate main worktree");
- wt_gitdir = repo_common_path(the_repository, "worktrees/%s/gitdir", wt->id);
+ wt_gitdir = repo_common_path(wt->repo, "worktrees/%s/gitdir", wt->id);
strbuf_realpath(&gitdir, wt_gitdir, 1);
strbuf_realpath(&path, path_, 1);
strbuf_addf(&dotgit, "%s/.git", path.buf);
@@ -658,7 +658,7 @@ static void repair_gitfile(struct worktree *wt,
goto done;
}
- path = repo_common_path(the_repository, "worktrees/%s", wt->id);
+ path = repo_common_path(wt->repo, "worktrees/%s", wt->id);
strbuf_realpath(&repo, path, 1);
strbuf_addf(&dotgit, "%s/.git", wt->path);
strbuf_addf(&gitdir, "%s/gitdir", repo.buf);
@@ -727,7 +727,7 @@ void repair_worktree_after_gitdir_move(struct worktree *wt, const char *old_path
if (is_main_worktree(wt))
goto done;
- path = repo_common_path(the_repository, "worktrees/%s/gitdir", wt->id);
+ path = repo_common_path(wt->repo, "worktrees/%s/gitdir", wt->id);
strbuf_realpath(&gitdir, path, 1);
if (strbuf_read_file(&dotgit, gitdir.buf, 0) < 0)
@@ -1042,7 +1042,7 @@ int init_worktree_config(struct repository *r)
*/
if (r->repository_format_worktree_config)
return 0;
- if ((res = repo_config_set_gently(the_repository, "extensions.worktreeConfig", "true")))
+ if ((res = repo_config_set_gently(r, "extensions.worktreeConfig", "true")))
return error(_("failed to set extensions.worktreeConfig setting"));
common_config_file = xstrfmt("%s/config", r->commondir);
--
2.55.0.175.ge4962bd3d5.dirty
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 5/7] worktree: pass repository to file-local functions
2026-07-09 8:29 [PATCH 0/7] refs: remove use of `the_repository` Patrick Steinhardt
` (3 preceding siblings ...)
2026-07-09 8:29 ` [PATCH 4/7] worktree: refactor code to use available repositories Patrick Steinhardt
@ 2026-07-09 8:29 ` Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 6/7] worktree: pass repository to public functions Patrick Steinhardt
` (2 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Patrick Steinhardt @ 2026-07-09 8:29 UTC (permalink / raw)
To: git
We have a bunch of file-local functions that use `the_repository`.
Adapt them so that the repository is instead passed as a parameter so
that we can get rid of this dependency.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
worktree.c | 47 ++++++++++++++++++++++++++---------------------
1 file changed, 26 insertions(+), 21 deletions(-)
diff --git a/worktree.c b/worktree.c
index 8b10dea179..ebbf9e27e9 100644
--- a/worktree.c
+++ b/worktree.c
@@ -111,27 +111,28 @@ static int is_main_worktree_bare(struct repository *repo)
/**
* get the main worktree
*/
-static struct worktree *get_main_worktree(int skip_reading_head)
+static struct worktree *get_main_worktree(struct repository *repo,
+ int skip_reading_head)
{
struct worktree *worktree = NULL;
struct strbuf worktree_path = STRBUF_INIT;
- strbuf_add_real_path(&worktree_path, repo_get_common_dir(the_repository));
+ strbuf_add_real_path(&worktree_path, repo_get_common_dir(repo));
strbuf_strip_suffix(&worktree_path, "/.git");
CALLOC_ARRAY(worktree, 1);
- worktree->repo = the_repository;
+ worktree->repo = repo;
worktree->path = strbuf_detach(&worktree_path, NULL);
worktree->is_current = is_current_worktree(worktree);
- worktree->is_bare = (the_repository->bare_cfg == 1) ||
- is_bare_repository(the_repository) ||
+ worktree->is_bare = (repo->bare_cfg == 1) ||
+ is_bare_repository(repo) ||
/*
* When in a secondary worktree we have to also verify if the main
* worktree is bare in $commondir/config.worktree.
* This check is unnecessary if we're currently in the main worktree,
* as prior checks already consulted all configs of the current worktree.
*/
- (!worktree->is_current && is_main_worktree_bare(the_repository));
+ (!worktree->is_current && is_main_worktree_bare(repo));
if (!skip_reading_head)
add_head_info(worktree);
@@ -182,7 +183,8 @@ struct worktree *get_linked_worktree(const char *id,
* retrieving worktree metadata that could be used when the worktree is known
* to not be in a healthy state, e.g. when creating or repairing it.
*/
-static struct worktree **get_worktrees_internal(int skip_reading_head)
+static struct worktree **get_worktrees_internal(struct repository *repo,
+ int skip_reading_head)
{
struct worktree **list = NULL;
struct strbuf path = STRBUF_INIT;
@@ -192,9 +194,9 @@ static struct worktree **get_worktrees_internal(int skip_reading_head)
ALLOC_ARRAY(list, alloc);
- list[counter++] = get_main_worktree(skip_reading_head);
+ list[counter++] = get_main_worktree(repo, skip_reading_head);
- strbuf_addf(&path, "%s/worktrees", repo_get_common_dir(the_repository));
+ strbuf_addf(&path, "%s/worktrees", repo_get_common_dir(repo));
dir = opendir(path.buf);
strbuf_release(&path);
if (dir) {
@@ -216,12 +218,12 @@ static struct worktree **get_worktrees_internal(int skip_reading_head)
struct worktree **get_worktrees(void)
{
- return get_worktrees_internal(0);
+ return get_worktrees_internal(the_repository, 0);
}
struct worktree **get_worktrees_without_reading_head(void)
{
- return get_worktrees_internal(1);
+ return get_worktrees_internal(the_repository, 1);
}
char *get_worktree_git_dir(const struct worktree *wt)
@@ -707,7 +709,7 @@ static void repair_noop(int iserr UNUSED,
void repair_worktrees(worktree_repair_fn fn, void *cb_data, int use_relative_paths)
{
- struct worktree **worktrees = get_worktrees_internal(1);
+ struct worktree **worktrees = get_worktrees_internal(the_repository, 1);
struct worktree **wt = worktrees + 1; /* +1 skips main worktree */
if (!fn)
@@ -752,7 +754,7 @@ void repair_worktree_after_gitdir_move(struct worktree *wt, const char *old_path
void repair_worktrees_after_gitdir_move(const char *old_path)
{
- struct worktree **worktrees = get_worktrees_internal(1);
+ struct worktree **worktrees = get_worktrees_internal(the_repository, 1);
struct worktree **wt = worktrees + 1; /* +1 skips main worktree */
for (; *wt; wt++)
@@ -786,7 +788,9 @@ static int is_main_worktree_path(const char *path)
*
* Returns -1 on failure and strbuf.len on success.
*/
-static ssize_t infer_backlink(const char *gitfile, struct strbuf *inferred)
+static ssize_t infer_backlink(struct repository *repo,
+ const char *gitfile,
+ struct strbuf *inferred)
{
struct strbuf actual = STRBUF_INIT;
const char *id;
@@ -801,7 +805,7 @@ static ssize_t infer_backlink(const char *gitfile, struct strbuf *inferred)
id++; /* advance past '/' to point at <id> */
if (!*id)
goto error;
- repo_common_path_replace(the_repository, inferred, "worktrees/%s", id);
+ repo_common_path_replace(repo, inferred, "worktrees/%s", id);
if (!is_directory(inferred->buf))
goto error;
@@ -842,7 +846,7 @@ void repair_worktree_at_path(const char *path,
goto done;
}
- infer_backlink(dotgit.buf, &inferred_backlink);
+ infer_backlink(the_repository, dotgit.buf, &inferred_backlink);
strbuf_realpath_forgiving(&inferred_backlink, inferred_backlink.buf, 0);
dotgit_contents = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err));
if (dotgit_contents) {
@@ -1017,12 +1021,13 @@ int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath,
return rc;
}
-static int move_config_setting(const char *key, const char *value,
+static int move_config_setting(struct repository *repo,
+ const char *key, const char *value,
const char *from_file, const char *to_file)
{
- if (repo_config_set_in_file_gently(the_repository, to_file, key, NULL, value))
+ if (repo_config_set_in_file_gently(repo, to_file, key, NULL, value))
return error(_("unable to set %s in '%s'"), key, to_file);
- if (repo_config_set_in_file_gently(the_repository, from_file, key, NULL, NULL))
+ if (repo_config_set_in_file_gently(repo, from_file, key, NULL, NULL))
return error(_("unable to unset %s in '%s'"), key, from_file);
return 0;
}
@@ -1058,7 +1063,7 @@ int init_worktree_config(struct repository *r)
* _could_ be negating a global core.bare=true.
*/
if (!git_configset_get_bool(&cs, "core.bare", &bare) && bare) {
- if ((res = move_config_setting("core.bare", "true",
+ if ((res = move_config_setting(r, "core.bare", "true",
common_config_file,
main_worktree_file)))
goto cleanup;
@@ -1070,7 +1075,7 @@ int init_worktree_config(struct repository *r)
* upgrade to worktree config.
*/
if (!git_configset_get_value(&cs, "core.worktree", &core_worktree, NULL)) {
- if ((res = move_config_setting("core.worktree", core_worktree,
+ if ((res = move_config_setting(r, "core.worktree", core_worktree,
common_config_file,
main_worktree_file)))
goto cleanup;
--
2.55.0.175.ge4962bd3d5.dirty
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 6/7] worktree: pass repository to public functions
2026-07-09 8:29 [PATCH 0/7] refs: remove use of `the_repository` Patrick Steinhardt
` (4 preceding siblings ...)
2026-07-09 8:29 ` [PATCH 5/7] worktree: pass repository to file-local functions Patrick Steinhardt
@ 2026-07-09 8:29 ` Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 7/7] refs: remove remaining uses of `the_repository` Patrick Steinhardt
2026-07-09 20:39 ` [PATCH 0/7] refs: remove use " Junio C Hamano
7 siblings, 0 replies; 16+ messages in thread
From: Patrick Steinhardt @ 2026-07-09 8:29 UTC (permalink / raw)
To: git
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>
---
branch.c | 4 +-
builtin/branch.c | 2 +-
builtin/config.c | 2 +-
builtin/fsck.c | 6 +--
builtin/gc.c | 2 +-
builtin/notes.c | 2 +-
builtin/receive-pack.c | 2 +-
builtin/reflog.c | 4 +-
builtin/refs.c | 2 +-
builtin/worktree.c | 24 +++++-----
reachable.c | 4 +-
ref-filter.c | 2 +-
refs.c | 2 +-
revision.c | 6 +--
setup.c | 7 +--
submodule.c | 2 +-
t/helper/test-ref-store.c | 2 +-
worktree.c | 115 ++++++++++++++++++++++++++--------------------
worktree.h | 27 +++++++----
19 files changed, 120 insertions(+), 97 deletions(-)
diff --git a/branch.c b/branch.c
index 243db7d0fc..b2ac403b19 100644
--- a/branch.c
+++ b/branch.c
@@ -394,7 +394,7 @@ static void prepare_checked_out_branches(void)
return;
initialized_checked_out_branches = 1;
- worktrees = get_worktrees();
+ worktrees = get_worktrees(the_repository);
while (worktrees[i]) {
char *old, *wt_gitdir;
@@ -846,7 +846,7 @@ void remove_branch_state(struct repository *r, int verbose)
void die_if_checked_out(const char *branch, int ignore_current_worktree)
{
- struct worktree **worktrees = get_worktrees();
+ struct worktree **worktrees = get_worktrees(the_repository);
for (int i = 0; worktrees[i]; i++) {
if (worktrees[i]->is_current && ignore_current_worktree)
diff --git a/builtin/branch.c b/builtin/branch.c
index 1572a4f9ef..c8fddf7f94 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -579,7 +579,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
const char *interpreted_oldname = NULL;
const char *interpreted_newname = NULL;
int recovery = 0, oldref_usage = 0;
- struct worktree **worktrees = get_worktrees();
+ struct worktree **worktrees = get_worktrees(the_repository);
if (check_branch_ref(&oldref, oldname)) {
/*
diff --git a/builtin/config.c b/builtin/config.c
index 8d8ec0beea..0882899c3f 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -974,7 +974,7 @@ static void location_options_init(struct config_location_options *opts,
opts->source.file = opts->file_to_free = repo_git_path(the_repository, "config");
opts->source.scope = CONFIG_SCOPE_LOCAL;
} else if (opts->use_worktree_config) {
- struct worktree **worktrees = get_worktrees();
+ struct worktree **worktrees = get_worktrees(the_repository);
if (the_repository->repository_format_worktree_config)
opts->source.file = opts->file_to_free =
repo_git_path(the_repository, "config.worktree");
diff --git a/builtin/fsck.c b/builtin/fsck.c
index 76b723f36d..a6c054e45b 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -632,7 +632,7 @@ static void snapshot_refs(struct repository *repo,
refs_for_each_ref_ext(get_main_ref_store(repo),
snapshot_ref, &data, &opts);
- worktrees = get_worktrees();
+ worktrees = get_worktrees(repo);
for (p = worktrees; *p; p++) {
struct worktree *wt = *p;
struct strbuf refname = STRBUF_INIT;
@@ -685,7 +685,7 @@ static void process_refs(struct repository *repo, struct snapshot *snap)
}
if (include_reflogs) {
- worktrees = get_worktrees();
+ worktrees = get_worktrees(repo);
for (p = worktrees; *p; p++) {
struct worktree *wt = *p;
@@ -1121,7 +1121,7 @@ int cmd_fsck(int argc,
verify_index_checksum = 1;
verify_ce_order = 1;
- worktrees = get_worktrees();
+ worktrees = get_worktrees(repo);
for (p = worktrees; *p; p++) {
struct worktree *wt = *p;
struct index_state istate =
diff --git a/builtin/gc.c b/builtin/gc.c
index d32af422af..46999a99ab 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -412,7 +412,7 @@ static int worktree_prune_condition(struct gc_config *cfg)
while (limit && (d = readdir_skip_dot_and_dotdot(dir))) {
char *wtpath;
strbuf_reset(&buf);
- if (should_prune_worktree(d->d_name, &buf, &wtpath, expiry_date))
+ if (should_prune_worktree(the_repository, d->d_name, &buf, &wtpath, expiry_date))
limit--;
free(wtpath);
}
diff --git a/builtin/notes.c b/builtin/notes.c
index 962df867c8..9f1f0ec840 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -989,7 +989,7 @@ static int merge(int argc, const char **argv, const char *prefix,
"NOTES_MERGE_PARTIAL", &result_oid, NULL,
0, UPDATE_REFS_DIE_ON_ERR);
/* Store ref-to-be-updated into .git/NOTES_MERGE_REF */
- worktrees = get_worktrees();
+ worktrees = get_worktrees(the_repository);
wt = find_shared_symref(worktrees, "NOTES_MERGE_REF",
notes_ref);
if (wt)
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 19eb6a1b61..b246c1ccae 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1503,7 +1503,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
struct object_id *old_oid = &cmd->old_oid;
struct object_id *new_oid = &cmd->new_oid;
int do_update_worktree = 0;
- struct worktree **worktrees = get_worktrees();
+ struct worktree **worktrees = get_worktrees(the_repository);
const struct worktree *worktree =
find_shared_symref(worktrees, "HEAD", name);
diff --git a/builtin/reflog.c b/builtin/reflog.c
index dcbfe89339..1211c58fa4 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -250,7 +250,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix,
struct string_list_item *item;
struct worktree **worktrees, **p;
- worktrees = get_worktrees();
+ worktrees = get_worktrees(the_repository);
for (p = worktrees; *p; p++) {
if (single_worktree && !(*p)->is_current)
continue;
@@ -374,7 +374,7 @@ static int cmd_reflog_drop(int argc, const char **argv, const char *prefix,
struct string_list_item *item;
struct worktree **worktrees, **p;
- worktrees = get_worktrees();
+ worktrees = get_worktrees(the_repository);
for (p = worktrees; *p; p++) {
if (single_worktree && !(*p)->is_current)
continue;
diff --git a/builtin/refs.c b/builtin/refs.c
index a9ca2058ee..5cd21c25fe 100644
--- a/builtin/refs.c
+++ b/builtin/refs.c
@@ -113,7 +113,7 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix,
repo_config(repo, git_fsck_config, &fsck_refs_options);
prepare_repo_settings(repo);
- worktrees = get_worktrees_without_reading_head();
+ worktrees = get_worktrees_without_reading_head(repo);
for (size_t i = 0; worktrees[i]; i++)
ret |= refs_fsck(get_worktree_ref_store(worktrees[i]),
&fsck_refs_options, worktrees[i]);
diff --git a/builtin/worktree.c b/builtin/worktree.c
index d21c43fde3..0689b3d3e0 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -226,7 +226,7 @@ static void prune_worktrees(void)
while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) {
char *path;
strbuf_reset(&reason);
- if (should_prune_worktree(d->d_name, &reason, &path, expire))
+ if (should_prune_worktree(the_repository, d->d_name, &reason, &path, expire))
prune_worktree(d->d_name, reason.buf);
else if (path)
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,
struct ref_store *wt_refs;
struct repo_config_values *cfg = repo_config_values(the_repository);
- worktrees = get_worktrees();
+ worktrees = get_worktrees(the_repository);
check_candidate_path(path, opts->force, worktrees, "add");
free_worktrees(worktrees);
worktrees = NULL;
@@ -539,7 +539,8 @@ static int add_worktree(const char *path, const char *refname,
strbuf_reset(&sb);
strbuf_addf(&sb, "%s/gitdir", sb_repo.buf);
- write_worktree_linking_files(sb_git.buf, sb.buf, opts->relative_paths);
+ write_worktree_linking_files(the_repository, sb_git.buf,
+ sb.buf, opts->relative_paths);
strbuf_reset(&sb);
strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
write_file(sb.buf, "../..");
@@ -547,7 +548,7 @@ static int add_worktree(const char *path, const char *refname,
/*
* Set up the ref store of the worktree and create the HEAD reference.
*/
- wt = get_linked_worktree(name, 1);
+ wt = get_linked_worktree(the_repository, name, 1);
if (!wt) {
ret = error(_("could not find created worktree '%s'"), name);
goto done;
@@ -1103,7 +1104,7 @@ static int list(int ac, const char **av, const char *prefix,
else if (!line_terminator && !porcelain)
die(_("the option '%s' requires '%s'"), "-z", "--porcelain");
else {
- struct worktree **worktrees = get_worktrees();
+ struct worktree **worktrees = get_worktrees(the_repository);
int path_maxwidth = 0, abbrev = DEFAULT_ABBREV, i;
struct worktree_display *display = NULL;
@@ -1146,7 +1147,7 @@ static int lock_worktree(int ac, const char **av, const char *prefix,
if (ac != 1)
usage_with_options(git_worktree_lock_usage, options);
- worktrees = get_worktrees();
+ worktrees = get_worktrees(the_repository);
wt = find_worktree(worktrees, prefix, av[0]);
if (!wt)
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,
if (ac != 1)
usage_with_options(git_worktree_unlock_usage, options);
- worktrees = get_worktrees();
+ worktrees = get_worktrees(the_repository);
wt = find_worktree(worktrees, prefix, av[0]);
if (!wt)
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,
strbuf_addstr(&dst, path);
free(path);
- worktrees = get_worktrees();
+ worktrees = get_worktrees(the_repository);
wt = find_worktree(worktrees, prefix, av[0]);
if (!wt)
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,
if (ac != 1)
usage_with_options(git_worktree_remove_usage, options);
- worktrees = get_worktrees();
+ worktrees = get_worktrees(the_repository);
wt = find_worktree(worktrees, prefix, av[0]);
if (!wt)
die(_("'%s' is not a working tree"), av[0]);
@@ -1456,8 +1457,9 @@ static int repair(int ac, const char **av, const char *prefix,
ac = parse_options(ac, av, prefix, options, git_worktree_repair_usage, 0);
p = ac > 0 ? av : self;
for (; *p; p++)
- repair_worktree_at_path(*p, report_repair, &rc, use_relative_paths);
- repair_worktrees(report_repair, &rc, use_relative_paths);
+ repair_worktree_at_path(the_repository, *p, report_repair,
+ &rc, use_relative_paths);
+ repair_worktrees(the_repository, report_repair, &rc, use_relative_paths);
return rc;
}
diff --git a/reachable.c b/reachable.c
index 101cfc2727..be87f487d8 100644
--- a/reachable.c
+++ b/reachable.c
@@ -62,7 +62,7 @@ static void add_rebase_files(struct rev_info *revs)
"rebase-merge/autostash",
"rebase-merge/orig-head",
};
- struct worktree **worktrees = get_worktrees();
+ struct worktree **worktrees = get_worktrees(the_repository);
for (struct worktree **wt = worktrees; *wt; wt++) {
char *wt_gitdir = get_worktree_git_dir(*wt);
@@ -319,7 +319,7 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
/* detached HEAD is not included in the list above */
refs_head_ref(get_main_ref_store(the_repository), add_one_ref, revs);
- other_head_refs(add_one_ref, revs);
+ other_head_refs(the_repository, add_one_ref, revs);
/* rebase autostash and orig-head */
add_rebase_files(revs);
diff --git a/ref-filter.c b/ref-filter.c
index 284796c49b..29aca08ce7 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -2402,7 +2402,7 @@ static void lazy_init_worktree_map(void)
if (ref_to_worktree_map.worktrees)
return;
- ref_to_worktree_map.worktrees = get_worktrees();
+ ref_to_worktree_map.worktrees = get_worktrees(the_repository);
hashmap_init(&(ref_to_worktree_map.map), ref_to_worktree_map_cmpfnc, NULL, 0);
populate_worktree_map(&(ref_to_worktree_map.map), ref_to_worktree_map.worktrees);
}
diff --git a/refs.c b/refs.c
index 1d24637891..d9957a266c 100644
--- a/refs.c
+++ b/refs.c
@@ -3328,7 +3328,7 @@ static int move_files(const char *from_path, const char *to_path, struct strbuf
static int has_worktrees(void)
{
- struct worktree **worktrees = get_worktrees();
+ struct worktree **worktrees = get_worktrees(the_repository);
int ret = 0;
size_t i;
diff --git a/revision.c b/revision.c
index 0c95edef59..7dd40a31d3 100644
--- a/revision.c
+++ b/revision.c
@@ -1711,7 +1711,7 @@ static void add_other_reflogs_to_pending(struct all_refs_cb *cb)
{
struct worktree **worktrees, **p;
- worktrees = get_worktrees();
+ worktrees = get_worktrees(the_repository);
for (p = worktrees; *p; p++) {
struct worktree *wt = *p;
@@ -1837,7 +1837,7 @@ void add_index_objects_to_pending(struct rev_info *revs, unsigned int flags)
if (revs->single_worktree)
return;
- worktrees = get_worktrees();
+ worktrees = get_worktrees(the_repository);
for (p = worktrees; *p; p++) {
struct worktree *wt = *p;
struct index_state istate = INDEX_STATE_INIT(revs->repo);
@@ -2813,7 +2813,7 @@ static int handle_revision_pseudo_opt(struct rev_info *revs,
struct all_refs_cb cb;
init_all_refs_cb(&cb, revs, *flags);
- other_head_refs(handle_one_ref, &cb);
+ other_head_refs(the_repository, handle_one_ref, &cb);
}
clear_ref_exclusions(&revs->ref_excludes);
} else if (!strcmp(arg, "--branches")) {
diff --git a/setup.c b/setup.c
index 0de56a074f..505e8d7bf2 100644
--- a/setup.c
+++ b/setup.c
@@ -2650,7 +2650,8 @@ static void create_object_directory(struct repository *repo)
strbuf_release(&path);
}
-static void separate_git_dir(const char *git_dir, const char *git_link)
+static void separate_git_dir(struct repository *repo,
+ const char *git_dir, const char *git_link)
{
struct stat st;
@@ -2666,7 +2667,7 @@ static void separate_git_dir(const char *git_dir, const char *git_link)
if (rename(src, git_dir))
die_errno(_("unable to move %s to %s"), src, git_dir);
- repair_worktrees_after_gitdir_move(src);
+ repair_worktrees_after_gitdir_move(repo, src);
}
write_file(git_link, "gitdir: %s", git_dir);
@@ -2823,7 +2824,7 @@ int init_db(struct repository *repo,
set_git_dir(repo, real_git_dir, 1);
git_dir = repo_get_git_dir(repo);
- separate_git_dir(git_dir, original_git_dir);
+ separate_git_dir(repo, git_dir, original_git_dir);
}
else {
set_git_dir(repo, git_dir, 1);
diff --git a/submodule.c b/submodule.c
index 93d0361072..c6dda4d156 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2494,7 +2494,7 @@ static void relocate_single_git_dir_into_superproject(const char *path,
if (validate_submodule_path(path) < 0)
exit(128);
- if (submodule_uses_worktrees(path))
+ if (submodule_uses_worktrees(the_repository, path))
die(_("relocate_gitdir for submodule '%s' with "
"more than one worktree not supported"), path);
diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c
index 3866d0aca4..5a9a3053d9 100644
--- a/t/helper/test-ref-store.c
+++ b/t/helper/test-ref-store.c
@@ -84,7 +84,7 @@ static const char **get_store(const char **argv, struct ref_store **refs)
*refs = repo_get_submodule_ref_store(the_repository, gitdir);
} else if (skip_prefix(argv[0], "worktree:", &gitdir)) {
- struct worktree **p, **worktrees = get_worktrees();
+ struct worktree **p, **worktrees = get_worktrees(the_repository);
for (p = worktrees; *p; p++) {
struct worktree *wt = *p;
diff --git a/worktree.c b/worktree.c
index ebbf9e27e9..cbf95328a3 100644
--- a/worktree.c
+++ b/worktree.c
@@ -1,4 +1,3 @@
-#define USE_THE_REPOSITORY_VARIABLE
#define DISABLE_SIGN_COMPARE_WARNINGS
#include "git-compat-util.h"
@@ -139,7 +138,8 @@ static struct worktree *get_main_worktree(struct repository *repo,
return worktree;
}
-struct worktree *get_linked_worktree(const char *id,
+struct worktree *get_linked_worktree(struct repository *repo,
+ const char *id,
int skip_reading_head)
{
struct worktree *worktree = NULL;
@@ -149,7 +149,7 @@ struct worktree *get_linked_worktree(const char *id,
if (!id)
die("Missing linked worktree name");
- repo_common_path_append(the_repository, &path, "worktrees/%s/gitdir", id);
+ repo_common_path_append(repo, &path, "worktrees/%s/gitdir", id);
if (strbuf_read_file(&worktree_path, path.buf, 0) <= 0)
/* invalid gitdir file */
goto done;
@@ -163,7 +163,7 @@ struct worktree *get_linked_worktree(const char *id,
}
CALLOC_ARRAY(worktree, 1);
- worktree->repo = the_repository;
+ worktree->repo = repo;
worktree->path = strbuf_detach(&worktree_path, NULL);
worktree->id = xstrdup(id);
worktree->is_current = is_current_worktree(worktree);
@@ -203,7 +203,7 @@ static struct worktree **get_worktrees_internal(struct repository *repo,
while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) {
struct worktree *linked = NULL;
- if ((linked = get_linked_worktree(d->d_name, skip_reading_head))) {
+ if ((linked = get_linked_worktree(repo, d->d_name, skip_reading_head))) {
ALLOC_GROW(list, counter + 1, alloc);
list[counter++] = linked;
}
@@ -216,14 +216,14 @@ static struct worktree **get_worktrees_internal(struct repository *repo,
return list;
}
-struct worktree **get_worktrees(void)
+struct worktree **get_worktrees(struct repository *repo)
{
- return get_worktrees_internal(the_repository, 0);
+ return get_worktrees_internal(repo, 0);
}
-struct worktree **get_worktrees_without_reading_head(void)
+struct worktree **get_worktrees_without_reading_head(struct repository *repo)
{
- return get_worktrees_internal(the_repository, 1);
+ return get_worktrees_internal(repo, 1);
}
char *get_worktree_git_dir(const struct worktree *wt)
@@ -336,7 +336,7 @@ const char *worktree_prune_reason(struct worktree *wt, timestamp_t expire)
if (wt->prune_reason_valid)
return wt->prune_reason;
- if (should_prune_worktree(wt->id, &reason, &path, expire))
+ if (should_prune_worktree(wt->repo, wt->id, &reason, &path, expire))
wt->prune_reason = strbuf_detach(&reason, NULL);
wt->prune_reason_valid = 1;
@@ -447,7 +447,8 @@ void update_worktree_location(struct worktree *wt, const char *path_,
strbuf_realpath(&path, path_, 1);
strbuf_addf(&dotgit, "%s/.git", path.buf);
if (fspathcmp(wt->path, path.buf)) {
- write_worktree_linking_files(dotgit.buf, gitdir.buf, use_relative_paths);
+ write_worktree_linking_files(wt->repo, dotgit.buf,
+ gitdir.buf, use_relative_paths);
free(wt->path);
wt->path = strbuf_detach(&path, NULL);
@@ -535,7 +536,8 @@ const struct worktree *find_shared_symref(struct worktree **worktrees,
return NULL;
}
-int submodule_uses_worktrees(const char *path)
+int submodule_uses_worktrees(struct repository *repo,
+ const char *path)
{
char *submodule_gitdir;
struct strbuf sb = STRBUF_INIT, err = STRBUF_INIT;
@@ -544,7 +546,7 @@ int submodule_uses_worktrees(const char *path)
int ret = 0;
struct repository_format format = REPOSITORY_FORMAT_INIT;
- submodule_gitdir = repo_submodule_path(the_repository,
+ submodule_gitdir = repo_submodule_path(repo,
path, "%s", "");
if (!submodule_gitdir)
return 0;
@@ -597,13 +599,14 @@ void strbuf_worktree_ref(const struct worktree *wt,
strbuf_addstr(sb, refname);
}
-int other_head_refs(refs_for_each_cb fn, void *cb_data)
+int other_head_refs(struct repository *repo,
+ refs_for_each_cb fn, void *cb_data)
{
struct worktree **worktrees, **p;
struct strbuf refname = STRBUF_INIT;
int ret = 0;
- worktrees = get_worktrees();
+ worktrees = get_worktrees(repo);
for (p = worktrees; *p; p++) {
struct worktree *wt = *p;
struct object_id oid;
@@ -614,7 +617,7 @@ int other_head_refs(refs_for_each_cb fn, void *cb_data)
strbuf_reset(&refname);
strbuf_worktree_ref(wt, &refname, "HEAD");
- if (refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
+ if (refs_resolve_ref_unsafe(get_main_ref_store(repo),
refname.buf,
RESOLVE_REF_READING,
&oid, &flag)) {
@@ -687,7 +690,8 @@ static void repair_gitfile(struct worktree *wt,
if (repair) {
fn(0, wt->path, repair, cb_data);
- write_worktree_linking_files(dotgit.buf, gitdir.buf, use_relative_paths);
+ write_worktree_linking_files(wt->repo, dotgit.buf,
+ gitdir.buf, use_relative_paths);
}
done:
@@ -707,9 +711,10 @@ static void repair_noop(int iserr UNUSED,
/* nothing */
}
-void repair_worktrees(worktree_repair_fn fn, void *cb_data, int use_relative_paths)
+void repair_worktrees(struct repository *repo, worktree_repair_fn fn,
+ void *cb_data, int use_relative_paths)
{
- struct worktree **worktrees = get_worktrees_internal(the_repository, 1);
+ struct worktree **worktrees = get_worktrees_internal(repo, 1);
struct worktree **wt = worktrees + 1; /* +1 skips main worktree */
if (!fn)
@@ -745,16 +750,17 @@ void repair_worktree_after_gitdir_move(struct worktree *wt, const char *old_path
if (!file_exists(dotgit.buf))
goto done;
- write_worktree_linking_files(dotgit.buf, gitdir.buf, is_relative_path);
+ write_worktree_linking_files(wt->repo, dotgit.buf,
+ gitdir.buf, is_relative_path);
done:
strbuf_release(&gitdir);
strbuf_release(&dotgit);
free(path);
}
-void repair_worktrees_after_gitdir_move(const char *old_path)
+void repair_worktrees_after_gitdir_move(struct repository *repo, const char *old_path)
{
- struct worktree **worktrees = get_worktrees_internal(the_repository, 1);
+ struct worktree **worktrees = get_worktrees_internal(repo, 1);
struct worktree **wt = worktrees + 1; /* +1 skips main worktree */
for (; *wt; wt++)
@@ -762,7 +768,7 @@ void repair_worktrees_after_gitdir_move(const char *old_path)
free_worktrees(worktrees);
}
-static int is_main_worktree_path(const char *path)
+static int is_main_worktree_path(struct repository *repo, const char *path)
{
struct strbuf target = STRBUF_INIT;
struct strbuf maindir = STRBUF_INIT;
@@ -770,7 +776,7 @@ static int is_main_worktree_path(const char *path)
strbuf_add_real_path(&target, path);
strbuf_strip_suffix(&target, "/.git");
- strbuf_add_real_path(&maindir, repo_get_common_dir(the_repository));
+ strbuf_add_real_path(&maindir, repo_get_common_dir(repo));
strbuf_strip_suffix(&maindir, "/.git");
cmp = fspathcmp(maindir.buf, target.buf);
@@ -821,7 +827,8 @@ static ssize_t infer_backlink(struct repository *repo,
* Repair <repo>/worktrees/<id>/gitdir if missing, corrupt, or not pointing at
* the worktree's path.
*/
-void repair_worktree_at_path(const char *path,
+void repair_worktree_at_path(struct repository *repo,
+ const char *path,
worktree_repair_fn fn, void *cb_data,
int use_relative_paths)
{
@@ -837,7 +844,7 @@ void repair_worktree_at_path(const char *path,
if (!fn)
fn = repair_noop;
- if (is_main_worktree_path(path))
+ if (is_main_worktree_path(repo, path))
goto done;
strbuf_addf(&dotgit, "%s/.git", path);
@@ -846,7 +853,7 @@ void repair_worktree_at_path(const char *path,
goto done;
}
- infer_backlink(the_repository, dotgit.buf, &inferred_backlink);
+ infer_backlink(repo, dotgit.buf, &inferred_backlink);
strbuf_realpath_forgiving(&inferred_backlink, inferred_backlink.buf, 0);
dotgit_contents = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err));
if (dotgit_contents) {
@@ -919,7 +926,8 @@ void repair_worktree_at_path(const char *path,
if (repair) {
fn(0, gitdir.buf, repair, cb_data);
- write_worktree_linking_files(dotgit.buf, gitdir.buf, use_relative_paths);
+ write_worktree_linking_files(repo, dotgit.buf,
+ gitdir.buf, use_relative_paths);
}
done:
free(dotgit_contents);
@@ -930,12 +938,16 @@ void repair_worktree_at_path(const char *path,
strbuf_release(&dotgit);
}
-int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath, timestamp_t expire)
+int should_prune_worktree(struct repository *repo,
+ const char *id,
+ struct strbuf *reason,
+ char **wtpath,
+ timestamp_t expire)
{
struct stat st;
struct strbuf dotgit = STRBUF_INIT;
struct strbuf gitdir = STRBUF_INIT;
- struct strbuf repo = STRBUF_INIT;
+ struct strbuf repo_path = STRBUF_INIT;
struct strbuf file = STRBUF_INIT;
char *path = NULL;
int rc = 0;
@@ -945,17 +957,17 @@ int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath,
*wtpath = NULL;
- path = repo_common_path(the_repository, "worktrees/%s", id);
- strbuf_realpath(&repo, path, 1);
+ path = repo_common_path(repo, "worktrees/%s", id);
+ strbuf_realpath(&repo_path, path, 1);
FREE_AND_NULL(path);
- strbuf_addf(&gitdir, "%s/gitdir", repo.buf);
- if (!is_directory(repo.buf)) {
+ strbuf_addf(&gitdir, "%s/gitdir", repo_path.buf);
+ if (!is_directory(repo_path.buf)) {
strbuf_addstr(reason, _("not a valid directory"));
rc = 1;
goto done;
}
- strbuf_addf(&file, "%s/locked", repo.buf);
+ strbuf_addf(&file, "%s/locked", repo_path.buf);
if (file_exists(file.buf)) {
goto done;
}
@@ -999,12 +1011,12 @@ int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath,
if (is_absolute_path(path)) {
strbuf_addstr(&dotgit, path);
} else {
- strbuf_addf(&dotgit, "%s/%s", repo.buf, path);
+ strbuf_addf(&dotgit, "%s/%s", repo_path.buf, path);
strbuf_realpath_forgiving(&dotgit, dotgit.buf, 0);
}
if (!file_exists(dotgit.buf)) {
strbuf_reset(&file);
- strbuf_addf(&file, "%s/index", repo.buf);
+ strbuf_addf(&file, "%s/index", repo_path.buf);
if (stat(file.buf, &st) || st.st_mtime <= expire) {
strbuf_addstr(reason, _("gitdir file points to non-existent location"));
rc = 1;
@@ -1016,7 +1028,7 @@ int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath,
free(path);
strbuf_release(&dotgit);
strbuf_release(&gitdir);
- strbuf_release(&repo);
+ strbuf_release(&repo_path);
strbuf_release(&file);
return rc;
}
@@ -1094,37 +1106,38 @@ int init_worktree_config(struct repository *r)
return res;
}
-void write_worktree_linking_files(const char *dotgit, const char *gitdir,
+void write_worktree_linking_files(struct repository *repo,
+ const char *dotgit, const char *gitdir,
int use_relative_paths)
{
struct strbuf path = STRBUF_INIT;
- struct strbuf repo = STRBUF_INIT;
+ struct strbuf repo_path = STRBUF_INIT;
struct strbuf tmp = STRBUF_INIT;
strbuf_addstr(&path, dotgit);
strbuf_strip_suffix(&path, "/.git");
strbuf_realpath(&path, path.buf, 1);
- strbuf_addstr(&repo, gitdir);
- strbuf_strip_suffix(&repo, "/gitdir");
- strbuf_realpath(&repo, repo.buf, 1);
+ strbuf_addstr(&repo_path, gitdir);
+ strbuf_strip_suffix(&repo_path, "/gitdir");
+ strbuf_realpath(&repo_path, repo_path.buf, 1);
- if (use_relative_paths && !the_repository->repository_format_relative_worktrees) {
- if (upgrade_repository_format(the_repository, 1) < 0)
+ if (use_relative_paths && !repo->repository_format_relative_worktrees) {
+ if (upgrade_repository_format(repo, 1) < 0)
die(_("unable to upgrade repository format to support relative worktrees"));
- if (repo_config_set_gently(the_repository, "extensions.relativeWorktrees", "true"))
+ if (repo_config_set_gently(repo, "extensions.relativeWorktrees", "true"))
die(_("unable to set extensions.relativeWorktrees setting"));
- the_repository->repository_format_relative_worktrees = 1;
+ repo->repository_format_relative_worktrees = 1;
}
if (use_relative_paths) {
- write_file(gitdir, "%s/.git", relative_path(path.buf, repo.buf, &tmp));
- write_file(dotgit, "gitdir: %s", relative_path(repo.buf, path.buf, &tmp));
+ write_file(gitdir, "%s/.git", relative_path(path.buf, repo_path.buf, &tmp));
+ write_file(dotgit, "gitdir: %s", relative_path(repo_path.buf, path.buf, &tmp));
} else {
write_file(gitdir, "%s/.git", path.buf);
- write_file(dotgit, "gitdir: %s", repo.buf);
+ write_file(dotgit, "gitdir: %s", repo_path.buf);
}
strbuf_release(&path);
- strbuf_release(&repo);
+ strbuf_release(&repo_path);
strbuf_release(&tmp);
}
diff --git a/worktree.h b/worktree.h
index 1075409f9a..fbb2757f5b 100644
--- a/worktree.h
+++ b/worktree.h
@@ -28,7 +28,7 @@ struct worktree {
* The caller is responsible for freeing the memory from the returned
* worktrees by calling free_worktrees().
*/
-struct worktree **get_worktrees(void);
+struct worktree **get_worktrees(struct repository *repo);
/*
* Like `get_worktrees`, but does not read HEAD. Skip reading HEAD allows to
@@ -36,7 +36,7 @@ struct worktree **get_worktrees(void);
* the HEAD ref. This is useful in contexts where it is assumed that the
* refdb may not be in a consistent state.
*/
-struct worktree **get_worktrees_without_reading_head(void);
+struct worktree **get_worktrees_without_reading_head(struct repository *repo);
/*
* Construct a struct worktree corresponding to repo->gitdir and
@@ -47,7 +47,7 @@ struct worktree *get_current_worktree(struct repository *repo);
/*
* Returns 1 if linked worktrees exist, 0 otherwise.
*/
-int submodule_uses_worktrees(const char *path);
+int submodule_uses_worktrees(struct repository *repo, const char *path);
/*
* Return git dir of the worktree. Note that the path may be relative.
@@ -76,7 +76,8 @@ struct worktree *find_worktree(struct worktree **list,
* Look up the worktree corresponding to `id`, or NULL of no such worktree
* exists.
*/
-struct worktree *get_linked_worktree(const char *id,
+struct worktree *get_linked_worktree(struct repository *repo,
+ const char *id,
int skip_reading_head);
/*
@@ -112,7 +113,8 @@ const char *worktree_prune_reason(struct worktree *wt, timestamp_t expire);
* `expire` defines a grace period to prune the worktree when its path
* does not exist.
*/
-int should_prune_worktree(const char *id,
+int should_prune_worktree(struct repository *repo,
+ const char *id,
struct strbuf *reason,
char **wtpath,
timestamp_t expire);
@@ -142,12 +144,14 @@ typedef void (* worktree_repair_fn)(int iserr, const char *path,
* function, if non-NULL, is called with the path of the worktree and a
* description of the repair or error, along with the callback user-data.
*/
-void repair_worktrees(worktree_repair_fn, void *cb_data, int use_relative_paths);
+void repair_worktrees(struct repository *repo, worktree_repair_fn,
+ void *cb_data, int use_relative_paths);
/*
* Repair the linked worktrees after the gitdir has been moved.
*/
-void repair_worktrees_after_gitdir_move(const char *old_path);
+void repair_worktrees_after_gitdir_move(struct repository *repo,
+ const char *old_path);
/*
* 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
* worktree and a description of the repair or error, along with the callback
* user-data.
*/
-void repair_worktree_at_path(const char *, worktree_repair_fn,
+void repair_worktree_at_path(struct repository *repo,
+ const char *path,
+ worktree_repair_fn fn,
void *cb_data, int use_relative_paths);
/*
@@ -196,7 +202,7 @@ int is_shared_symref(const struct worktree *wt,
* Similar to head_ref() for all HEADs _except_ one from the current
* worktree, which is covered by head_ref().
*/
-int other_head_refs(refs_for_each_cb fn, void *cb_data);
+int other_head_refs(struct repository *repo, refs_for_each_cb fn, void *cb_data);
int is_worktree_being_rebased(const struct worktree *wt, const char *target);
int is_worktree_being_bisected(const struct worktree *wt, const char *target);
@@ -239,7 +245,8 @@ int init_worktree_config(struct repository *r);
* dotgit: "/path/to/foo/.git"
* gitdir: "/path/to/repo/worktrees/foo/gitdir"
*/
-void write_worktree_linking_files(const char *dotgit, const char *gitdir,
+void write_worktree_linking_files(struct repository *repo,
+ const char *dotgit, const char *gitdir,
int use_relative_paths);
#endif
--
2.55.0.175.ge4962bd3d5.dirty
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 7/7] refs: remove remaining uses of `the_repository`
2026-07-09 8:29 [PATCH 0/7] refs: remove use of `the_repository` Patrick Steinhardt
` (5 preceding siblings ...)
2026-07-09 8:29 ` [PATCH 6/7] worktree: pass repository to public functions Patrick Steinhardt
@ 2026-07-09 8:29 ` Patrick Steinhardt
2026-07-09 20:39 ` [PATCH 0/7] refs: remove use " Junio C Hamano
7 siblings, 0 replies; 16+ messages in thread
From: Patrick Steinhardt @ 2026-07-09 8:29 UTC (permalink / raw)
To: git
There are still a couple of callsites that use `the_repository`. Convert
these to instead use a repository injected by the caller. This allows us
to remove `USE_THE_REPOSITORY_VARIABLE`.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
branch.c | 2 +-
builtin/branch.c | 14 +++++++++-----
builtin/check-ref-format.c | 2 +-
builtin/checkout.c | 2 +-
builtin/merge.c | 2 +-
builtin/worktree.c | 8 ++++----
refs.c | 23 +++++++++--------------
refs.h | 5 +++--
8 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/branch.c b/branch.c
index b2ac403b19..4f38905bad 100644
--- a/branch.c
+++ b/branch.c
@@ -372,7 +372,7 @@ int read_branch_desc(struct strbuf *buf, const char *branch_name)
*/
int validate_branchname(const char *name, struct strbuf *ref)
{
- if (check_branch_ref(ref, name)) {
+ if (check_branch_ref(the_repository, ref, name)) {
int code = die_message(_("'%s' is not a valid branch name"), name);
advise_if_enabled(ADVICE_REF_SYNTAX,
_("See 'git help check-ref-format'"));
diff --git a/builtin/branch.c b/builtin/branch.c
index c8fddf7f94..be26ec0750 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -259,7 +259,8 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
char *target = NULL;
int flags = 0;
- copy_branchname(&bname, argv[i], allowed_interpret);
+ copy_branchname(the_repository, &bname,
+ argv[i], allowed_interpret);
free(name);
name = mkpathdup(fmt, bname.buf);
@@ -581,7 +582,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
int recovery = 0, oldref_usage = 0;
struct worktree **worktrees = get_worktrees(the_repository);
- if (check_branch_ref(&oldref, oldname)) {
+ if (check_branch_ref(the_repository, &oldref, oldname)) {
/*
* Bad name --- this could be an attempt to rename a
* ref that we used to allow to be created by accident.
@@ -898,7 +899,8 @@ int cmd_branch(int argc,
die(_("cannot give description to detached HEAD"));
branch_name = head;
} else if (argc == 1) {
- copy_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
+ copy_branchname(the_repository, &buf, argv[0],
+ INTERPRET_BRANCH_LOCAL);
branch_name = buf.buf;
} else {
die(_("cannot edit description of more than one branch"));
@@ -941,7 +943,8 @@ int cmd_branch(int argc,
if (!argc)
branch = branch_get(NULL);
else if (argc == 1) {
- copy_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
+ copy_branchname(the_repository, &buf, argv[0],
+ INTERPRET_BRANCH_LOCAL);
branch = branch_get(buf.buf);
} else
die(_("too many arguments to set new upstream"));
@@ -971,7 +974,8 @@ int cmd_branch(int argc,
if (!argc)
branch = branch_get(NULL);
else if (argc == 1) {
- copy_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
+ copy_branchname(the_repository, &buf, argv[0],
+ INTERPRET_BRANCH_LOCAL);
branch = branch_get(buf.buf);
} else
die(_("too many arguments to unset upstream"));
diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c
index e42b0444ea..fd1c9c0e0c 100644
--- a/builtin/check-ref-format.c
+++ b/builtin/check-ref-format.c
@@ -45,7 +45,7 @@ static int check_ref_format_branch(const char *arg)
int nongit;
setup_git_directory_gently(the_repository, &nongit);
- if (check_branch_ref(&sb, arg) ||
+ if (check_branch_ref(the_repository, &sb, arg) ||
!skip_prefix(sb.buf, "refs/heads/", &name))
die("'%s' is not a valid branch name", arg);
printf("%s\n", name);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index aee84ca897..55e3a89a85 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -805,7 +805,7 @@ static void setup_branch_path(struct branch_info *branch)
&branch->oid, &branch->refname, 0))
repo_get_oid_committish(the_repository, branch->name, &branch->oid);
- copy_branchname(&buf, branch->name, INTERPRET_BRANCH_LOCAL);
+ copy_branchname(the_repository, &buf, branch->name, INTERPRET_BRANCH_LOCAL);
if (strcmp(buf.buf, branch->name)) {
free(branch->name);
branch->name = xstrdup(buf.buf);
diff --git a/builtin/merge.c b/builtin/merge.c
index 5b46a596f0..58d1b7bb07 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -553,7 +553,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
char *found_ref = NULL;
int len, early;
- copy_branchname(&bname, remote, 0);
+ copy_branchname(the_repository, &bname, remote, 0);
remote = bname.buf;
oidclr(&branch_head, the_repository->hash_algo);
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 0689b3d3e0..6397e149a8 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -481,7 +481,7 @@ static int add_worktree(const char *path, const char *refname,
worktrees = NULL;
/* is 'refname' a branch or commit? */
- if (!opts->detach && !check_branch_ref(&symref, refname) &&
+ if (!opts->detach && !check_branch_ref(the_repository, &symref, refname) &&
refs_ref_exists(get_main_ref_store(the_repository), symref.buf)) {
is_branch = 1;
if (!opts->force)
@@ -650,7 +650,7 @@ static void print_preparing_worktree_line(int detach,
fprintf_ln(stderr, _("Preparing worktree (new branch '%s')"), new_branch);
} else {
struct strbuf s = STRBUF_INIT;
- if (!detach && !check_branch_ref(&s, branch) &&
+ if (!detach && !check_branch_ref(the_repository, &s, branch) &&
refs_ref_exists(get_main_ref_store(the_repository), s.buf))
fprintf_ln(stderr, _("Preparing worktree (checking out '%s')"),
branch);
@@ -772,7 +772,7 @@ static char *dwim_branch(const char *path, char **new_branch)
char *branchname = xstrndup(s, n);
struct strbuf ref = STRBUF_INIT;
- branch_exists = !check_branch_ref(&ref, branchname) &&
+ branch_exists = !check_branch_ref(the_repository, &ref, branchname) &&
refs_ref_exists(get_main_ref_store(the_repository),
ref.buf);
strbuf_release(&ref);
@@ -869,7 +869,7 @@ static int add(int ac, const char **av, const char *prefix,
new_branch = new_branch_force;
if (!opts.force &&
- !check_branch_ref(&symref, new_branch) &&
+ !check_branch_ref(the_repository, &symref, new_branch) &&
refs_ref_exists(get_main_ref_store(the_repository), symref.buf))
die_if_checked_out(symref.buf, 0);
strbuf_release(&symref);
diff --git a/refs.c b/refs.c
index d9957a266c..92d5df5b71 100644
--- a/refs.c
+++ b/refs.c
@@ -2,8 +2,6 @@
* The backend-independent part of the reference module.
*/
-#define USE_THE_REPOSITORY_VARIABLE
-
#include "git-compat-util.h"
#include "abspath.h"
#include "advice.h"
@@ -744,14 +742,15 @@ static char *substitute_branch_name(struct repository *r,
return NULL;
}
-void copy_branchname(struct strbuf *sb, const char *name,
+void copy_branchname(struct repository *repo,
+ struct strbuf *sb, const char *name,
enum interpret_branch_kind allowed)
{
int len = strlen(name);
struct interpret_branch_name_options options = {
.allowed = allowed
};
- int used = repo_interpret_branch_name(the_repository, name, len, sb,
+ int used = repo_interpret_branch_name(repo, name, len, sb,
&options);
if (used < 0)
@@ -759,10 +758,10 @@ void copy_branchname(struct strbuf *sb, const char *name,
strbuf_add(sb, name + used, len - used);
}
-int check_branch_ref(struct strbuf *sb, const char *name)
+int check_branch_ref(struct repository *repo, struct strbuf *sb, const char *name)
{
if (startup_info->have_repository)
- copy_branchname(sb, name, INTERPRET_BRANCH_LOCAL);
+ copy_branchname(repo, sb, name, INTERPRET_BRANCH_LOCAL);
else
strbuf_addstr(sb, name);
@@ -3326,9 +3325,9 @@ static int move_files(const char *from_path, const char *to_path, struct strbuf
return ret;
}
-static int has_worktrees(void)
+static int has_worktrees(struct repository *repo)
{
- struct worktree **worktrees = get_worktrees(the_repository);
+ struct worktree **worktrees = get_worktrees(repo);
int ret = 0;
size_t i;
@@ -3373,12 +3372,8 @@ int repo_migrate_ref_storage_format(struct repository *repo,
* Worktrees complicate the migration because every worktree has a
* separate ref storage. While it should be feasible to implement, this
* is pushed out to a future iteration.
- *
- * TODO: we should really be passing the caller-provided repository to
- * `has_worktrees()`, but our worktree subsystem doesn't yet support
- * that.
*/
- if (has_worktrees()) {
+ if (has_worktrees(repo)) {
strbuf_addstr(errbuf, "migrating repositories with worktrees is not supported yet");
ret = -1;
goto done;
@@ -3503,7 +3498,7 @@ int repo_migrate_ref_storage_format(struct repository *repo,
* repository format so that clients will use the new ref store.
* We also need to swap out the repository's main ref store.
*/
- initialize_repository_version(the_repository, hash_algo_by_ptr(repo->hash_algo), format, 1);
+ initialize_repository_version(repo, hash_algo_by_ptr(repo->hash_algo), format, 1);
/*
* Unset the old ref store and release it. `get_main_ref_store()` will
diff --git a/refs.h b/refs.h
index a381022c77..9979446d15 100644
--- a/refs.h
+++ b/refs.h
@@ -234,7 +234,8 @@ char *repo_default_branch_name(struct repository *r, int quiet);
* If "allowed" is non-zero, restrict the set of allowed expansions. See
* repo_interpret_branch_name() for details.
*/
-void copy_branchname(struct strbuf *sb, const char *name,
+void copy_branchname(struct repository *repo,
+ struct strbuf *sb, const char *name,
enum interpret_branch_kind allowed);
/*
@@ -243,7 +244,7 @@ void copy_branchname(struct strbuf *sb, const char *name,
*
* The return value is "0" if the result is valid, and "-1" otherwise.
*/
-int check_branch_ref(struct strbuf *sb, const char *name);
+int check_branch_ref(struct repository *repo, struct strbuf *sb, const char *name);
/*
* Similar for a tag name in refs/tags/.
--
2.55.0.175.ge4962bd3d5.dirty
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 1/7] refs/packed: de-globalize handling of "core.packedRefsTimeout"
2026-07-09 8:29 ` [PATCH 1/7] refs/packed: de-globalize handling of "core.packedRefsTimeout" Patrick Steinhardt
@ 2026-07-09 18:52 ` Junio C Hamano
2026-07-10 5:56 ` Patrick Steinhardt
0 siblings, 1 reply; 16+ messages in thread
From: Junio C Hamano @ 2026-07-09 18:52 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
Patrick Steinhardt <ps@pks.im> writes:
> diff --git a/refs/packed-backend.c b/refs/packed-backend.c
> index 499cb55dfa..5c49c06493 100644
> --- a/refs/packed-backend.c
> +++ b/refs/packed-backend.c
> @@ -162,6 +162,13 @@ struct packed_ref_store {
> * `packed_ref_store`) must not be freed.
> */
> struct tempfile *tempfile;
> +
> + /*
> + * Timeout when taking the "packed-refs.lock" file. configurable via
> + * "core.packedRefsTimeout".
> + */
> + bool timeout_configured;
> + int timeout_value;
> };
>
> /*
> @@ -1233,12 +1240,10 @@ int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err)
> struct packed_ref_store *refs =
> packed_downcast(ref_store, REF_STORE_WRITE | REF_STORE_MAIN,
> "packed_refs_lock");
> - static int timeout_configured = 0;
> - static int timeout_value = 1000;
>
> - if (!timeout_configured) {
> - repo_config_get_int(the_repository, "core.packedrefstimeout", &timeout_value);
> - timeout_configured = 1;
In the original code, when core.packedrefstimeout is not configured,
our call to repo_config_get_int() does not touch timeout_value. As
a result, we get the static 1000 and flip the "configured" flag to
prevent this _value from further getting updated.
> + if (!refs->timeout_configured) {
> + repo_config_get_int(ref_store->repo, "core.packedrefstimeout", &refs->timeout_value);
> + refs->timeout_configured = true;
But what happens in the new code when core.packedrefstimeout is not
configured? It is up to whoever initialised refs->timeout_value.
If I am not mistaken, packed_ref_store_init() does xcalloc(), lets
base_ref_store_init() initialise some members, initialises a few
members itself (such as .store_flags and .path), and leaves other
members, including .timeout_configured and .timeout_value,
NUL-filled. .timeout_configured starting as false is perfectly
fine, but shouldn't we initialise .timeout_value to 1000 as before?
Thanks.
> @@ -1249,7 +1254,7 @@ int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err)
> if (hold_lock_file_for_update_timeout(
> &refs->lock,
> refs->path,
> - flags, timeout_value) < 0) {
> + flags, refs->timeout_value) < 0) {
> unable_to_lock_message(refs->path, errno, err);
> return -1;
> }
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/7] refs: remove use of `the_repository`
2026-07-09 8:29 [PATCH 0/7] refs: remove use of `the_repository` Patrick Steinhardt
` (6 preceding siblings ...)
2026-07-09 8:29 ` [PATCH 7/7] refs: remove remaining uses of `the_repository` Patrick Steinhardt
@ 2026-07-09 20:39 ` Junio C Hamano
2026-07-10 5:56 ` Patrick Steinhardt
7 siblings, 1 reply; 16+ messages in thread
From: Junio C Hamano @ 2026-07-09 20:39 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
Patrick Steinhardt <ps@pks.im> writes:
> The series is built on top of f85a7e6620 (Start Git 2.56 cycle,
> 2026-07-06) with ps/refs-writing-subcommands at 002fe677ca
> (builtin/refs: add "rename" subcommand, 2026-07-06) merged into it.
> Despite that, there's a small set of conflicts with "seen" that can be
> merged like this:
Thanks for a heads-up.
This seems to break so many tests when merged to either 'jch' or
'seen', even though all of them pass standalone. I did not have
time to figure out what interactions with which other topic are
causing the breakages.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/7] refs: remove use of `the_repository`
2026-07-09 20:39 ` [PATCH 0/7] refs: remove use " Junio C Hamano
@ 2026-07-10 5:56 ` Patrick Steinhardt
2026-07-10 6:14 ` Patrick Steinhardt
2026-07-10 14:48 ` Junio C Hamano
0 siblings, 2 replies; 16+ messages in thread
From: Patrick Steinhardt @ 2026-07-10 5:56 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Thu, Jul 09, 2026 at 01:39:03PM -0700, Junio C Hamano wrote:
> Patrick Steinhardt <ps@pks.im> writes:
>
> > The series is built on top of f85a7e6620 (Start Git 2.56 cycle,
> > 2026-07-06) with ps/refs-writing-subcommands at 002fe677ca
> > (builtin/refs: add "rename" subcommand, 2026-07-06) merged into it.
> > Despite that, there's a small set of conflicts with "seen" that can be
> > merged like this:
>
> Thanks for a heads-up.
>
> This seems to break so many tests when merged to either 'jch' or
> 'seen', even though all of them pass standalone. I did not have
> time to figure out what interactions with which other topic are
> causing the breakages.
Oh, interesting. I'll investigate what other topic this has interactions
with. Thanks!
Patrick
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 1/7] refs/packed: de-globalize handling of "core.packedRefsTimeout"
2026-07-09 18:52 ` Junio C Hamano
@ 2026-07-10 5:56 ` Patrick Steinhardt
0 siblings, 0 replies; 16+ messages in thread
From: Patrick Steinhardt @ 2026-07-10 5:56 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Thu, Jul 09, 2026 at 11:52:11AM -0700, Junio C Hamano wrote:
> Patrick Steinhardt <ps@pks.im> writes:
>
> > diff --git a/refs/packed-backend.c b/refs/packed-backend.c
> > index 499cb55dfa..5c49c06493 100644
> > --- a/refs/packed-backend.c
> > +++ b/refs/packed-backend.c
> > @@ -162,6 +162,13 @@ struct packed_ref_store {
> > * `packed_ref_store`) must not be freed.
> > */
> > struct tempfile *tempfile;
> > +
> > + /*
> > + * Timeout when taking the "packed-refs.lock" file. configurable via
> > + * "core.packedRefsTimeout".
> > + */
> > + bool timeout_configured;
> > + int timeout_value;
> > };
> >
> > /*
> > @@ -1233,12 +1240,10 @@ int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err)
> > struct packed_ref_store *refs =
> > packed_downcast(ref_store, REF_STORE_WRITE | REF_STORE_MAIN,
> > "packed_refs_lock");
> > - static int timeout_configured = 0;
> > - static int timeout_value = 1000;
> >
> > - if (!timeout_configured) {
> > - repo_config_get_int(the_repository, "core.packedrefstimeout", &timeout_value);
> > - timeout_configured = 1;
>
> In the original code, when core.packedrefstimeout is not configured,
> our call to repo_config_get_int() does not touch timeout_value. As
> a result, we get the static 1000 and flip the "configured" flag to
> prevent this _value from further getting updated.
>
> > + if (!refs->timeout_configured) {
> > + repo_config_get_int(ref_store->repo, "core.packedrefstimeout", &refs->timeout_value);
> > + refs->timeout_configured = true;
>
> But what happens in the new code when core.packedrefstimeout is not
> configured? It is up to whoever initialised refs->timeout_value.
>
> If I am not mistaken, packed_ref_store_init() does xcalloc(), lets
> base_ref_store_init() initialise some members, initialises a few
> members itself (such as .store_flags and .path), and leaves other
> members, including .timeout_configured and .timeout_value,
> NUL-filled. .timeout_configured starting as false is perfectly
> fine, but shouldn't we initialise .timeout_value to 1000 as before?
Ugh, we should. That's what happens when you tack on a last-minute patch
to a series you had sitting around for weeks. Thanks for noticing!
Patrick
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/7] refs: remove use of `the_repository`
2026-07-10 5:56 ` Patrick Steinhardt
@ 2026-07-10 6:14 ` Patrick Steinhardt
2026-07-10 16:57 ` Junio C Hamano
2026-07-10 14:48 ` Junio C Hamano
1 sibling, 1 reply; 16+ messages in thread
From: Patrick Steinhardt @ 2026-07-10 6:14 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Fri, Jul 10, 2026 at 07:56:19AM +0200, Patrick Steinhardt wrote:
> On Thu, Jul 09, 2026 at 01:39:03PM -0700, Junio C Hamano wrote:
> > Patrick Steinhardt <ps@pks.im> writes:
> >
> > > The series is built on top of f85a7e6620 (Start Git 2.56 cycle,
> > > 2026-07-06) with ps/refs-writing-subcommands at 002fe677ca
> > > (builtin/refs: add "rename" subcommand, 2026-07-06) merged into it.
> > > Despite that, there's a small set of conflicts with "seen" that can be
> > > merged like this:
> >
> > Thanks for a heads-up.
> >
> > This seems to break so many tests when merged to either 'jch' or
> > 'seen', even though all of them pass standalone. I did not have
> > time to figure out what interactions with which other topic are
> > causing the breakages.
>
> Oh, interesting. I'll investigate what other topic this has interactions
> with. Thanks!
Hm, curious, I cannot reproduce any of these failures at all, everything
is passing locally when merging "seen" into my branch. Did you maybe
mismerge the changes in "setup.c" by accident? That seems like the most
likely reason as you mention that it breaks lots of tests, and "setup.c"
is of course involved with all of them.
For reference, this is what the final result of the conflicting part
looks like on my side:
if (real_git_dir) {
struct stat st;
if (!exist_ok && !stat(git_dir, &st))
die(_("%s already exists"), git_dir);
if (!exist_ok && !stat(real_git_dir, &st))
die(_("%s already exists"), real_git_dir);
apply_and_export_relative_gitdir(repo, real_git_dir, 1);
git_dir = repo_get_git_dir(repo);
separate_git_dir(repo, git_dir, original_git_dir);
} else {
apply_and_export_relative_gitdir(repo, git_dir, 1);
git_dir = repo_get_git_dir(repo);
}
Thanks!
Patrick
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/7] refs: remove use of `the_repository`
2026-07-10 5:56 ` Patrick Steinhardt
2026-07-10 6:14 ` Patrick Steinhardt
@ 2026-07-10 14:48 ` Junio C Hamano
1 sibling, 0 replies; 16+ messages in thread
From: Junio C Hamano @ 2026-07-10 14:48 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
Patrick Steinhardt <ps@pks.im> writes:
> On Thu, Jul 09, 2026 at 01:39:03PM -0700, Junio C Hamano wrote:
>> Patrick Steinhardt <ps@pks.im> writes:
>>
>> > The series is built on top of f85a7e6620 (Start Git 2.56 cycle,
>> > 2026-07-06) with ps/refs-writing-subcommands at 002fe677ca
>> > (builtin/refs: add "rename" subcommand, 2026-07-06) merged into it.
>> > Despite that, there's a small set of conflicts with "seen" that can be
>> > merged like this:
>>
>> Thanks for a heads-up.
>>
>> This seems to break so many tests when merged to either 'jch' or
>> 'seen', even though all of them pass standalone. I did not have
>> time to figure out what interactions with which other topic are
>> causing the breakages.
>
> Oh, interesting. I'll investigate what other topic this has interactions
> with. Thanks!
Thanks.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/7] refs: remove use of `the_repository`
2026-07-10 6:14 ` Patrick Steinhardt
@ 2026-07-10 16:57 ` Junio C Hamano
2026-07-10 20:24 ` Junio C Hamano
0 siblings, 1 reply; 16+ messages in thread
From: Junio C Hamano @ 2026-07-10 16:57 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
Patrick Steinhardt <ps@pks.im> writes:
> Hm, curious, I cannot reproduce any of these failures at all, everything
> is passing locally when merging "seen" into my branch. Did you maybe
> mismerge the changes in "setup.c" by accident? That seems like the most
> likely reason as you mention that it breaks lots of tests, and "setup.c"
> is of course involved with all of them.
It is more than probable that it was what happened. Will retry the
merge during the integration run I'll make later today.
Thanks.
>
> For reference, this is what the final result of the conflicting part
> looks like on my side:
>
> if (real_git_dir) {
> struct stat st;
>
> if (!exist_ok && !stat(git_dir, &st))
> die(_("%s already exists"), git_dir);
>
> if (!exist_ok && !stat(real_git_dir, &st))
> die(_("%s already exists"), real_git_dir);
>
> apply_and_export_relative_gitdir(repo, real_git_dir, 1);
> git_dir = repo_get_git_dir(repo);
> separate_git_dir(repo, git_dir, original_git_dir);
> } else {
> apply_and_export_relative_gitdir(repo, git_dir, 1);
> git_dir = repo_get_git_dir(repo);
> }
>
> Thanks!
>
> Patrick
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/7] refs: remove use of `the_repository`
2026-07-10 16:57 ` Junio C Hamano
@ 2026-07-10 20:24 ` Junio C Hamano
0 siblings, 0 replies; 16+ messages in thread
From: Junio C Hamano @ 2026-07-10 20:24 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
Junio C Hamano <gitster@pobox.com> writes:
> It is more than probable that it was what happened. Will retry the
> merge during the integration run I'll make later today.
>
> Thanks.
And indeed, I had a mismerge.
Thanks, the topic is back in.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-07-10 20:24 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-09 8:29 [PATCH 0/7] refs: remove use of `the_repository` Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 1/7] refs/packed: de-globalize handling of "core.packedRefsTimeout" Patrick Steinhardt
2026-07-09 18:52 ` Junio C Hamano
2026-07-10 5:56 ` Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 2/7] refs/packed: drop `USE_THE_REPOSITORY_VARIABLE` Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 3/7] refs/files: " Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 4/7] worktree: refactor code to use available repositories Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 5/7] worktree: pass repository to file-local functions Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 6/7] worktree: pass repository to public functions Patrick Steinhardt
2026-07-09 8:29 ` [PATCH 7/7] refs: remove remaining uses of `the_repository` Patrick Steinhardt
2026-07-09 20:39 ` [PATCH 0/7] refs: remove use " Junio C Hamano
2026-07-10 5:56 ` Patrick Steinhardt
2026-07-10 6:14 ` Patrick Steinhardt
2026-07-10 16:57 ` Junio C Hamano
2026-07-10 20:24 ` Junio C Hamano
2026-07-10 14:48 ` Junio C Hamano
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.