* [PATCH 0/3] wt-status: reduce reliance on global state
@ 2026-01-31 18:57 Shreyansh Paliwal
2026-01-31 18:57 ` [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
` (5 more replies)
0 siblings, 6 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-01-31 18:57 UTC (permalink / raw)
To: git; +Cc: gitster, Shreyansh Paliwal
In wt-status.c code still relies on some global variables, including
the_repository and the_hash_algo, even in cases where a repository
instance is already available via struct wt_status or struct worktree.
In patch 1/3, replace direct uses of the_repository with repository
instances already available in local structs.
In patch 2/3, update function parameters and calls to pass struct
repository or struct wt_status explicitly where no local repository
access was available.
In patch 3/3, replace remaining uses of the global the_hash_algo with the
hash algorithm stored in the respective repository instance.
These changes remove all direct uses of the_repository and
the_hash_algo from wt-status.c and reduce its dependence on global state.
Shreyansh Paliwal (3):
wt-status: replace uses of the_repository with local repository
instances
wt-status: pass struct repository and wt_status through function
parameters
wt-status: use hash_algo from local repository instead of global
the_hash_algo
wt-status.c | 76 ++++++++++++++++++++++++++---------------------------
1 file changed, 38 insertions(+), 38 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances
2026-01-31 18:57 [PATCH 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
@ 2026-01-31 18:57 ` Shreyansh Paliwal
2026-02-02 10:02 ` Karthik Nayak
2026-01-31 18:57 ` [PATCH 2/3] wt-status: pass struct repository and wt_status through function parameters Shreyansh Paliwal
` (4 subsequent siblings)
5 siblings, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-01-31 18:57 UTC (permalink / raw)
To: git; +Cc: gitster, Shreyansh Paliwal
Many instances of the_repository are used in wt-status.c even when a
local repository is already available via struct wt_status or struct
worktree.
Replace direct uses of the global the_repository with the repository
instance carried by the local structs (e.g. s->repo, wt->repo).
This helps reduce reliance on global repository state.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
wt-status.c | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index e12adb26b9..9f4d8fda7f 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
s->use_color = GIT_COLOR_UNKNOWN;
s->relative_paths = 1;
- s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
+ s->branch = refs_resolve_refdup(get_main_ref_store(s->repo),
"HEAD", 0, NULL, NULL);
s->reference = "HEAD";
s->fp = stdout;
- s->index_file = repo_get_index_file(the_repository);
+ s->index_file = repo_get_index_file(s->repo);
s->change.strdup_strings = 1;
s->untracked.strdup_strings = 1;
s->ignored.strdup_strings = 1;
@@ -646,7 +646,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
repo_init_revisions(s->repo, &rev, NULL);
memset(&opt, 0, sizeof(opt));
- opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
+ opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.flags.override_submodule_config = 1;
@@ -1146,7 +1146,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
rev.diffopt.ita_invisible_in_index = 1;
memset(&opt, 0, sizeof(opt));
- opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
+ opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
@@ -1317,9 +1317,9 @@ static int split_commit_in_progress(struct wt_status *s)
!s->branch || strcmp(s->branch, "HEAD"))
return 0;
- if (refs_read_ref_full(get_main_ref_store(the_repository), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+ if (refs_read_ref_full(get_main_ref_store(s->repo), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
&head_oid, &head_flags) ||
- refs_read_ref_full(get_main_ref_store(the_repository), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+ refs_read_ref_full(get_main_ref_store(s->repo), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
&orig_head_oid, &orig_head_flags))
return 0;
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
@@ -1432,7 +1432,7 @@ static void show_rebase_information(struct wt_status *s,
i++)
status_printf_ln(s, color, " %s", have_done.items[i].string);
if (have_done.nr > nr_lines_to_show && s->hints) {
- char *path = repo_git_path(the_repository, "rebase-merge/done");
+ char *path = repo_git_path(s->repo, "rebase-merge/done");
status_printf_ln(s, color,
_(" (see more in file %s)"), path);
free(path);
@@ -1534,7 +1534,7 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
else
status_printf_ln(s, color,
_("You are currently cherry-picking commit %s."),
- repo_find_unique_abbrev(the_repository, &s->state.cherry_pick_head_oid,
+ repo_find_unique_abbrev(s->repo, &s->state.cherry_pick_head_oid,
DEFAULT_ABBREV));
if (s->hints) {
@@ -1564,7 +1564,7 @@ static void show_revert_in_progress(struct wt_status *s,
else
status_printf_ln(s, color,
_("You are currently reverting commit %s."),
- repo_find_unique_abbrev(the_repository, &s->state.revert_head_oid,
+ repo_find_unique_abbrev(s->repo, &s->state.revert_head_oid,
DEFAULT_ABBREV));
if (s->hints) {
if (has_unmerged(s))
@@ -1624,7 +1624,7 @@ static char *get_branch(const struct worktree *wt, const char *path)
struct object_id oid;
const char *branch_name;
- if (strbuf_read_file(&sb, worktree_git_path(the_repository, wt, "%s", path), 0) <= 0)
+ if (strbuf_read_file(&sb, worktree_git_path(wt->repo, wt, "%s", path), 0) <= 0)
goto got_nothing;
while (sb.len && sb.buf[sb.len - 1] == '\n')
@@ -1691,7 +1691,7 @@ static void wt_status_get_detached_from(struct repository *r,
char *ref = NULL;
strbuf_init(&cb.buf, 0);
- if (refs_for_each_reflog_ent_reverse(get_main_ref_store(the_repository), "HEAD", grab_1st_switch, &cb) <= 0) {
+ if (refs_for_each_reflog_ent_reverse(get_main_ref_store(r), "HEAD", grab_1st_switch, &cb) <= 0) {
strbuf_release(&cb.buf);
return;
}
@@ -1723,18 +1723,18 @@ int wt_status_check_rebase(const struct worktree *wt,
{
struct stat st;
- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
+ if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply"), &st)) {
+ if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply/applying"), &st)) {
state->am_in_progress = 1;
- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/patch"), &st) && !st.st_size)
+ if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply/patch"), &st) && !st.st_size)
state->am_empty_patch = 1;
} else {
state->rebase_in_progress = 1;
state->branch = get_branch(wt, "rebase-apply/head-name");
state->onto = get_branch(wt, "rebase-apply/onto");
}
- } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
- if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
+ } else if (!stat(worktree_git_path(wt->repo, wt, "rebase-merge"), &st)) {
+ if (!stat(worktree_git_path(wt->repo, wt, "rebase-merge/interactive"), &st))
state->rebase_interactive_in_progress = 1;
else
state->rebase_in_progress = 1;
@@ -1750,7 +1750,7 @@ int wt_status_check_bisect(const struct worktree *wt,
{
struct stat st;
- if (!stat(worktree_git_path(the_repository, wt, "BISECT_LOG"), &st)) {
+ if (!stat(worktree_git_path(wt->repo, wt, "BISECT_LOG"), &st)) {
state->bisect_in_progress = 1;
state->bisecting_from = get_branch(wt, "BISECT_START");
return 1;
@@ -2099,7 +2099,7 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
upstream_is_gone = 1;
}
- short_base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
+ short_base = refs_shorten_unambiguous_ref(get_main_ref_store(s->repo),
base, 0);
color_fprintf(s->fp, header_color, "...");
color_fprintf(s->fp, branch_color_remote, "%s", short_base);
@@ -2233,7 +2233,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
ab_info = stat_tracking_info(branch, &nr_ahead, &nr_behind,
&base, 0, s->ahead_behind_flags);
if (base) {
- base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
+ base = refs_shorten_unambiguous_ref(get_main_ref_store(s->repo),
base, 0);
fprintf(s->fp, "# branch.upstream %s%c", base, eol);
free((char *)base);
--
2.52.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-01-31 18:57 [PATCH 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
2026-01-31 18:57 ` [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
@ 2026-01-31 18:57 ` Shreyansh Paliwal
2026-01-31 18:57 ` [PATCH 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
` (3 subsequent siblings)
5 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-01-31 18:57 UTC (permalink / raw)
To: git; +Cc: gitster, Shreyansh Paliwal
Some functions in wt-status.c relied on the_repository because no
repository instance was available in their local scope.
Update these functions to accept struct repository or struct
wt_status as parameters, and adjust callers accordingly.
Replace remaining uses of the_repository in these functions with the
passed-in repository instance.
This completely removes the use of the_repository global variable
in wt-status.c.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
wt-status.c | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index 9f4d8fda7f..eb1a3a254b 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -984,17 +984,17 @@ static int stash_count_refs(const char *refname UNUSED,
return 0;
}
-static int count_stash_entries(void)
+static int count_stash_entries(struct repository *r)
{
int n = 0;
- refs_for_each_reflog_ent(get_main_ref_store(the_repository),
+ refs_for_each_reflog_ent(get_main_ref_store(r),
"refs/stash", stash_count_refs, &n);
return n;
}
static void wt_longstatus_print_stash_summary(struct wt_status *s)
{
- int stash_count = count_stash_entries();
+ int stash_count = count_stash_entries(s->repo);
if (stash_count > 0)
status_printf_ln(s, GIT_COLOR_NORMAL,
@@ -1287,10 +1287,10 @@ static void show_am_in_progress(struct wt_status *s,
wt_longstatus_print_trailer(s);
}
-static char *read_line_from_git_path(const char *filename)
+static char *read_line_from_git_path(struct repository *r, const char *filename)
{
struct strbuf buf = STRBUF_INIT;
- FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
+ FILE *fp = fopen_or_warn(repo_git_path_append(r, &buf,
"%s", filename), "r");
if (!fp) {
@@ -1325,8 +1325,8 @@ static int split_commit_in_progress(struct wt_status *s)
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
return 0;
- rebase_amend = read_line_from_git_path("rebase-merge/amend");
- rebase_orig_head = read_line_from_git_path("rebase-merge/orig-head");
+ rebase_amend = read_line_from_git_path(s->repo, "rebase-merge/amend");
+ rebase_orig_head = read_line_from_git_path(s->repo, "rebase-merge/orig-head");
if (!rebase_amend || !rebase_orig_head)
; /* fall through, no split in progress */
@@ -1350,7 +1350,7 @@ static int split_commit_in_progress(struct wt_status *s)
* The function assumes that the line does not contain useless spaces
* before or after the command.
*/
-static void abbrev_oid_in_line(struct strbuf *line)
+static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
{
struct string_list split = STRING_LIST_INIT_DUP;
struct object_id oid;
@@ -1362,7 +1362,7 @@ static void abbrev_oid_in_line(struct strbuf *line)
return;
if ((2 <= string_list_split(&split, line->buf, " ", 2)) &&
- !repo_get_oid(the_repository, split.items[1].string, &oid)) {
+ !repo_get_oid(r, split.items[1].string, &oid)) {
strbuf_reset(line);
strbuf_addf(line, "%s ", split.items[0].string);
strbuf_add_unique_abbrev(line, &oid, DEFAULT_ABBREV);
@@ -1372,10 +1372,10 @@ static void abbrev_oid_in_line(struct strbuf *line)
string_list_clear(&split, 0);
}
-static int read_rebase_todolist(const char *fname, struct string_list *lines)
+static int read_rebase_todolist(struct repository *r, const char *fname, struct string_list *lines)
{
struct strbuf buf = STRBUF_INIT;
- FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
+ FILE *f = fopen(repo_git_path_append(r, &buf, "%s", fname), "r");
int ret;
if (!f) {
@@ -1384,7 +1384,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)
goto out;
}
die_errno("Could not open file %s for reading",
- repo_git_path_replace(the_repository, &buf, "%s", fname));
+ repo_git_path_replace(r, &buf, "%s", fname));
}
while (!strbuf_getline_lf(&buf, f)) {
if (starts_with(buf.buf, comment_line_str))
@@ -1392,7 +1392,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)
strbuf_trim(&buf);
if (!buf.len)
continue;
- abbrev_oid_in_line(&buf);
+ abbrev_oid_in_line(r, &buf);
string_list_append(lines, buf.buf);
}
fclose(f);
@@ -1413,8 +1413,8 @@ static void show_rebase_information(struct wt_status *s,
struct string_list have_done = STRING_LIST_INIT_DUP;
struct string_list yet_to_do = STRING_LIST_INIT_DUP;
- read_rebase_todolist("rebase-merge/done", &have_done);
- if (read_rebase_todolist("rebase-merge/git-rebase-todo",
+ read_rebase_todolist(s->repo, "rebase-merge/done", &have_done);
+ if (read_rebase_todolist(s->repo, "rebase-merge/git-rebase-todo",
&yet_to_do))
status_printf_ln(s, color,
_("git-rebase-todo is missing."));
@@ -2259,7 +2259,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
*/
static void wt_porcelain_v2_print_stash(struct wt_status *s)
{
- int stash_count = count_stash_entries();
+ int stash_count = count_stash_entries(s->repo);
char eol = s->null_termination ? '\0' : '\n';
if (stash_count > 0)
--
2.52.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo
2026-01-31 18:57 [PATCH 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
2026-01-31 18:57 ` [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
2026-01-31 18:57 ` [PATCH 2/3] wt-status: pass struct repository and wt_status through function parameters Shreyansh Paliwal
@ 2026-01-31 18:57 ` Shreyansh Paliwal
2026-02-02 10:03 ` Karthik Nayak
2026-02-05 10:13 ` [PATCH V2 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
` (2 subsequent siblings)
5 siblings, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-01-31 18:57 UTC (permalink / raw)
To: git; +Cc: gitster, Shreyansh Paliwal
wt-status.c uses the global the_hash_algo even though a repository
instance is already available via struct repository *r.
Replace uses of the_hash_algo with the hash algorithm stored in the
associated repository (r->hash_algo).
This removes another dependency on global state and keeps wt-status
consistent with local repository usage.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
wt-status.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index eb1a3a254b..933d744cea 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1815,10 +1815,10 @@ void wt_status_get_state(struct repository *r,
if (!sequencer_get_last_command(r, &action)) {
if (action == REPLAY_PICK && !state->cherry_pick_in_progress) {
state->cherry_pick_in_progress = 1;
- oidcpy(&state->cherry_pick_head_oid, null_oid(the_hash_algo));
+ oidcpy(&state->cherry_pick_head_oid, null_oid(r->hash_algo));
} else if (action == REPLAY_REVERT && !state->revert_in_progress) {
state->revert_in_progress = 1;
- oidcpy(&state->revert_head_oid, null_oid(the_hash_algo));
+ oidcpy(&state->revert_head_oid, null_oid(r->hash_algo));
}
}
if (get_detached_from)
@@ -2630,7 +2630,7 @@ int has_uncommitted_changes(struct repository *r,
* We have no head (or it's corrupt); use the empty tree,
* which will complain if the index is non-empty.
*/
- struct tree *tree = lookup_tree(r, the_hash_algo->empty_tree);
+ struct tree *tree = lookup_tree(r, r->hash_algo->empty_tree);
add_pending_object(&rev_info, &tree->object, "");
}
--
2.52.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* Re: [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances
2026-01-31 18:57 ` [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
@ 2026-02-02 10:02 ` Karthik Nayak
2026-02-02 18:42 ` Junio C Hamano
2026-02-02 18:57 ` Shreyansh Paliwal
0 siblings, 2 replies; 69+ messages in thread
From: Karthik Nayak @ 2026-02-02 10:02 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster
[-- Attachment #1: Type: text/plain, Size: 7919 bytes --]
Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
> Many instances of the_repository are used in wt-status.c even when a
> local repository is already available via struct wt_status or struct
> worktree.
>
One missing information is why is it safe to make this change? If is a
repository field, is it holding the same information, is it always
defined?
> Replace direct uses of the global the_repository with the repository
> instance carried by the local structs (e.g. s->repo, wt->repo).
>
> This helps reduce reliance on global repository state.
>
> Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
> ---
> wt-status.c | 38 +++++++++++++++++++-------------------
> 1 file changed, 19 insertions(+), 19 deletions(-)
>
> diff --git a/wt-status.c b/wt-status.c
> index e12adb26b9..9f4d8fda7f 100644
> --- a/wt-status.c
> +++ b/wt-status.c
> @@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
> s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
> s->use_color = GIT_COLOR_UNKNOWN;
> s->relative_paths = 1;
> - s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
> + s->branch = refs_resolve_refdup(get_main_ref_store(s->repo),
> "HEAD", 0, NULL, NULL);
Wouldn't it make more sense to use the function argument 'r' here?
> s->reference = "HEAD";
> s->fp = stdout;
> - s->index_file = repo_get_index_file(the_repository);
> + s->index_file = repo_get_index_file(s->repo);
> s->change.strdup_strings = 1;
> s->untracked.strdup_strings = 1;
> s->ignored.strdup_strings = 1;
> @@ -646,7 +646,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
>
> repo_init_revisions(s->repo, &rev, NULL);
> memset(&opt, 0, sizeof(opt));
> - opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
> + opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
> setup_revisions(0, NULL, &rev, &opt);
>
> rev.diffopt.flags.override_submodule_config = 1;
> @@ -1146,7 +1146,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
> rev.diffopt.ita_invisible_in_index = 1;
>
> memset(&opt, 0, sizeof(opt));
> - opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
> + opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
> setup_revisions(0, NULL, &rev, &opt);
>
> rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
> @@ -1317,9 +1317,9 @@ static int split_commit_in_progress(struct wt_status *s)
> !s->branch || strcmp(s->branch, "HEAD"))
> return 0;
>
> - if (refs_read_ref_full(get_main_ref_store(the_repository), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
> + if (refs_read_ref_full(get_main_ref_store(s->repo), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
> &head_oid, &head_flags) ||
> - refs_read_ref_full(get_main_ref_store(the_repository), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
> + refs_read_ref_full(get_main_ref_store(s->repo), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
> &orig_head_oid, &orig_head_flags))
> return 0;
> if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
> @@ -1432,7 +1432,7 @@ static void show_rebase_information(struct wt_status *s,
> i++)
> status_printf_ln(s, color, " %s", have_done.items[i].string);
> if (have_done.nr > nr_lines_to_show && s->hints) {
> - char *path = repo_git_path(the_repository, "rebase-merge/done");
> + char *path = repo_git_path(s->repo, "rebase-merge/done");
> status_printf_ln(s, color,
> _(" (see more in file %s)"), path);
> free(path);
> @@ -1534,7 +1534,7 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
> else
> status_printf_ln(s, color,
> _("You are currently cherry-picking commit %s."),
> - repo_find_unique_abbrev(the_repository, &s->state.cherry_pick_head_oid,
> + repo_find_unique_abbrev(s->repo, &s->state.cherry_pick_head_oid,
> DEFAULT_ABBREV));
>
> if (s->hints) {
> @@ -1564,7 +1564,7 @@ static void show_revert_in_progress(struct wt_status *s,
> else
> status_printf_ln(s, color,
> _("You are currently reverting commit %s."),
> - repo_find_unique_abbrev(the_repository, &s->state.revert_head_oid,
> + repo_find_unique_abbrev(s->repo, &s->state.revert_head_oid,
> DEFAULT_ABBREV));
> if (s->hints) {
> if (has_unmerged(s))
> @@ -1624,7 +1624,7 @@ static char *get_branch(const struct worktree *wt, const char *path)
> struct object_id oid;
> const char *branch_name;
>
> - if (strbuf_read_file(&sb, worktree_git_path(the_repository, wt, "%s", path), 0) <= 0)
> + if (strbuf_read_file(&sb, worktree_git_path(wt->repo, wt, "%s", path), 0) <= 0)
> goto got_nothing;
>
> while (sb.len && sb.buf[sb.len - 1] == '\n')
> @@ -1691,7 +1691,7 @@ static void wt_status_get_detached_from(struct repository *r,
> char *ref = NULL;
>
> strbuf_init(&cb.buf, 0);
> - if (refs_for_each_reflog_ent_reverse(get_main_ref_store(the_repository), "HEAD", grab_1st_switch, &cb) <= 0) {
> + if (refs_for_each_reflog_ent_reverse(get_main_ref_store(r), "HEAD", grab_1st_switch, &cb) <= 0) {
> strbuf_release(&cb.buf);
> return;
> }
> @@ -1723,18 +1723,18 @@ int wt_status_check_rebase(const struct worktree *wt,
> {
> struct stat st;
>
> - if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
> - if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
> + if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply"), &st)) {
> + if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply/applying"), &st)) {
In the same file we make a call 'wt_status_check_rebase(NULL, state)',
so wouldn't this break?
> state->am_in_progress = 1;
> - if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/patch"), &st) && !st.st_size)
> + if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply/patch"), &st) && !st.st_size)
> state->am_empty_patch = 1;
> } else {
> state->rebase_in_progress = 1;
> state->branch = get_branch(wt, "rebase-apply/head-name");
> state->onto = get_branch(wt, "rebase-apply/onto");
> }
> - } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
> - if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
> + } else if (!stat(worktree_git_path(wt->repo, wt, "rebase-merge"), &st)) {
> + if (!stat(worktree_git_path(wt->repo, wt, "rebase-merge/interactive"), &st))
> state->rebase_interactive_in_progress = 1;
> else
> state->rebase_in_progress = 1;
> @@ -1750,7 +1750,7 @@ int wt_status_check_bisect(const struct worktree *wt,
> {
> struct stat st;
>
> - if (!stat(worktree_git_path(the_repository, wt, "BISECT_LOG"), &st)) {
> + if (!stat(worktree_git_path(wt->repo, wt, "BISECT_LOG"), &st)) {
> state->bisect_in_progress = 1;
> state->bisecting_from = get_branch(wt, "BISECT_START");
> return 1;
> @@ -2099,7 +2099,7 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
> upstream_is_gone = 1;
> }
>
> - short_base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
> + short_base = refs_shorten_unambiguous_ref(get_main_ref_store(s->repo),
> base, 0);
> color_fprintf(s->fp, header_color, "...");
> color_fprintf(s->fp, branch_color_remote, "%s", short_base);
> @@ -2233,7 +2233,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
> ab_info = stat_tracking_info(branch, &nr_ahead, &nr_behind,
> &base, 0, s->ahead_behind_flags);
> if (base) {
> - base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
> + base = refs_shorten_unambiguous_ref(get_main_ref_store(s->repo),
> base, 0);
> fprintf(s->fp, "# branch.upstream %s%c", base, eol);
> free((char *)base);
> --
> 2.52.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo
2026-01-31 18:57 ` [PATCH 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
@ 2026-02-02 10:03 ` Karthik Nayak
2026-02-02 19:03 ` Shreyansh Paliwal
0 siblings, 1 reply; 69+ messages in thread
From: Karthik Nayak @ 2026-02-02 10:03 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster
[-- Attachment #1: Type: text/plain, Size: 533 bytes --]
Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
> wt-status.c uses the global the_hash_algo even though a repository
> instance is already available via struct repository *r.
>
> Replace uses of the_hash_algo with the hash algorithm stored in the
> associated repository (r->hash_algo).
>
> This removes another dependency on global state and keeps wt-status
> consistent with local repository usage.
>
One final question is, does this mean we can remove
`USE_THE_REPOSITORY_VARIABLE` after these changes? If not, why?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-02 10:02 ` Karthik Nayak
@ 2026-02-02 18:42 ` Junio C Hamano
2026-02-02 18:57 ` Shreyansh Paliwal
1 sibling, 0 replies; 69+ messages in thread
From: Junio C Hamano @ 2026-02-02 18:42 UTC (permalink / raw)
To: Karthik Nayak; +Cc: Shreyansh Paliwal, git
Karthik Nayak <karthik.188@gmail.com> writes:
> One missing information is why is it safe to make this change? If is a
> repository field, is it holding the same information, is it always
> defined?
> ...
>> @@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
>> s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
>> s->use_color = GIT_COLOR_UNKNOWN;
>> s->relative_paths = 1;
>> - s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
>> + s->branch = refs_resolve_refdup(get_main_ref_store(s->repo),
>> "HEAD", 0, NULL, NULL);
>
> Wouldn't it make more sense to use the function argument 'r' here?
>> @@ -1723,18 +1723,18 @@ int wt_status_check_rebase(const struct worktree *wt,
>> {
>> struct stat st;
>>
>> - if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
>> - if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
>> + if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply"), &st)) {
>> + if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply/applying"), &st)) {
>
> In the same file we make a call 'wt_status_check_rebase(NULL, state)',
> so wouldn't this break?
Good questions. Thanks for a quick review.
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-02 10:02 ` Karthik Nayak
2026-02-02 18:42 ` Junio C Hamano
@ 2026-02-02 18:57 ` Shreyansh Paliwal
2026-02-02 22:41 ` Junio C Hamano
2026-02-03 10:58 ` Phillip Wood
1 sibling, 2 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-02 18:57 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188
> > Many instances of the_repository are used in wt-status.c even when a
> > local repository is already available via struct wt_status or struct
> > worktree.
> >
>
> One missing information is why is it safe to make this change? If is a
> repository field, is it holding the same information, is it always
> defined?
Yes I should have included explanation as well.
I have explained below, let me know if this thought process
is valid or not.
The replacement of all the_repository with s->repo in this patch are mostly
to cases where a repository instance is already available via struct wt_status.
In the current flow, all functions operating on struct wt_status *s
are called via commit.c. There, status_init_config() calls
wt_status_prepare(), which initializes the struct wt_status and
assigns s->repo from the repository instance passed in by the caller.
As a result, s->repo is guaranteed to be initialized whenever these
functions are invoked.
And commit.c itself still relies on the_repository, within wt-status.c,
the local repository pointer refers to the same underlying
repository object that the_repository would have pointed to, indirectly
until we make commit.c also free of the_repository.
> > diff --git a/wt-status.c b/wt-status.c
> > index e12adb26b9..9f4d8fda7f 100644
> > --- a/wt-status.c
> > +++ b/wt-status.c
> > @@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
> > s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
> > s->use_color = GIT_COLOR_UNKNOWN;
> > s->relative_paths = 1;
> > - s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
> > + s->branch = refs_resolve_refdup(get_main_ref_store(s->repo),
> > "HEAD", 0, NULL, NULL);
>
> Wouldn't it make more sense to use the function argument 'r' here?
In wt_status_prepare(), s->repo is initialized to r at the top of
the function, so both refer to the same repository instance. However,
using r directly is more explicit and avoids indirect use.
will change this in V2.
> > @@ -1723,18 +1723,18 @@ int wt_status_check_rebase(const struct worktree *wt,
> > {
> > struct stat st;
> >
> > - if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
> > - if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
> > + if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply"), &st)) {
> > + if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply/applying"), &st)) {
>
> In the same file we make a call 'wt_status_check_rebase(NULL, state)',
> so wouldn't this break?
Yes my bad, it would throw a segfault error.
I think the best way to handle this is to explicitly check for the
wt to be valid like this,
if (wt==NULL)
return 0;
Falling back to the_repository in this case, would probably
defeat the purpose.
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo
2026-02-02 10:03 ` Karthik Nayak
@ 2026-02-02 19:03 ` Shreyansh Paliwal
2026-02-04 10:18 ` Karthik Nayak
0 siblings, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-02 19:03 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188
> > wt-status.c uses the global the_hash_algo even though a repository
> > instance is already available via struct repository *r.
> >
> > Replace uses of the_hash_algo with the hash algorithm stored in the
> > associated repository (r->hash_algo).
> >
> > This removes another dependency on global state and keeps wt-status
> > consistent with local repository usage.
> >
>
> One final question is, does this mean we can remove
> `USE_THE_REPOSITORY_VARIABLE` after these changes? If not, why?
We cannot remove `USE_THE_REPOSITORY_VARIABLE` yet, because the changes done only
remove the direct use of the_hash_algo and the_repository,
but 'USE_THE_REPOSITORY_VARIABLE' is for all the global variables
that are still in use.
In particular wt-status.c still relies on the following globals,
* core_apply_sparse_checkout, this is already being addressed in an
ongoing patch series [1], so I intentionally did not modify it.
* comment_line_str and DEFAULT_ABBREV, these both still are used in
wt-status.c but they dont have any local instance in wt-status.c,
or in any other form.
Removing these would require a wider refactoring (adding in struct wt_status,
adding helper functions etc) and I believe is better handled as a separate patch series.
Though I require some guidance on the preferred approach for handling
comment_line_str and DEFAULT_ABBREV going forward.
Thanks for reviewing.
Best,
Shreyansh
[1]- https://lore.kernel.org/git/5e56e1cc4172cfff9e917a068184e102aa70bf1d.1769256839.git.belkid98@gmail.com/t/#u
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-02 18:57 ` Shreyansh Paliwal
@ 2026-02-02 22:41 ` Junio C Hamano
2026-02-02 23:03 ` Junio C Hamano
2026-02-03 10:58 ` Phillip Wood
1 sibling, 1 reply; 69+ messages in thread
From: Junio C Hamano @ 2026-02-02 22:41 UTC (permalink / raw)
To: Shreyansh Paliwal; +Cc: git, karthik.188
Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>> > diff --git a/wt-status.c b/wt-status.c
>> > index e12adb26b9..9f4d8fda7f 100644
>> > --- a/wt-status.c
>> > +++ b/wt-status.c
>> > @@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
>> > s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
>> > s->use_color = GIT_COLOR_UNKNOWN;
>> > s->relative_paths = 1;
>> > - s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
>> > + s->branch = refs_resolve_refdup(get_main_ref_store(s->repo),
>> > "HEAD", 0, NULL, NULL);
>>
>> Wouldn't it make more sense to use the function argument 'r' here?
>
> In wt_status_prepare(), s->repo is initialized to r at the top of
> the function, so both refer to the same repository instance. However,
> using r directly is more explicit and avoids indirect use.
> will change this in V2.
Would we benefit from further clean-up, either before or after this
change, to lose the "struct repository *r" parameter, if we know
that we can depend on s->repo being the repository we are collecting
the status information in the wt_status structure for?
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-02 22:41 ` Junio C Hamano
@ 2026-02-02 23:03 ` Junio C Hamano
2026-02-03 9:53 ` Shreyansh Paliwal
0 siblings, 1 reply; 69+ messages in thread
From: Junio C Hamano @ 2026-02-02 23:03 UTC (permalink / raw)
To: Shreyansh Paliwal; +Cc: git, karthik.188
Junio C Hamano <gitster@pobox.com> writes:
> Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>
>>> > diff --git a/wt-status.c b/wt-status.c
>>> > index e12adb26b9..9f4d8fda7f 100644
>>> > --- a/wt-status.c
>>> > +++ b/wt-status.c
>>> > @@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
>>> > s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
>>> > s->use_color = GIT_COLOR_UNKNOWN;
>>> > s->relative_paths = 1;
>>> > - s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
>>> > + s->branch = refs_resolve_refdup(get_main_ref_store(s->repo),
>>> > "HEAD", 0, NULL, NULL);
>>>
>>> Wouldn't it make more sense to use the function argument 'r' here?
>>
>> In wt_status_prepare(), s->repo is initialized to r at the top of
>> the function, so both refer to the same repository instance. However,
>> using r directly is more explicit and avoids indirect use.
>> will change this in V2.
>
> Would we benefit from further clean-up, either before or after this
> change, to lose the "struct repository *r" parameter, if we know
> that we can depend on s->repo being the repository we are collecting
> the status information in the wt_status structure for?
Clarification. This function is like an initializer for the struct
wt_status instance at 's', so it has to take both "struct repository"
parameter, but what I meant was other wt_status_foo() functions that
take both r and s as parameters. Once s has been initialized and
s->repo becomes valid, passing r as a separate parameter, as if you
can feed a different instance of "struct repo", becomes confusing
and a source of bugs.
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-02 23:03 ` Junio C Hamano
@ 2026-02-03 9:53 ` Shreyansh Paliwal
2026-02-03 11:06 ` Phillip Wood
0 siblings, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-03 9:53 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188
> > Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
> >
> >>> > diff --git a/wt-status.c b/wt-status.c
> >>> > index e12adb26b9..9f4d8fda7f 100644
> >>> > --- a/wt-status.c
> >>> > +++ b/wt-status.c
> >>> > @@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
> >>> > s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
> >>> > s->use_color = GIT_COLOR_UNKNOWN;
> >>> > s->relative_paths = 1;
> >>> > - s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
> >>> > + s->branch = refs_resolve_refdup(get_main_ref_store(s->repo),
> >>> > "HEAD", 0, NULL, NULL);
> >>>
> >>> Wouldn't it make more sense to use the function argument 'r' here?
> >>
> >> In wt_status_prepare(), s->repo is initialized to r at the top of
> >> the function, so both refer to the same repository instance. However,
> >> using r directly is more explicit and avoids indirect use.
> >> will change this in V2.
> >
> > Would we benefit from further clean-up, either before or after this
> > change, to lose the "struct repository *r" parameter, if we know
> > that we can depend on s->repo being the repository we are collecting
> > the status information in the wt_status structure for?
>
> Clarification. This function is like an initializer for the struct
> wt_status instance at 's', so it has to take both "struct repository"
> parameter, but what I meant was other wt_status_foo() functions that
> take both r and s as parameters. Once s has been initialized and
> s->repo becomes valid, passing r as a separate parameter, as if you
> can feed a different instance of "struct repo", becomes confusing
> and a source of bugs.
Actually wt_status_prepare() is the only function which is taking both
struct wt_status *s and struct repository *r, because it has to initialize
's' with the help of 'r'.
But all the other wt_status_.. helper functions only take one of the following,
i.e. either they take struct wt_status *s which is fine, or they take
struct repository *r.
If we trace the callers of the functions with struct repository *r,
they are either being called in wt_status.c in which s->repo is being passed
as a parameter at the end so it shouldn't cause any issues,
and for any other file callers, the_repository is being passed,
so to remove struct repository *r, we would have to setup struct wt_status
in those files as well.
Best,
Shreyansh
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-02 18:57 ` Shreyansh Paliwal
2026-02-02 22:41 ` Junio C Hamano
@ 2026-02-03 10:58 ` Phillip Wood
2026-02-03 15:15 ` Shreyansh Paliwal
1 sibling, 1 reply; 69+ messages in thread
From: Phillip Wood @ 2026-02-03 10:58 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster, karthik.188
On 02/02/2026 18:57, Shreyansh Paliwal wrote:
>>> Many instances of the_repository are used in wt-status.c even when a
>>> local repository is already available via struct wt_status or struct
>>> worktree.
>>>
>>
>> One missing information is why is it safe to make this change? If is a
>> repository field, is it holding the same information, is it always
>> defined?
>
> Yes I should have included explanation as well.
> I have explained below, let me know if this thought process
> is valid or not.
>
> The replacement of all the_repository with s->repo in this patch are mostly
> to cases where a repository instance is already available via struct wt_status.
>
> In the current flow, all functions operating on struct wt_status *s
> are called via commit.c. There, status_init_config() calls
> wt_status_prepare(), which initializes the struct wt_status and
> assigns s->repo from the repository instance passed in by the caller.
> As a result, s->repo is guaranteed to be initialized whenever these
> functions are invoked.
>
> And commit.c itself still relies on the_repository, within wt-status.c,
> the local repository pointer refers to the same underlying
> repository object that the_repository would have pointed to, indirectly
> until we make commit.c also free of the_repository.
Good explanation, that would be a very useful addition to the commit message
>>> diff --git a/wt-status.c b/wt-status.c
>>> index e12adb26b9..9f4d8fda7f 100644
>>> --- a/wt-status.c
>>> +++ b/wt-status.c
>>> @@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
>>> s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
>>> s->use_color = GIT_COLOR_UNKNOWN;
>>> s->relative_paths = 1;
>>> - s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
>>> + s->branch = refs_resolve_refdup(get_main_ref_store(s->repo),
>>> "HEAD", 0, NULL, NULL);
>>
>> Wouldn't it make more sense to use the function argument 'r' here?
>
> In wt_status_prepare(), s->repo is initialized to r at the top of
> the function, so both refer to the same repository instance. However,
> using r directly is more explicit and avoids indirect use.
> will change this in V2.
Yes, a few more context lines makes it is clear that either is safe.
>>> @@ -1723,18 +1723,18 @@ int wt_status_check_rebase(const struct worktree *wt,
>>> {
>>> struct stat st;
>>>
>>> - if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
>>> - if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
>>> + if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply"), &st)) {
>>> + if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply/applying"), &st)) {
>>
>> In the same file we make a call 'wt_status_check_rebase(NULL, state)',
>> so wouldn't this break?
>
> Yes my bad, it would throw a segfault error.
> I think the best way to handle this is to explicitly check for the
> wt to be valid like this,
>
> if (wt==NULL)
> return 0;
That would change the behavior of the function though as it will no
longer check if the rebase directories exist. You should pass the
repository down from the caller.
Thanks for working on this
Phillip
> Falling back to the_repository in this case, would probably
> defeat the purpose.
>
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-03 9:53 ` Shreyansh Paliwal
@ 2026-02-03 11:06 ` Phillip Wood
2026-02-03 15:20 ` Shreyansh Paliwal
0 siblings, 1 reply; 69+ messages in thread
From: Phillip Wood @ 2026-02-03 11:06 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster, karthik.188
On 03/02/2026 09:53, Shreyansh Paliwal wrote:
>>
>> Clarification. This function is like an initializer for the struct
>> wt_status instance at 's', so it has to take both "struct repository"
>> parameter, but what I meant was other wt_status_foo() functions that
>> take both r and s as parameters. Once s has been initialized and
>> s->repo becomes valid, passing r as a separate parameter, as if you
>> can feed a different instance of "struct repo", becomes confusing
>> and a source of bugs.
>
> Actually wt_status_prepare() is the only function which is taking both
> struct wt_status *s and struct repository *r, because it has to initialize
> 's' with the help of 'r'.
> But all the other wt_status_.. helper functions only take one of the following,
> i.e. either they take struct wt_status *s which is fine, or they take
> struct repository *r.
You're correct, but I had the same reaction as Junio initially as I was
confused by the functions that take a "struct repository" and "struct
wt_status_state" which does not contain a repository, but at first
glance looks a lot like "struct wt_status" which does.
Thanks
Phillip
> If we trace the callers of the functions with struct repository *r,
> they are either being called in wt_status.c in which s->repo is being passed
> as a parameter at the end so it shouldn't cause any issues,
> and for any other file callers, the_repository is being passed,
> so to remove struct repository *r, we would have to setup struct wt_status
> in those files as well.
>
> Best,
> Shreyansh
>
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-03 10:58 ` Phillip Wood
@ 2026-02-03 15:15 ` Shreyansh Paliwal
0 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-03 15:15 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123
> > The replacement of all the_repository with s->repo in this patch are mostly
> > to cases where a repository instance is already available via struct wt_status.
> >
> > In the current flow, all functions operating on struct wt_status *s
> > are called via commit.c. There, status_init_config() calls
> > wt_status_prepare(), which initializes the struct wt_status and
> > assigns s->repo from the repository instance passed in by the caller.
> > As a result, s->repo is guaranteed to be initialized whenever these
> > functions are invoked.
> >
> > And commit.c itself still relies on the_repository, within wt-status.c,
> > the local repository pointer refers to the same underlying
> > repository object that the_repository would have pointed to, indirectly
> > until we make commit.c also free of the_repository.
>
> Good explanation, that would be a very useful addition to the commit message
Sure I will include this in v2.
> >>> @@ -1723,18 +1723,18 @@ int wt_status_check_rebase(const struct worktree *wt,
> >>> {
> >>> struct stat st;
> >>>
> >>> - if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
> >>> - if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
> >>> + if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply"), &st)) {
> >>> + if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply/applying"), &st)) {
> >>
> >> In the same file we make a call 'wt_status_check_rebase(NULL, state)',
> >> so wouldn't this break?
> >
> > Yes my bad, it would throw a segfault error.
> > I think the best way to handle this is to explicitly check for the
> > wt to be valid like this,
> >
> > if (wt==NULL)
> > return 0;
>
> That would change the behavior of the function though as it will no
> longer check if the rebase directories exist. You should pass the
> repository down from the caller.
Yes agreed.
I will pass s->repo as struct repository *r in this function. Thanks.
Best,
Shreyansh
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-03 11:06 ` Phillip Wood
@ 2026-02-03 15:20 ` Shreyansh Paliwal
0 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-03 15:20 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123
> On 03/02/2026 09:53, Shreyansh Paliwal wrote:
> >>
> >> Clarification. This function is like an initializer for the struct
> >> wt_status instance at 's', so it has to take both "struct repository"
> >> parameter, but what I meant was other wt_status_foo() functions that
> >> take both r and s as parameters. Once s has been initialized and
> >> s->repo becomes valid, passing r as a separate parameter, as if you
> >> can feed a different instance of "struct repo", becomes confusing
> >> and a source of bugs.
> >
> > Actually wt_status_prepare() is the only function which is taking both
> > struct wt_status *s and struct repository *r, because it has to initialize
> > 's' with the help of 'r'.
> > But all the other wt_status_.. helper functions only take one of the following,
> > i.e. either they take struct wt_status *s which is fine, or they take
> > struct repository *r.
>
> You're correct, but I had the same reaction as Junio initially as I was
> confused by the functions that take a "struct repository" and "struct
> wt_status_state" which does not contain a repository, but at first
> glance looks a lot like "struct wt_status" which does.
Ah, got it. Even I got confused by this once :)
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo
2026-02-02 19:03 ` Shreyansh Paliwal
@ 2026-02-04 10:18 ` Karthik Nayak
2026-02-04 11:22 ` Shreyansh Paliwal
0 siblings, 1 reply; 69+ messages in thread
From: Karthik Nayak @ 2026-02-04 10:18 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster
[-- Attachment #1: Type: text/plain, Size: 2034 bytes --]
Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>> > wt-status.c uses the global the_hash_algo even though a repository
>> > instance is already available via struct repository *r.
>> >
>> > Replace uses of the_hash_algo with the hash algorithm stored in the
>> > associated repository (r->hash_algo).
>> >
>> > This removes another dependency on global state and keeps wt-status
>> > consistent with local repository usage.
>> >
>>
>> One final question is, does this mean we can remove
>> `USE_THE_REPOSITORY_VARIABLE` after these changes? If not, why?
>
> We cannot remove `USE_THE_REPOSITORY_VARIABLE` yet, because the changes done only
> remove the direct use of the_hash_algo and the_repository,
> but 'USE_THE_REPOSITORY_VARIABLE' is for all the global variables
> that are still in use.
>
> In particular wt-status.c still relies on the following globals,
>
> * core_apply_sparse_checkout, this is already being addressed in an
> ongoing patch series [1], so I intentionally did not modify it.
>
> * comment_line_str and DEFAULT_ABBREV, these both still are used in
> wt-status.c but they dont have any local instance in wt-status.c,
> or in any other form.
>
Understandable.
> Removing these would require a wider refactoring (adding in struct wt_status,
> adding helper functions etc) and I believe is better handled as a separate patch series.
>
Yeah, my intent wasn't to have all the cleanup done in this series, but
rather to ensure we have enough information presented. You've already
explained the reason. It would be great if you could add this
information to the cover.
> Though I require some guidance on the preferred approach for handling
> comment_line_str and DEFAULT_ABBREV going forward.
>
Happy to help out. Generally using an RFC patch series generally has the
best outcome, since it provides material to base discussions on.
> Thanks for reviewing.
>
> Best,
> Shreyansh
>
> [1]- https://lore.kernel.org/git/5e56e1cc4172cfff9e917a068184e102aa70bf1d.1769256839.git.belkid98@gmail.com/t/#u
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo
2026-02-04 10:18 ` Karthik Nayak
@ 2026-02-04 11:22 ` Shreyansh Paliwal
0 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-04 11:22 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188
> > We cannot remove `USE_THE_REPOSITORY_VARIABLE` yet, because the changes done only
> > remove the direct use of the_hash_algo and the_repository,
> > but 'USE_THE_REPOSITORY_VARIABLE' is for all the global variables
> > that are still in use.
> >
> > In particular wt-status.c still relies on the following globals,
> >
> > * core_apply_sparse_checkout, this is already being addressed in an
> > ongoing patch series [1], so I intentionally did not modify it.
> >
> > * comment_line_str and DEFAULT_ABBREV, these both still are used in
> > wt-status.c but they dont have any local instance in wt-status.c,
> > or in any other form.
> >
>
> Understandable.
>
> > Removing these would require a wider refactoring (adding in struct wt_status,
> > adding helper functions etc) and I believe is better handled as a separate patch series.
> >
>
> Yeah, my intent wasn't to have all the cleanup done in this series, but
> rather to ensure we have enough information presented. You've already
> explained the reason. It would be great if you could add this
> information to the cover.
Yes sure, I will add in v2.
> > Though I require some guidance on the preferred approach for handling
> > comment_line_str and DEFAULT_ABBREV going forward.
> >
>
> Happy to help out. Generally using an RFC patch series generally has the
> best outcome, since it provides material to base discussions on.
Thanks, I will try to send an RFC patch series regarding this after the v2.
Best,
Shreyansh
^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH V2 0/3] wt-status: reduce reliance on global state
2026-01-31 18:57 [PATCH 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
` (2 preceding siblings ...)
2026-01-31 18:57 ` [PATCH 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
@ 2026-02-05 10:13 ` Shreyansh Paliwal
2026-02-05 10:13 ` [PATCH V2 1/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
` (4 more replies)
2026-02-17 17:29 ` [PATCH v4 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
2026-02-18 17:53 ` [PATCH v5 " Shreyansh Paliwal
5 siblings, 5 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-05 10:13 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123, Shreyansh Paliwal
In wt-status.c code still relies on some global variables, including
the_repository and the_hash_algo, even in cases where a repository
instance is already available via struct wt_status or struct worktree.
In patch 1/3, replace direct uses of the_repository with repository
instances already available in local structs.
In patch 2/3, update function parameters and calls to pass struct
repository or struct wt_status explicitly where no local repository
access was available.
In patch 3/3, replace remaining uses of the global the_hash_algo with the
hash algorithm stored in the respective repository instance.
These changes remove all direct uses of the_repository and
the_hash_algo from wt-status.c and reduce its dependence on global state.
The 'USE_THE_REPOSITORY_VARIABLE' macro cannot yet be removed, since these
patches only eliminate direct uses of the_repository and the_hash_algo,
while other global variables are still referenced.
In particular wt-status.c still relies on the following globals,
* core_apply_sparse_checkout, this is already being addressed in an
ongoing patch series [1].
* comment_line_str and DEFAULT_ABBREV, these both still are used in
wt-status.c but they dont have any equivalent local instances.
[1]- https://lore.kernel.org/git/5e56e1cc4172cfff9e917a068184e102aa70bf1d.1769256839.git.belkid98@gmail.com/t/#u
Shreyansh Paliwal (3):
wt-status: replace uses of the_repository with local repository
instances
wt-status: pass struct repository and wt_status through function
parameters
wt-status: use hash_algo from local repository instead of global
the_hash_algo
branch.c | 2 +-
worktree.c | 2 +-
wt-status.c | 85 +++++++++++++++++++++++++++--------------------------
wt-status.h | 5 ++--
4 files changed, 48 insertions(+), 46 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH V2 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-05 10:13 ` [PATCH V2 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
@ 2026-02-05 10:13 ` Shreyansh Paliwal
2026-02-05 10:59 ` Karthik Nayak
2026-02-05 10:13 ` [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters Shreyansh Paliwal
` (3 subsequent siblings)
4 siblings, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-05 10:13 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123, Shreyansh Paliwal
wt-status.c uses the global the_repository in several places even when
a repository instance is already available via struct wt_status or
struct worktree.
Replace these direct uses of the_repository with the repository carried
by the local structs (e.g. s->repo, wt->repo).
The replacements of all the_repository with s->repo are mostly
to cases where a repository instance is already available via
struct wt_status. All functions operating on struct wt_status *s
are only used after s is initialized by wt_status_prepare(),
which sets s->repo from the repository provided by the caller.
As a result, s->repo is guaranteed to be available and consistent
whenever these functions are invoked.
This reduces reliance on global state and keeps wt-status consistent,
though many functions operating on struct wt_status *s
are called via commit.c and it still relies on the_repository,
but within wt-status.c the local repository pointer
refers to the same underlying repository object.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
wt-status.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index e12adb26b9..f71addc35f 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
s->use_color = GIT_COLOR_UNKNOWN;
s->relative_paths = 1;
- s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
+ s->branch = refs_resolve_refdup(get_main_ref_store(r),
"HEAD", 0, NULL, NULL);
s->reference = "HEAD";
s->fp = stdout;
- s->index_file = repo_get_index_file(the_repository);
+ s->index_file = repo_get_index_file(s->repo);
s->change.strdup_strings = 1;
s->untracked.strdup_strings = 1;
s->ignored.strdup_strings = 1;
@@ -646,7 +646,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
repo_init_revisions(s->repo, &rev, NULL);
memset(&opt, 0, sizeof(opt));
- opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
+ opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.flags.override_submodule_config = 1;
@@ -1146,7 +1146,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
rev.diffopt.ita_invisible_in_index = 1;
memset(&opt, 0, sizeof(opt));
- opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
+ opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
@@ -1317,9 +1317,9 @@ static int split_commit_in_progress(struct wt_status *s)
!s->branch || strcmp(s->branch, "HEAD"))
return 0;
- if (refs_read_ref_full(get_main_ref_store(the_repository), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+ if (refs_read_ref_full(get_main_ref_store(s->repo), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
&head_oid, &head_flags) ||
- refs_read_ref_full(get_main_ref_store(the_repository), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+ refs_read_ref_full(get_main_ref_store(s->repo), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
&orig_head_oid, &orig_head_flags))
return 0;
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
@@ -1432,7 +1432,7 @@ static void show_rebase_information(struct wt_status *s,
i++)
status_printf_ln(s, color, " %s", have_done.items[i].string);
if (have_done.nr > nr_lines_to_show && s->hints) {
- char *path = repo_git_path(the_repository, "rebase-merge/done");
+ char *path = repo_git_path(s->repo, "rebase-merge/done");
status_printf_ln(s, color,
_(" (see more in file %s)"), path);
free(path);
@@ -1534,7 +1534,7 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
else
status_printf_ln(s, color,
_("You are currently cherry-picking commit %s."),
- repo_find_unique_abbrev(the_repository, &s->state.cherry_pick_head_oid,
+ repo_find_unique_abbrev(s->repo, &s->state.cherry_pick_head_oid,
DEFAULT_ABBREV));
if (s->hints) {
@@ -1564,7 +1564,7 @@ static void show_revert_in_progress(struct wt_status *s,
else
status_printf_ln(s, color,
_("You are currently reverting commit %s."),
- repo_find_unique_abbrev(the_repository, &s->state.revert_head_oid,
+ repo_find_unique_abbrev(s->repo, &s->state.revert_head_oid,
DEFAULT_ABBREV));
if (s->hints) {
if (has_unmerged(s))
@@ -1624,7 +1624,7 @@ static char *get_branch(const struct worktree *wt, const char *path)
struct object_id oid;
const char *branch_name;
- if (strbuf_read_file(&sb, worktree_git_path(the_repository, wt, "%s", path), 0) <= 0)
+ if (strbuf_read_file(&sb, worktree_git_path(wt->repo, wt, "%s", path), 0) <= 0)
goto got_nothing;
while (sb.len && sb.buf[sb.len - 1] == '\n')
@@ -1691,7 +1691,7 @@ static void wt_status_get_detached_from(struct repository *r,
char *ref = NULL;
strbuf_init(&cb.buf, 0);
- if (refs_for_each_reflog_ent_reverse(get_main_ref_store(the_repository), "HEAD", grab_1st_switch, &cb) <= 0) {
+ if (refs_for_each_reflog_ent_reverse(get_main_ref_store(r), "HEAD", grab_1st_switch, &cb) <= 0) {
strbuf_release(&cb.buf);
return;
}
@@ -1750,7 +1750,7 @@ int wt_status_check_bisect(const struct worktree *wt,
{
struct stat st;
- if (!stat(worktree_git_path(the_repository, wt, "BISECT_LOG"), &st)) {
+ if (!stat(worktree_git_path(wt->repo, wt, "BISECT_LOG"), &st)) {
state->bisect_in_progress = 1;
state->bisecting_from = get_branch(wt, "BISECT_START");
return 1;
@@ -2099,7 +2099,7 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
upstream_is_gone = 1;
}
- short_base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
+ short_base = refs_shorten_unambiguous_ref(get_main_ref_store(s->repo),
base, 0);
color_fprintf(s->fp, header_color, "...");
color_fprintf(s->fp, branch_color_remote, "%s", short_base);
@@ -2233,7 +2233,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
ab_info = stat_tracking_info(branch, &nr_ahead, &nr_behind,
&base, 0, s->ahead_behind_flags);
if (base) {
- base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
+ base = refs_shorten_unambiguous_ref(get_main_ref_store(s->repo),
base, 0);
fprintf(s->fp, "# branch.upstream %s%c", base, eol);
free((char *)base);
--
2.52.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-05 10:13 ` [PATCH V2 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
2026-02-05 10:13 ` [PATCH V2 1/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
@ 2026-02-05 10:13 ` Shreyansh Paliwal
2026-02-05 11:09 ` Karthik Nayak
2026-02-05 10:13 ` [PATCH V2 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
` (2 subsequent siblings)
4 siblings, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-05 10:13 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123, Shreyansh Paliwal
Some functions in wt-status.c relied on the_repository because no
repository instance was available in their local scope.
There is also a specific case in wt_status_check_rebase() where the
worktree can be NULL, so accessing wt->repo may lead to a segfault.
Update these functions to accept a struct repository or struct
wt_status parameter, and adjust callers accordingly. Replace the
remaining uses of the_repository in these functions with the
passed-in repository instance.
This removes the use of the_repository global variable from
wt-status.c completely.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
branch.c | 2 +-
worktree.c | 2 +-
wt-status.c | 51 ++++++++++++++++++++++++++-------------------------
wt-status.h | 5 +++--
4 files changed, 31 insertions(+), 29 deletions(-)
diff --git a/branch.c b/branch.c
index 243db7d0fc..9fe2df8cef 100644
--- a/branch.c
+++ b/branch.c
@@ -412,7 +412,7 @@ static void prepare_checked_out_branches(void)
free(old);
}
- if (wt_status_check_rebase(wt, &state) &&
+ if (wt_status_check_rebase(wt->repo, wt, &state) &&
(state.rebase_in_progress || state.rebase_interactive_in_progress) &&
state.branch) {
struct strbuf ref = STRBUF_INIT;
diff --git a/worktree.c b/worktree.c
index 9308389cb6..d05531813c 100644
--- a/worktree.c
+++ b/worktree.c
@@ -443,7 +443,7 @@ int is_worktree_being_rebased(const struct worktree *wt,
int found_rebase;
memset(&state, 0, sizeof(state));
- found_rebase = wt_status_check_rebase(wt, &state) &&
+ found_rebase = wt_status_check_rebase(wt->repo, wt, &state) &&
(state.rebase_in_progress ||
state.rebase_interactive_in_progress) &&
state.branch &&
diff --git a/wt-status.c b/wt-status.c
index f71addc35f..b008682043 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -984,17 +984,17 @@ static int stash_count_refs(const char *refname UNUSED,
return 0;
}
-static int count_stash_entries(void)
+static int count_stash_entries(struct repository *r)
{
int n = 0;
- refs_for_each_reflog_ent(get_main_ref_store(the_repository),
+ refs_for_each_reflog_ent(get_main_ref_store(r),
"refs/stash", stash_count_refs, &n);
return n;
}
static void wt_longstatus_print_stash_summary(struct wt_status *s)
{
- int stash_count = count_stash_entries();
+ int stash_count = count_stash_entries(s->repo);
if (stash_count > 0)
status_printf_ln(s, GIT_COLOR_NORMAL,
@@ -1287,10 +1287,10 @@ static void show_am_in_progress(struct wt_status *s,
wt_longstatus_print_trailer(s);
}
-static char *read_line_from_git_path(const char *filename)
+static char *read_line_from_git_path(struct repository *r, const char *filename)
{
struct strbuf buf = STRBUF_INIT;
- FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
+ FILE *fp = fopen_or_warn(repo_git_path_append(r, &buf,
"%s", filename), "r");
if (!fp) {
@@ -1325,8 +1325,8 @@ static int split_commit_in_progress(struct wt_status *s)
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
return 0;
- rebase_amend = read_line_from_git_path("rebase-merge/amend");
- rebase_orig_head = read_line_from_git_path("rebase-merge/orig-head");
+ rebase_amend = read_line_from_git_path(s->repo, "rebase-merge/amend");
+ rebase_orig_head = read_line_from_git_path(s->repo, "rebase-merge/orig-head");
if (!rebase_amend || !rebase_orig_head)
; /* fall through, no split in progress */
@@ -1350,7 +1350,7 @@ static int split_commit_in_progress(struct wt_status *s)
* The function assumes that the line does not contain useless spaces
* before or after the command.
*/
-static void abbrev_oid_in_line(struct strbuf *line)
+static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
{
struct string_list split = STRING_LIST_INIT_DUP;
struct object_id oid;
@@ -1362,7 +1362,7 @@ static void abbrev_oid_in_line(struct strbuf *line)
return;
if ((2 <= string_list_split(&split, line->buf, " ", 2)) &&
- !repo_get_oid(the_repository, split.items[1].string, &oid)) {
+ !repo_get_oid(r, split.items[1].string, &oid)) {
strbuf_reset(line);
strbuf_addf(line, "%s ", split.items[0].string);
strbuf_add_unique_abbrev(line, &oid, DEFAULT_ABBREV);
@@ -1372,10 +1372,10 @@ static void abbrev_oid_in_line(struct strbuf *line)
string_list_clear(&split, 0);
}
-static int read_rebase_todolist(const char *fname, struct string_list *lines)
+static int read_rebase_todolist(struct repository *r, const char *fname, struct string_list *lines)
{
struct strbuf buf = STRBUF_INIT;
- FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
+ FILE *f = fopen(repo_git_path_append(r, &buf, "%s", fname), "r");
int ret;
if (!f) {
@@ -1384,7 +1384,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)
goto out;
}
die_errno("Could not open file %s for reading",
- repo_git_path_replace(the_repository, &buf, "%s", fname));
+ repo_git_path_replace(r, &buf, "%s", fname));
}
while (!strbuf_getline_lf(&buf, f)) {
if (starts_with(buf.buf, comment_line_str))
@@ -1392,7 +1392,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)
strbuf_trim(&buf);
if (!buf.len)
continue;
- abbrev_oid_in_line(&buf);
+ abbrev_oid_in_line(r, &buf);
string_list_append(lines, buf.buf);
}
fclose(f);
@@ -1413,8 +1413,8 @@ static void show_rebase_information(struct wt_status *s,
struct string_list have_done = STRING_LIST_INIT_DUP;
struct string_list yet_to_do = STRING_LIST_INIT_DUP;
- read_rebase_todolist("rebase-merge/done", &have_done);
- if (read_rebase_todolist("rebase-merge/git-rebase-todo",
+ read_rebase_todolist(s->repo, "rebase-merge/done", &have_done);
+ if (read_rebase_todolist(s->repo, "rebase-merge/git-rebase-todo",
&yet_to_do))
status_printf_ln(s, color,
_("git-rebase-todo is missing."));
@@ -1718,23 +1718,24 @@ static void wt_status_get_detached_from(struct repository *r,
strbuf_release(&cb.buf);
}
-int wt_status_check_rebase(const struct worktree *wt,
- struct wt_status_state *state)
+int wt_status_check_rebase(struct repository *r,
+ const struct worktree *wt,
+ struct wt_status_state *state)
{
struct stat st;
- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
+ if (!stat(worktree_git_path(r, wt, "rebase-apply"), &st)) {
+ if (!stat(worktree_git_path(r, wt, "rebase-apply/applying"), &st)) {
state->am_in_progress = 1;
- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/patch"), &st) && !st.st_size)
+ if (!stat(worktree_git_path(r, wt, "rebase-apply/patch"), &st) && !st.st_size)
state->am_empty_patch = 1;
} else {
state->rebase_in_progress = 1;
state->branch = get_branch(wt, "rebase-apply/head-name");
state->onto = get_branch(wt, "rebase-apply/onto");
}
- } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
- if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
+ } else if (!stat(worktree_git_path(r, wt, "rebase-merge"), &st)) {
+ if (!stat(worktree_git_path(r, wt, "rebase-merge/interactive"), &st))
state->rebase_interactive_in_progress = 1;
else
state->rebase_in_progress = 1;
@@ -1797,9 +1798,9 @@ void wt_status_get_state(struct repository *r,
enum replay_action action;
if (!stat(git_path_merge_head(r), &st)) {
- wt_status_check_rebase(NULL, state);
+ wt_status_check_rebase(r, NULL, state);
state->merge_in_progress = 1;
- } else if (wt_status_check_rebase(NULL, state)) {
+ } else if (wt_status_check_rebase(r, NULL, state)) {
; /* all set */
} else if (refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&
!repo_get_oid(r, "CHERRY_PICK_HEAD", &oid)) {
@@ -2259,7 +2260,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
*/
static void wt_porcelain_v2_print_stash(struct wt_status *s)
{
- int stash_count = count_stash_entries();
+ int stash_count = count_stash_entries(s->repo);
char eol = s->null_termination ? '\0' : '\n';
if (stash_count > 0)
diff --git a/wt-status.h b/wt-status.h
index e40a27214a..110e3907f8 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -164,8 +164,9 @@ void wt_status_state_free_buffers(struct wt_status_state *s);
void wt_status_get_state(struct repository *repo,
struct wt_status_state *state,
int get_detached_from);
-int wt_status_check_rebase(const struct worktree *wt,
- struct wt_status_state *state);
+int wt_status_check_rebase(struct repository *r,
+ const struct worktree *wt,
+ struct wt_status_state *state);
int wt_status_check_bisect(const struct worktree *wt,
struct wt_status_state *state);
--
2.52.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH V2 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo
2026-02-05 10:13 ` [PATCH V2 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
2026-02-05 10:13 ` [PATCH V2 1/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
2026-02-05 10:13 ` [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters Shreyansh Paliwal
@ 2026-02-05 10:13 ` Shreyansh Paliwal
2026-02-05 10:27 ` [PATCH V2 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
2026-02-07 10:00 ` [PATCH v3 " Shreyansh Paliwal
4 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-05 10:13 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123, Shreyansh Paliwal
wt-status.c still uses the global the_hash_algo even though a repository
instance is already available via struct wt_status.
Replace uses of the_hash_algo with the hash algorithm stored in the
associated repository (s->repo->hash_algo or r->hash_algo).
This removes another dependency on global state and keeps wt-status
consistent with local repository usage.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
wt-status.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index b008682043..52dfd87919 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1816,10 +1816,10 @@ void wt_status_get_state(struct repository *r,
if (!sequencer_get_last_command(r, &action)) {
if (action == REPLAY_PICK && !state->cherry_pick_in_progress) {
state->cherry_pick_in_progress = 1;
- oidcpy(&state->cherry_pick_head_oid, null_oid(the_hash_algo));
+ oidcpy(&state->cherry_pick_head_oid, null_oid(r->hash_algo));
} else if (action == REPLAY_REVERT && !state->revert_in_progress) {
state->revert_in_progress = 1;
- oidcpy(&state->revert_head_oid, null_oid(the_hash_algo));
+ oidcpy(&state->revert_head_oid, null_oid(r->hash_algo));
}
}
if (get_detached_from)
@@ -2631,7 +2631,7 @@ int has_uncommitted_changes(struct repository *r,
* We have no head (or it's corrupt); use the empty tree,
* which will complain if the index is non-empty.
*/
- struct tree *tree = lookup_tree(r, the_hash_algo->empty_tree);
+ struct tree *tree = lookup_tree(r, r->hash_algo->empty_tree);
add_pending_object(&rev_info, &tree->object, "");
}
--
2.52.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* Re: [PATCH V2 0/3] wt-status: reduce reliance on global state
2026-02-05 10:13 ` [PATCH V2 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
` (2 preceding siblings ...)
2026-02-05 10:13 ` [PATCH V2 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
@ 2026-02-05 10:27 ` Shreyansh Paliwal
2026-02-05 15:53 ` Phillip Wood
2026-02-07 10:00 ` [PATCH v3 " Shreyansh Paliwal
4 siblings, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-05 10:27 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123
I forgot to include the changes in the version.
Changes in V2,
- Explained the changes and the reason more elaborately in commit message.
- Passed struct repository instead of accessing struct worktree in
wt_status_check_rebase() and shifted this change to patch 2/3 instead of 1/3.
- Added information about leftover globals in the cover.
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-05 10:13 ` [PATCH V2 1/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
@ 2026-02-05 10:59 ` Karthik Nayak
2026-02-05 11:11 ` Karthik Nayak
0 siblings, 1 reply; 69+ messages in thread
From: Karthik Nayak @ 2026-02-05 10:59 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster, phillip.wood123
[-- Attachment #1: Type: text/plain, Size: 5864 bytes --]
Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
> wt-status.c uses the global the_repository in several places even when
> a repository instance is already available via struct wt_status or
> struct worktree.
>
> Replace these direct uses of the_repository with the repository carried
> by the local structs (e.g. s->repo, wt->repo).
>
> The replacements of all the_repository with s->repo are mostly
> to cases where a repository instance is already available via
> struct wt_status. All functions operating on struct wt_status *s
> are only used after s is initialized by wt_status_prepare(),
> which sets s->repo from the repository provided by the caller.
> As a result, s->repo is guaranteed to be available and consistent
> whenever these functions are invoked.
>
> This reduces reliance on global state and keeps wt-status consistent,
> though many functions operating on struct wt_status *s
> are called via commit.c and it still relies on the_repository,
> but within wt-status.c the local repository pointer
> refers to the same underlying repository object.
>
> Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
> ---
> wt-status.c | 28 ++++++++++++++--------------
> 1 file changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/wt-status.c b/wt-status.c
> index e12adb26b9..f71addc35f 100644
> --- a/wt-status.c
> +++ b/wt-status.c
> @@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
> s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
> s->use_color = GIT_COLOR_UNKNOWN;
> s->relative_paths = 1;
> - s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
> + s->branch = refs_resolve_refdup(get_main_ref_store(r),
> "HEAD", 0, NULL, NULL);
> s->reference = "HEAD";
> s->fp = stdout;
> - s->index_file = repo_get_index_file(the_repository);
> + s->index_file = repo_get_index_file(s->repo);
> s->change.strdup_strings = 1;
> s->untracked.strdup_strings = 1;
> s->ignored.strdup_strings = 1;
> @@ -646,7 +646,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
>
> repo_init_revisions(s->repo, &rev, NULL);
> memset(&opt, 0, sizeof(opt));
> - opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
> + opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
> setup_revisions(0, NULL, &rev, &opt);
>
> rev.diffopt.flags.override_submodule_config = 1;
> @@ -1146,7 +1146,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
> rev.diffopt.ita_invisible_in_index = 1;
>
> memset(&opt, 0, sizeof(opt));
> - opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
> + opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
> setup_revisions(0, NULL, &rev, &opt);
>
> rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
> @@ -1317,9 +1317,9 @@ static int split_commit_in_progress(struct wt_status *s)
> !s->branch || strcmp(s->branch, "HEAD"))
> return 0;
>
> - if (refs_read_ref_full(get_main_ref_store(the_repository), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
> + if (refs_read_ref_full(get_main_ref_store(s->repo), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
> &head_oid, &head_flags) ||
> - refs_read_ref_full(get_main_ref_store(the_repository), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
> + refs_read_ref_full(get_main_ref_store(s->repo), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
> &orig_head_oid, &orig_head_flags))
> return 0;
> if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
> @@ -1432,7 +1432,7 @@ static void show_rebase_information(struct wt_status *s,
> i++)
> status_printf_ln(s, color, " %s", have_done.items[i].string);
> if (have_done.nr > nr_lines_to_show && s->hints) {
> - char *path = repo_git_path(the_repository, "rebase-merge/done");
> + char *path = repo_git_path(s->repo, "rebase-merge/done");
> status_printf_ln(s, color,
> _(" (see more in file %s)"), path);
> free(path);
> @@ -1534,7 +1534,7 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
> else
> status_printf_ln(s, color,
> _("You are currently cherry-picking commit %s."),
> - repo_find_unique_abbrev(the_repository, &s->state.cherry_pick_head_oid,
> + repo_find_unique_abbrev(s->repo, &s->state.cherry_pick_head_oid,
> DEFAULT_ABBREV));
>
> if (s->hints) {
> @@ -1564,7 +1564,7 @@ static void show_revert_in_progress(struct wt_status *s,
> else
> status_printf_ln(s, color,
> _("You are currently reverting commit %s."),
> - repo_find_unique_abbrev(the_repository, &s->state.revert_head_oid,
> + repo_find_unique_abbrev(s->repo, &s->state.revert_head_oid,
> DEFAULT_ABBREV));
> if (s->hints) {
> if (has_unmerged(s))
> @@ -1624,7 +1624,7 @@ static char *get_branch(const struct worktree *wt, const char *path)
> struct object_id oid;
> const char *branch_name;
>
> - if (strbuf_read_file(&sb, worktree_git_path(the_repository, wt, "%s", path), 0) <= 0)
> + if (strbuf_read_file(&sb, worktree_git_path(wt->repo, wt, "%s", path), 0) <= 0)
> goto got_nothing;
>
So if you look into `worktree_git_path()`, it has a certain check
if (wt && wt->repo != r)
BUG("worktree not connected to expected repository");
But this is okay with your change, the only question is, do we know wt
is always defined here? Unfortunately, wt can be NULL here, in the same
file we have:
wt_status_check_rebase(NULL, state);
-> get_branch(NULL, ...)
Which would crash, no? This is applicable for other parts of the code
too were we're now using wt->repo.
This is also what I was requesting in the previous round, about
explaining why it is safe to make a particular change.
[snip]
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-05 10:13 ` [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters Shreyansh Paliwal
@ 2026-02-05 11:09 ` Karthik Nayak
2026-02-05 12:04 ` Shreyansh Paliwal
2026-02-05 15:58 ` Phillip Wood
0 siblings, 2 replies; 69+ messages in thread
From: Karthik Nayak @ 2026-02-05 11:09 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster, phillip.wood123
[-- Attachment #1: Type: text/plain, Size: 830 bytes --]
Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
> Some functions in wt-status.c relied on the_repository because no
> repository instance was available in their local scope.
> There is also a specific case in wt_status_check_rebase() where the
> worktree can be NULL, so accessing wt->repo may lead to a segfault.
>
> Update these functions to accept a struct repository or struct
> wt_status parameter, and adjust callers accordingly. Replace the
> remaining uses of the_repository in these functions with the
> passed-in repository instance.
>
> This removes the use of the_repository global variable from
> wt-status.c completely.
>
Okay, but this doesn't fix the issue I stated in the previous commit. I
do wonder if we can re-order the commits and pass the repo struct to
functions like 'get_branch()'.
[snip]
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-05 10:59 ` Karthik Nayak
@ 2026-02-05 11:11 ` Karthik Nayak
2026-02-05 12:18 ` Shreyansh Paliwal
0 siblings, 1 reply; 69+ messages in thread
From: Karthik Nayak @ 2026-02-05 11:11 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster, phillip.wood123
[-- Attachment #1: Type: text/plain, Size: 6253 bytes --]
Karthik Nayak <karthik.188@gmail.com> writes:
> Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>
>> wt-status.c uses the global the_repository in several places even when
>> a repository instance is already available via struct wt_status or
>> struct worktree.
>>
>> Replace these direct uses of the_repository with the repository carried
>> by the local structs (e.g. s->repo, wt->repo).
>>
>> The replacements of all the_repository with s->repo are mostly
>> to cases where a repository instance is already available via
>> struct wt_status. All functions operating on struct wt_status *s
>> are only used after s is initialized by wt_status_prepare(),
>> which sets s->repo from the repository provided by the caller.
>> As a result, s->repo is guaranteed to be available and consistent
>> whenever these functions are invoked.
>>
>> This reduces reliance on global state and keeps wt-status consistent,
>> though many functions operating on struct wt_status *s
>> are called via commit.c and it still relies on the_repository,
>> but within wt-status.c the local repository pointer
>> refers to the same underlying repository object.
>>
>> Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
>> ---
>> wt-status.c | 28 ++++++++++++++--------------
>> 1 file changed, 14 insertions(+), 14 deletions(-)
>>
>> diff --git a/wt-status.c b/wt-status.c
>> index e12adb26b9..f71addc35f 100644
>> --- a/wt-status.c
>> +++ b/wt-status.c
>> @@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
>> s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
>> s->use_color = GIT_COLOR_UNKNOWN;
>> s->relative_paths = 1;
>> - s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
>> + s->branch = refs_resolve_refdup(get_main_ref_store(r),
>> "HEAD", 0, NULL, NULL);
>> s->reference = "HEAD";
>> s->fp = stdout;
>> - s->index_file = repo_get_index_file(the_repository);
>> + s->index_file = repo_get_index_file(s->repo);
>> s->change.strdup_strings = 1;
>> s->untracked.strdup_strings = 1;
>> s->ignored.strdup_strings = 1;
>> @@ -646,7 +646,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
>>
>> repo_init_revisions(s->repo, &rev, NULL);
>> memset(&opt, 0, sizeof(opt));
>> - opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
>> + opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
>> setup_revisions(0, NULL, &rev, &opt);
>>
>> rev.diffopt.flags.override_submodule_config = 1;
>> @@ -1146,7 +1146,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
>> rev.diffopt.ita_invisible_in_index = 1;
>>
>> memset(&opt, 0, sizeof(opt));
>> - opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
>> + opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
>> setup_revisions(0, NULL, &rev, &opt);
>>
>> rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
>> @@ -1317,9 +1317,9 @@ static int split_commit_in_progress(struct wt_status *s)
>> !s->branch || strcmp(s->branch, "HEAD"))
>> return 0;
>>
>> - if (refs_read_ref_full(get_main_ref_store(the_repository), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
>> + if (refs_read_ref_full(get_main_ref_store(s->repo), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
>> &head_oid, &head_flags) ||
>> - refs_read_ref_full(get_main_ref_store(the_repository), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
>> + refs_read_ref_full(get_main_ref_store(s->repo), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
>> &orig_head_oid, &orig_head_flags))
>> return 0;
>> if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
>> @@ -1432,7 +1432,7 @@ static void show_rebase_information(struct wt_status *s,
>> i++)
>> status_printf_ln(s, color, " %s", have_done.items[i].string);
>> if (have_done.nr > nr_lines_to_show && s->hints) {
>> - char *path = repo_git_path(the_repository, "rebase-merge/done");
>> + char *path = repo_git_path(s->repo, "rebase-merge/done");
>> status_printf_ln(s, color,
>> _(" (see more in file %s)"), path);
>> free(path);
>> @@ -1534,7 +1534,7 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
>> else
>> status_printf_ln(s, color,
>> _("You are currently cherry-picking commit %s."),
>> - repo_find_unique_abbrev(the_repository, &s->state.cherry_pick_head_oid,
>> + repo_find_unique_abbrev(s->repo, &s->state.cherry_pick_head_oid,
>> DEFAULT_ABBREV));
>>
>> if (s->hints) {
>> @@ -1564,7 +1564,7 @@ static void show_revert_in_progress(struct wt_status *s,
>> else
>> status_printf_ln(s, color,
>> _("You are currently reverting commit %s."),
>> - repo_find_unique_abbrev(the_repository, &s->state.revert_head_oid,
>> + repo_find_unique_abbrev(s->repo, &s->state.revert_head_oid,
>> DEFAULT_ABBREV));
>> if (s->hints) {
>> if (has_unmerged(s))
>> @@ -1624,7 +1624,7 @@ static char *get_branch(const struct worktree *wt, const char *path)
>> struct object_id oid;
>> const char *branch_name;
>>
>> - if (strbuf_read_file(&sb, worktree_git_path(the_repository, wt, "%s", path), 0) <= 0)
>> + if (strbuf_read_file(&sb, worktree_git_path(wt->repo, wt, "%s", path), 0) <= 0)
>> goto got_nothing;
>>
>
> So if you look into `worktree_git_path()`, it has a certain check
>
> if (wt && wt->repo != r)
> BUG("worktree not connected to expected repository");
>
> But this is okay with your change, the only question is, do we know wt
> is always defined here? Unfortunately, wt can be NULL here, in the same
> file we have:
>
> wt_status_check_rebase(NULL, state);
> -> get_branch(NULL, ...)
>
> Which would crash, no? This is applicable for other parts of the code
> too were we're now using wt->repo.
>
> This is also what I was requesting in the previous round, about
> explaining why it is safe to make a particular change.
>
> [snip]
One question, did you run the entire test suite with these changes? I
would hope that we have tests which would fail if my inference is
correct. If not, there's a gap in our tests too.
- Karthik
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-05 11:09 ` Karthik Nayak
@ 2026-02-05 12:04 ` Shreyansh Paliwal
2026-02-06 9:24 ` Karthik Nayak
2026-02-05 15:58 ` Phillip Wood
1 sibling, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-05 12:04 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 1391 bytes --]
> > Some functions in wt-status.c relied on the_repository because no
> > repository instance was available in their local scope.
> > There is also a specific case in wt_status_check_rebase() where the
> > worktree can be NULL, so accessing wt->repo may lead to a segfault.
> >
> > Update these functions to accept a struct repository or struct
> > wt_status parameter, and adjust callers accordingly. Replace the
> > remaining uses of the_repository in these functions with the
> > passed-in repository instance.
> >
> > This removes the use of the_repository global variable from
> > wt-status.c completely.
> >
>
> Okay, but this doesn't fix the issue I stated in the previous commit. I
> do wonder if we can re-order the commits and pass the repo struct to
> functions like 'get_branch()'.
Sorry, I didn’t fully think through what you were pointing out in the
previous version. I initially assumed you were only referring to the
specific call involving wt_status_check_rebase(NULL, state).
So struct worktree *wt is not guaranteed to be defined and can be
NULL. Because of that, relying on wt->repo is unsafe.
Instead, rather than depending on the worktree for repository access (wt->repo),
we can pass struct repository explicitly through the relevant call
stack, like in functions get_branch() and wt_status_check_bisect().
I hope I have understood it correctly.
Best,
Shreyansh
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-05 11:11 ` Karthik Nayak
@ 2026-02-05 12:18 ` Shreyansh Paliwal
2026-02-05 16:08 ` Phillip Wood
0 siblings, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-05 12:18 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 1283 bytes --]
[...]
> >> + if (strbuf_read_file(&sb, worktree_git_path(wt->repo, wt, "%s", path), 0) <= 0)
> >> goto got_nothing;
> >>
> >
> > So if you look into `worktree_git_path()`, it has a certain check
> >
> > if (wt && wt->repo != r)
> > BUG("worktree not connected to expected repository");
> >
> > But this is okay with your change, the only question is, do we know wt
> > is always defined here? Unfortunately, wt can be NULL here, in the same
> > file we have:
> >
> > wt_status_check_rebase(NULL, state);
> > -> get_branch(NULL, ...)
> >
> > Which would crash, no? This is applicable for other parts of the code
> > too were we're now using wt->repo.
> >
> > This is also what I was requesting in the previous round, about
> > explaining why it is safe to make a particular change.
> >
> > [snip]
>
> One question, did you run the entire test suite with these changes? I
> would hope that we have tests which would fail if my inference is
> correct. If not, there's a gap in our tests too.
You’re right, I hadn’t run the tests initially, as I assumed
this was a refactor-only change.
After running the tests, I do see failures, which confirms the issue.
I’ll make sure to always run the tests before sending a patch going
forward.
Thanks for pointing this out :)
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 0/3] wt-status: reduce reliance on global state
2026-02-05 10:27 ` [PATCH V2 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
@ 2026-02-05 15:53 ` Phillip Wood
2026-02-05 17:39 ` Shreyansh Paliwal
0 siblings, 1 reply; 69+ messages in thread
From: Phillip Wood @ 2026-02-05 15:53 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster, karthik.188
On 05/02/2026 10:27, Shreyansh Paliwal wrote:
> I forgot to include the changes in the version.
>
> Changes in V2,
> - Explained the changes and the reason more elaborately in commit message.
> - Passed struct repository instead of accessing struct worktree in
> wt_status_check_rebase() and shifted this change to patch 2/3 instead of 1/3.
> - Added information about leftover globals in the cover.
As well as describing the changes it is very helpful to include a range-diff to
show what's changed - see the --range-diff option to "git format-patch". I've
pasted the range-diff between V1 and V2 below
Thanks
Phillip
1: 1bf5449c7a8 ! 1: 7285c64e672 wt-status: replace uses of the_repository with local repository instances
@@ Metadata
## Commit message ##
wt-status: replace uses of the_repository with local repository instances
- Many instances of the_repository are used in wt-status.c even when a
- local repository is already available via struct wt_status or struct
- worktree.
-
- Replace direct uses of the global the_repository with the repository
- instance carried by the local structs (e.g. s->repo, wt->repo).
-
- This helps reduce reliance on global repository state.
+ wt-status.c uses the global the_repository in several places even when
+ a repository instance is already available via struct wt_status or
+ struct worktree.
+
+ Replace these direct uses of the_repository with the repository carried
+ by the local structs (e.g. s->repo, wt->repo).
+
+ The replacements of all the_repository with s->repo are mostly
+ to cases where a repository instance is already available via
+ struct wt_status. All functions operating on struct wt_status *s
+ are only used after s is initialized by wt_status_prepare(),
+ which sets s->repo from the repository provided by the caller.
+ As a result, s->repo is guaranteed to be available and consistent
+ whenever these functions are invoked.
+
+ This reduces reliance on global state and keeps wt-status consistent,
+ though many functions operating on struct wt_status *s
+ are called via commit.c and it still relies on the_repository,
+ but within wt-status.c the local repository pointer
+ refers to the same underlying repository object.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
@@ wt-status.c: void wt_status_prepare(struct repository *r, struct wt_status *s)
s->use_color = GIT_COLOR_UNKNOWN;
s->relative_paths = 1;
- s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
-+ s->branch = refs_resolve_refdup(get_main_ref_store(s->repo),
++ s->branch = refs_resolve_refdup(get_main_ref_store(r),
"HEAD", 0, NULL, NULL);
s->reference = "HEAD";
s->fp = stdout;
@@ wt-status.c: static void wt_status_get_detached_from(struct repository *r,
strbuf_release(&cb.buf);
return;
}
-@@ wt-status.c: int wt_status_check_rebase(const struct worktree *wt,
- {
- struct stat st;
-
-- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
-- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
-+ if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply"), &st)) {
-+ if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply/applying"), &st)) {
- state->am_in_progress = 1;
-- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/patch"), &st) && !st.st_size)
-+ if (!stat(worktree_git_path(wt->repo, wt, "rebase-apply/patch"), &st) && !st.st_size)
- state->am_empty_patch = 1;
- } else {
- state->rebase_in_progress = 1;
- state->branch = get_branch(wt, "rebase-apply/head-name");
- state->onto = get_branch(wt, "rebase-apply/onto");
- }
-- } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
-- if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
-+ } else if (!stat(worktree_git_path(wt->repo, wt, "rebase-merge"), &st)) {
-+ if (!stat(worktree_git_path(wt->repo, wt, "rebase-merge/interactive"), &st))
- state->rebase_interactive_in_progress = 1;
- else
- state->rebase_in_progress = 1;
@@ wt-status.c: int wt_status_check_bisect(const struct worktree *wt,
{
struct stat st;
2: 8a0b489c3be ! 2: 0a04c957f12 wt-status: pass struct repository and wt_status through function parameters
@@ Commit message
Some functions in wt-status.c relied on the_repository because no
repository instance was available in their local scope.
-
- Update these functions to accept struct repository or struct
- wt_status as parameters, and adjust callers accordingly.
-
- Replace remaining uses of the_repository in these functions with the
+ There is also a specific case in wt_status_check_rebase() where the
+ worktree can be NULL, so accessing wt->repo may lead to a segfault.
+
+ Update these functions to accept a struct repository or struct
+ wt_status parameter, and adjust callers accordingly. Replace the
+ remaining uses of the_repository in these functions with the
passed-in repository instance.
- This completely removes the use of the_repository global variable
- in wt-status.c.
+ This removes the use of the_repository global variable from
+ wt-status.c completely.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
+ ## branch.c ##
+@@ branch.c: static void prepare_checked_out_branches(void)
+ free(old);
+ }
+
+- if (wt_status_check_rebase(wt, &state) &&
++ if (wt_status_check_rebase(wt->repo, wt, &state) &&
+ (state.rebase_in_progress || state.rebase_interactive_in_progress) &&
+ state.branch) {
+ struct strbuf ref = STRBUF_INIT;
+
+ ## worktree.c ##
+@@ worktree.c: int is_worktree_being_rebased(const struct worktree *wt,
+ int found_rebase;
+
+ memset(&state, 0, sizeof(state));
+- found_rebase = wt_status_check_rebase(wt, &state) &&
++ found_rebase = wt_status_check_rebase(wt->repo, wt, &state) &&
+ (state.rebase_in_progress ||
+ state.rebase_interactive_in_progress) &&
+ state.branch &&
+
## wt-status.c ##
@@ wt-status.c: static int stash_count_refs(const char *refname UNUSED,
return 0;
@@ wt-status.c: static void show_rebase_information(struct wt_status *s,
&yet_to_do))
status_printf_ln(s, color,
_("git-rebase-todo is missing."));
+@@ wt-status.c: static void wt_status_get_detached_from(struct repository *r,
+ strbuf_release(&cb.buf);
+ }
+
+-int wt_status_check_rebase(const struct worktree *wt,
+- struct wt_status_state *state)
++int wt_status_check_rebase(struct repository *r,
++ const struct worktree *wt,
++ struct wt_status_state *state)
+ {
+ struct stat st;
+
+- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
+- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
++ if (!stat(worktree_git_path(r, wt, "rebase-apply"), &st)) {
++ if (!stat(worktree_git_path(r, wt, "rebase-apply/applying"), &st)) {
+ state->am_in_progress = 1;
+- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/patch"), &st) && !st.st_size)
++ if (!stat(worktree_git_path(r, wt, "rebase-apply/patch"), &st) && !st.st_size)
+ state->am_empty_patch = 1;
+ } else {
+ state->rebase_in_progress = 1;
+ state->branch = get_branch(wt, "rebase-apply/head-name");
+ state->onto = get_branch(wt, "rebase-apply/onto");
+ }
+- } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
+- if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
++ } else if (!stat(worktree_git_path(r, wt, "rebase-merge"), &st)) {
++ if (!stat(worktree_git_path(r, wt, "rebase-merge/interactive"), &st))
+ state->rebase_interactive_in_progress = 1;
+ else
+ state->rebase_in_progress = 1;
+@@ wt-status.c: void wt_status_get_state(struct repository *r,
+ enum replay_action action;
+
+ if (!stat(git_path_merge_head(r), &st)) {
+- wt_status_check_rebase(NULL, state);
++ wt_status_check_rebase(r, NULL, state);
+ state->merge_in_progress = 1;
+- } else if (wt_status_check_rebase(NULL, state)) {
++ } else if (wt_status_check_rebase(r, NULL, state)) {
+ ; /* all set */
+ } else if (refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&
+ !repo_get_oid(r, "CHERRY_PICK_HEAD", &oid)) {
@@ wt-status.c: static void wt_porcelain_v2_print_tracking(struct wt_status *s)
*/
static void wt_porcelain_v2_print_stash(struct wt_status *s)
@@ wt-status.c: static void wt_porcelain_v2_print_tracking(struct wt_status *s)
char eol = s->null_termination ? '\0' : '\n';
if (stash_count > 0)
+
+ ## wt-status.h ##
+@@ wt-status.h: void wt_status_state_free_buffers(struct wt_status_state *s);
+ void wt_status_get_state(struct repository *repo,
+ struct wt_status_state *state,
+ int get_detached_from);
+-int wt_status_check_rebase(const struct worktree *wt,
+- struct wt_status_state *state);
++int wt_status_check_rebase(struct repository *r,
++ const struct worktree *wt,
++ struct wt_status_state *state);
+ int wt_status_check_bisect(const struct worktree *wt,
+ struct wt_status_state *state);
+
3: e2cf365bad5 ! 3: 74b28d95299 wt-status: use hash_algo from local repository instead of global the_hash_algo
@@ Metadata
## Commit message ##
wt-status: use hash_algo from local repository instead of global the_hash_algo
- wt-status.c uses the global the_hash_algo even though a repository
- instance is already available via struct repository *r.
+ wt-status.c still uses the global the_hash_algo even though a repository
+ instance is already available via struct wt_status.
Replace uses of the_hash_algo with the hash algorithm stored in the
- associated repository (r->hash_algo).
+ associated repository (s->repo->hash_algo or r->hash_algo).
This removes another dependency on global state and keeps wt-status
consistent with local repository usage.
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-05 11:09 ` Karthik Nayak
2026-02-05 12:04 ` Shreyansh Paliwal
@ 2026-02-05 15:58 ` Phillip Wood
1 sibling, 0 replies; 69+ messages in thread
From: Phillip Wood @ 2026-02-05 15:58 UTC (permalink / raw)
To: Karthik Nayak, Shreyansh Paliwal, git; +Cc: gitster
On 05/02/2026 11:09, Karthik Nayak wrote:
> Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>
>> Some functions in wt-status.c relied on the_repository because no
>> repository instance was available in their local scope.
>> There is also a specific case in wt_status_check_rebase() where the
>> worktree can be NULL, so accessing wt->repo may lead to a segfault.
>>
>> Update these functions to accept a struct repository or struct
>> wt_status parameter, and adjust callers accordingly.
These callers pass wt->repo so it's important to explain that the
callers all have a non-NULL worktree instance so passing wt->repo to
wt_status_check_rebase() is safe.
>> Replace the
>> remaining uses of the_repository in these functions with the
>> passed-in repository instance.
>>
>> This removes the use of the_repository global variable from
>> wt-status.c completely.
>>
>
> Okay, but this doesn't fix the issue I stated in the previous commit. I
> do wonder if we can re-order the commits and pass the repo struct to
> functions like 'get_branch()'.
That sounds like a good suggestion
Thanks
Phillip
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-05 12:18 ` Shreyansh Paliwal
@ 2026-02-05 16:08 ` Phillip Wood
2026-02-05 17:41 ` Shreyansh Paliwal
0 siblings, 1 reply; 69+ messages in thread
From: Phillip Wood @ 2026-02-05 16:08 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster, karthik.188
On 05/02/2026 12:18, Shreyansh Paliwal wrote:
>>
>> One question, did you run the entire test suite with these changes? I
>> would hope that we have tests which would fail if my inference is
>> correct. If not, there's a gap in our tests too.
>
> You’re right, I hadn’t run the tests initially, as I assumed
> this was a refactor-only change.
The whole point of regression tests is to check that refactors do not
change the behavior. If you have an account on github or gitlab there
are some instructions for setting the up the CI to run when you push in
Documentation/SumbittingPatches.
Thanks
Phillip
>
> After running the tests, I do see failures, which confirms the issue.
> I’ll make sure to always run the tests before sending a patch going
> forward.
>
> Thanks for pointing this out :)
>
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 0/3] wt-status: reduce reliance on global state
2026-02-05 15:53 ` Phillip Wood
@ 2026-02-05 17:39 ` Shreyansh Paliwal
2026-02-05 18:02 ` Kristoffer Haugsbakk
0 siblings, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-05 17:39 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123
> On 05/02/2026 10:27, Shreyansh Paliwal wrote:
> > I forgot to include the changes in the version.
> >
> > Changes in V2,
> > - Explained the changes and the reason more elaborately in commit message.
> > - Passed struct repository instead of accessing struct worktree in
> > wt_status_check_rebase() and shifted this change to patch 2/3 instead of 1/3.
> > - Added information about leftover globals in the cover.
>
> As well as describing the changes it is very helpful to include a range-diff to
> show what's changed - see the --range-diff option to "git format-patch". I've
> pasted the range-diff between V1 and V2 below
Thanks, I will keep this in mind.
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 1/3] wt-status: replace uses of the_repository with local repository instances
2026-02-05 16:08 ` Phillip Wood
@ 2026-02-05 17:41 ` Shreyansh Paliwal
0 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-05 17:41 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 670 bytes --]
> On 05/02/2026 12:18, Shreyansh Paliwal wrote:
> >>
> >> One question, did you run the entire test suite with these changes? I
> >> would hope that we have tests which would fail if my inference is
> >> correct. If not, there's a gap in our tests too.
> >
> > You’re right, I hadn’t run the tests initially, as I assumed
> > this was a refactor-only change.
>
> The whole point of regression tests is to check that refactors do not
> change the behavior. If you have an account on github or gitlab there
> are some instructions for setting the up the CI to run when you push in
> Documentation/SumbittingPatches.
Got it, I will look into it.
Best,
Shreyansh
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 0/3] wt-status: reduce reliance on global state
2026-02-05 17:39 ` Shreyansh Paliwal
@ 2026-02-05 18:02 ` Kristoffer Haugsbakk
2026-02-05 18:18 ` Shreyansh Paliwal
0 siblings, 1 reply; 69+ messages in thread
From: Kristoffer Haugsbakk @ 2026-02-05 18:02 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: Junio C Hamano, Karthik Nayak, Phillip Wood
On Thu, Feb 5, 2026, at 18:39, Shreyansh Paliwal wrote:
>>[snip]
>> As well as describing the changes it is very helpful to include a range-diff to
>> show what's changed - see the --range-diff option to "git format-patch". I've
>> pasted the range-diff between V1 and V2 below
>
> Thanks, I will keep this in mind.
I’m personally a happy user of `--interdiff` in addition. It’s a nice
supplement. :)
https://lore.kernel.org/git/CAPig+cSErj4ZB9bHB8mZfzNkiaN_EpjT6b4b=cfsf_+KMqytiA@mail.gmail.com/
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 0/3] wt-status: reduce reliance on global state
2026-02-05 18:02 ` Kristoffer Haugsbakk
@ 2026-02-05 18:18 ` Shreyansh Paliwal
0 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-05 18:18 UTC (permalink / raw)
To: git; +Cc: gitster, kristofferhaugsbakk, karthik.188, phillip.wood123
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 572 bytes --]
> On Thu, Feb 5, 2026, at 18:39, Shreyansh Paliwal wrote:
> >>[snip]
> >> As well as describing the changes it is very helpful to include a range-diff to
> >> show what's changed - see the --range-diff option to "git format-patch". I've
> >> pasted the range-diff between V1 and V2 below
> >
> > Thanks, I will keep this in mind.
>
> I’m personally a happy user of `--interdiff` in addition. It’s a nice
> supplement. :)
>
> https://lore.kernel.org/git/CAPig+cSErj4ZB9bHB8mZfzNkiaN_EpjT6b4b=cfsf_+KMqytiA@mail.gmail.com/
Sounds good, I will try out both in the v3.
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-05 12:04 ` Shreyansh Paliwal
@ 2026-02-06 9:24 ` Karthik Nayak
2026-02-06 9:32 ` Shreyansh Paliwal
0 siblings, 1 reply; 69+ messages in thread
From: Karthik Nayak @ 2026-02-06 9:24 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster, phillip.wood123
[-- Attachment #1: Type: text/plain, Size: 1793 bytes --]
Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>> > Some functions in wt-status.c relied on the_repository because no
>> > repository instance was available in their local scope.
>> > There is also a specific case in wt_status_check_rebase() where the
>> > worktree can be NULL, so accessing wt->repo may lead to a segfault.
>> >
>> > Update these functions to accept a struct repository or struct
>> > wt_status parameter, and adjust callers accordingly. Replace the
>> > remaining uses of the_repository in these functions with the
>> > passed-in repository instance.
>> >
>> > This removes the use of the_repository global variable from
>> > wt-status.c completely.
>> >
>>
>> Okay, but this doesn't fix the issue I stated in the previous commit. I
>> do wonder if we can re-order the commits and pass the repo struct to
>> functions like 'get_branch()'.
>
> Sorry, I didn’t fully think through what you were pointing out in the
> previous version. I initially assumed you were only referring to the
> specific call involving wt_status_check_rebase(NULL, state).
>
> So struct worktree *wt is not guaranteed to be defined and can be
> NULL. Because of that, relying on wt->repo is unsafe.
> Instead, rather than depending on the worktree for repository access (wt->repo),
> we can pass struct repository explicitly through the relevant call
> stack, like in functions get_branch() and wt_status_check_bisect().
> I hope I have understood it correctly.
>
> Best,
> Shreyansh
I would say its not that black and white. There's a lot of context
around it. There are places where `struct worktree *wt` should
definitely be defined. So we have to take it on a case by case basis.
Which is what makes these refactors a bit tricky.
Karthik
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-06 9:24 ` Karthik Nayak
@ 2026-02-06 9:32 ` Shreyansh Paliwal
2026-02-06 12:57 ` Shreyansh Paliwal
0 siblings, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-06 9:32 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 1963 bytes --]
> Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>
> >> > Some functions in wt-status.c relied on the_repository because no
> >> > repository instance was available in their local scope.
> >> > There is also a specific case in wt_status_check_rebase() where the
> >> > worktree can be NULL, so accessing wt->repo may lead to a segfault.
> >> >
> >> > Update these functions to accept a struct repository or struct
> >> > wt_status parameter, and adjust callers accordingly. Replace the
> >> > remaining uses of the_repository in these functions with the
> >> > passed-in repository instance.
> >> >
> >> > This removes the use of the_repository global variable from
> >> > wt-status.c completely.
> >> >
> >>
> >> Okay, but this doesn't fix the issue I stated in the previous commit. I
> >> do wonder if we can re-order the commits and pass the repo struct to
> >> functions like 'get_branch()'.
> >
> > Sorry, I didn’t fully think through what you were pointing out in the
> > previous version. I initially assumed you were only referring to the
> > specific call involving wt_status_check_rebase(NULL, state).
> >
> > So struct worktree *wt is not guaranteed to be defined and can be
> > NULL. Because of that, relying on wt->repo is unsafe.
> > Instead, rather than depending on the worktree for repository access (wt->repo),
> > we can pass struct repository explicitly through the relevant call
> > stack, like in functions get_branch() and wt_status_check_bisect().
> > I hope I have understood it correctly.
> >
> > Best,
> > Shreyansh
>
> I would say its not that black and white. There's a lot of context
> around it. There are places where `struct worktree *wt` should
> definitely be defined. So we have to take it on a case by case basis.
> Which is what makes these refactors a bit tricky.
But lets say if we do pass struct repository explicitly wherever it is doubtful,
rather than relying on worktree, does it have any downside ?
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-06 9:32 ` Shreyansh Paliwal
@ 2026-02-06 12:57 ` Shreyansh Paliwal
2026-02-06 14:54 ` Phillip Wood
0 siblings, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-06 12:57 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123, Shreyansh Paliwal
I tried this out below, and it showed no fails in tests.
After this we can just directly replace all the_repository with 'r' or 's->repo'
without the hassle of checking the worktree is defined or not.
Let me know what you think.
Thanks.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
branch.c | 4 ++--
worktree.c | 4 ++--
wt-status.c | 48 +++++++++++++++++++++++++-----------------------
wt-status.h | 6 ++++--
4 files changed, 33 insertions(+), 29 deletions(-)
diff --git a/branch.c b/branch.c
index 243db7d0fc..0a0097dd85 100644
--- a/branch.c
+++ b/branch.c
@@ -412,7 +412,7 @@ static void prepare_checked_out_branches(void)
free(old);
}
- if (wt_status_check_rebase(wt, &state) &&
+ if (wt_status_check_rebase(the_repository, wt, &state) &&
(state.rebase_in_progress || state.rebase_interactive_in_progress) &&
state.branch) {
struct strbuf ref = STRBUF_INIT;
@@ -425,7 +425,7 @@ static void prepare_checked_out_branches(void)
}
wt_status_state_free_buffers(&state);
- if (wt_status_check_bisect(wt, &state) &&
+ if (wt_status_check_bisect(the_repository, wt, &state) &&
state.bisecting_from) {
struct strbuf ref = STRBUF_INIT;
strbuf_addf(&ref, "refs/heads/%s", state.bisecting_from);
diff --git a/worktree.c b/worktree.c
index 9308389cb6..86eff384ae 100644
--- a/worktree.c
+++ b/worktree.c
@@ -443,7 +443,7 @@ int is_worktree_being_rebased(const struct worktree *wt,
int found_rebase;
memset(&state, 0, sizeof(state));
- found_rebase = wt_status_check_rebase(wt, &state) &&
+ found_rebase = wt_status_check_rebase(the_repository, wt, &state) &&
(state.rebase_in_progress ||
state.rebase_interactive_in_progress) &&
state.branch &&
@@ -460,7 +460,7 @@ int is_worktree_being_bisected(const struct worktree *wt,
int found_bisect;
memset(&state, 0, sizeof(state));
- found_bisect = wt_status_check_bisect(wt, &state) &&
+ found_bisect = wt_status_check_bisect(the_repository, wt, &state) &&
state.bisecting_from &&
skip_prefix(target, "refs/heads/", &target) &&
!strcmp(state.bisecting_from, target);
diff --git a/wt-status.c b/wt-status.c
index e12adb26b9..ea81418bdd 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -984,7 +984,7 @@ static int stash_count_refs(const char *refname UNUSED,
return 0;
}
-static int count_stash_entries(void)
+static int count_stash_entries(struct repository *r)
{
int n = 0;
refs_for_each_reflog_ent(get_main_ref_store(the_repository),
@@ -994,7 +994,7 @@ static int count_stash_entries(void)
static void wt_longstatus_print_stash_summary(struct wt_status *s)
{
- int stash_count = count_stash_entries();
+ int stash_count = count_stash_entries(s->repo);
if (stash_count > 0)
status_printf_ln(s, GIT_COLOR_NORMAL,
@@ -1287,7 +1287,7 @@ static void show_am_in_progress(struct wt_status *s,
wt_longstatus_print_trailer(s);
}
-static char *read_line_from_git_path(const char *filename)
+static char *read_line_from_git_path(struct repository *r, char *filename)
{
struct strbuf buf = STRBUF_INIT;
FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
@@ -1325,8 +1325,8 @@ static int split_commit_in_progress(struct wt_status *s)
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
return 0;
- rebase_amend = read_line_from_git_path("rebase-merge/amend");
- rebase_orig_head = read_line_from_git_path("rebase-merge/orig-head");
+ rebase_amend = read_line_from_git_path(s->repo, "rebase-merge/amend");
+ rebase_orig_head = read_line_from_git_path(s->repo, "rebase-merge/orig-head");
if (!rebase_amend || !rebase_orig_head)
; /* fall through, no split in progress */
@@ -1350,7 +1350,7 @@ static int split_commit_in_progress(struct wt_status *s)
* The function assumes that the line does not contain useless spaces
* before or after the command.
*/
-static void abbrev_oid_in_line(struct strbuf *line)
+static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
{
struct string_list split = STRING_LIST_INIT_DUP;
struct object_id oid;
@@ -1372,7 +1372,7 @@ static void abbrev_oid_in_line(struct strbuf *line)
string_list_clear(&split, 0);
}
-static int read_rebase_todolist(const char *fname, struct string_list *lines)
+static int read_rebase_todolist(struct repository *r, char *fname, struct string_list *lines)
{
struct strbuf buf = STRBUF_INIT;
FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
@@ -1392,7 +1392,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)
strbuf_trim(&buf);
if (!buf.len)
continue;
- abbrev_oid_in_line(&buf);
+ abbrev_oid_in_line(r, &buf);
string_list_append(lines, buf.buf);
}
fclose(f);
@@ -1413,8 +1413,8 @@ static void show_rebase_information(struct wt_status *s,
struct string_list have_done = STRING_LIST_INIT_DUP;
struct string_list yet_to_do = STRING_LIST_INIT_DUP;
- read_rebase_todolist("rebase-merge/done", &have_done);
- if (read_rebase_todolist("rebase-merge/git-rebase-todo",
+ read_rebase_todolist(s->repo, "rebase-merge/done", &have_done);
+ if (read_rebase_todolist(s->repo, "rebase-merge/git-rebase-todo",
&yet_to_do))
status_printf_ln(s, color,
_("git-rebase-todo is missing."));
@@ -1618,7 +1618,7 @@ static void show_sparse_checkout_in_use(struct wt_status *s,
/*
* Extract branch information from rebase/bisect
*/
-static char *get_branch(const struct worktree *wt, const char *path)
+static char *get_branch(struct repository *r, struct worktree *wt, const char *path)
{
struct strbuf sb = STRBUF_INIT;
struct object_id oid;
@@ -1718,8 +1718,9 @@ static void wt_status_get_detached_from(struct repository *r,
strbuf_release(&cb.buf);
}
-int wt_status_check_rebase(const struct worktree *wt,
- struct wt_status_state *state)
+int wt_status_check_rebase(struct repository *r,
+ const struct worktree *wt,
+ struct wt_status_state *state)
{
struct stat st;
@@ -1730,29 +1731,30 @@ int wt_status_check_rebase(const struct worktree *wt,
state->am_empty_patch = 1;
} else {
state->rebase_in_progress = 1;
- state->branch = get_branch(wt, "rebase-apply/head-name");
- state->onto = get_branch(wt, "rebase-apply/onto");
+ state->branch = get_branch(r, wt, "rebase-apply/head-name");
+ state->onto = get_branch(r, wt, "rebase-apply/onto");
}
} else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
state->rebase_interactive_in_progress = 1;
else
state->rebase_in_progress = 1;
- state->branch = get_branch(wt, "rebase-merge/head-name");
- state->onto = get_branch(wt, "rebase-merge/onto");
+ state->branch = get_branch(r, wt, "rebase-merge/head-name");
+ state->onto = get_branch(r, wt, "rebase-merge/onto");
} else
return 0;
return 1;
}
-int wt_status_check_bisect(const struct worktree *wt,
+int wt_status_check_bisect(struct repository *r,
+ struct worktree *wt,
struct wt_status_state *state)
{
struct stat st;
if (!stat(worktree_git_path(the_repository, wt, "BISECT_LOG"), &st)) {
state->bisect_in_progress = 1;
- state->bisecting_from = get_branch(wt, "BISECT_START");
+ state->bisecting_from = get_branch(r, wt, "BISECT_START");
return 1;
}
return 0;
@@ -1797,16 +1799,16 @@ void wt_status_get_state(struct repository *r,
enum replay_action action;
if (!stat(git_path_merge_head(r), &st)) {
- wt_status_check_rebase(NULL, state);
+ wt_status_check_rebase(r, NULL, state);
state->merge_in_progress = 1;
- } else if (wt_status_check_rebase(NULL, state)) {
+ } else if (wt_status_check_rebase(r, NULL, state)) {
; /* all set */
} else if (refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&
!repo_get_oid(r, "CHERRY_PICK_HEAD", &oid)) {
state->cherry_pick_in_progress = 1;
oidcpy(&state->cherry_pick_head_oid, &oid);
}
- wt_status_check_bisect(NULL, state);
+ wt_status_check_bisect(r, NULL, state);
if (refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD") &&
!repo_get_oid(r, "REVERT_HEAD", &oid)) {
state->revert_in_progress = 1;
@@ -2259,7 +2261,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
*/
static void wt_porcelain_v2_print_stash(struct wt_status *s)
{
- int stash_count = count_stash_entries();
+ int stash_count = count_stash_entries(s->repo);
char eol = s->null_termination ? '\0' : '\n';
if (stash_count > 0)
diff --git a/wt-status.h b/wt-status.h
index e40a27214a..5ac3d96210 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -164,9 +164,11 @@ void wt_status_state_free_buffers(struct wt_status_state *s);
void wt_status_get_state(struct repository *repo,
struct wt_status_state *state,
int get_detached_from);
-int wt_status_check_rebase(const struct worktree *wt,
+int wt_status_check_rebase(struct repository *r,
+ struct worktree *wt,
struct wt_status_state *state);
-int wt_status_check_bisect(const struct worktree *wt,
+int wt_status_check_bisect(struct repository *r,
+ struct worktree *wt,
struct wt_status_state *state);
__attribute__((format (printf, 3, 4)))
--
2.52.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-06 12:57 ` Shreyansh Paliwal
@ 2026-02-06 14:54 ` Phillip Wood
2026-02-06 17:06 ` Shreyansh Paliwal
0 siblings, 1 reply; 69+ messages in thread
From: Phillip Wood @ 2026-02-06 14:54 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster, karthik.188
On 06/02/2026 12:57, Shreyansh Paliwal wrote:
> I tried this out below, and it showed no fails in tests.
> After this we can just directly replace all the_repository with 'r' or 's->repo'
> without the hassle of checking the worktree is defined or not.
As we're trying to remove uses of "the_repository" I think you should
use "wt->repo" where we know always "wt != NULL". There are not many
callers of these functions so is easy to do necessary analysis (see below).
> diff --git a/branch.c b/branch.c
> index 243db7d0fc..0a0097dd85 100644
> --- a/branch.c
> +++ b/branch.c
> @@ -412,7 +412,7 @@ static void prepare_checked_out_branches(void)
> free(old);
> }
>
> - if (wt_status_check_rebase(wt, &state) &&
> + if (wt_status_check_rebase(the_repository, wt, &state) &&
As I said yesterday we know "wt != NULL" here so it is fine to use
"wt->repo" rather than introduce a new use of "the_repository", you just
need to explain that in the commit message.
> (state.rebase_in_progress || state.rebase_interactive_in_progress) &&
> state.branch) {
> struct strbuf ref = STRBUF_INIT;
> @@ -425,7 +425,7 @@ static void prepare_checked_out_branches(void)
> }
> wt_status_state_free_buffers(&state);
>
> - if (wt_status_check_bisect(wt, &state) &&
> + if (wt_status_check_bisect(the_repository, wt, &state) &&
The same is true here.
> state.bisecting_from) {
> struct strbuf ref = STRBUF_INIT;
> strbuf_addf(&ref, "refs/heads/%s", state.bisecting_from);
> diff --git a/worktree.c b/worktree.c
> index 9308389cb6..86eff384ae 100644
> --- a/worktree.c
> +++ b/worktree.c
> @@ -443,7 +443,7 @@ int is_worktree_being_rebased(const struct worktree *wt,
> int found_rebase;
>
> memset(&state, 0, sizeof(state));
> - found_rebase = wt_status_check_rebase(wt, &state) &&
> + found_rebase = wt_status_check_rebase(the_repository, wt, &state) &&
This function is called from
builtin/branch.c:reject_rebase_or_bisect_branch() with "wt != NULL". It
is also called from worktree.c:is_shared_symref() which dereferences wt
before calling this function so we can assume "wt != NULL" there as
well. That means we can use "wt->repo" here.
> (state.rebase_in_progress ||
> state.rebase_interactive_in_progress) &&
> state.branch &&
> @@ -460,7 +460,7 @@ int is_worktree_being_bisected(const struct worktree *wt,
> int found_bisect;
>
> memset(&state, 0, sizeof(state));
> - found_bisect = wt_status_check_bisect(wt, &state) &&
> + found_bisect = wt_status_check_bisect(the_repository, wt, &state) &&
The same analysis for is_worktree_being_rebased() applies here.
The changes to get_branch() below look sensible
Thanks
Phillip
> state.bisecting_from &&
> skip_prefix(target, "refs/heads/", &target) &&
> !strcmp(state.bisecting_from, target);
> diff --git a/wt-status.c b/wt-status.c
> index e12adb26b9..ea81418bdd 100644
> --- a/wt-status.c
> +++ b/wt-status.c
> @@ -984,7 +984,7 @@ static int stash_count_refs(const char *refname UNUSED,
> return 0;
> }
>
> -static int count_stash_entries(void)
> +static int count_stash_entries(struct repository *r)
> {
> int n = 0;
> refs_for_each_reflog_ent(get_main_ref_store(the_repository),
> @@ -994,7 +994,7 @@ static int count_stash_entries(void)
>
> static void wt_longstatus_print_stash_summary(struct wt_status *s)
> {
> - int stash_count = count_stash_entries();
> + int stash_count = count_stash_entries(s->repo);
>
> if (stash_count > 0)
> status_printf_ln(s, GIT_COLOR_NORMAL,
> @@ -1287,7 +1287,7 @@ static void show_am_in_progress(struct wt_status *s,
> wt_longstatus_print_trailer(s);
> }
>
> -static char *read_line_from_git_path(const char *filename)
> +static char *read_line_from_git_path(struct repository *r, char *filename)
> {
> struct strbuf buf = STRBUF_INIT;
> FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
> @@ -1325,8 +1325,8 @@ static int split_commit_in_progress(struct wt_status *s)
> if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
> return 0;
>
> - rebase_amend = read_line_from_git_path("rebase-merge/amend");
> - rebase_orig_head = read_line_from_git_path("rebase-merge/orig-head");
> + rebase_amend = read_line_from_git_path(s->repo, "rebase-merge/amend");
> + rebase_orig_head = read_line_from_git_path(s->repo, "rebase-merge/orig-head");
>
> if (!rebase_amend || !rebase_orig_head)
> ; /* fall through, no split in progress */
> @@ -1350,7 +1350,7 @@ static int split_commit_in_progress(struct wt_status *s)
> * The function assumes that the line does not contain useless spaces
> * before or after the command.
> */
> -static void abbrev_oid_in_line(struct strbuf *line)
> +static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
> {
> struct string_list split = STRING_LIST_INIT_DUP;
> struct object_id oid;
> @@ -1372,7 +1372,7 @@ static void abbrev_oid_in_line(struct strbuf *line)
> string_list_clear(&split, 0);
> }
>
> -static int read_rebase_todolist(const char *fname, struct string_list *lines)
> +static int read_rebase_todolist(struct repository *r, char *fname, struct string_list *lines)
> {
> struct strbuf buf = STRBUF_INIT;
> FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
> @@ -1392,7 +1392,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)
> strbuf_trim(&buf);
> if (!buf.len)
> continue;
> - abbrev_oid_in_line(&buf);
> + abbrev_oid_in_line(r, &buf);
> string_list_append(lines, buf.buf);
> }
> fclose(f);
> @@ -1413,8 +1413,8 @@ static void show_rebase_information(struct wt_status *s,
> struct string_list have_done = STRING_LIST_INIT_DUP;
> struct string_list yet_to_do = STRING_LIST_INIT_DUP;
>
> - read_rebase_todolist("rebase-merge/done", &have_done);
> - if (read_rebase_todolist("rebase-merge/git-rebase-todo",
> + read_rebase_todolist(s->repo, "rebase-merge/done", &have_done);
> + if (read_rebase_todolist(s->repo, "rebase-merge/git-rebase-todo",
> &yet_to_do))
> status_printf_ln(s, color,
> _("git-rebase-todo is missing."));
> @@ -1618,7 +1618,7 @@ static void show_sparse_checkout_in_use(struct wt_status *s,
> /*
> * Extract branch information from rebase/bisect
> */
> -static char *get_branch(const struct worktree *wt, const char *path)
> +static char *get_branch(struct repository *r, struct worktree *wt, const char *path)
> {
> struct strbuf sb = STRBUF_INIT;
> struct object_id oid;
> @@ -1718,8 +1718,9 @@ static void wt_status_get_detached_from(struct repository *r,
> strbuf_release(&cb.buf);
> }
>
> -int wt_status_check_rebase(const struct worktree *wt,
> - struct wt_status_state *state)
> +int wt_status_check_rebase(struct repository *r,
> + const struct worktree *wt,
> + struct wt_status_state *state)
> {
> struct stat st;
>
> @@ -1730,29 +1731,30 @@ int wt_status_check_rebase(const struct worktree *wt,
> state->am_empty_patch = 1;
> } else {
> state->rebase_in_progress = 1;
> - state->branch = get_branch(wt, "rebase-apply/head-name");
> - state->onto = get_branch(wt, "rebase-apply/onto");
> + state->branch = get_branch(r, wt, "rebase-apply/head-name");
> + state->onto = get_branch(r, wt, "rebase-apply/onto");
> }
> } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
> if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
> state->rebase_interactive_in_progress = 1;
> else
> state->rebase_in_progress = 1;
> - state->branch = get_branch(wt, "rebase-merge/head-name");
> - state->onto = get_branch(wt, "rebase-merge/onto");
> + state->branch = get_branch(r, wt, "rebase-merge/head-name");
> + state->onto = get_branch(r, wt, "rebase-merge/onto");
> } else
> return 0;
> return 1;
> }
>
> -int wt_status_check_bisect(const struct worktree *wt,
> +int wt_status_check_bisect(struct repository *r,
> + struct worktree *wt,
> struct wt_status_state *state)
> {
> struct stat st;
>
> if (!stat(worktree_git_path(the_repository, wt, "BISECT_LOG"), &st)) {
> state->bisect_in_progress = 1;
> - state->bisecting_from = get_branch(wt, "BISECT_START");
> + state->bisecting_from = get_branch(r, wt, "BISECT_START");
> return 1;
> }
> return 0;
> @@ -1797,16 +1799,16 @@ void wt_status_get_state(struct repository *r,
> enum replay_action action;
>
> if (!stat(git_path_merge_head(r), &st)) {
> - wt_status_check_rebase(NULL, state);
> + wt_status_check_rebase(r, NULL, state);
> state->merge_in_progress = 1;
> - } else if (wt_status_check_rebase(NULL, state)) {
> + } else if (wt_status_check_rebase(r, NULL, state)) {
> ; /* all set */
> } else if (refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&
> !repo_get_oid(r, "CHERRY_PICK_HEAD", &oid)) {
> state->cherry_pick_in_progress = 1;
> oidcpy(&state->cherry_pick_head_oid, &oid);
> }
> - wt_status_check_bisect(NULL, state);
> + wt_status_check_bisect(r, NULL, state);
> if (refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD") &&
> !repo_get_oid(r, "REVERT_HEAD", &oid)) {
> state->revert_in_progress = 1;
> @@ -2259,7 +2261,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
> */
> static void wt_porcelain_v2_print_stash(struct wt_status *s)
> {
> - int stash_count = count_stash_entries();
> + int stash_count = count_stash_entries(s->repo);
> char eol = s->null_termination ? '\0' : '\n';
>
> if (stash_count > 0)
> diff --git a/wt-status.h b/wt-status.h
> index e40a27214a..5ac3d96210 100644
> --- a/wt-status.h
> +++ b/wt-status.h
> @@ -164,9 +164,11 @@ void wt_status_state_free_buffers(struct wt_status_state *s);
> void wt_status_get_state(struct repository *repo,
> struct wt_status_state *state,
> int get_detached_from);
> -int wt_status_check_rebase(const struct worktree *wt,
> +int wt_status_check_rebase(struct repository *r,
> + struct worktree *wt,
> struct wt_status_state *state);
> -int wt_status_check_bisect(const struct worktree *wt,
> +int wt_status_check_bisect(struct repository *r,
> + struct worktree *wt,
> struct wt_status_state *state);
>
> __attribute__((format (printf, 3, 4)))
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-06 14:54 ` Phillip Wood
@ 2026-02-06 17:06 ` Shreyansh Paliwal
0 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-06 17:06 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123
> On 06/02/2026 12:57, Shreyansh Paliwal wrote:
> > I tried this out below, and it showed no fails in tests.
> > After this we can just directly replace all the_repository with 'r' or 's->repo'
> > without the hassle of checking the worktree is defined or not.
>
> As we're trying to remove uses of "the_repository" I think you should
> use "wt->repo" where we know always "wt != NULL". There are not many
> callers of these functions so is easy to do necessary analysis (see below).
>
> > diff --git a/branch.c b/branch.c
> > index 243db7d0fc..0a0097dd85 100644
> > --- a/branch.c
> > +++ b/branch.c
> > @@ -412,7 +412,7 @@ static void prepare_checked_out_branches(void)
> > free(old);
> > }
> >
> > - if (wt_status_check_rebase(wt, &state) &&
> > + if (wt_status_check_rebase(the_repository, wt, &state) &&
>
> As I said yesterday we know "wt != NULL" here so it is fine to use
> "wt->repo" rather than introduce a new use of "the_repository", you just
> need to explain that in the commit message.
>
> > (state.rebase_in_progress || state.rebase_interactive_in_progress) &&
> > state.branch) {
> > struct strbuf ref = STRBUF_INIT;
> > @@ -425,7 +425,7 @@ static void prepare_checked_out_branches(void)
> > }
> > wt_status_state_free_buffers(&state);
> >
> > - if (wt_status_check_bisect(wt, &state) &&
> > + if (wt_status_check_bisect(the_repository, wt, &state) &&
>
> The same is true here.
>
> > state.bisecting_from) {
> > struct strbuf ref = STRBUF_INIT;
> > strbuf_addf(&ref, "refs/heads/%s", state.bisecting_from);
> > diff --git a/worktree.c b/worktree.c
> > index 9308389cb6..86eff384ae 100644
> > --- a/worktree.c
> > +++ b/worktree.c
> > @@ -443,7 +443,7 @@ int is_worktree_being_rebased(const struct worktree *wt,
> > int found_rebase;
> >
> > memset(&state, 0, sizeof(state));
> > - found_rebase = wt_status_check_rebase(wt, &state) &&
> > + found_rebase = wt_status_check_rebase(the_repository, wt, &state) &&
>
> This function is called from
> builtin/branch.c:reject_rebase_or_bisect_branch() with "wt != NULL". It
> is also called from worktree.c:is_shared_symref() which dereferences wt
> before calling this function so we can assume "wt != NULL" there as
> well. That means we can use "wt->repo" here.
>
> > (state.rebase_in_progress ||
> > state.rebase_interactive_in_progress) &&
> > state.branch &&
> > @@ -460,7 +460,7 @@ int is_worktree_being_bisected(const struct worktree *wt,
> > int found_bisect;
> >
> > memset(&state, 0, sizeof(state));
> > - found_bisect = wt_status_check_bisect(wt, &state) &&
> > + found_bisect = wt_status_check_bisect(the_repository, wt, &state) &&
>
> The same analysis for is_worktree_being_rebased() applies here.
>
> The changes to get_branch() below look sensible
Thank you for explaining this and for each case.
I have understood where wt->repo can be used safely.
Will make changes and send a v3.
Hopefully that will be good to go :)
Best,
Shreyansh
^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH v3 0/3] wt-status: reduce reliance on global state
2026-02-05 10:13 ` [PATCH V2 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
` (3 preceding siblings ...)
2026-02-05 10:27 ` [PATCH V2 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
@ 2026-02-07 10:00 ` Shreyansh Paliwal
2026-02-07 10:00 ` [PATCH v3 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
` (2 more replies)
4 siblings, 3 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-07 10:00 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123, Shreyansh Paliwal
In wt-status.c code still relies on some global variables, including
the_repository and the_hash_algo, even in cases where a repository
instance is already available via struct wt_status or struct worktree.
In patch 1/3, update function parameters and callers to pass struct
repository where no local repository access was available.
In patch 2/3, replace direct uses of the_repository with repository
instances already available in local structs.
In patch 3/3, replace remaining uses of the global the_hash_algo with the
hash algorithm stored in the respective repository instance.
These changes remove all direct uses of the_repository and
the_hash_algo from wt-status.c and reduce its dependence on global state.
The 'USE_THE_REPOSITORY_VARIABLE' macro cannot yet be removed, since these
patches only eliminate direct uses of the_repository and the_hash_algo,
while other global variables are still referenced.
In particular wt-status.c still relies on the following globals,
* core_apply_sparse_checkout, this is already being addressed in an
ongoing patch series [1].
* comment_line_str and DEFAULT_ABBREV, these both still are used in
wt-status.c but they dont have any equivalent local instances.
[1]- https://lore.kernel.org/git/5e56e1cc4172cfff9e917a068184e102aa70bf1d.1769256839.git.belkid98@gmail.com/t/#u
Shreyansh Paliwal (3):
wt-status: pass struct repository through function parameters
wt-status: replace uses of the_repository with local repository instances
wt-status: use hash_algo from local repository instead of global the_hash_algo
branch.c | 4 +--
worktree.c | 4 +--
wt-status.c | 102 ++++++++++++++++++++++++++--------------------------
wt-status.h | 6 ++--
4 files changed, 60 insertions(+), 56 deletions(-)
---
Changes in v2:
- Reordered the first 2 patches for better flow.
- Instead of relying on wt->repo in wt_status_check_rebase() and
wt_status_check_bisect() addded struct repository.
- Added extra explainations in the commit message for the usage of wt
and being it not NULL.
Range-diff against v2:
2: 2af0113f6f ! 1: 960216e45c wt-status: pass struct repository and wt_status through function parameters
@@ Metadata
Author: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
## Commit message ##
- wt-status: pass struct repository and wt_status through function parameters
+ wt-status: pass struct repository through function parameters
- Some functions in wt-status.c relied on the_repository because no
- repository instance was available in their local scope.
- There is also a specific case in wt_status_check_rebase() where the
- worktree can be NULL, so accessing wt->repo may lead to a segfault.
+ Some functions in wt-status.c (count_stash_entries(),
+ read_line_from_git_path(), abbrev_oid_in_line(), read_rebase_todolist())
+ do not have access to a local repository instance and rely on the_repository.
- Update these functions to accept a struct repository or struct
- wt_status parameter, and adjust callers accordingly. Replace the
- remaining uses of the_repository in these functions with the
- passed-in repository instance.
+ Add a struct repository *r parameter to these functions, and pass the local
+ repository through the callers.
- This removes the use of the_repository global variable from
- wt-status.c completely.
+ get_branch(), wt_status_check_rebase() and wt_status_check_bisect() already
+ receive a struct worktree *, which can provide access to the repository.
+ However, some callers pass NULL as the worktree like in wt_status_get_state(),
+ which would make using wt->repo unsafe and lead to segfault issues.
+ Add an explicit struct repository * parameter to these functions as well,
+ and pass the repository through the callers.
+
+ Both wt_status_check_rebase() and wt_status_check_bisect() are called from
+ branch.c and worktree.c,
+
+ * In branch.c, wt is always non-NULL as the functions are called within an
+ interation over worktrees in prepare_checked_out_branches().
+ * In worktree.c the functions are called from is_worktree_being_rebased() and
+ is_worktree_being_bisected() respectively which are further called from
+ builtin/branch.c in reject_rebase_or_bisect_branch() which has a non-NULL
+ worktree as it is called inside an iteration over worktrees as well.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
@@ branch.c: static void prepare_checked_out_branches(void)
(state.rebase_in_progress || state.rebase_interactive_in_progress) &&
state.branch) {
struct strbuf ref = STRBUF_INIT;
+@@ branch.c: static void prepare_checked_out_branches(void)
+ }
+ wt_status_state_free_buffers(&state);
+
+- if (wt_status_check_bisect(wt, &state) &&
++ if (wt_status_check_bisect(wt->repo, wt, &state) &&
+ state.bisecting_from) {
+ struct strbuf ref = STRBUF_INIT;
+ strbuf_addf(&ref, "refs/heads/%s", state.bisecting_from);
## worktree.c ##
@@ worktree.c: int is_worktree_being_rebased(const struct worktree *wt,
@@ worktree.c: int is_worktree_being_rebased(const struct worktree *wt,
(state.rebase_in_progress ||
state.rebase_interactive_in_progress) &&
state.branch &&
+@@ worktree.c: int is_worktree_being_bisected(const struct worktree *wt,
+ int found_bisect;
+
+ memset(&state, 0, sizeof(state));
+- found_bisect = wt_status_check_bisect(wt, &state) &&
++ found_bisect = wt_status_check_bisect(wt->repo, wt, &state) &&
+ state.bisecting_from &&
+ skip_prefix(target, "refs/heads/", &target) &&
+ !strcmp(state.bisecting_from, target);
## wt-status.c ##
@@ wt-status.c: static int stash_count_refs(const char *refname UNUSED,
@@ wt-status.c: static int stash_count_refs(const char *refname UNUSED,
+static int count_stash_entries(struct repository *r)
{
int n = 0;
-- refs_for_each_reflog_ent(get_main_ref_store(the_repository),
-+ refs_for_each_reflog_ent(get_main_ref_store(r),
- "refs/stash", stash_count_refs, &n);
- return n;
- }
+ refs_for_each_reflog_ent(get_main_ref_store(the_repository),
+@@ wt-status.c: static int count_stash_entries(void)
static void wt_longstatus_print_stash_summary(struct wt_status *s)
{
@@ wt-status.c: static void show_am_in_progress(struct wt_status *s,
}
-static char *read_line_from_git_path(const char *filename)
-+static char *read_line_from_git_path(struct repository *r, const char *filename)
++static char *read_line_from_git_path(struct repository *r, char *filename)
{
struct strbuf buf = STRBUF_INIT;
-- FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
-+ FILE *fp = fopen_or_warn(repo_git_path_append(r, &buf,
- "%s", filename), "r");
-
- if (!fp) {
+ FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
@@ wt-status.c: static int split_commit_in_progress(struct wt_status *s)
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
return 0;
@@ wt-status.c: static int split_commit_in_progress(struct wt_status *s)
{
struct string_list split = STRING_LIST_INIT_DUP;
struct object_id oid;
-@@ wt-status.c: static void abbrev_oid_in_line(struct strbuf *line)
- return;
-
- if ((2 <= string_list_split(&split, line->buf, " ", 2)) &&
-- !repo_get_oid(the_repository, split.items[1].string, &oid)) {
-+ !repo_get_oid(r, split.items[1].string, &oid)) {
- strbuf_reset(line);
- strbuf_addf(line, "%s ", split.items[0].string);
- strbuf_add_unique_abbrev(line, &oid, DEFAULT_ABBREV);
@@ wt-status.c: static void abbrev_oid_in_line(struct strbuf *line)
string_list_clear(&split, 0);
}
-static int read_rebase_todolist(const char *fname, struct string_list *lines)
-+static int read_rebase_todolist(struct repository *r, const char *fname, struct string_list *lines)
++static int read_rebase_todolist(struct repository *r, char *fname, struct string_list *lines)
{
struct strbuf buf = STRBUF_INIT;
-- FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
-+ FILE *f = fopen(repo_git_path_append(r, &buf, "%s", fname), "r");
- int ret;
-
- if (!f) {
-@@ wt-status.c: static int read_rebase_todolist(const char *fname, struct string_list *lines)
- goto out;
- }
- die_errno("Could not open file %s for reading",
-- repo_git_path_replace(the_repository, &buf, "%s", fname));
-+ repo_git_path_replace(r, &buf, "%s", fname));
- }
- while (!strbuf_getline_lf(&buf, f)) {
- if (starts_with(buf.buf, comment_line_str))
+ FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
@@ wt-status.c: static int read_rebase_todolist(const char *fname, struct string_list *lines)
strbuf_trim(&buf);
if (!buf.len)
@@ wt-status.c: static void show_rebase_information(struct wt_status *s,
&yet_to_do))
status_printf_ln(s, color,
_("git-rebase-todo is missing."));
+@@ wt-status.c: static void show_sparse_checkout_in_use(struct wt_status *s,
+ /*
+ * Extract branch information from rebase/bisect
+ */
+-static char *get_branch(const struct worktree *wt, const char *path)
++static char *get_branch(struct repository *r, struct worktree *wt, const char *path)
+ {
+ struct strbuf sb = STRBUF_INIT;
+ struct object_id oid;
@@ wt-status.c: static void wt_status_get_detached_from(struct repository *r,
strbuf_release(&cb.buf);
}
@@ wt-status.c: static void wt_status_get_detached_from(struct repository *r,
-int wt_status_check_rebase(const struct worktree *wt,
- struct wt_status_state *state)
+int wt_status_check_rebase(struct repository *r,
-+ const struct worktree *wt,
-+ struct wt_status_state *state)
++ const struct worktree *wt,
++ struct wt_status_state *state)
{
struct stat st;
-- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
-- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
-+ if (!stat(worktree_git_path(r, wt, "rebase-apply"), &st)) {
-+ if (!stat(worktree_git_path(r, wt, "rebase-apply/applying"), &st)) {
- state->am_in_progress = 1;
-- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/patch"), &st) && !st.st_size)
-+ if (!stat(worktree_git_path(r, wt, "rebase-apply/patch"), &st) && !st.st_size)
+@@ wt-status.c: int wt_status_check_rebase(const struct worktree *wt,
state->am_empty_patch = 1;
} else {
state->rebase_in_progress = 1;
- state->branch = get_branch(wt, "rebase-apply/head-name");
- state->onto = get_branch(wt, "rebase-apply/onto");
+- state->branch = get_branch(wt, "rebase-apply/head-name");
+- state->onto = get_branch(wt, "rebase-apply/onto");
++ state->branch = get_branch(r, wt, "rebase-apply/head-name");
++ state->onto = get_branch(r, wt, "rebase-apply/onto");
}
-- } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
-- if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
-+ } else if (!stat(worktree_git_path(r, wt, "rebase-merge"), &st)) {
-+ if (!stat(worktree_git_path(r, wt, "rebase-merge/interactive"), &st))
+ } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
+ if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
state->rebase_interactive_in_progress = 1;
else
state->rebase_in_progress = 1;
+- state->branch = get_branch(wt, "rebase-merge/head-name");
+- state->onto = get_branch(wt, "rebase-merge/onto");
++ state->branch = get_branch(r, wt, "rebase-merge/head-name");
++ state->onto = get_branch(r, wt, "rebase-merge/onto");
+ } else
+ return 0;
+ return 1;
+ }
+
+-int wt_status_check_bisect(const struct worktree *wt,
++int wt_status_check_bisect(struct repository *r,
++ struct worktree *wt,
+ struct wt_status_state *state)
+ {
+ struct stat st;
+
+ if (!stat(worktree_git_path(the_repository, wt, "BISECT_LOG"), &st)) {
+ state->bisect_in_progress = 1;
+- state->bisecting_from = get_branch(wt, "BISECT_START");
++ state->bisecting_from = get_branch(r, wt, "BISECT_START");
+ return 1;
+ }
+ return 0;
@@ wt-status.c: void wt_status_get_state(struct repository *r,
enum replay_action action;
@@ wt-status.c: void wt_status_get_state(struct repository *r,
; /* all set */
} else if (refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&
!repo_get_oid(r, "CHERRY_PICK_HEAD", &oid)) {
+ state->cherry_pick_in_progress = 1;
+ oidcpy(&state->cherry_pick_head_oid, &oid);
+ }
+- wt_status_check_bisect(NULL, state);
++ wt_status_check_bisect(r, NULL, state);
+ if (refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD") &&
+ !repo_get_oid(r, "REVERT_HEAD", &oid)) {
+ state->revert_in_progress = 1;
@@ wt-status.c: static void wt_porcelain_v2_print_tracking(struct wt_status *s)
*/
static void wt_porcelain_v2_print_stash(struct wt_status *s)
@@ wt-status.h: void wt_status_state_free_buffers(struct wt_status_state *s);
struct wt_status_state *state,
int get_detached_from);
-int wt_status_check_rebase(const struct worktree *wt,
-- struct wt_status_state *state);
+int wt_status_check_rebase(struct repository *r,
-+ const struct worktree *wt,
-+ struct wt_status_state *state);
- int wt_status_check_bisect(const struct worktree *wt,
++ struct worktree *wt,
+ struct wt_status_state *state);
+-int wt_status_check_bisect(const struct worktree *wt,
++int wt_status_check_bisect(struct repository *r,
++ struct worktree *wt,
struct wt_status_state *state);
+ __attribute__((format (printf, 3, 4)))
1: 556735dfd4 ! 2: 906e682cd7 wt-status: replace uses of the_repository with local repository instances
@@ Commit message
wt-status: replace uses of the_repository with local repository instances
wt-status.c uses the global the_repository in several places even when
- a repository instance is already available via struct wt_status or
- struct worktree.
+ a repository instance is already available via struct wt_status *s or
+ struct repository *r.
- Replace these direct uses of the_repository with the repository carried
- by the local structs (e.g. s->repo, wt->repo).
+ Replace these uses of the_repository with the repository available
+ in the local context (eg. s->repo or r).
The replacements of all the_repository with s->repo are mostly
to cases where a repository instance is already available via
- struct wt_status. All functions operating on struct wt_status *s
- are only used after s is initialized by wt_status_prepare(),
+ struct wt_status *s and struct repository *r, all functions operating on
+ struct wt_status *s are only used after s is initialized by wt_status_prepare(),
which sets s->repo from the repository provided by the caller.
- As a result, s->repo is guaranteed to be available and consistent
- whenever these functions are invoked.
+ As a result, s->repo is guaranteed to be available and consistent whenever
+ these functions are invoked.
This reduces reliance on global state and keeps wt-status consistent,
though many functions operating on struct wt_status *s
@@ wt-status.c: void wt_status_prepare(struct repository *r, struct wt_status *s)
s->reference = "HEAD";
s->fp = stdout;
- s->index_file = repo_get_index_file(the_repository);
-+ s->index_file = repo_get_index_file(s->repo);
++ s->index_file = repo_get_index_file(r);
s->change.strdup_strings = 1;
s->untracked.strdup_strings = 1;
s->ignored.strdup_strings = 1;
@@ wt-status.c: static void wt_status_collect_changes_index(struct wt_status *s)
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.flags.override_submodule_config = 1;
+@@ wt-status.c: static int stash_count_refs(const char *refname UNUSED,
+ static int count_stash_entries(struct repository *r)
+ {
+ int n = 0;
+- refs_for_each_reflog_ent(get_main_ref_store(the_repository),
++ refs_for_each_reflog_ent(get_main_ref_store(r),
+ "refs/stash", stash_count_refs, &n);
+ return n;
+ }
@@ wt-status.c: static void wt_longstatus_print_verbose(struct wt_status *s)
rev.diffopt.ita_invisible_in_index = 1;
@@ wt-status.c: static void wt_longstatus_print_verbose(struct wt_status *s)
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
+@@ wt-status.c: static void show_am_in_progress(struct wt_status *s,
+ static char *read_line_from_git_path(struct repository *r, char *filename)
+ {
+ struct strbuf buf = STRBUF_INIT;
+- FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
++ FILE *fp = fopen_or_warn(repo_git_path_append(r, &buf,
+ "%s", filename), "r");
+
+ if (!fp) {
@@ wt-status.c: static int split_commit_in_progress(struct wt_status *s)
!s->branch || strcmp(s->branch, "HEAD"))
return 0;
@@ wt-status.c: static int split_commit_in_progress(struct wt_status *s)
&orig_head_oid, &orig_head_flags))
return 0;
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
+@@ wt-status.c: static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
+ return;
+
+ if ((2 <= string_list_split(&split, line->buf, " ", 2)) &&
+- !repo_get_oid(the_repository, split.items[1].string, &oid)) {
++ !repo_get_oid(r, split.items[1].string, &oid)) {
+ strbuf_reset(line);
+ strbuf_addf(line, "%s ", split.items[0].string);
+ strbuf_add_unique_abbrev(line, &oid, DEFAULT_ABBREV);
+@@ wt-status.c: static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
+ static int read_rebase_todolist(struct repository *r, char *fname, struct string_list *lines)
+ {
+ struct strbuf buf = STRBUF_INIT;
+- FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
++ FILE *f = fopen(repo_git_path_append(r, &buf, "%s", fname), "r");
+ int ret;
+
+ if (!f) {
+@@ wt-status.c: static int read_rebase_todolist(struct repository *r, char *fname, struct string
+ goto out;
+ }
+ die_errno("Could not open file %s for reading",
+- repo_git_path_replace(the_repository, &buf, "%s", fname));
++ repo_git_path_replace(r, &buf, "%s", fname));
+ }
+ while (!strbuf_getline_lf(&buf, f)) {
+ if (starts_with(buf.buf, comment_line_str))
@@ wt-status.c: static void show_rebase_information(struct wt_status *s,
i++)
status_printf_ln(s, color, " %s", have_done.items[i].string);
@@ wt-status.c: static void show_revert_in_progress(struct wt_status *s,
DEFAULT_ABBREV));
if (s->hints) {
if (has_unmerged(s))
-@@ wt-status.c: static char *get_branch(const struct worktree *wt, const char *path)
+@@ wt-status.c: static char *get_branch(struct repository *r, struct worktree *wt, const char *p
struct object_id oid;
const char *branch_name;
- if (strbuf_read_file(&sb, worktree_git_path(the_repository, wt, "%s", path), 0) <= 0)
-+ if (strbuf_read_file(&sb, worktree_git_path(wt->repo, wt, "%s", path), 0) <= 0)
++ if (strbuf_read_file(&sb, worktree_git_path(r, wt, "%s", path), 0) <= 0)
goto got_nothing;
while (sb.len && sb.buf[sb.len - 1] == '\n')
@@ wt-status.c: static void wt_status_get_detached_from(struct repository *r,
strbuf_release(&cb.buf);
return;
}
-@@ wt-status.c: int wt_status_check_bisect(const struct worktree *wt,
+@@ wt-status.c: int wt_status_check_rebase(struct repository *r,
+ {
+ struct stat st;
+
+- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
+- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
++ if (!stat(worktree_git_path(r, wt, "rebase-apply"), &st)) {
++ if (!stat(worktree_git_path(r, wt, "rebase-apply/applying"), &st)) {
+ state->am_in_progress = 1;
+- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/patch"), &st) && !st.st_size)
++ if (!stat(worktree_git_path(r, wt, "rebase-apply/patch"), &st) && !st.st_size)
+ state->am_empty_patch = 1;
+ } else {
+ state->rebase_in_progress = 1;
+ state->branch = get_branch(r, wt, "rebase-apply/head-name");
+ state->onto = get_branch(r, wt, "rebase-apply/onto");
+ }
+- } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
+- if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
++ } else if (!stat(worktree_git_path(r, wt, "rebase-merge"), &st)) {
++ if (!stat(worktree_git_path(r, wt, "rebase-merge/interactive"), &st))
+ state->rebase_interactive_in_progress = 1;
+ else
+ state->rebase_in_progress = 1;
+@@ wt-status.c: int wt_status_check_bisect(struct repository *r,
{
struct stat st;
- if (!stat(worktree_git_path(the_repository, wt, "BISECT_LOG"), &st)) {
-+ if (!stat(worktree_git_path(wt->repo, wt, "BISECT_LOG"), &st)) {
++ if (!stat(worktree_git_path(r, wt, "BISECT_LOG"), &st)) {
state->bisect_in_progress = 1;
- state->bisecting_from = get_branch(wt, "BISECT_START");
+ state->bisecting_from = get_branch(r, wt, "BISECT_START");
return 1;
@@ wt-status.c: static void wt_shortstatus_print_tracking(struct wt_status *s)
upstream_is_gone = 1;
3: b745a08d96 = 3: 9c0a1d82ad wt-status: use hash_algo from local repository instead of global the_hash_algo
--
2.52.0
^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH v3 1/3] wt-status: pass struct repository through function parameters
2026-02-07 10:00 ` [PATCH v3 " Shreyansh Paliwal
@ 2026-02-07 10:00 ` Shreyansh Paliwal
2026-02-08 1:14 ` Junio C Hamano
2026-02-08 1:21 ` Junio C Hamano
2026-02-07 10:00 ` [PATCH v3 2/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
2026-02-07 10:00 ` [PATCH v3 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
2 siblings, 2 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-07 10:00 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123, Shreyansh Paliwal
Some functions in wt-status.c (count_stash_entries(),
read_line_from_git_path(), abbrev_oid_in_line(), read_rebase_todolist())
do not have access to a local repository instance and rely on the_repository.
Add a struct repository *r parameter to these functions, and pass the local
repository through the callers.
get_branch(), wt_status_check_rebase() and wt_status_check_bisect() already
receive a struct worktree *, which can provide access to the repository.
However, some callers pass NULL as the worktree like in wt_status_get_state(),
which would make using wt->repo unsafe and lead to segfault issues.
Add an explicit struct repository * parameter to these functions as well,
and pass the repository through the callers.
Both wt_status_check_rebase() and wt_status_check_bisect() are called from
branch.c and worktree.c,
* In branch.c, wt is always non-NULL as the functions are called within an
interation over worktrees in prepare_checked_out_branches().
* In worktree.c the functions are called from is_worktree_being_rebased() and
is_worktree_being_bisected() respectively which are further called from
builtin/branch.c in reject_rebase_or_bisect_branch() which has a non-NULL
worktree as it is called inside an iteration over worktrees as well.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
branch.c | 4 ++--
worktree.c | 4 ++--
wt-status.c | 48 +++++++++++++++++++++++++-----------------------
wt-status.h | 6 ++++--
4 files changed, 33 insertions(+), 29 deletions(-)
diff --git a/branch.c b/branch.c
index 243db7d0fc..e3cf273339 100644
--- a/branch.c
+++ b/branch.c
@@ -412,7 +412,7 @@ static void prepare_checked_out_branches(void)
free(old);
}
- if (wt_status_check_rebase(wt, &state) &&
+ if (wt_status_check_rebase(wt->repo, wt, &state) &&
(state.rebase_in_progress || state.rebase_interactive_in_progress) &&
state.branch) {
struct strbuf ref = STRBUF_INIT;
@@ -425,7 +425,7 @@ static void prepare_checked_out_branches(void)
}
wt_status_state_free_buffers(&state);
- if (wt_status_check_bisect(wt, &state) &&
+ if (wt_status_check_bisect(wt->repo, wt, &state) &&
state.bisecting_from) {
struct strbuf ref = STRBUF_INIT;
strbuf_addf(&ref, "refs/heads/%s", state.bisecting_from);
diff --git a/worktree.c b/worktree.c
index 9308389cb6..0708d202cc 100644
--- a/worktree.c
+++ b/worktree.c
@@ -443,7 +443,7 @@ int is_worktree_being_rebased(const struct worktree *wt,
int found_rebase;
memset(&state, 0, sizeof(state));
- found_rebase = wt_status_check_rebase(wt, &state) &&
+ found_rebase = wt_status_check_rebase(wt->repo, wt, &state) &&
(state.rebase_in_progress ||
state.rebase_interactive_in_progress) &&
state.branch &&
@@ -460,7 +460,7 @@ int is_worktree_being_bisected(const struct worktree *wt,
int found_bisect;
memset(&state, 0, sizeof(state));
- found_bisect = wt_status_check_bisect(wt, &state) &&
+ found_bisect = wt_status_check_bisect(wt->repo, wt, &state) &&
state.bisecting_from &&
skip_prefix(target, "refs/heads/", &target) &&
!strcmp(state.bisecting_from, target);
diff --git a/wt-status.c b/wt-status.c
index e12adb26b9..ea81418bdd 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -984,7 +984,7 @@ static int stash_count_refs(const char *refname UNUSED,
return 0;
}
-static int count_stash_entries(void)
+static int count_stash_entries(struct repository *r)
{
int n = 0;
refs_for_each_reflog_ent(get_main_ref_store(the_repository),
@@ -994,7 +994,7 @@ static int count_stash_entries(void)
static void wt_longstatus_print_stash_summary(struct wt_status *s)
{
- int stash_count = count_stash_entries();
+ int stash_count = count_stash_entries(s->repo);
if (stash_count > 0)
status_printf_ln(s, GIT_COLOR_NORMAL,
@@ -1287,7 +1287,7 @@ static void show_am_in_progress(struct wt_status *s,
wt_longstatus_print_trailer(s);
}
-static char *read_line_from_git_path(const char *filename)
+static char *read_line_from_git_path(struct repository *r, char *filename)
{
struct strbuf buf = STRBUF_INIT;
FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
@@ -1325,8 +1325,8 @@ static int split_commit_in_progress(struct wt_status *s)
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
return 0;
- rebase_amend = read_line_from_git_path("rebase-merge/amend");
- rebase_orig_head = read_line_from_git_path("rebase-merge/orig-head");
+ rebase_amend = read_line_from_git_path(s->repo, "rebase-merge/amend");
+ rebase_orig_head = read_line_from_git_path(s->repo, "rebase-merge/orig-head");
if (!rebase_amend || !rebase_orig_head)
; /* fall through, no split in progress */
@@ -1350,7 +1350,7 @@ static int split_commit_in_progress(struct wt_status *s)
* The function assumes that the line does not contain useless spaces
* before or after the command.
*/
-static void abbrev_oid_in_line(struct strbuf *line)
+static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
{
struct string_list split = STRING_LIST_INIT_DUP;
struct object_id oid;
@@ -1372,7 +1372,7 @@ static void abbrev_oid_in_line(struct strbuf *line)
string_list_clear(&split, 0);
}
-static int read_rebase_todolist(const char *fname, struct string_list *lines)
+static int read_rebase_todolist(struct repository *r, char *fname, struct string_list *lines)
{
struct strbuf buf = STRBUF_INIT;
FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
@@ -1392,7 +1392,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)
strbuf_trim(&buf);
if (!buf.len)
continue;
- abbrev_oid_in_line(&buf);
+ abbrev_oid_in_line(r, &buf);
string_list_append(lines, buf.buf);
}
fclose(f);
@@ -1413,8 +1413,8 @@ static void show_rebase_information(struct wt_status *s,
struct string_list have_done = STRING_LIST_INIT_DUP;
struct string_list yet_to_do = STRING_LIST_INIT_DUP;
- read_rebase_todolist("rebase-merge/done", &have_done);
- if (read_rebase_todolist("rebase-merge/git-rebase-todo",
+ read_rebase_todolist(s->repo, "rebase-merge/done", &have_done);
+ if (read_rebase_todolist(s->repo, "rebase-merge/git-rebase-todo",
&yet_to_do))
status_printf_ln(s, color,
_("git-rebase-todo is missing."));
@@ -1618,7 +1618,7 @@ static void show_sparse_checkout_in_use(struct wt_status *s,
/*
* Extract branch information from rebase/bisect
*/
-static char *get_branch(const struct worktree *wt, const char *path)
+static char *get_branch(struct repository *r, struct worktree *wt, const char *path)
{
struct strbuf sb = STRBUF_INIT;
struct object_id oid;
@@ -1718,8 +1718,9 @@ static void wt_status_get_detached_from(struct repository *r,
strbuf_release(&cb.buf);
}
-int wt_status_check_rebase(const struct worktree *wt,
- struct wt_status_state *state)
+int wt_status_check_rebase(struct repository *r,
+ const struct worktree *wt,
+ struct wt_status_state *state)
{
struct stat st;
@@ -1730,29 +1731,30 @@ int wt_status_check_rebase(const struct worktree *wt,
state->am_empty_patch = 1;
} else {
state->rebase_in_progress = 1;
- state->branch = get_branch(wt, "rebase-apply/head-name");
- state->onto = get_branch(wt, "rebase-apply/onto");
+ state->branch = get_branch(r, wt, "rebase-apply/head-name");
+ state->onto = get_branch(r, wt, "rebase-apply/onto");
}
} else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
state->rebase_interactive_in_progress = 1;
else
state->rebase_in_progress = 1;
- state->branch = get_branch(wt, "rebase-merge/head-name");
- state->onto = get_branch(wt, "rebase-merge/onto");
+ state->branch = get_branch(r, wt, "rebase-merge/head-name");
+ state->onto = get_branch(r, wt, "rebase-merge/onto");
} else
return 0;
return 1;
}
-int wt_status_check_bisect(const struct worktree *wt,
+int wt_status_check_bisect(struct repository *r,
+ struct worktree *wt,
struct wt_status_state *state)
{
struct stat st;
if (!stat(worktree_git_path(the_repository, wt, "BISECT_LOG"), &st)) {
state->bisect_in_progress = 1;
- state->bisecting_from = get_branch(wt, "BISECT_START");
+ state->bisecting_from = get_branch(r, wt, "BISECT_START");
return 1;
}
return 0;
@@ -1797,16 +1799,16 @@ void wt_status_get_state(struct repository *r,
enum replay_action action;
if (!stat(git_path_merge_head(r), &st)) {
- wt_status_check_rebase(NULL, state);
+ wt_status_check_rebase(r, NULL, state);
state->merge_in_progress = 1;
- } else if (wt_status_check_rebase(NULL, state)) {
+ } else if (wt_status_check_rebase(r, NULL, state)) {
; /* all set */
} else if (refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&
!repo_get_oid(r, "CHERRY_PICK_HEAD", &oid)) {
state->cherry_pick_in_progress = 1;
oidcpy(&state->cherry_pick_head_oid, &oid);
}
- wt_status_check_bisect(NULL, state);
+ wt_status_check_bisect(r, NULL, state);
if (refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD") &&
!repo_get_oid(r, "REVERT_HEAD", &oid)) {
state->revert_in_progress = 1;
@@ -2259,7 +2261,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
*/
static void wt_porcelain_v2_print_stash(struct wt_status *s)
{
- int stash_count = count_stash_entries();
+ int stash_count = count_stash_entries(s->repo);
char eol = s->null_termination ? '\0' : '\n';
if (stash_count > 0)
diff --git a/wt-status.h b/wt-status.h
index e40a27214a..5ac3d96210 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -164,9 +164,11 @@ void wt_status_state_free_buffers(struct wt_status_state *s);
void wt_status_get_state(struct repository *repo,
struct wt_status_state *state,
int get_detached_from);
-int wt_status_check_rebase(const struct worktree *wt,
+int wt_status_check_rebase(struct repository *r,
+ struct worktree *wt,
struct wt_status_state *state);
-int wt_status_check_bisect(const struct worktree *wt,
+int wt_status_check_bisect(struct repository *r,
+ struct worktree *wt,
struct wt_status_state *state);
__attribute__((format (printf, 3, 4)))
--
2.52.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v3 2/3] wt-status: replace uses of the_repository with local repository instances
2026-02-07 10:00 ` [PATCH v3 " Shreyansh Paliwal
2026-02-07 10:00 ` [PATCH v3 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
@ 2026-02-07 10:00 ` Shreyansh Paliwal
2026-02-07 10:00 ` [PATCH v3 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
2 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-07 10:00 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123, Shreyansh Paliwal
wt-status.c uses the global the_repository in several places even when
a repository instance is already available via struct wt_status *s or
struct repository *r.
Replace these uses of the_repository with the repository available
in the local context (eg. s->repo or r).
The replacements of all the_repository with s->repo are mostly
to cases where a repository instance is already available via
struct wt_status *s and struct repository *r, all functions operating on
struct wt_status *s are only used after s is initialized by wt_status_prepare(),
which sets s->repo from the repository provided by the caller.
As a result, s->repo is guaranteed to be available and consistent whenever
these functions are invoked.
This reduces reliance on global state and keeps wt-status consistent,
though many functions operating on struct wt_status *s
are called via commit.c and it still relies on the_repository,
but within wt-status.c the local repository pointer
refers to the same underlying repository object.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
wt-status.c | 48 ++++++++++++++++++++++++------------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index ea81418bdd..0270d544d9 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
s->use_color = GIT_COLOR_UNKNOWN;
s->relative_paths = 1;
- s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
+ s->branch = refs_resolve_refdup(get_main_ref_store(r),
"HEAD", 0, NULL, NULL);
s->reference = "HEAD";
s->fp = stdout;
- s->index_file = repo_get_index_file(the_repository);
+ s->index_file = repo_get_index_file(r);
s->change.strdup_strings = 1;
s->untracked.strdup_strings = 1;
s->ignored.strdup_strings = 1;
@@ -646,7 +646,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
repo_init_revisions(s->repo, &rev, NULL);
memset(&opt, 0, sizeof(opt));
- opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
+ opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.flags.override_submodule_config = 1;
@@ -987,7 +987,7 @@ static int stash_count_refs(const char *refname UNUSED,
static int count_stash_entries(struct repository *r)
{
int n = 0;
- refs_for_each_reflog_ent(get_main_ref_store(the_repository),
+ refs_for_each_reflog_ent(get_main_ref_store(r),
"refs/stash", stash_count_refs, &n);
return n;
}
@@ -1146,7 +1146,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
rev.diffopt.ita_invisible_in_index = 1;
memset(&opt, 0, sizeof(opt));
- opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
+ opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
@@ -1290,7 +1290,7 @@ static void show_am_in_progress(struct wt_status *s,
static char *read_line_from_git_path(struct repository *r, char *filename)
{
struct strbuf buf = STRBUF_INIT;
- FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
+ FILE *fp = fopen_or_warn(repo_git_path_append(r, &buf,
"%s", filename), "r");
if (!fp) {
@@ -1317,9 +1317,9 @@ static int split_commit_in_progress(struct wt_status *s)
!s->branch || strcmp(s->branch, "HEAD"))
return 0;
- if (refs_read_ref_full(get_main_ref_store(the_repository), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+ if (refs_read_ref_full(get_main_ref_store(s->repo), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
&head_oid, &head_flags) ||
- refs_read_ref_full(get_main_ref_store(the_repository), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+ refs_read_ref_full(get_main_ref_store(s->repo), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
&orig_head_oid, &orig_head_flags))
return 0;
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
@@ -1362,7 +1362,7 @@ static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
return;
if ((2 <= string_list_split(&split, line->buf, " ", 2)) &&
- !repo_get_oid(the_repository, split.items[1].string, &oid)) {
+ !repo_get_oid(r, split.items[1].string, &oid)) {
strbuf_reset(line);
strbuf_addf(line, "%s ", split.items[0].string);
strbuf_add_unique_abbrev(line, &oid, DEFAULT_ABBREV);
@@ -1375,7 +1375,7 @@ static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
static int read_rebase_todolist(struct repository *r, char *fname, struct string_list *lines)
{
struct strbuf buf = STRBUF_INIT;
- FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
+ FILE *f = fopen(repo_git_path_append(r, &buf, "%s", fname), "r");
int ret;
if (!f) {
@@ -1384,7 +1384,7 @@ static int read_rebase_todolist(struct repository *r, char *fname, struct string
goto out;
}
die_errno("Could not open file %s for reading",
- repo_git_path_replace(the_repository, &buf, "%s", fname));
+ repo_git_path_replace(r, &buf, "%s", fname));
}
while (!strbuf_getline_lf(&buf, f)) {
if (starts_with(buf.buf, comment_line_str))
@@ -1432,7 +1432,7 @@ static void show_rebase_information(struct wt_status *s,
i++)
status_printf_ln(s, color, " %s", have_done.items[i].string);
if (have_done.nr > nr_lines_to_show && s->hints) {
- char *path = repo_git_path(the_repository, "rebase-merge/done");
+ char *path = repo_git_path(s->repo, "rebase-merge/done");
status_printf_ln(s, color,
_(" (see more in file %s)"), path);
free(path);
@@ -1534,7 +1534,7 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
else
status_printf_ln(s, color,
_("You are currently cherry-picking commit %s."),
- repo_find_unique_abbrev(the_repository, &s->state.cherry_pick_head_oid,
+ repo_find_unique_abbrev(s->repo, &s->state.cherry_pick_head_oid,
DEFAULT_ABBREV));
if (s->hints) {
@@ -1564,7 +1564,7 @@ static void show_revert_in_progress(struct wt_status *s,
else
status_printf_ln(s, color,
_("You are currently reverting commit %s."),
- repo_find_unique_abbrev(the_repository, &s->state.revert_head_oid,
+ repo_find_unique_abbrev(s->repo, &s->state.revert_head_oid,
DEFAULT_ABBREV));
if (s->hints) {
if (has_unmerged(s))
@@ -1624,7 +1624,7 @@ static char *get_branch(struct repository *r, struct worktree *wt, const char *p
struct object_id oid;
const char *branch_name;
- if (strbuf_read_file(&sb, worktree_git_path(the_repository, wt, "%s", path), 0) <= 0)
+ if (strbuf_read_file(&sb, worktree_git_path(r, wt, "%s", path), 0) <= 0)
goto got_nothing;
while (sb.len && sb.buf[sb.len - 1] == '\n')
@@ -1691,7 +1691,7 @@ static void wt_status_get_detached_from(struct repository *r,
char *ref = NULL;
strbuf_init(&cb.buf, 0);
- if (refs_for_each_reflog_ent_reverse(get_main_ref_store(the_repository), "HEAD", grab_1st_switch, &cb) <= 0) {
+ if (refs_for_each_reflog_ent_reverse(get_main_ref_store(r), "HEAD", grab_1st_switch, &cb) <= 0) {
strbuf_release(&cb.buf);
return;
}
@@ -1724,18 +1724,18 @@ int wt_status_check_rebase(struct repository *r,
{
struct stat st;
- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
+ if (!stat(worktree_git_path(r, wt, "rebase-apply"), &st)) {
+ if (!stat(worktree_git_path(r, wt, "rebase-apply/applying"), &st)) {
state->am_in_progress = 1;
- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/patch"), &st) && !st.st_size)
+ if (!stat(worktree_git_path(r, wt, "rebase-apply/patch"), &st) && !st.st_size)
state->am_empty_patch = 1;
} else {
state->rebase_in_progress = 1;
state->branch = get_branch(r, wt, "rebase-apply/head-name");
state->onto = get_branch(r, wt, "rebase-apply/onto");
}
- } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
- if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
+ } else if (!stat(worktree_git_path(r, wt, "rebase-merge"), &st)) {
+ if (!stat(worktree_git_path(r, wt, "rebase-merge/interactive"), &st))
state->rebase_interactive_in_progress = 1;
else
state->rebase_in_progress = 1;
@@ -1752,7 +1752,7 @@ int wt_status_check_bisect(struct repository *r,
{
struct stat st;
- if (!stat(worktree_git_path(the_repository, wt, "BISECT_LOG"), &st)) {
+ if (!stat(worktree_git_path(r, wt, "BISECT_LOG"), &st)) {
state->bisect_in_progress = 1;
state->bisecting_from = get_branch(r, wt, "BISECT_START");
return 1;
@@ -2101,7 +2101,7 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
upstream_is_gone = 1;
}
- short_base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
+ short_base = refs_shorten_unambiguous_ref(get_main_ref_store(s->repo),
base, 0);
color_fprintf(s->fp, header_color, "...");
color_fprintf(s->fp, branch_color_remote, "%s", short_base);
@@ -2235,7 +2235,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
ab_info = stat_tracking_info(branch, &nr_ahead, &nr_behind,
&base, 0, s->ahead_behind_flags);
if (base) {
- base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
+ base = refs_shorten_unambiguous_ref(get_main_ref_store(s->repo),
base, 0);
fprintf(s->fp, "# branch.upstream %s%c", base, eol);
free((char *)base);
--
2.52.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v3 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo
2026-02-07 10:00 ` [PATCH v3 " Shreyansh Paliwal
2026-02-07 10:00 ` [PATCH v3 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
2026-02-07 10:00 ` [PATCH v3 2/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
@ 2026-02-07 10:00 ` Shreyansh Paliwal
2 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-07 10:00 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123, Shreyansh Paliwal
wt-status.c still uses the global the_hash_algo even though a repository
instance is already available via struct wt_status.
Replace uses of the_hash_algo with the hash algorithm stored in the
associated repository (s->repo->hash_algo or r->hash_algo).
This removes another dependency on global state and keeps wt-status
consistent with local repository usage.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
wt-status.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index 0270d544d9..b68b3d3fde 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1817,10 +1817,10 @@ void wt_status_get_state(struct repository *r,
if (!sequencer_get_last_command(r, &action)) {
if (action == REPLAY_PICK && !state->cherry_pick_in_progress) {
state->cherry_pick_in_progress = 1;
- oidcpy(&state->cherry_pick_head_oid, null_oid(the_hash_algo));
+ oidcpy(&state->cherry_pick_head_oid, null_oid(r->hash_algo));
} else if (action == REPLAY_REVERT && !state->revert_in_progress) {
state->revert_in_progress = 1;
- oidcpy(&state->revert_head_oid, null_oid(the_hash_algo));
+ oidcpy(&state->revert_head_oid, null_oid(r->hash_algo));
}
}
if (get_detached_from)
@@ -2632,7 +2632,7 @@ int has_uncommitted_changes(struct repository *r,
* We have no head (or it's corrupt); use the empty tree,
* which will complain if the index is non-empty.
*/
- struct tree *tree = lookup_tree(r, the_hash_algo->empty_tree);
+ struct tree *tree = lookup_tree(r, r->hash_algo->empty_tree);
add_pending_object(&rev_info, &tree->object, "");
}
--
2.52.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* Re: [PATCH v3 1/3] wt-status: pass struct repository through function parameters
2026-02-07 10:00 ` [PATCH v3 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
@ 2026-02-08 1:14 ` Junio C Hamano
2026-02-08 4:55 ` [PATCH V2 2/3] wt-status: pass struct repository and wt_status " Shreyansh Paliwal
2026-02-09 8:36 ` [PATCH v3 1/3] wt-status: pass struct repository " Karthik Nayak
2026-02-08 1:21 ` Junio C Hamano
1 sibling, 2 replies; 69+ messages in thread
From: Junio C Hamano @ 2026-02-08 1:14 UTC (permalink / raw)
To: Shreyansh Paliwal; +Cc: git, karthik.188, phillip.wood123
Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
> branch.c | 4 ++--
> worktree.c | 4 ++--
> wt-status.c | 48 +++++++++++++++++++++++++-----------------------
> wt-status.h | 6 ++++--
> 4 files changed, 33 insertions(+), 29 deletions(-)
>
> diff --git a/branch.c b/branch.c
> index 243db7d0fc..e3cf273339 100644
> --- a/branch.c
> +++ b/branch.c
> @@ -412,7 +412,7 @@ static void prepare_checked_out_branches(void)
> free(old);
> }
>
> - if (wt_status_check_rebase(wt, &state) &&
> + if (wt_status_check_rebase(wt->repo, wt, &state) &&
I am not sure if this is an improvement for callers of the API.
Isn't wt_anything() that takes a worktree "wt" supposed to work with
the wt->repo repository? Or is the API designed to be used to take
any repository object that is _different_ from wt->repo? I am
assuming it is the former, and if so, the only effect of adding a
repository parameter to a function that already takes struct
worktree is to invite a programming error to pass a repository that
the wt is not designed to work with, isn't it?
> - if (wt_status_check_bisect(wt, &state) &&
> + if (wt_status_check_bisect(wt->repo, wt, &state) &&
Ditto.
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v3 1/3] wt-status: pass struct repository through function parameters
2026-02-07 10:00 ` [PATCH v3 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
2026-02-08 1:14 ` Junio C Hamano
@ 2026-02-08 1:21 ` Junio C Hamano
2026-02-08 4:44 ` [PATCH V2 2/3] wt-status: pass struct repository and wt_status " Shreyansh Paliwal
1 sibling, 1 reply; 69+ messages in thread
From: Junio C Hamano @ 2026-02-08 1:21 UTC (permalink / raw)
To: Shreyansh Paliwal; +Cc: git, karthik.188, phillip.wood123
Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
> -int wt_status_check_rebase(const struct worktree *wt,
> - struct wt_status_state *state)
> +int wt_status_check_rebase(struct repository *r,
> + const struct worktree *wt,
> + struct wt_status_state *state)
Funny indentation.
Besides, should we adding a yet another repository parameter to the
function? The worktree wt knows what repository it belongs to.
> -int wt_status_check_bisect(const struct worktree *wt,
> +int wt_status_check_bisect(struct repository *r,
> + struct worktree *wt,
> struct wt_status_state *state)
Same comment about "r" vs "wt->repo" applies here.
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-08 1:21 ` Junio C Hamano
@ 2026-02-08 4:44 ` Shreyansh Paliwal
2026-02-08 6:08 ` Junio C Hamano
0 siblings, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-08 4:44 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123
> Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>
> > -int wt_status_check_rebase(const struct worktree *wt,
> > - struct wt_status_state *state)
> > +int wt_status_check_rebase(struct repository *r,
> > + const struct worktree *wt,
> > + struct wt_status_state *state)
>
> Funny indentation.
my bad, will fix it.
>
> Besides, should we adding a yet another repository parameter to the
> function? The worktree wt knows what repository it belongs to.
>
> > -int wt_status_check_bisect(const struct worktree *wt,
> > +int wt_status_check_bisect(struct repository *r,
> > + struct worktree *wt,
> > struct wt_status_state *state)
>
> Same comment about "r" vs "wt->repo" applies here.
Actually adding another repository parameter to both of these functions
is needed because of the calls like wt_status_check_rebase(NULL, state)
and wt_status_check_bisect(NULL, state) from wt_status_get_state().
In the case where wt is NULL, accessing wt->repo can lead to issues.
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-08 1:14 ` Junio C Hamano
@ 2026-02-08 4:55 ` Shreyansh Paliwal
2026-02-09 8:36 ` [PATCH v3 1/3] wt-status: pass struct repository " Karthik Nayak
1 sibling, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-08 4:55 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123
> Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>
> > branch.c | 4 ++--
> > worktree.c | 4 ++--
> > wt-status.c | 48 +++++++++++++++++++++++++-----------------------
> > wt-status.h | 6 ++++--
> > 4 files changed, 33 insertions(+), 29 deletions(-)
> >
> > diff --git a/branch.c b/branch.c
> > index 243db7d0fc..e3cf273339 100644
> > --- a/branch.c
> > +++ b/branch.c
> > @@ -412,7 +412,7 @@ static void prepare_checked_out_branches(void)
> > free(old);
> > }
> >
> > - if (wt_status_check_rebase(wt, &state) &&
> > + if (wt_status_check_rebase(wt->repo, wt, &state) &&
>
> I am not sure if this is an improvement for callers of the API.
>
> Isn't wt_anything() that takes a worktree "wt" supposed to work with
> the wt->repo repository? Or is the API designed to be used to take
> any repository object that is _different_ from wt->repo? I am
> assuming it is the former, and if so, the only effect of adding a
> repository parameter to a function that already takes struct
> worktree is to invite a programming error to pass a repository that
> the wt is not designed to work with, isn't it?
>
> > - if (wt_status_check_bisect(wt, &state) &&
> > + if (wt_status_check_bisect(wt->repo, wt, &state) &&
>
> Ditto.
You are right that when a worktree is present, the repository
associated with should be wt->repo, and callers should not be expected
to provide something different.
The reason I introduced an explicit struct repository *r
parameter I have included in the previous reply.
So the intention is not to allow a repository different from
wt->repo, but to make it possible to operate in the absence of a
worktree. When wt is non-NULL, the expectation remains that callers
pass wt->repo, and in the case in which passed repo and wt->repo are
different worktree_git_path() would handle this case in a BUG().
Best,
Shreyansh
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-08 4:44 ` [PATCH V2 2/3] wt-status: pass struct repository and wt_status " Shreyansh Paliwal
@ 2026-02-08 6:08 ` Junio C Hamano
2026-02-08 15:25 ` Shreyansh Paliwal
0 siblings, 1 reply; 69+ messages in thread
From: Junio C Hamano @ 2026-02-08 6:08 UTC (permalink / raw)
To: Shreyansh Paliwal; +Cc: git, karthik.188, phillip.wood123
Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>> Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>>
>> > -int wt_status_check_rebase(const struct worktree *wt,
>> > - struct wt_status_state *state)
>> > +int wt_status_check_rebase(struct repository *r,
>> > + const struct worktree *wt,
>> > + struct wt_status_state *state)
>>
>> Funny indentation.
>
> my bad, will fix it.
>
>>
>> Besides, should we adding a yet another repository parameter to the
>> function? The worktree wt knows what repository it belongs to.
>>
>> > -int wt_status_check_bisect(const struct worktree *wt,
>> > +int wt_status_check_bisect(struct repository *r,
>> > + struct worktree *wt,
>> > struct wt_status_state *state)
>>
>> Same comment about "r" vs "wt->repo" applies here.
>
> Actually adding another repository parameter to both of these functions
> is needed because of the calls like wt_status_check_rebase(NULL, state)
> and wt_status_check_bisect(NULL, state) from wt_status_get_state().
> In the case where wt is NULL, accessing wt->repo can lead to issues.
But stopping thought at that point is not a reasonable thing to do,
immediately after you notice that wt is sometimes NULL. It merely
means that unconditionally dereferencing wt->repo without thinking
is not good enough, doesn't it?
And what is the case where worktree is NULL? What are we doing with
worktree set to NULL? Is it when secondary worktrees do not come
into the picture at all and you can safely use the_repository?
... goes and looks ...
Ahh, I think the real culprit that needs cleaning up is the worktree
API, where they pass NULL to mean "the primary worktree that has its
.git/ directory at its natural place". So it may not necessarily be
the_repository we are dealing with. There is *no* such client code
right now, but we could imagine that a program that starts in a
repository visits the primary worktree of another repository and
asks the worktree status there, and once such a client code appears,
we need to be able to say "we are dealing with the primary worktree
for this repository".
In the longer run, I think we should fix the worktree API so that
even for the primary worktree we will always have a non-NULL "struct
worktree" object, perhaps with its .id member set to NULL to signal
that it is the primary worktree, so that we do not have to have this
strange "we must pass repository redundantly even though we are
passing worktree" API elsewhere. Not just this code you are making
worse, path.c:worktree_git_path() already is a victim of this
misdesign of the worktree API. It has "if wt is given, then the r
parameter should be the same as wt->repo" nonsense, which we
wouldn't have had to have if we had a worktree object even for the
primary worktree, Look at how ugly that code is, and weep X-<.
And the same misdesign of the worktree API has caused your [1/3] to
pass 'r' but yet still depend on the_repository, which you had to
fix in [2/3], in this function.
So, I dunno. If you are ambitious, you may want to clean up the
worktree API before this series. Alternatively you may be able to
punt on the parts of the wt-status that interact with worktree API,
and move the rest of wt-status less dependent on the_repository, but
I am not sure.
Thanks.
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-08 6:08 ` Junio C Hamano
@ 2026-02-08 15:25 ` Shreyansh Paliwal
2026-02-09 9:02 ` Karthik Nayak
0 siblings, 1 reply; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-08 15:25 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123
> Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>
> >> Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
> >>
> >> > -int wt_status_check_rebase(const struct worktree *wt,
> >> > - struct wt_status_state *state)
> >> > +int wt_status_check_rebase(struct repository *r,
> >> > + const struct worktree *wt,
> >> > + struct wt_status_state *state)
> >>
> >> Funny indentation.
> >
> > my bad, will fix it.
> >
> >>
> >> Besides, should we adding a yet another repository parameter to the
> >> function? The worktree wt knows what repository it belongs to.
> >>
> >> > -int wt_status_check_bisect(const struct worktree *wt,
> >> > +int wt_status_check_bisect(struct repository *r,
> >> > + struct worktree *wt,
> >> > struct wt_status_state *state)
> >>
> >> Same comment about "r" vs "wt->repo" applies here.
> >
> > Actually adding another repository parameter to both of these functions
> > is needed because of the calls like wt_status_check_rebase(NULL, state)
> > and wt_status_check_bisect(NULL, state) from wt_status_get_state().
> > In the case where wt is NULL, accessing wt->repo can lead to issues.
>
> But stopping thought at that point is not a reasonable thing to do,
> immediately after you notice that wt is sometimes NULL. It merely
> means that unconditionally dereferencing wt->repo without thinking
> is not good enough, doesn't it?
>
> And what is the case where worktree is NULL? What are we doing with
> worktree set to NULL? Is it when secondary worktrees do not come
> into the picture at all and you can safely use the_repository?
>
> ... goes and looks ...
>
> Ahh, I think the real culprit that needs cleaning up is the worktree
> API, where they pass NULL to mean "the primary worktree that has its
> .git/ directory at its natural place". So it may not necessarily be
> the_repository we are dealing with. There is *no* such client code
> right now, but we could imagine that a program that starts in a
> repository visits the primary worktree of another repository and
> asks the worktree status there, and once such a client code appears,
> we need to be able to say "we are dealing with the primary worktree
> for this repository".
>
> In the longer run, I think we should fix the worktree API so that
> even for the primary worktree we will always have a non-NULL "struct
> worktree" object, perhaps with its .id member set to NULL to signal
> that it is the primary worktree, so that we do not have to have this
> strange "we must pass repository redundantly even though we are
> passing worktree" API elsewhere. Not just this code you are making
> worse, path.c:worktree_git_path() already is a victim of this
> misdesign of the worktree API. It has "if wt is given, then the r
> parameter should be the same as wt->repo" nonsense, which we
> wouldn't have had to have if we had a worktree object even for the
> primary worktree, Look at how ugly that code is, and weep X-<.
>
> And the same misdesign of the worktree API has caused your [1/3] to
> pass 'r' but yet still depend on the_repository, which you had to
> fix in [2/3], in this function.
>
> So, I dunno. If you are ambitious, you may want to clean up the
> worktree API before this series. Alternatively you may be able to
> punt on the parts of the wt-status that interact with worktree API,
> and move the rest of wt-status less dependent on the_repository, but
> I am not sure.
Thank you very much for the detailed explanation and for pointing towards
the bigger picture.
From what I have understood, the worktree being NULL refers to the
primary worktree (as it does not indicate which repository so it means in
respect to the_repository). So if we want to access the primary worktree
of a specific repository or even the local repository, NULL does not carry
enough information.
And obviously, using NULL as primary worktree introduces extra checks and
measures as we saw in the previous discussion.
I would be very interested (and the more logical step) to fixing worktree api
first, and then revisiting the wt-status series on top of that, once the API
makes it possible to rely on wt->repo without the NULL risks.
So a possible in the worktree api cleanup approach could be,
* Make primary worktree as an instance of struct worktree but seperate
it by having a marker like id = NULL.
* Add this primary worktree in the struct repository (e.g. repo->primary_wt).
* Update/add functions, then find places that currently pass NULL
and convert them to use primary worktree object instead.
Let me know if I have the right understanding with this, and also would love
to hear more guidance on the direction with this worktree api cleanup. Thanks.
Best,
Shreyansh
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v3 1/3] wt-status: pass struct repository through function parameters
2026-02-08 1:14 ` Junio C Hamano
2026-02-08 4:55 ` [PATCH V2 2/3] wt-status: pass struct repository and wt_status " Shreyansh Paliwal
@ 2026-02-09 8:36 ` Karthik Nayak
1 sibling, 0 replies; 69+ messages in thread
From: Karthik Nayak @ 2026-02-09 8:36 UTC (permalink / raw)
To: Junio C Hamano, Shreyansh Paliwal; +Cc: git, phillip.wood123
[-- Attachment #1: Type: text/plain, Size: 1562 bytes --]
Junio C Hamano <gitster@pobox.com> writes:
> Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>
>> branch.c | 4 ++--
>> worktree.c | 4 ++--
>> wt-status.c | 48 +++++++++++++++++++++++++-----------------------
>> wt-status.h | 6 ++++--
>> 4 files changed, 33 insertions(+), 29 deletions(-)
>>
>> diff --git a/branch.c b/branch.c
>> index 243db7d0fc..e3cf273339 100644
>> --- a/branch.c
>> +++ b/branch.c
>> @@ -412,7 +412,7 @@ static void prepare_checked_out_branches(void)
>> free(old);
>> }
>>
>> - if (wt_status_check_rebase(wt, &state) &&
>> + if (wt_status_check_rebase(wt->repo, wt, &state) &&
>
> I am not sure if this is an improvement for callers of the API.
>
> Isn't wt_anything() that takes a worktree "wt" supposed to work with
> the wt->repo repository? Or is the API designed to be used to take
> any repository object that is _different_ from wt->repo? I am
> assuming it is the former, and if so, the only effect of adding a
> repository parameter to a function that already takes struct
> worktree is to invite a programming error to pass a repository that
> the wt is not designed to work with, isn't it?
>
Absolutely, In a previous version, the patched directly used `wt->repo`.
I pointed out that there are instances where `wt` could be NULL as per
the existing flow. So this change is in accordance with that. Overall I
think the fix should ideally be around how we work with worktrees.
>> - if (wt_status_check_bisect(wt, &state) &&
>> + if (wt_status_check_bisect(wt->repo, wt, &state) &&
>
> Ditto.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-08 15:25 ` Shreyansh Paliwal
@ 2026-02-09 9:02 ` Karthik Nayak
2026-02-09 13:43 ` Shreyansh Paliwal
2026-02-09 16:13 ` Junio C Hamano
0 siblings, 2 replies; 69+ messages in thread
From: Karthik Nayak @ 2026-02-09 9:02 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster, phillip.wood123
[-- Attachment #1: Type: text/plain, Size: 4865 bytes --]
Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
[snip]
>> > Actually adding another repository parameter to both of these functions
>> > is needed because of the calls like wt_status_check_rebase(NULL, state)
>> > and wt_status_check_bisect(NULL, state) from wt_status_get_state().
>> > In the case where wt is NULL, accessing wt->repo can lead to issues.
>>
>> But stopping thought at that point is not a reasonable thing to do,
>> immediately after you notice that wt is sometimes NULL. It merely
>> means that unconditionally dereferencing wt->repo without thinking
>> is not good enough, doesn't it?
>>
>> And what is the case where worktree is NULL? What are we doing with
>> worktree set to NULL? Is it when secondary worktrees do not come
>> into the picture at all and you can safely use the_repository?
>>
>> ... goes and looks ...
>>
>> Ahh, I think the real culprit that needs cleaning up is the worktree
>> API, where they pass NULL to mean "the primary worktree that has its
>> .git/ directory at its natural place". So it may not necessarily be
>> the_repository we are dealing with. There is *no* such client code
>> right now, but we could imagine that a program that starts in a
>> repository visits the primary worktree of another repository and
>> asks the worktree status there, and once such a client code appears,
>> we need to be able to say "we are dealing with the primary worktree
>> for this repository".
>>
>> In the longer run, I think we should fix the worktree API so that
>> even for the primary worktree we will always have a non-NULL "struct
>> worktree" object, perhaps with its .id member set to NULL to signal
>> that it is the primary worktree, so that we do not have to have this
>> strange "we must pass repository redundantly even though we are
>> passing worktree" API elsewhere. Not just this code you are making
>> worse, path.c:worktree_git_path() already is a victim of this
>> misdesign of the worktree API. It has "if wt is given, then the r
>> parameter should be the same as wt->repo" nonsense, which we
>> wouldn't have had to have if we had a worktree object even for the
>> primary worktree, Look at how ugly that code is, and weep X-<.
>>
>> And the same misdesign of the worktree API has caused your [1/3] to
>> pass 'r' but yet still depend on the_repository, which you had to
>> fix in [2/3], in this function.
>>
>> So, I dunno. If you are ambitious, you may want to clean up the
>> worktree API before this series. Alternatively you may be able to
>> punt on the parts of the wt-status that interact with worktree API,
>> and move the rest of wt-status less dependent on the_repository, but
>> I am not sure.
>
> Thank you very much for the detailed explanation and for pointing towards
> the bigger picture.
>
> From what I have understood, the worktree being NULL refers to the
> primary worktree (as it does not indicate which repository so it means in
> respect to the_repository). So if we want to access the primary worktree
> of a specific repository or even the local repository, NULL does not carry
> enough information.
> And obviously, using NULL as primary worktree introduces extra checks and
> measures as we saw in the previous discussion.
>
> I would be very interested (and the more logical step) to fixing worktree api
> first, and then revisiting the wt-status series on top of that, once the API
> makes it possible to rely on wt->repo without the NULL risks.
>
> So a possible in the worktree api cleanup approach could be,
>
> * Make primary worktree as an instance of struct worktree but seperate
> it by having a marker like id = NULL.
>
I would like to point out that we already have a function which provides
a main worktree, see both `get_main_worktree()` & `is_main_worktree()`.
In short, a worktree with id = NULL seems to be treated as the main
worktree.
The harder part would be correcting all code where `struct worktree *`
is passed and has special meaning for NULL vs non-NULL. See
`strbuf_worktree_gitdir()` which also distinguishes between `wt ==
NULL`, `wt->id == NULL` and `wt->id != NULL`.
So cleanup would require identifying all such spots and fixing them too.
> * Add this primary worktree in the struct repository (e.g. repo->primary_wt).
>
This also is tricky. We currently already store all worktrees in the
repository in `struct strmap worktree_ref_stores`. Here, for the main
worktree we use '\' (see `get_worktree_ref_store()`). So perhaps we
should formalize using `\` for the main worktree everywhere.
> * Update/add functions, then find places that currently pass NULL
> and convert them to use primary worktree object instead.
>
> Let me know if I have the right understanding with this, and also would love
> to hear more guidance on the direction with this worktree api cleanup. Thanks.
>
> Best,
> Shreyansh
Karthik
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-09 9:02 ` Karthik Nayak
@ 2026-02-09 13:43 ` Shreyansh Paliwal
2026-02-09 16:13 ` Junio C Hamano
1 sibling, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-09 13:43 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188, phillip.wood123
[...]
> > Thank you very much for the detailed explanation and for pointing towards
> > the bigger picture.
> >
> > From what I have understood, the worktree being NULL refers to the
> > primary worktree (as it does not indicate which repository so it means in
> > respect to the_repository). So if we want to access the primary worktree
> > of a specific repository or even the local repository, NULL does not carry
> > enough information.
> > And obviously, using NULL as primary worktree introduces extra checks and
> > measures as we saw in the previous discussion.
> >
> > I would be very interested (and the more logical step) to fixing worktree api
> > first, and then revisiting the wt-status series on top of that, once the API
> > makes it possible to rely on wt->repo without the NULL risks.
> >
> > So a possible in the worktree api cleanup approach could be,
> >
> > * Make primary worktree as an instance of struct worktree but seperate
> > it by having a marker like id = NULL.
> >
>
> I would like to point out that we already have a function which provides
> a main worktree, see both `get_main_worktree()` & `is_main_worktree()`.
> In short, a worktree with id = NULL seems to be treated as the main
> worktree.
>
> The harder part would be correcting all code where `struct worktree *`
> is passed and has special meaning for NULL vs non-NULL. See
> `strbuf_worktree_gitdir()` which also distinguishes between `wt ==
> NULL`, `wt->id == NULL` and `wt->id != NULL`.
>
> So cleanup would require identifying all such spots and fixing them too.
>
> > * Add this primary worktree in the struct repository (e.g. repo->primary_wt).
> >
>
> This also is tricky. We currently already store all worktrees in the
> repository in `struct strmap worktree_ref_stores`. Here, for the main
> worktree we use '\' (see `get_worktree_ref_store()`). So perhaps we
> should formalize using `\` for the main worktree everywhere.
Thanks for these points, I definitely need a better understanding of the
whole worktree api usage and flow before anything further. So I am going to
spend some time on it. Once I have a clearer picture, I will send a
seperate rfc attempt on this cleanup and we can discuss it further there.
Best,
Shreyansh
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-09 9:02 ` Karthik Nayak
2026-02-09 13:43 ` Shreyansh Paliwal
@ 2026-02-09 16:13 ` Junio C Hamano
2026-02-10 9:50 ` Karthik Nayak
1 sibling, 1 reply; 69+ messages in thread
From: Junio C Hamano @ 2026-02-09 16:13 UTC (permalink / raw)
To: Karthik Nayak; +Cc: Shreyansh Paliwal, git, phillip.wood123
Karthik Nayak <karthik.188@gmail.com> writes:
> I would like to point out that we already have a function which provides
> a main worktree, see both `get_main_worktree()` & `is_main_worktree()`.
> In short, a worktree with id = NULL seems to be treated as the main
> worktree.
>
> The harder part would be correcting all code where `struct worktree *`
> is passed and has special meaning for NULL vs non-NULL. See
> `strbuf_worktree_gitdir()` which also distinguishes between `wt ==
> NULL`, `wt->id == NULL` and `wt->id != NULL`.
>
> So cleanup would require identifying all such spots and fixing them too.
Yup. That is why I upfront said "if you are ambitious" ;-)
> This also is tricky. We currently already store all worktrees in the
> repository in `struct strmap worktree_ref_stores`. Here, for the main
> worktree we use '\' (see `get_worktree_ref_store()`). So perhaps we
> should formalize using `\` for the main worktree everywhere.
Is this a joke, is my terminal broken, or is my MUA hallucinating?
I see a couple of backslashes in the above, and in the code I have
a forward slash instead.
But you are right, ref-store-map does use a slash to indicate the
primary one, while worktree itself uses a NULL, which is somewhat
understandable (NULL would not be a convenient hashmap key). And I
do not think I see any downsides (other than "This used to take NULL
as the sign of primari-ness but now we need to use a '/' instead"
fixes we need everywhere) to use "/" on the wt->id side offhand.
Thanks.
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters
2026-02-09 16:13 ` Junio C Hamano
@ 2026-02-10 9:50 ` Karthik Nayak
0 siblings, 0 replies; 69+ messages in thread
From: Karthik Nayak @ 2026-02-10 9:50 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Shreyansh Paliwal, git, phillip.wood123
[-- Attachment #1: Type: text/plain, Size: 1701 bytes --]
Junio C Hamano <gitster@pobox.com> writes:
> Karthik Nayak <karthik.188@gmail.com> writes:
>
>> I would like to point out that we already have a function which provides
>> a main worktree, see both `get_main_worktree()` & `is_main_worktree()`.
>> In short, a worktree with id = NULL seems to be treated as the main
>> worktree.
>>
>> The harder part would be correcting all code where `struct worktree *`
>> is passed and has special meaning for NULL vs non-NULL. See
>> `strbuf_worktree_gitdir()` which also distinguishes between `wt ==
>> NULL`, `wt->id == NULL` and `wt->id != NULL`.
>>
>> So cleanup would require identifying all such spots and fixing them too.
>
> Yup. That is why I upfront said "if you are ambitious" ;-)
>
>> This also is tricky. We currently already store all worktrees in the
>> repository in `struct strmap worktree_ref_stores`. Here, for the main
>> worktree we use '\' (see `get_worktree_ref_store()`). So perhaps we
>> should formalize using `\` for the main worktree everywhere.
>
> Is this a joke, is my terminal broken, or is my MUA hallucinating?
> I see a couple of backslashes in the above, and in the code I have
> a forward slash instead.
>
Seems like my fingers didn't type what my mind thought of.
> But you are right, ref-store-map does use a slash to indicate the
> primary one, while worktree itself uses a NULL, which is somewhat
> understandable (NULL would not be a convenient hashmap key). And I
> do not think I see any downsides (other than "This used to take NULL
> as the sign of primari-ness but now we need to use a '/' instead"
> fixes we need everywhere) to use "/" on the wt->id side offhand.
>
> Thanks.
Yeah I share the same sentiment.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH v4 0/3] wt-status: reduce reliance on global state
2026-01-31 18:57 [PATCH 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
` (3 preceding siblings ...)
2026-02-05 10:13 ` [PATCH V2 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
@ 2026-02-17 17:29 ` Shreyansh Paliwal
2026-02-17 17:29 ` [PATCH v4 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
` (3 more replies)
2026-02-18 17:53 ` [PATCH v5 " Shreyansh Paliwal
5 siblings, 4 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-17 17:29 UTC (permalink / raw)
To: git; +Cc: phillip.wood123, gitster, karthik.188, Shreyansh Paliwal
In wt-status.c code still relies on some global variables, including
the_repository and the_hash_algo, even in cases where a repository
instance is already available via struct wt_status or struct repository.
In patch 1/3, update function parameters and callers to pass struct
repository where no local repository access was available.
In patch 2/3, replace direct uses of the_repository with repository
instances already available in local structs.
In patch 3/3, replace remaining uses of the global the_hash_algo with the
hash algorithm stored in the respective repository instance.
These changes remove uses of the_repository and the_hash_algo from
wt-status.c and reduce its dependence on global state.
The 'USE_THE_REPOSITORY_VARIABLE' macro cannot yet be removed, since these
patches only eliminate some uses of the_repository and the_hash_algo,
while some global variables are still referenced.
In particular wt-status.c still relies on the following globals,
* the_repository, this is still used in functions like worktree_git_path() and
wt_status_check_bisect/rebase() which are dependant on the worktree API and they
are being handled in a seperate patch series[1].
* core_apply_sparse_checkout, this is already being addressed in an
ongoing patch series [2].
* comment_line_str and DEFAULT_ABBREV, these both still are used in
wt-status.c but they dont have any equivalent local instances.
[1]- https://lore.kernel.org/git/20260213120529.15475-1-shreyanshpaliwalcmsmn@gmail.com/T/#mf664ad751faaf2eaca138302b1cc9d3856c9fec3
[2]- https://lore.kernel.org/git/5e56e1cc4172cfff9e917a068184e102aa70bf1d.1769256839.git.belkid98@gmail.com/t/#u
Shreyansh Paliwal (3):
wt-status: pass struct repository through function parameters
wt-status: replace uses of the_repository with local repository
instances
wt-status: use hash_algo from local repository instead of global
the_hash_algo
wt-status.c | 62 ++++++++++++++++++++++++++---------------------------
1 file changed, 31 insertions(+), 31 deletions(-)
---
Changes in v4:
- removed the changes regarding worktree_git_path() and
wt_status_check_bisect/rebase() as they are better handled seperately.
Range-diff against v3:
1: 960216e45c ! 1: a3683a5e17 wt-status: pass struct repository through function parameters
@@ Commit message
do not have access to a local repository instance and rely on the_repository.
Add a struct repository *r parameter to these functions, and pass the local
- repository through the callers.
-
- get_branch(), wt_status_check_rebase() and wt_status_check_bisect() already
- receive a struct worktree *, which can provide access to the repository.
- However, some callers pass NULL as the worktree like in wt_status_get_state(),
- which would make using wt->repo unsafe and lead to segfault issues.
- Add an explicit struct repository * parameter to these functions as well,
- and pass the repository through the callers.
-
- Both wt_status_check_rebase() and wt_status_check_bisect() are called from
- branch.c and worktree.c,
-
- * In branch.c, wt is always non-NULL as the functions are called within an
- interation over worktrees in prepare_checked_out_branches().
- * In worktree.c the functions are called from is_worktree_being_rebased() and
- is_worktree_being_bisected() respectively which are further called from
- builtin/branch.c in reject_rebase_or_bisect_branch() which has a non-NULL
- worktree as it is called inside an iteration over worktrees as well.
+ repository through the callers where already they can access a local repository
+ instance either directly by struct repository *r or
+ by struct wt_state *s (s->repo).
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
- ## branch.c ##
-@@ branch.c: static void prepare_checked_out_branches(void)
- free(old);
- }
-
-- if (wt_status_check_rebase(wt, &state) &&
-+ if (wt_status_check_rebase(wt->repo, wt, &state) &&
- (state.rebase_in_progress || state.rebase_interactive_in_progress) &&
- state.branch) {
- struct strbuf ref = STRBUF_INIT;
-@@ branch.c: static void prepare_checked_out_branches(void)
- }
- wt_status_state_free_buffers(&state);
-
-- if (wt_status_check_bisect(wt, &state) &&
-+ if (wt_status_check_bisect(wt->repo, wt, &state) &&
- state.bisecting_from) {
- struct strbuf ref = STRBUF_INIT;
- strbuf_addf(&ref, "refs/heads/%s", state.bisecting_from);
-
- ## worktree.c ##
-@@ worktree.c: int is_worktree_being_rebased(const struct worktree *wt,
- int found_rebase;
-
- memset(&state, 0, sizeof(state));
-- found_rebase = wt_status_check_rebase(wt, &state) &&
-+ found_rebase = wt_status_check_rebase(wt->repo, wt, &state) &&
- (state.rebase_in_progress ||
- state.rebase_interactive_in_progress) &&
- state.branch &&
-@@ worktree.c: int is_worktree_being_bisected(const struct worktree *wt,
- int found_bisect;
-
- memset(&state, 0, sizeof(state));
-- found_bisect = wt_status_check_bisect(wt, &state) &&
-+ found_bisect = wt_status_check_bisect(wt->repo, wt, &state) &&
- state.bisecting_from &&
- skip_prefix(target, "refs/heads/", &target) &&
- !strcmp(state.bisecting_from, target);
-
## wt-status.c ##
@@ wt-status.c: static int stash_count_refs(const char *refname UNUSED,
return 0;
@@ wt-status.c: static void show_am_in_progress(struct wt_status *s,
}
-static char *read_line_from_git_path(const char *filename)
-+static char *read_line_from_git_path(struct repository *r, char *filename)
++static char *read_line_from_git_path(struct repository *r, const char *filename)
{
struct strbuf buf = STRBUF_INIT;
FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
@@ wt-status.c: static void abbrev_oid_in_line(struct strbuf *line)
}
-static int read_rebase_todolist(const char *fname, struct string_list *lines)
-+static int read_rebase_todolist(struct repository *r, char *fname, struct string_list *lines)
++static int read_rebase_todolist(struct repository *r, const char *fname, struct string_list *lines)
{
struct strbuf buf = STRBUF_INIT;
FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
@@ wt-status.c: static void show_rebase_information(struct wt_status *s,
&yet_to_do))
status_printf_ln(s, color,
_("git-rebase-todo is missing."));
-@@ wt-status.c: static void show_sparse_checkout_in_use(struct wt_status *s,
- /*
- * Extract branch information from rebase/bisect
- */
--static char *get_branch(const struct worktree *wt, const char *path)
-+static char *get_branch(struct repository *r, struct worktree *wt, const char *path)
- {
- struct strbuf sb = STRBUF_INIT;
- struct object_id oid;
-@@ wt-status.c: static void wt_status_get_detached_from(struct repository *r,
- strbuf_release(&cb.buf);
- }
-
--int wt_status_check_rebase(const struct worktree *wt,
-- struct wt_status_state *state)
-+int wt_status_check_rebase(struct repository *r,
-+ const struct worktree *wt,
-+ struct wt_status_state *state)
- {
- struct stat st;
-
-@@ wt-status.c: int wt_status_check_rebase(const struct worktree *wt,
- state->am_empty_patch = 1;
- } else {
- state->rebase_in_progress = 1;
-- state->branch = get_branch(wt, "rebase-apply/head-name");
-- state->onto = get_branch(wt, "rebase-apply/onto");
-+ state->branch = get_branch(r, wt, "rebase-apply/head-name");
-+ state->onto = get_branch(r, wt, "rebase-apply/onto");
- }
- } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
- if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
- state->rebase_interactive_in_progress = 1;
- else
- state->rebase_in_progress = 1;
-- state->branch = get_branch(wt, "rebase-merge/head-name");
-- state->onto = get_branch(wt, "rebase-merge/onto");
-+ state->branch = get_branch(r, wt, "rebase-merge/head-name");
-+ state->onto = get_branch(r, wt, "rebase-merge/onto");
- } else
- return 0;
- return 1;
- }
-
--int wt_status_check_bisect(const struct worktree *wt,
-+int wt_status_check_bisect(struct repository *r,
-+ struct worktree *wt,
- struct wt_status_state *state)
- {
- struct stat st;
-
- if (!stat(worktree_git_path(the_repository, wt, "BISECT_LOG"), &st)) {
- state->bisect_in_progress = 1;
-- state->bisecting_from = get_branch(wt, "BISECT_START");
-+ state->bisecting_from = get_branch(r, wt, "BISECT_START");
- return 1;
- }
- return 0;
-@@ wt-status.c: void wt_status_get_state(struct repository *r,
- enum replay_action action;
-
- if (!stat(git_path_merge_head(r), &st)) {
-- wt_status_check_rebase(NULL, state);
-+ wt_status_check_rebase(r, NULL, state);
- state->merge_in_progress = 1;
-- } else if (wt_status_check_rebase(NULL, state)) {
-+ } else if (wt_status_check_rebase(r, NULL, state)) {
- ; /* all set */
- } else if (refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&
- !repo_get_oid(r, "CHERRY_PICK_HEAD", &oid)) {
- state->cherry_pick_in_progress = 1;
- oidcpy(&state->cherry_pick_head_oid, &oid);
- }
-- wt_status_check_bisect(NULL, state);
-+ wt_status_check_bisect(r, NULL, state);
- if (refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD") &&
- !repo_get_oid(r, "REVERT_HEAD", &oid)) {
- state->revert_in_progress = 1;
@@ wt-status.c: static void wt_porcelain_v2_print_tracking(struct wt_status *s)
*/
static void wt_porcelain_v2_print_stash(struct wt_status *s)
@@ wt-status.c: static void wt_porcelain_v2_print_tracking(struct wt_status *s)
char eol = s->null_termination ? '\0' : '\n';
if (stash_count > 0)
-
- ## wt-status.h ##
-@@ wt-status.h: void wt_status_state_free_buffers(struct wt_status_state *s);
- void wt_status_get_state(struct repository *repo,
- struct wt_status_state *state,
- int get_detached_from);
--int wt_status_check_rebase(const struct worktree *wt,
-+int wt_status_check_rebase(struct repository *r,
-+ struct worktree *wt,
- struct wt_status_state *state);
--int wt_status_check_bisect(const struct worktree *wt,
-+int wt_status_check_bisect(struct repository *r,
-+ struct worktree *wt,
- struct wt_status_state *state);
-
- __attribute__((format (printf, 3, 4)))
2: 906e682cd7 ! 2: f3b4c3e972 wt-status: replace uses of the_repository with local repository instances
@@ Commit message
struct repository *r.
Replace these uses of the_repository with the repository available
- in the local context (eg. s->repo or r).
+ in the local context (i.e. s->repo or r).
The replacements of all the_repository with s->repo are mostly
to cases where a repository instance is already available via
@@ wt-status.c: static void wt_longstatus_print_verbose(struct wt_status *s)
rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
@@ wt-status.c: static void show_am_in_progress(struct wt_status *s,
- static char *read_line_from_git_path(struct repository *r, char *filename)
+ static char *read_line_from_git_path(struct repository *r, const char *filename)
{
struct strbuf buf = STRBUF_INIT;
- FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
@@ wt-status.c: static void abbrev_oid_in_line(struct repository *r, struct strbuf
strbuf_addf(line, "%s ", split.items[0].string);
strbuf_add_unique_abbrev(line, &oid, DEFAULT_ABBREV);
@@ wt-status.c: static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
- static int read_rebase_todolist(struct repository *r, char *fname, struct string_list *lines)
+ static int read_rebase_todolist(struct repository *r, const char *fname, struct string_list *lines)
{
struct strbuf buf = STRBUF_INIT;
- FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
@@ wt-status.c: static void abbrev_oid_in_line(struct repository *r, struct strbuf
int ret;
if (!f) {
-@@ wt-status.c: static int read_rebase_todolist(struct repository *r, char *fname, struct string
+@@ wt-status.c: static int read_rebase_todolist(struct repository *r, const char *fname, struct
goto out;
}
die_errno("Could not open file %s for reading",
@@ wt-status.c: static void show_revert_in_progress(struct wt_status *s,
DEFAULT_ABBREV));
if (s->hints) {
if (has_unmerged(s))
-@@ wt-status.c: static char *get_branch(struct repository *r, struct worktree *wt, const char *p
- struct object_id oid;
- const char *branch_name;
-
-- if (strbuf_read_file(&sb, worktree_git_path(the_repository, wt, "%s", path), 0) <= 0)
-+ if (strbuf_read_file(&sb, worktree_git_path(r, wt, "%s", path), 0) <= 0)
- goto got_nothing;
-
- while (sb.len && sb.buf[sb.len - 1] == '\n')
@@ wt-status.c: static void wt_status_get_detached_from(struct repository *r,
char *ref = NULL;
@@ wt-status.c: static void wt_status_get_detached_from(struct repository *r,
strbuf_release(&cb.buf);
return;
}
-@@ wt-status.c: int wt_status_check_rebase(struct repository *r,
- {
- struct stat st;
-
-- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
-- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
-+ if (!stat(worktree_git_path(r, wt, "rebase-apply"), &st)) {
-+ if (!stat(worktree_git_path(r, wt, "rebase-apply/applying"), &st)) {
- state->am_in_progress = 1;
-- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/patch"), &st) && !st.st_size)
-+ if (!stat(worktree_git_path(r, wt, "rebase-apply/patch"), &st) && !st.st_size)
- state->am_empty_patch = 1;
- } else {
- state->rebase_in_progress = 1;
- state->branch = get_branch(r, wt, "rebase-apply/head-name");
- state->onto = get_branch(r, wt, "rebase-apply/onto");
- }
-- } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
-- if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
-+ } else if (!stat(worktree_git_path(r, wt, "rebase-merge"), &st)) {
-+ if (!stat(worktree_git_path(r, wt, "rebase-merge/interactive"), &st))
- state->rebase_interactive_in_progress = 1;
- else
- state->rebase_in_progress = 1;
-@@ wt-status.c: int wt_status_check_bisect(struct repository *r,
- {
- struct stat st;
-
-- if (!stat(worktree_git_path(the_repository, wt, "BISECT_LOG"), &st)) {
-+ if (!stat(worktree_git_path(r, wt, "BISECT_LOG"), &st)) {
- state->bisect_in_progress = 1;
- state->bisecting_from = get_branch(r, wt, "BISECT_START");
- return 1;
@@ wt-status.c: static void wt_shortstatus_print_tracking(struct wt_status *s)
upstream_is_gone = 1;
}
3: 9c0a1d82ad = 3: 7efaf6b3fb wt-status: use hash_algo from local repository instead of global the_hash_algo
--
2.53.0
^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH v4 1/3] wt-status: pass struct repository through function parameters
2026-02-17 17:29 ` [PATCH v4 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
@ 2026-02-17 17:29 ` Shreyansh Paliwal
2026-02-17 17:29 ` [PATCH v4 2/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
` (2 subsequent siblings)
3 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-17 17:29 UTC (permalink / raw)
To: git; +Cc: phillip.wood123, gitster, karthik.188, Shreyansh Paliwal
Some functions in wt-status.c (count_stash_entries(),
read_line_from_git_path(), abbrev_oid_in_line(), read_rebase_todolist())
do not have access to a local repository instance and rely on the_repository.
Add a struct repository *r parameter to these functions, and pass the local
repository through the callers where already they can access a local repository
instance either directly by struct repository *r or
by struct wt_state *s (s->repo).
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
wt-status.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index e12adb26b9..e10565f495 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -984,7 +984,7 @@ static int stash_count_refs(const char *refname UNUSED,
return 0;
}
-static int count_stash_entries(void)
+static int count_stash_entries(struct repository *r)
{
int n = 0;
refs_for_each_reflog_ent(get_main_ref_store(the_repository),
@@ -994,7 +994,7 @@ static int count_stash_entries(void)
static void wt_longstatus_print_stash_summary(struct wt_status *s)
{
- int stash_count = count_stash_entries();
+ int stash_count = count_stash_entries(s->repo);
if (stash_count > 0)
status_printf_ln(s, GIT_COLOR_NORMAL,
@@ -1287,7 +1287,7 @@ static void show_am_in_progress(struct wt_status *s,
wt_longstatus_print_trailer(s);
}
-static char *read_line_from_git_path(const char *filename)
+static char *read_line_from_git_path(struct repository *r, const char *filename)
{
struct strbuf buf = STRBUF_INIT;
FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
@@ -1325,8 +1325,8 @@ static int split_commit_in_progress(struct wt_status *s)
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
return 0;
- rebase_amend = read_line_from_git_path("rebase-merge/amend");
- rebase_orig_head = read_line_from_git_path("rebase-merge/orig-head");
+ rebase_amend = read_line_from_git_path(s->repo, "rebase-merge/amend");
+ rebase_orig_head = read_line_from_git_path(s->repo, "rebase-merge/orig-head");
if (!rebase_amend || !rebase_orig_head)
; /* fall through, no split in progress */
@@ -1350,7 +1350,7 @@ static int split_commit_in_progress(struct wt_status *s)
* The function assumes that the line does not contain useless spaces
* before or after the command.
*/
-static void abbrev_oid_in_line(struct strbuf *line)
+static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
{
struct string_list split = STRING_LIST_INIT_DUP;
struct object_id oid;
@@ -1372,7 +1372,7 @@ static void abbrev_oid_in_line(struct strbuf *line)
string_list_clear(&split, 0);
}
-static int read_rebase_todolist(const char *fname, struct string_list *lines)
+static int read_rebase_todolist(struct repository *r, const char *fname, struct string_list *lines)
{
struct strbuf buf = STRBUF_INIT;
FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
@@ -1392,7 +1392,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)
strbuf_trim(&buf);
if (!buf.len)
continue;
- abbrev_oid_in_line(&buf);
+ abbrev_oid_in_line(r, &buf);
string_list_append(lines, buf.buf);
}
fclose(f);
@@ -1413,8 +1413,8 @@ static void show_rebase_information(struct wt_status *s,
struct string_list have_done = STRING_LIST_INIT_DUP;
struct string_list yet_to_do = STRING_LIST_INIT_DUP;
- read_rebase_todolist("rebase-merge/done", &have_done);
- if (read_rebase_todolist("rebase-merge/git-rebase-todo",
+ read_rebase_todolist(s->repo, "rebase-merge/done", &have_done);
+ if (read_rebase_todolist(s->repo, "rebase-merge/git-rebase-todo",
&yet_to_do))
status_printf_ln(s, color,
_("git-rebase-todo is missing."));
@@ -2259,7 +2259,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
*/
static void wt_porcelain_v2_print_stash(struct wt_status *s)
{
- int stash_count = count_stash_entries();
+ int stash_count = count_stash_entries(s->repo);
char eol = s->null_termination ? '\0' : '\n';
if (stash_count > 0)
--
2.53.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 2/3] wt-status: replace uses of the_repository with local repository instances
2026-02-17 17:29 ` [PATCH v4 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
2026-02-17 17:29 ` [PATCH v4 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
@ 2026-02-17 17:29 ` Shreyansh Paliwal
2026-02-17 17:29 ` [PATCH v4 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
2026-02-18 16:13 ` [PATCH v4 0/3] wt-status: reduce reliance on global state Phillip Wood
3 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-17 17:29 UTC (permalink / raw)
To: git; +Cc: phillip.wood123, gitster, karthik.188, Shreyansh Paliwal
wt-status.c uses the global the_repository in several places even when
a repository instance is already available via struct wt_status *s or
struct repository *r.
Replace these uses of the_repository with the repository available
in the local context (i.e. s->repo or r).
The replacements of all the_repository with s->repo are mostly
to cases where a repository instance is already available via
struct wt_status *s and struct repository *r, all functions operating on
struct wt_status *s are only used after s is initialized by wt_status_prepare(),
which sets s->repo from the repository provided by the caller.
As a result, s->repo is guaranteed to be available and consistent whenever
these functions are invoked.
This reduces reliance on global state and keeps wt-status consistent,
though many functions operating on struct wt_status *s
are called via commit.c and it still relies on the_repository,
but within wt-status.c the local repository pointer
refers to the same underlying repository object.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
wt-status.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index e10565f495..b44b8377e5 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
s->use_color = GIT_COLOR_UNKNOWN;
s->relative_paths = 1;
- s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
+ s->branch = refs_resolve_refdup(get_main_ref_store(r),
"HEAD", 0, NULL, NULL);
s->reference = "HEAD";
s->fp = stdout;
- s->index_file = repo_get_index_file(the_repository);
+ s->index_file = repo_get_index_file(r);
s->change.strdup_strings = 1;
s->untracked.strdup_strings = 1;
s->ignored.strdup_strings = 1;
@@ -646,7 +646,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
repo_init_revisions(s->repo, &rev, NULL);
memset(&opt, 0, sizeof(opt));
- opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
+ opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.flags.override_submodule_config = 1;
@@ -987,7 +987,7 @@ static int stash_count_refs(const char *refname UNUSED,
static int count_stash_entries(struct repository *r)
{
int n = 0;
- refs_for_each_reflog_ent(get_main_ref_store(the_repository),
+ refs_for_each_reflog_ent(get_main_ref_store(r),
"refs/stash", stash_count_refs, &n);
return n;
}
@@ -1146,7 +1146,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
rev.diffopt.ita_invisible_in_index = 1;
memset(&opt, 0, sizeof(opt));
- opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
+ opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
@@ -1290,7 +1290,7 @@ static void show_am_in_progress(struct wt_status *s,
static char *read_line_from_git_path(struct repository *r, const char *filename)
{
struct strbuf buf = STRBUF_INIT;
- FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
+ FILE *fp = fopen_or_warn(repo_git_path_append(r, &buf,
"%s", filename), "r");
if (!fp) {
@@ -1317,9 +1317,9 @@ static int split_commit_in_progress(struct wt_status *s)
!s->branch || strcmp(s->branch, "HEAD"))
return 0;
- if (refs_read_ref_full(get_main_ref_store(the_repository), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+ if (refs_read_ref_full(get_main_ref_store(s->repo), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
&head_oid, &head_flags) ||
- refs_read_ref_full(get_main_ref_store(the_repository), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+ refs_read_ref_full(get_main_ref_store(s->repo), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
&orig_head_oid, &orig_head_flags))
return 0;
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
@@ -1362,7 +1362,7 @@ static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
return;
if ((2 <= string_list_split(&split, line->buf, " ", 2)) &&
- !repo_get_oid(the_repository, split.items[1].string, &oid)) {
+ !repo_get_oid(r, split.items[1].string, &oid)) {
strbuf_reset(line);
strbuf_addf(line, "%s ", split.items[0].string);
strbuf_add_unique_abbrev(line, &oid, DEFAULT_ABBREV);
@@ -1375,7 +1375,7 @@ static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
static int read_rebase_todolist(struct repository *r, const char *fname, struct string_list *lines)
{
struct strbuf buf = STRBUF_INIT;
- FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
+ FILE *f = fopen(repo_git_path_append(r, &buf, "%s", fname), "r");
int ret;
if (!f) {
@@ -1384,7 +1384,7 @@ static int read_rebase_todolist(struct repository *r, const char *fname, struct
goto out;
}
die_errno("Could not open file %s for reading",
- repo_git_path_replace(the_repository, &buf, "%s", fname));
+ repo_git_path_replace(r, &buf, "%s", fname));
}
while (!strbuf_getline_lf(&buf, f)) {
if (starts_with(buf.buf, comment_line_str))
@@ -1432,7 +1432,7 @@ static void show_rebase_information(struct wt_status *s,
i++)
status_printf_ln(s, color, " %s", have_done.items[i].string);
if (have_done.nr > nr_lines_to_show && s->hints) {
- char *path = repo_git_path(the_repository, "rebase-merge/done");
+ char *path = repo_git_path(s->repo, "rebase-merge/done");
status_printf_ln(s, color,
_(" (see more in file %s)"), path);
free(path);
@@ -1534,7 +1534,7 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
else
status_printf_ln(s, color,
_("You are currently cherry-picking commit %s."),
- repo_find_unique_abbrev(the_repository, &s->state.cherry_pick_head_oid,
+ repo_find_unique_abbrev(s->repo, &s->state.cherry_pick_head_oid,
DEFAULT_ABBREV));
if (s->hints) {
@@ -1564,7 +1564,7 @@ static void show_revert_in_progress(struct wt_status *s,
else
status_printf_ln(s, color,
_("You are currently reverting commit %s."),
- repo_find_unique_abbrev(the_repository, &s->state.revert_head_oid,
+ repo_find_unique_abbrev(s->repo, &s->state.revert_head_oid,
DEFAULT_ABBREV));
if (s->hints) {
if (has_unmerged(s))
@@ -1691,7 +1691,7 @@ static void wt_status_get_detached_from(struct repository *r,
char *ref = NULL;
strbuf_init(&cb.buf, 0);
- if (refs_for_each_reflog_ent_reverse(get_main_ref_store(the_repository), "HEAD", grab_1st_switch, &cb) <= 0) {
+ if (refs_for_each_reflog_ent_reverse(get_main_ref_store(r), "HEAD", grab_1st_switch, &cb) <= 0) {
strbuf_release(&cb.buf);
return;
}
@@ -2099,7 +2099,7 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
upstream_is_gone = 1;
}
- short_base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
+ short_base = refs_shorten_unambiguous_ref(get_main_ref_store(s->repo),
base, 0);
color_fprintf(s->fp, header_color, "...");
color_fprintf(s->fp, branch_color_remote, "%s", short_base);
@@ -2233,7 +2233,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
ab_info = stat_tracking_info(branch, &nr_ahead, &nr_behind,
&base, 0, s->ahead_behind_flags);
if (base) {
- base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
+ base = refs_shorten_unambiguous_ref(get_main_ref_store(s->repo),
base, 0);
fprintf(s->fp, "# branch.upstream %s%c", base, eol);
free((char *)base);
--
2.53.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo
2026-02-17 17:29 ` [PATCH v4 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
2026-02-17 17:29 ` [PATCH v4 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
2026-02-17 17:29 ` [PATCH v4 2/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
@ 2026-02-17 17:29 ` Shreyansh Paliwal
2026-02-18 16:13 ` [PATCH v4 0/3] wt-status: reduce reliance on global state Phillip Wood
3 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-17 17:29 UTC (permalink / raw)
To: git; +Cc: phillip.wood123, gitster, karthik.188, Shreyansh Paliwal
wt-status.c still uses the global the_hash_algo even though a repository
instance is already available via struct wt_status.
Replace uses of the_hash_algo with the hash algorithm stored in the
associated repository (s->repo->hash_algo or r->hash_algo).
This removes another dependency on global state and keeps wt-status
consistent with local repository usage.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
wt-status.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index b44b8377e5..264281fb67 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1815,10 +1815,10 @@ void wt_status_get_state(struct repository *r,
if (!sequencer_get_last_command(r, &action)) {
if (action == REPLAY_PICK && !state->cherry_pick_in_progress) {
state->cherry_pick_in_progress = 1;
- oidcpy(&state->cherry_pick_head_oid, null_oid(the_hash_algo));
+ oidcpy(&state->cherry_pick_head_oid, null_oid(r->hash_algo));
} else if (action == REPLAY_REVERT && !state->revert_in_progress) {
state->revert_in_progress = 1;
- oidcpy(&state->revert_head_oid, null_oid(the_hash_algo));
+ oidcpy(&state->revert_head_oid, null_oid(r->hash_algo));
}
}
if (get_detached_from)
@@ -2630,7 +2630,7 @@ int has_uncommitted_changes(struct repository *r,
* We have no head (or it's corrupt); use the empty tree,
* which will complain if the index is non-empty.
*/
- struct tree *tree = lookup_tree(r, the_hash_algo->empty_tree);
+ struct tree *tree = lookup_tree(r, r->hash_algo->empty_tree);
add_pending_object(&rev_info, &tree->object, "");
}
--
2.53.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* Re: [PATCH v4 0/3] wt-status: reduce reliance on global state
2026-02-17 17:29 ` [PATCH v4 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
` (2 preceding siblings ...)
2026-02-17 17:29 ` [PATCH v4 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
@ 2026-02-18 16:13 ` Phillip Wood
2026-02-18 16:48 ` Shreyansh Paliwal
3 siblings, 1 reply; 69+ messages in thread
From: Phillip Wood @ 2026-02-18 16:13 UTC (permalink / raw)
To: Shreyansh Paliwal, git; +Cc: gitster, karthik.188
On 17/02/2026 17:29, Shreyansh Paliwal wrote:
> In wt-status.c code still relies on some global variables, including
> the_repository and the_hash_algo, even in cases where a repository
> instance is already available via struct wt_status or struct repository.
>
> In patch 1/3, update function parameters and callers to pass struct
> repository where no local repository access was available.
This breaks the build when running "make DEVELOPER=1"
wt-status.c: In function ‘count_stash_entries’:
wt-status.c:1011:51: error: unused parameter ‘r’ [-Werror=unused-parameter]
1011 | static int count_stash_entries(struct repository *r)
| ~~~~~~~~~~~~~~~~~~~^
wt-status.c: In function ‘read_line_from_git_path’:
wt-status.c:1314:57: error: unused parameter ‘r’ [-Werror=unused-parameter]
1314 | static char *read_line_from_git_path(struct repository *r,
const char *filename)
| ~~~~~~~~~~~~~~~~~~~^
wt-status.c: In function ‘abbrev_oid_in_line’:
wt-status.c:1377:51: error: unused parameter ‘r’ [-Werror=unused-parameter]
1377 | static void abbrev_oid_in_line(struct repository *r, struct
strbuf *line)
| ~~~~~~~~~~~~~~~~~~~^
It would be better to use the new argument to replace "the_repository"
in this patch. There aren't that many so the patch is still a manageable
size.
> In patch 2/3, replace direct uses of the_repository with repository
> instances already available in local structs.
>
> In patch 3/3, replace remaining uses of the global the_hash_algo with the
> hash algorithm stored in the respective repository instance.
These both look good, though I think the commit message for the second
patch could be reflowed to give a more consistent line length.
Thanks
Phillip
> These changes remove uses of the_repository and the_hash_algo from
> wt-status.c and reduce its dependence on global state.
>
> The 'USE_THE_REPOSITORY_VARIABLE' macro cannot yet be removed, since these
> patches only eliminate some uses of the_repository and the_hash_algo,
> while some global variables are still referenced.
>
> In particular wt-status.c still relies on the following globals,
>
> * the_repository, this is still used in functions like worktree_git_path() and
> wt_status_check_bisect/rebase() which are dependant on the worktree API and they
> are being handled in a seperate patch series[1].
>
> * core_apply_sparse_checkout, this is already being addressed in an
> ongoing patch series [2].
>
> * comment_line_str and DEFAULT_ABBREV, these both still are used in
> wt-status.c but they dont have any equivalent local instances.
>
> [1]- https://lore.kernel.org/git/20260213120529.15475-1-shreyanshpaliwalcmsmn@gmail.com/T/#mf664ad751faaf2eaca138302b1cc9d3856c9fec3
> [2]- https://lore.kernel.org/git/5e56e1cc4172cfff9e917a068184e102aa70bf1d.1769256839.git.belkid98@gmail.com/t/#u
>
> Shreyansh Paliwal (3):
> wt-status: pass struct repository through function parameters
> wt-status: replace uses of the_repository with local repository
> instances
> wt-status: use hash_algo from local repository instead of global
> the_hash_algo
>
> wt-status.c | 62 ++++++++++++++++++++++++++---------------------------
> 1 file changed, 31 insertions(+), 31 deletions(-)
>
> ---
> Changes in v4:
> - removed the changes regarding worktree_git_path() and
> wt_status_check_bisect/rebase() as they are better handled seperately.
>
> Range-diff against v3:
> 1: 960216e45c ! 1: a3683a5e17 wt-status: pass struct repository through function parameters
> @@ Commit message
> do not have access to a local repository instance and rely on the_repository.
>
> Add a struct repository *r parameter to these functions, and pass the local
> - repository through the callers.
> -
> - get_branch(), wt_status_check_rebase() and wt_status_check_bisect() already
> - receive a struct worktree *, which can provide access to the repository.
> - However, some callers pass NULL as the worktree like in wt_status_get_state(),
> - which would make using wt->repo unsafe and lead to segfault issues.
> - Add an explicit struct repository * parameter to these functions as well,
> - and pass the repository through the callers.
> -
> - Both wt_status_check_rebase() and wt_status_check_bisect() are called from
> - branch.c and worktree.c,
> -
> - * In branch.c, wt is always non-NULL as the functions are called within an
> - interation over worktrees in prepare_checked_out_branches().
> - * In worktree.c the functions are called from is_worktree_being_rebased() and
> - is_worktree_being_bisected() respectively which are further called from
> - builtin/branch.c in reject_rebase_or_bisect_branch() which has a non-NULL
> - worktree as it is called inside an iteration over worktrees as well.
> + repository through the callers where already they can access a local repository
> + instance either directly by struct repository *r or
> + by struct wt_state *s (s->repo).
>
> Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
>
> - ## branch.c ##
> -@@ branch.c: static void prepare_checked_out_branches(void)
> - free(old);
> - }
> -
> -- if (wt_status_check_rebase(wt, &state) &&
> -+ if (wt_status_check_rebase(wt->repo, wt, &state) &&
> - (state.rebase_in_progress || state.rebase_interactive_in_progress) &&
> - state.branch) {
> - struct strbuf ref = STRBUF_INIT;
> -@@ branch.c: static void prepare_checked_out_branches(void)
> - }
> - wt_status_state_free_buffers(&state);
> -
> -- if (wt_status_check_bisect(wt, &state) &&
> -+ if (wt_status_check_bisect(wt->repo, wt, &state) &&
> - state.bisecting_from) {
> - struct strbuf ref = STRBUF_INIT;
> - strbuf_addf(&ref, "refs/heads/%s", state.bisecting_from);
> -
> - ## worktree.c ##
> -@@ worktree.c: int is_worktree_being_rebased(const struct worktree *wt,
> - int found_rebase;
> -
> - memset(&state, 0, sizeof(state));
> -- found_rebase = wt_status_check_rebase(wt, &state) &&
> -+ found_rebase = wt_status_check_rebase(wt->repo, wt, &state) &&
> - (state.rebase_in_progress ||
> - state.rebase_interactive_in_progress) &&
> - state.branch &&
> -@@ worktree.c: int is_worktree_being_bisected(const struct worktree *wt,
> - int found_bisect;
> -
> - memset(&state, 0, sizeof(state));
> -- found_bisect = wt_status_check_bisect(wt, &state) &&
> -+ found_bisect = wt_status_check_bisect(wt->repo, wt, &state) &&
> - state.bisecting_from &&
> - skip_prefix(target, "refs/heads/", &target) &&
> - !strcmp(state.bisecting_from, target);
> -
> ## wt-status.c ##
> @@ wt-status.c: static int stash_count_refs(const char *refname UNUSED,
> return 0;
> @@ wt-status.c: static void show_am_in_progress(struct wt_status *s,
> }
>
> -static char *read_line_from_git_path(const char *filename)
> -+static char *read_line_from_git_path(struct repository *r, char *filename)
> ++static char *read_line_from_git_path(struct repository *r, const char *filename)
> {
> struct strbuf buf = STRBUF_INIT;
> FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
> @@ wt-status.c: static void abbrev_oid_in_line(struct strbuf *line)
> }
>
> -static int read_rebase_todolist(const char *fname, struct string_list *lines)
> -+static int read_rebase_todolist(struct repository *r, char *fname, struct string_list *lines)
> ++static int read_rebase_todolist(struct repository *r, const char *fname, struct string_list *lines)
> {
> struct strbuf buf = STRBUF_INIT;
> FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
> @@ wt-status.c: static void show_rebase_information(struct wt_status *s,
> &yet_to_do))
> status_printf_ln(s, color,
> _("git-rebase-todo is missing."));
> -@@ wt-status.c: static void show_sparse_checkout_in_use(struct wt_status *s,
> - /*
> - * Extract branch information from rebase/bisect
> - */
> --static char *get_branch(const struct worktree *wt, const char *path)
> -+static char *get_branch(struct repository *r, struct worktree *wt, const char *path)
> - {
> - struct strbuf sb = STRBUF_INIT;
> - struct object_id oid;
> -@@ wt-status.c: static void wt_status_get_detached_from(struct repository *r,
> - strbuf_release(&cb.buf);
> - }
> -
> --int wt_status_check_rebase(const struct worktree *wt,
> -- struct wt_status_state *state)
> -+int wt_status_check_rebase(struct repository *r,
> -+ const struct worktree *wt,
> -+ struct wt_status_state *state)
> - {
> - struct stat st;
> -
> -@@ wt-status.c: int wt_status_check_rebase(const struct worktree *wt,
> - state->am_empty_patch = 1;
> - } else {
> - state->rebase_in_progress = 1;
> -- state->branch = get_branch(wt, "rebase-apply/head-name");
> -- state->onto = get_branch(wt, "rebase-apply/onto");
> -+ state->branch = get_branch(r, wt, "rebase-apply/head-name");
> -+ state->onto = get_branch(r, wt, "rebase-apply/onto");
> - }
> - } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
> - if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
> - state->rebase_interactive_in_progress = 1;
> - else
> - state->rebase_in_progress = 1;
> -- state->branch = get_branch(wt, "rebase-merge/head-name");
> -- state->onto = get_branch(wt, "rebase-merge/onto");
> -+ state->branch = get_branch(r, wt, "rebase-merge/head-name");
> -+ state->onto = get_branch(r, wt, "rebase-merge/onto");
> - } else
> - return 0;
> - return 1;
> - }
> -
> --int wt_status_check_bisect(const struct worktree *wt,
> -+int wt_status_check_bisect(struct repository *r,
> -+ struct worktree *wt,
> - struct wt_status_state *state)
> - {
> - struct stat st;
> -
> - if (!stat(worktree_git_path(the_repository, wt, "BISECT_LOG"), &st)) {
> - state->bisect_in_progress = 1;
> -- state->bisecting_from = get_branch(wt, "BISECT_START");
> -+ state->bisecting_from = get_branch(r, wt, "BISECT_START");
> - return 1;
> - }
> - return 0;
> -@@ wt-status.c: void wt_status_get_state(struct repository *r,
> - enum replay_action action;
> -
> - if (!stat(git_path_merge_head(r), &st)) {
> -- wt_status_check_rebase(NULL, state);
> -+ wt_status_check_rebase(r, NULL, state);
> - state->merge_in_progress = 1;
> -- } else if (wt_status_check_rebase(NULL, state)) {
> -+ } else if (wt_status_check_rebase(r, NULL, state)) {
> - ; /* all set */
> - } else if (refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&
> - !repo_get_oid(r, "CHERRY_PICK_HEAD", &oid)) {
> - state->cherry_pick_in_progress = 1;
> - oidcpy(&state->cherry_pick_head_oid, &oid);
> - }
> -- wt_status_check_bisect(NULL, state);
> -+ wt_status_check_bisect(r, NULL, state);
> - if (refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD") &&
> - !repo_get_oid(r, "REVERT_HEAD", &oid)) {
> - state->revert_in_progress = 1;
> @@ wt-status.c: static void wt_porcelain_v2_print_tracking(struct wt_status *s)
> */
> static void wt_porcelain_v2_print_stash(struct wt_status *s)
> @@ wt-status.c: static void wt_porcelain_v2_print_tracking(struct wt_status *s)
> char eol = s->null_termination ? '\0' : '\n';
>
> if (stash_count > 0)
> -
> - ## wt-status.h ##
> -@@ wt-status.h: void wt_status_state_free_buffers(struct wt_status_state *s);
> - void wt_status_get_state(struct repository *repo,
> - struct wt_status_state *state,
> - int get_detached_from);
> --int wt_status_check_rebase(const struct worktree *wt,
> -+int wt_status_check_rebase(struct repository *r,
> -+ struct worktree *wt,
> - struct wt_status_state *state);
> --int wt_status_check_bisect(const struct worktree *wt,
> -+int wt_status_check_bisect(struct repository *r,
> -+ struct worktree *wt,
> - struct wt_status_state *state);
> -
> - __attribute__((format (printf, 3, 4)))
> 2: 906e682cd7 ! 2: f3b4c3e972 wt-status: replace uses of the_repository with local repository instances
> @@ Commit message
> struct repository *r.
>
> Replace these uses of the_repository with the repository available
> - in the local context (eg. s->repo or r).
> + in the local context (i.e. s->repo or r).
>
> The replacements of all the_repository with s->repo are mostly
> to cases where a repository instance is already available via
> @@ wt-status.c: static void wt_longstatus_print_verbose(struct wt_status *s)
>
> rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
> @@ wt-status.c: static void show_am_in_progress(struct wt_status *s,
> - static char *read_line_from_git_path(struct repository *r, char *filename)
> + static char *read_line_from_git_path(struct repository *r, const char *filename)
> {
> struct strbuf buf = STRBUF_INIT;
> - FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
> @@ wt-status.c: static void abbrev_oid_in_line(struct repository *r, struct strbuf
> strbuf_addf(line, "%s ", split.items[0].string);
> strbuf_add_unique_abbrev(line, &oid, DEFAULT_ABBREV);
> @@ wt-status.c: static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
> - static int read_rebase_todolist(struct repository *r, char *fname, struct string_list *lines)
> + static int read_rebase_todolist(struct repository *r, const char *fname, struct string_list *lines)
> {
> struct strbuf buf = STRBUF_INIT;
> - FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
> @@ wt-status.c: static void abbrev_oid_in_line(struct repository *r, struct strbuf
> int ret;
>
> if (!f) {
> -@@ wt-status.c: static int read_rebase_todolist(struct repository *r, char *fname, struct string
> +@@ wt-status.c: static int read_rebase_todolist(struct repository *r, const char *fname, struct
> goto out;
> }
> die_errno("Could not open file %s for reading",
> @@ wt-status.c: static void show_revert_in_progress(struct wt_status *s,
> DEFAULT_ABBREV));
> if (s->hints) {
> if (has_unmerged(s))
> -@@ wt-status.c: static char *get_branch(struct repository *r, struct worktree *wt, const char *p
> - struct object_id oid;
> - const char *branch_name;
> -
> -- if (strbuf_read_file(&sb, worktree_git_path(the_repository, wt, "%s", path), 0) <= 0)
> -+ if (strbuf_read_file(&sb, worktree_git_path(r, wt, "%s", path), 0) <= 0)
> - goto got_nothing;
> -
> - while (sb.len && sb.buf[sb.len - 1] == '\n')
> @@ wt-status.c: static void wt_status_get_detached_from(struct repository *r,
> char *ref = NULL;
>
> @@ wt-status.c: static void wt_status_get_detached_from(struct repository *r,
> strbuf_release(&cb.buf);
> return;
> }
> -@@ wt-status.c: int wt_status_check_rebase(struct repository *r,
> - {
> - struct stat st;
> -
> -- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) {
> -- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) {
> -+ if (!stat(worktree_git_path(r, wt, "rebase-apply"), &st)) {
> -+ if (!stat(worktree_git_path(r, wt, "rebase-apply/applying"), &st)) {
> - state->am_in_progress = 1;
> -- if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/patch"), &st) && !st.st_size)
> -+ if (!stat(worktree_git_path(r, wt, "rebase-apply/patch"), &st) && !st.st_size)
> - state->am_empty_patch = 1;
> - } else {
> - state->rebase_in_progress = 1;
> - state->branch = get_branch(r, wt, "rebase-apply/head-name");
> - state->onto = get_branch(r, wt, "rebase-apply/onto");
> - }
> -- } else if (!stat(worktree_git_path(the_repository, wt, "rebase-merge"), &st)) {
> -- if (!stat(worktree_git_path(the_repository, wt, "rebase-merge/interactive"), &st))
> -+ } else if (!stat(worktree_git_path(r, wt, "rebase-merge"), &st)) {
> -+ if (!stat(worktree_git_path(r, wt, "rebase-merge/interactive"), &st))
> - state->rebase_interactive_in_progress = 1;
> - else
> - state->rebase_in_progress = 1;
> -@@ wt-status.c: int wt_status_check_bisect(struct repository *r,
> - {
> - struct stat st;
> -
> -- if (!stat(worktree_git_path(the_repository, wt, "BISECT_LOG"), &st)) {
> -+ if (!stat(worktree_git_path(r, wt, "BISECT_LOG"), &st)) {
> - state->bisect_in_progress = 1;
> - state->bisecting_from = get_branch(r, wt, "BISECT_START");
> - return 1;
> @@ wt-status.c: static void wt_shortstatus_print_tracking(struct wt_status *s)
> upstream_is_gone = 1;
> }
> 3: 9c0a1d82ad = 3: 7efaf6b3fb wt-status: use hash_algo from local repository instead of global the_hash_algo
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 0/3] wt-status: reduce reliance on global state
2026-02-18 16:13 ` [PATCH v4 0/3] wt-status: reduce reliance on global state Phillip Wood
@ 2026-02-18 16:48 ` Shreyansh Paliwal
0 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-18 16:48 UTC (permalink / raw)
To: git; +Cc: phillip.wood123, gitster, karthik.188
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 2054 bytes --]
> On 17/02/2026 17:29, Shreyansh Paliwal wrote:
> > In wt-status.c code still relies on some global variables, including
> > the_repository and the_hash_algo, even in cases where a repository
> > instance is already available via struct wt_status or struct repository.
> >
> > In patch 1/3, update function parameters and callers to pass struct
> > repository where no local repository access was available.
>
> This breaks the build when running "make DEVELOPER=1"
>
> wt-status.c: In function ‘count_stash_entries’:
> wt-status.c:1011:51: error: unused parameter ‘r’ [-Werror=unused-parameter]
> 1011 | static int count_stash_entries(struct repository *r)
> | ~~~~~~~~~~~~~~~~~~~^
> wt-status.c: In function ‘read_line_from_git_path’:
> wt-status.c:1314:57: error: unused parameter ‘r’ [-Werror=unused-parameter]
> 1314 | static char *read_line_from_git_path(struct repository *r,
> const char *filename)
> | ~~~~~~~~~~~~~~~~~~~^
> wt-status.c: In function ‘abbrev_oid_in_line’:
> wt-status.c:1377:51: error: unused parameter ‘r’ [-Werror=unused-parameter]
> 1377 | static void abbrev_oid_in_line(struct repository *r, struct
> strbuf *line)
> | ~~~~~~~~~~~~~~~~~~~^
>
> It would be better to use the new argument to replace "the_repository"
> in this patch. There aren't that many so the patch is still a manageable
> size.
Thanks for catching that. I ran the build and test suite after all the commits
at once so it got overlooked.
> > In patch 2/3, replace direct uses of the_repository with repository
> > instances already available in local structs.
> >
> > In patch 3/3, replace remaining uses of the global the_hash_algo with the
> > hash algorithm stored in the respective repository instance.
>
> These both look good, though I think the commit message for the second
> patch could be reflowed to give a more consistent line length.
I will send a revised version. Thanks.
Best,
Shreyansh
^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH v5 0/3] wt-status: reduce reliance on global state
2026-01-31 18:57 [PATCH 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
` (4 preceding siblings ...)
2026-02-17 17:29 ` [PATCH v4 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
@ 2026-02-18 17:53 ` Shreyansh Paliwal
2026-02-18 17:53 ` [PATCH v5 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
` (3 more replies)
5 siblings, 4 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-18 17:53 UTC (permalink / raw)
To: git; +Cc: phillip.wood123, gitster, karthik.188, Shreyansh Paliwal
In wt-status.c code still relies on some global variables, including
the_repository and the_hash_algo, even in cases where a repository instance
is already available via struct wt_status or struct repository.
In patch 1/3, update function parameters and callers to pass and use struct
repository instead of the_repository where no local repository access was
available.
In patch 2/3, replace direct uses of the_repository with repository
instances already available in local structs.
In patch 3/3, replace remaining uses of the global the_hash_algo with the
hash algorithm stored in the respective repository instance.
These changes remove uses of the_repository and the_hash_algo from
wt-status.c and reduce its dependence on global state.
The 'USE_THE_REPOSITORY_VARIABLE' macro cannot yet be removed, since these
patches only eliminate some uses of the_repository and the_hash_algo, while
some global variables are still referenced.
In particular wt-status.c still relies on the following globals,
* the_repository, this is still used in functions like worktree_git_path()
and wt_status_check_bisect/rebase() which are dependant on the worktree
API and they are being handled in a seperate patch series[1].
* core_apply_sparse_checkout, this is already being addressed in an ongoing
patch series [2].
* comment_line_str and DEFAULT_ABBREV, these both still are used in
wt-status.c but they dont have any equivalent local instances.
[1]- https://lore.kernel.org/git/20260213120529.15475-1-shreyanshpaliwalcmsmn@gmail.com/T/#mf664ad751faaf2eaca138302b1cc9d3856c9fec3
[2]- https://lore.kernel.org/git/5e56e1cc4172cfff9e917a068184e102aa70bf1d.1769256839.git.belkid98@gmail.com/t/#u
Shreyansh Paliwal (3):
wt-status: pass struct repository through function parameters
wt-status: replace uses of the_repository with local repository
instances
wt-status: use hash_algo from local repository instead of global
the_hash_algo
wt-status.c | 62 ++++++++++++++++++++++++++---------------------------
1 file changed, 31 insertions(+), 31 deletions(-)
---
Changes in v5:
- Added the usage of struct repository *r in addition to adding it as a parameter to the functions,
in patch 1/3 instead of doing that in 2/3.
Range-diff against v4:
1: a3683a5e17 ! 1: 620cf8832b wt-status: pass struct repository through function parameters
@@ Commit message
wt-status: pass struct repository through function parameters
Some functions in wt-status.c (count_stash_entries(),
- read_line_from_git_path(), abbrev_oid_in_line(), read_rebase_todolist())
- do not have access to a local repository instance and rely on the_repository.
+ read_line_from_git_path(), abbrev_oid_in_line(), and
+ read_rebase_todolist()) rely on the_repository as they do not have access
+ to a local repository instance.
- Add a struct repository *r parameter to these functions, and pass the local
- repository through the callers where already they can access a local repository
- instance either directly by struct repository *r or
- by struct wt_state *s (s->repo).
+ Add a struct repository *r parameter to these functions and pass the local
+ repository instance through the callers, which already have access to it
+ either directly by struct repository *r or indirectly by struct wt_state
+ *s (s->repo).
+
+ Replace uses of the_repository in these functions with the passed parameter.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
@@ wt-status.c: static int stash_count_refs(const char *refname UNUSED,
+static int count_stash_entries(struct repository *r)
{
int n = 0;
- refs_for_each_reflog_ent(get_main_ref_store(the_repository),
-@@ wt-status.c: static int count_stash_entries(void)
+- refs_for_each_reflog_ent(get_main_ref_store(the_repository),
++ refs_for_each_reflog_ent(get_main_ref_store(r),
+ "refs/stash", stash_count_refs, &n);
+ return n;
+ }
static void wt_longstatus_print_stash_summary(struct wt_status *s)
{
@@ wt-status.c: static void show_am_in_progress(struct wt_status *s,
+static char *read_line_from_git_path(struct repository *r, const char *filename)
{
struct strbuf buf = STRBUF_INIT;
- FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
+- FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
++ FILE *fp = fopen_or_warn(repo_git_path_append(r, &buf,
+ "%s", filename), "r");
+
+ if (!fp) {
@@ wt-status.c: static int split_commit_in_progress(struct wt_status *s)
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
return 0;
@@ wt-status.c: static int split_commit_in_progress(struct wt_status *s)
{
struct string_list split = STRING_LIST_INIT_DUP;
struct object_id oid;
+@@ wt-status.c: static void abbrev_oid_in_line(struct strbuf *line)
+ return;
+
+ if ((2 <= string_list_split(&split, line->buf, " ", 2)) &&
+- !repo_get_oid(the_repository, split.items[1].string, &oid)) {
++ !repo_get_oid(r, split.items[1].string, &oid)) {
+ strbuf_reset(line);
+ strbuf_addf(line, "%s ", split.items[0].string);
+ strbuf_add_unique_abbrev(line, &oid, DEFAULT_ABBREV);
@@ wt-status.c: static void abbrev_oid_in_line(struct strbuf *line)
string_list_clear(&split, 0);
}
@@ wt-status.c: static void abbrev_oid_in_line(struct strbuf *line)
+static int read_rebase_todolist(struct repository *r, const char *fname, struct string_list *lines)
{
struct strbuf buf = STRBUF_INIT;
- FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
+- FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
++ FILE *f = fopen(repo_git_path_append(r, &buf, "%s", fname), "r");
+ int ret;
+
+ if (!f) {
+@@ wt-status.c: static int read_rebase_todolist(const char *fname, struct string_list *lines)
+ goto out;
+ }
+ die_errno("Could not open file %s for reading",
+- repo_git_path_replace(the_repository, &buf, "%s", fname));
++ repo_git_path_replace(r, &buf, "%s", fname));
+ }
+ while (!strbuf_getline_lf(&buf, f)) {
+ if (starts_with(buf.buf, comment_line_str))
@@ wt-status.c: static int read_rebase_todolist(const char *fname, struct string_list *lines)
strbuf_trim(&buf);
if (!buf.len)
2: f3b4c3e972 ! 2: 13e0c5bcd7 wt-status: replace uses of the_repository with local repository instances
@@ Metadata
## Commit message ##
wt-status: replace uses of the_repository with local repository instances
- wt-status.c uses the global the_repository in several places even when
- a repository instance is already available via struct wt_status *s or
- struct repository *r.
+ wt-status.c uses the global the_repository in several places even when a
+ repository instance is already available via struct wt_status *s or struct
+ repository *r.
- Replace these uses of the_repository with the repository available
- in the local context (i.e. s->repo or r).
+ Replace these uses of the_repository with the repository available in the
+ local context (i.e. s->repo or r).
- The replacements of all the_repository with s->repo are mostly
- to cases where a repository instance is already available via
- struct wt_status *s and struct repository *r, all functions operating on
- struct wt_status *s are only used after s is initialized by wt_status_prepare(),
- which sets s->repo from the repository provided by the caller.
- As a result, s->repo is guaranteed to be available and consistent whenever
- these functions are invoked.
+ The replacements of all the_repository with s->repo are mostly to cases
+ where a repository instance is already available via struct wt_status *s
+ and struct repository *r, all functions operating on struct wt_status *s
+ are only used after s is initialized by wt_status_prepare(), which sets
+ s->repo from the repository provided by the caller. As a result, s->repo is
+ guaranteed to be available and consistent whenever these functions are
+ invoked.
This reduces reliance on global state and keeps wt-status consistent,
- though many functions operating on struct wt_status *s
- are called via commit.c and it still relies on the_repository,
- but within wt-status.c the local repository pointer
- refers to the same underlying repository object.
+ though many functions operating on struct wt_status *s are called via
+ commit.c and it still relies on the_repository, but within wt-status.c the
+ local repository pointer refers to the same underlying repository object.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
@@ wt-status.c: static void wt_status_collect_changes_index(struct wt_status *s)
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.flags.override_submodule_config = 1;
-@@ wt-status.c: static int stash_count_refs(const char *refname UNUSED,
- static int count_stash_entries(struct repository *r)
- {
- int n = 0;
-- refs_for_each_reflog_ent(get_main_ref_store(the_repository),
-+ refs_for_each_reflog_ent(get_main_ref_store(r),
- "refs/stash", stash_count_refs, &n);
- return n;
- }
@@ wt-status.c: static void wt_longstatus_print_verbose(struct wt_status *s)
rev.diffopt.ita_invisible_in_index = 1;
@@ wt-status.c: static void wt_longstatus_print_verbose(struct wt_status *s)
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
-@@ wt-status.c: static void show_am_in_progress(struct wt_status *s,
- static char *read_line_from_git_path(struct repository *r, const char *filename)
- {
- struct strbuf buf = STRBUF_INIT;
-- FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
-+ FILE *fp = fopen_or_warn(repo_git_path_append(r, &buf,
- "%s", filename), "r");
-
- if (!fp) {
@@ wt-status.c: static int split_commit_in_progress(struct wt_status *s)
!s->branch || strcmp(s->branch, "HEAD"))
return 0;
@@ wt-status.c: static int split_commit_in_progress(struct wt_status *s)
&orig_head_oid, &orig_head_flags))
return 0;
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
-@@ wt-status.c: static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
- return;
-
- if ((2 <= string_list_split(&split, line->buf, " ", 2)) &&
-- !repo_get_oid(the_repository, split.items[1].string, &oid)) {
-+ !repo_get_oid(r, split.items[1].string, &oid)) {
- strbuf_reset(line);
- strbuf_addf(line, "%s ", split.items[0].string);
- strbuf_add_unique_abbrev(line, &oid, DEFAULT_ABBREV);
-@@ wt-status.c: static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
- static int read_rebase_todolist(struct repository *r, const char *fname, struct string_list *lines)
- {
- struct strbuf buf = STRBUF_INIT;
-- FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
-+ FILE *f = fopen(repo_git_path_append(r, &buf, "%s", fname), "r");
- int ret;
-
- if (!f) {
-@@ wt-status.c: static int read_rebase_todolist(struct repository *r, const char *fname, struct
- goto out;
- }
- die_errno("Could not open file %s for reading",
-- repo_git_path_replace(the_repository, &buf, "%s", fname));
-+ repo_git_path_replace(r, &buf, "%s", fname));
- }
- while (!strbuf_getline_lf(&buf, f)) {
- if (starts_with(buf.buf, comment_line_str))
@@ wt-status.c: static void show_rebase_information(struct wt_status *s,
i++)
status_printf_ln(s, color, " %s", have_done.items[i].string);
3: 7efaf6b3fb = 3: 2bf22dd925 wt-status: use hash_algo from local repository instead of global the_hash_algo
--
2.53.0
^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH v5 1/3] wt-status: pass struct repository through function parameters
2026-02-18 17:53 ` [PATCH v5 " Shreyansh Paliwal
@ 2026-02-18 17:53 ` Shreyansh Paliwal
2026-02-18 17:53 ` [PATCH v5 2/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
` (2 subsequent siblings)
3 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-18 17:53 UTC (permalink / raw)
To: git; +Cc: phillip.wood123, gitster, karthik.188, Shreyansh Paliwal
Some functions in wt-status.c (count_stash_entries(),
read_line_from_git_path(), abbrev_oid_in_line(), and
read_rebase_todolist()) rely on the_repository as they do not have access
to a local repository instance.
Add a struct repository *r parameter to these functions and pass the local
repository instance through the callers, which already have access to it
either directly by struct repository *r or indirectly by struct wt_state
*s (s->repo).
Replace uses of the_repository in these functions with the passed parameter.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
wt-status.c | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index e12adb26b9..97c2e10a8c 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -984,17 +984,17 @@ static int stash_count_refs(const char *refname UNUSED,
return 0;
}
-static int count_stash_entries(void)
+static int count_stash_entries(struct repository *r)
{
int n = 0;
- refs_for_each_reflog_ent(get_main_ref_store(the_repository),
+ refs_for_each_reflog_ent(get_main_ref_store(r),
"refs/stash", stash_count_refs, &n);
return n;
}
static void wt_longstatus_print_stash_summary(struct wt_status *s)
{
- int stash_count = count_stash_entries();
+ int stash_count = count_stash_entries(s->repo);
if (stash_count > 0)
status_printf_ln(s, GIT_COLOR_NORMAL,
@@ -1287,10 +1287,10 @@ static void show_am_in_progress(struct wt_status *s,
wt_longstatus_print_trailer(s);
}
-static char *read_line_from_git_path(const char *filename)
+static char *read_line_from_git_path(struct repository *r, const char *filename)
{
struct strbuf buf = STRBUF_INIT;
- FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf,
+ FILE *fp = fopen_or_warn(repo_git_path_append(r, &buf,
"%s", filename), "r");
if (!fp) {
@@ -1325,8 +1325,8 @@ static int split_commit_in_progress(struct wt_status *s)
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
return 0;
- rebase_amend = read_line_from_git_path("rebase-merge/amend");
- rebase_orig_head = read_line_from_git_path("rebase-merge/orig-head");
+ rebase_amend = read_line_from_git_path(s->repo, "rebase-merge/amend");
+ rebase_orig_head = read_line_from_git_path(s->repo, "rebase-merge/orig-head");
if (!rebase_amend || !rebase_orig_head)
; /* fall through, no split in progress */
@@ -1350,7 +1350,7 @@ static int split_commit_in_progress(struct wt_status *s)
* The function assumes that the line does not contain useless spaces
* before or after the command.
*/
-static void abbrev_oid_in_line(struct strbuf *line)
+static void abbrev_oid_in_line(struct repository *r, struct strbuf *line)
{
struct string_list split = STRING_LIST_INIT_DUP;
struct object_id oid;
@@ -1362,7 +1362,7 @@ static void abbrev_oid_in_line(struct strbuf *line)
return;
if ((2 <= string_list_split(&split, line->buf, " ", 2)) &&
- !repo_get_oid(the_repository, split.items[1].string, &oid)) {
+ !repo_get_oid(r, split.items[1].string, &oid)) {
strbuf_reset(line);
strbuf_addf(line, "%s ", split.items[0].string);
strbuf_add_unique_abbrev(line, &oid, DEFAULT_ABBREV);
@@ -1372,10 +1372,10 @@ static void abbrev_oid_in_line(struct strbuf *line)
string_list_clear(&split, 0);
}
-static int read_rebase_todolist(const char *fname, struct string_list *lines)
+static int read_rebase_todolist(struct repository *r, const char *fname, struct string_list *lines)
{
struct strbuf buf = STRBUF_INIT;
- FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r");
+ FILE *f = fopen(repo_git_path_append(r, &buf, "%s", fname), "r");
int ret;
if (!f) {
@@ -1384,7 +1384,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)
goto out;
}
die_errno("Could not open file %s for reading",
- repo_git_path_replace(the_repository, &buf, "%s", fname));
+ repo_git_path_replace(r, &buf, "%s", fname));
}
while (!strbuf_getline_lf(&buf, f)) {
if (starts_with(buf.buf, comment_line_str))
@@ -1392,7 +1392,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)
strbuf_trim(&buf);
if (!buf.len)
continue;
- abbrev_oid_in_line(&buf);
+ abbrev_oid_in_line(r, &buf);
string_list_append(lines, buf.buf);
}
fclose(f);
@@ -1413,8 +1413,8 @@ static void show_rebase_information(struct wt_status *s,
struct string_list have_done = STRING_LIST_INIT_DUP;
struct string_list yet_to_do = STRING_LIST_INIT_DUP;
- read_rebase_todolist("rebase-merge/done", &have_done);
- if (read_rebase_todolist("rebase-merge/git-rebase-todo",
+ read_rebase_todolist(s->repo, "rebase-merge/done", &have_done);
+ if (read_rebase_todolist(s->repo, "rebase-merge/git-rebase-todo",
&yet_to_do))
status_printf_ln(s, color,
_("git-rebase-todo is missing."));
@@ -2259,7 +2259,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
*/
static void wt_porcelain_v2_print_stash(struct wt_status *s)
{
- int stash_count = count_stash_entries();
+ int stash_count = count_stash_entries(s->repo);
char eol = s->null_termination ? '\0' : '\n';
if (stash_count > 0)
--
2.53.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v5 2/3] wt-status: replace uses of the_repository with local repository instances
2026-02-18 17:53 ` [PATCH v5 " Shreyansh Paliwal
2026-02-18 17:53 ` [PATCH v5 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
@ 2026-02-18 17:53 ` Shreyansh Paliwal
2026-02-18 17:53 ` [PATCH v5 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
2026-03-06 22:31 ` [PATCH v5 0/3] wt-status: reduce reliance on global state Junio C Hamano
3 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-18 17:53 UTC (permalink / raw)
To: git; +Cc: phillip.wood123, gitster, karthik.188, Shreyansh Paliwal
wt-status.c uses the global the_repository in several places even when a
repository instance is already available via struct wt_status *s or struct
repository *r.
Replace these uses of the_repository with the repository available in the
local context (i.e. s->repo or r).
The replacements of all the_repository with s->repo are mostly to cases
where a repository instance is already available via struct wt_status *s
and struct repository *r, all functions operating on struct wt_status *s
are only used after s is initialized by wt_status_prepare(), which sets
s->repo from the repository provided by the caller. As a result, s->repo is
guaranteed to be available and consistent whenever these functions are
invoked.
This reduces reliance on global state and keeps wt-status consistent,
though many functions operating on struct wt_status *s are called via
commit.c and it still relies on the_repository, but within wt-status.c the
local repository pointer refers to the same underlying repository object.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
wt-status.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index 97c2e10a8c..b44b8377e5 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -150,11 +150,11 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
s->use_color = GIT_COLOR_UNKNOWN;
s->relative_paths = 1;
- s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
+ s->branch = refs_resolve_refdup(get_main_ref_store(r),
"HEAD", 0, NULL, NULL);
s->reference = "HEAD";
s->fp = stdout;
- s->index_file = repo_get_index_file(the_repository);
+ s->index_file = repo_get_index_file(r);
s->change.strdup_strings = 1;
s->untracked.strdup_strings = 1;
s->ignored.strdup_strings = 1;
@@ -646,7 +646,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
repo_init_revisions(s->repo, &rev, NULL);
memset(&opt, 0, sizeof(opt));
- opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
+ opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.flags.override_submodule_config = 1;
@@ -1146,7 +1146,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
rev.diffopt.ita_invisible_in_index = 1;
memset(&opt, 0, sizeof(opt));
- opt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;
+ opt.def = s->is_initial ? empty_tree_oid_hex(s->repo->hash_algo) : s->reference;
setup_revisions(0, NULL, &rev, &opt);
rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
@@ -1317,9 +1317,9 @@ static int split_commit_in_progress(struct wt_status *s)
!s->branch || strcmp(s->branch, "HEAD"))
return 0;
- if (refs_read_ref_full(get_main_ref_store(the_repository), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+ if (refs_read_ref_full(get_main_ref_store(s->repo), "HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
&head_oid, &head_flags) ||
- refs_read_ref_full(get_main_ref_store(the_repository), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+ refs_read_ref_full(get_main_ref_store(s->repo), "ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
&orig_head_oid, &orig_head_flags))
return 0;
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
@@ -1432,7 +1432,7 @@ static void show_rebase_information(struct wt_status *s,
i++)
status_printf_ln(s, color, " %s", have_done.items[i].string);
if (have_done.nr > nr_lines_to_show && s->hints) {
- char *path = repo_git_path(the_repository, "rebase-merge/done");
+ char *path = repo_git_path(s->repo, "rebase-merge/done");
status_printf_ln(s, color,
_(" (see more in file %s)"), path);
free(path);
@@ -1534,7 +1534,7 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
else
status_printf_ln(s, color,
_("You are currently cherry-picking commit %s."),
- repo_find_unique_abbrev(the_repository, &s->state.cherry_pick_head_oid,
+ repo_find_unique_abbrev(s->repo, &s->state.cherry_pick_head_oid,
DEFAULT_ABBREV));
if (s->hints) {
@@ -1564,7 +1564,7 @@ static void show_revert_in_progress(struct wt_status *s,
else
status_printf_ln(s, color,
_("You are currently reverting commit %s."),
- repo_find_unique_abbrev(the_repository, &s->state.revert_head_oid,
+ repo_find_unique_abbrev(s->repo, &s->state.revert_head_oid,
DEFAULT_ABBREV));
if (s->hints) {
if (has_unmerged(s))
@@ -1691,7 +1691,7 @@ static void wt_status_get_detached_from(struct repository *r,
char *ref = NULL;
strbuf_init(&cb.buf, 0);
- if (refs_for_each_reflog_ent_reverse(get_main_ref_store(the_repository), "HEAD", grab_1st_switch, &cb) <= 0) {
+ if (refs_for_each_reflog_ent_reverse(get_main_ref_store(r), "HEAD", grab_1st_switch, &cb) <= 0) {
strbuf_release(&cb.buf);
return;
}
@@ -2099,7 +2099,7 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
upstream_is_gone = 1;
}
- short_base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
+ short_base = refs_shorten_unambiguous_ref(get_main_ref_store(s->repo),
base, 0);
color_fprintf(s->fp, header_color, "...");
color_fprintf(s->fp, branch_color_remote, "%s", short_base);
@@ -2233,7 +2233,7 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
ab_info = stat_tracking_info(branch, &nr_ahead, &nr_behind,
&base, 0, s->ahead_behind_flags);
if (base) {
- base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
+ base = refs_shorten_unambiguous_ref(get_main_ref_store(s->repo),
base, 0);
fprintf(s->fp, "# branch.upstream %s%c", base, eol);
free((char *)base);
--
2.53.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v5 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo
2026-02-18 17:53 ` [PATCH v5 " Shreyansh Paliwal
2026-02-18 17:53 ` [PATCH v5 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
2026-02-18 17:53 ` [PATCH v5 2/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
@ 2026-02-18 17:53 ` Shreyansh Paliwal
2026-03-06 22:31 ` [PATCH v5 0/3] wt-status: reduce reliance on global state Junio C Hamano
3 siblings, 0 replies; 69+ messages in thread
From: Shreyansh Paliwal @ 2026-02-18 17:53 UTC (permalink / raw)
To: git; +Cc: phillip.wood123, gitster, karthik.188, Shreyansh Paliwal
wt-status.c still uses the global the_hash_algo even though a repository
instance is already available via struct wt_status.
Replace uses of the_hash_algo with the hash algorithm stored in the
associated repository (s->repo->hash_algo or r->hash_algo).
This removes another dependency on global state and keeps wt-status
consistent with local repository usage.
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
---
wt-status.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index b44b8377e5..264281fb67 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1815,10 +1815,10 @@ void wt_status_get_state(struct repository *r,
if (!sequencer_get_last_command(r, &action)) {
if (action == REPLAY_PICK && !state->cherry_pick_in_progress) {
state->cherry_pick_in_progress = 1;
- oidcpy(&state->cherry_pick_head_oid, null_oid(the_hash_algo));
+ oidcpy(&state->cherry_pick_head_oid, null_oid(r->hash_algo));
} else if (action == REPLAY_REVERT && !state->revert_in_progress) {
state->revert_in_progress = 1;
- oidcpy(&state->revert_head_oid, null_oid(the_hash_algo));
+ oidcpy(&state->revert_head_oid, null_oid(r->hash_algo));
}
}
if (get_detached_from)
@@ -2630,7 +2630,7 @@ int has_uncommitted_changes(struct repository *r,
* We have no head (or it's corrupt); use the empty tree,
* which will complain if the index is non-empty.
*/
- struct tree *tree = lookup_tree(r, the_hash_algo->empty_tree);
+ struct tree *tree = lookup_tree(r, r->hash_algo->empty_tree);
add_pending_object(&rev_info, &tree->object, "");
}
--
2.53.0
^ permalink raw reply related [flat|nested] 69+ messages in thread
* Re: [PATCH v5 0/3] wt-status: reduce reliance on global state
2026-02-18 17:53 ` [PATCH v5 " Shreyansh Paliwal
` (2 preceding siblings ...)
2026-02-18 17:53 ` [PATCH v5 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
@ 2026-03-06 22:31 ` Junio C Hamano
2026-03-09 10:32 ` Karthik Nayak
2026-03-09 10:35 ` Phillip Wood
3 siblings, 2 replies; 69+ messages in thread
From: Junio C Hamano @ 2026-03-06 22:31 UTC (permalink / raw)
To: Shreyansh Paliwal; +Cc: git, phillip.wood123, karthik.188
Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
> Changes in v5:
> - Added the usage of struct repository *r in addition to adding it as a parameter to the functions,
> in patch 1/3 instead of doing that in 2/3.
We haven't seen any reviews on the latest round, but the previous
iterations all had good discussions. Is everybody find this round
satisfactory? If so, let me mark the topic for 'next'.
Thanks.
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v5 0/3] wt-status: reduce reliance on global state
2026-03-06 22:31 ` [PATCH v5 0/3] wt-status: reduce reliance on global state Junio C Hamano
@ 2026-03-09 10:32 ` Karthik Nayak
2026-03-09 18:30 ` Junio C Hamano
2026-03-09 10:35 ` Phillip Wood
1 sibling, 1 reply; 69+ messages in thread
From: Karthik Nayak @ 2026-03-09 10:32 UTC (permalink / raw)
To: Junio C Hamano, Shreyansh Paliwal; +Cc: git, phillip.wood123
[-- Attachment #1: Type: text/plain, Size: 568 bytes --]
Junio C Hamano <gitster@pobox.com> writes:
> Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>
>> Changes in v5:
>> - Added the usage of struct repository *r in addition to adding it as a parameter to the functions,
>> in patch 1/3 instead of doing that in 2/3.
>
> We haven't seen any reviews on the latest round, but the previous
> iterations all had good discussions. Is everybody find this round
> satisfactory? If so, let me mark the topic for 'next'.
>
> Thanks.
I'm happy with the current version. Makes sense to move it to 'next'.
Thanks
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v5 0/3] wt-status: reduce reliance on global state
2026-03-06 22:31 ` [PATCH v5 0/3] wt-status: reduce reliance on global state Junio C Hamano
2026-03-09 10:32 ` Karthik Nayak
@ 2026-03-09 10:35 ` Phillip Wood
1 sibling, 0 replies; 69+ messages in thread
From: Phillip Wood @ 2026-03-09 10:35 UTC (permalink / raw)
To: Junio C Hamano, Shreyansh Paliwal; +Cc: git, karthik.188
On 06/03/2026 22:31, Junio C Hamano wrote:
> Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>
>> Changes in v5:
>> - Added the usage of struct repository *r in addition to adding it as a parameter to the functions,
>> in patch 1/3 instead of doing that in 2/3.
>
> We haven't seen any reviews on the latest round, but the previous
> iterations all had good discussions. Is everybody find this round
> satisfactory? If so, let me mark the topic for 'next'.
Yes this looks good, lets merge it (sorry I thought I'd reviewed this
round when it was posted but clearly didn't actually get round to it)
Thanks
Phillip
^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v5 0/3] wt-status: reduce reliance on global state
2026-03-09 10:32 ` Karthik Nayak
@ 2026-03-09 18:30 ` Junio C Hamano
0 siblings, 0 replies; 69+ messages in thread
From: Junio C Hamano @ 2026-03-09 18:30 UTC (permalink / raw)
To: Karthik Nayak, phillip.wood123; +Cc: Shreyansh Paliwal, git
Karthik Nayak <karthik.188@gmail.com> writes:
> Junio C Hamano <gitster@pobox.com> writes:
>
>> Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com> writes:
>>
>>> Changes in v5:
>>> - Added the usage of struct repository *r in addition to adding it as a parameter to the functions,
>>> in patch 1/3 instead of doing that in 2/3.
>>
>> We haven't seen any reviews on the latest round, but the previous
>> iterations all had good discussions. Is everybody find this round
>> satisfactory? If so, let me mark the topic for 'next'.
>>
>> Thanks.
>
> I'm happy with the current version. Makes sense to move it to 'next'.
>
> Thanks
Thanks for reviewing and helping the series to become in good shape.
^ permalink raw reply [flat|nested] 69+ messages in thread
end of thread, other threads:[~2026-03-09 18:30 UTC | newest]
Thread overview: 69+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-31 18:57 [PATCH 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
2026-01-31 18:57 ` [PATCH 1/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
2026-02-02 10:02 ` Karthik Nayak
2026-02-02 18:42 ` Junio C Hamano
2026-02-02 18:57 ` Shreyansh Paliwal
2026-02-02 22:41 ` Junio C Hamano
2026-02-02 23:03 ` Junio C Hamano
2026-02-03 9:53 ` Shreyansh Paliwal
2026-02-03 11:06 ` Phillip Wood
2026-02-03 15:20 ` Shreyansh Paliwal
2026-02-03 10:58 ` Phillip Wood
2026-02-03 15:15 ` Shreyansh Paliwal
2026-01-31 18:57 ` [PATCH 2/3] wt-status: pass struct repository and wt_status through function parameters Shreyansh Paliwal
2026-01-31 18:57 ` [PATCH 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
2026-02-02 10:03 ` Karthik Nayak
2026-02-02 19:03 ` Shreyansh Paliwal
2026-02-04 10:18 ` Karthik Nayak
2026-02-04 11:22 ` Shreyansh Paliwal
2026-02-05 10:13 ` [PATCH V2 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
2026-02-05 10:13 ` [PATCH V2 1/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
2026-02-05 10:59 ` Karthik Nayak
2026-02-05 11:11 ` Karthik Nayak
2026-02-05 12:18 ` Shreyansh Paliwal
2026-02-05 16:08 ` Phillip Wood
2026-02-05 17:41 ` Shreyansh Paliwal
2026-02-05 10:13 ` [PATCH V2 2/3] wt-status: pass struct repository and wt_status through function parameters Shreyansh Paliwal
2026-02-05 11:09 ` Karthik Nayak
2026-02-05 12:04 ` Shreyansh Paliwal
2026-02-06 9:24 ` Karthik Nayak
2026-02-06 9:32 ` Shreyansh Paliwal
2026-02-06 12:57 ` Shreyansh Paliwal
2026-02-06 14:54 ` Phillip Wood
2026-02-06 17:06 ` Shreyansh Paliwal
2026-02-05 15:58 ` Phillip Wood
2026-02-05 10:13 ` [PATCH V2 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
2026-02-05 10:27 ` [PATCH V2 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
2026-02-05 15:53 ` Phillip Wood
2026-02-05 17:39 ` Shreyansh Paliwal
2026-02-05 18:02 ` Kristoffer Haugsbakk
2026-02-05 18:18 ` Shreyansh Paliwal
2026-02-07 10:00 ` [PATCH v3 " Shreyansh Paliwal
2026-02-07 10:00 ` [PATCH v3 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
2026-02-08 1:14 ` Junio C Hamano
2026-02-08 4:55 ` [PATCH V2 2/3] wt-status: pass struct repository and wt_status " Shreyansh Paliwal
2026-02-09 8:36 ` [PATCH v3 1/3] wt-status: pass struct repository " Karthik Nayak
2026-02-08 1:21 ` Junio C Hamano
2026-02-08 4:44 ` [PATCH V2 2/3] wt-status: pass struct repository and wt_status " Shreyansh Paliwal
2026-02-08 6:08 ` Junio C Hamano
2026-02-08 15:25 ` Shreyansh Paliwal
2026-02-09 9:02 ` Karthik Nayak
2026-02-09 13:43 ` Shreyansh Paliwal
2026-02-09 16:13 ` Junio C Hamano
2026-02-10 9:50 ` Karthik Nayak
2026-02-07 10:00 ` [PATCH v3 2/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
2026-02-07 10:00 ` [PATCH v3 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
2026-02-17 17:29 ` [PATCH v4 0/3] wt-status: reduce reliance on global state Shreyansh Paliwal
2026-02-17 17:29 ` [PATCH v4 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
2026-02-17 17:29 ` [PATCH v4 2/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
2026-02-17 17:29 ` [PATCH v4 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
2026-02-18 16:13 ` [PATCH v4 0/3] wt-status: reduce reliance on global state Phillip Wood
2026-02-18 16:48 ` Shreyansh Paliwal
2026-02-18 17:53 ` [PATCH v5 " Shreyansh Paliwal
2026-02-18 17:53 ` [PATCH v5 1/3] wt-status: pass struct repository through function parameters Shreyansh Paliwal
2026-02-18 17:53 ` [PATCH v5 2/3] wt-status: replace uses of the_repository with local repository instances Shreyansh Paliwal
2026-02-18 17:53 ` [PATCH v5 3/3] wt-status: use hash_algo from local repository instead of global the_hash_algo Shreyansh Paliwal
2026-03-06 22:31 ` [PATCH v5 0/3] wt-status: reduce reliance on global state Junio C Hamano
2026-03-09 10:32 ` Karthik Nayak
2026-03-09 18:30 ` Junio C Hamano
2026-03-09 10:35 ` Phillip Wood
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox