[PATCH 6/7] rerere: bundle global state into a struct
- From
Patrick Steinhardt <ps@pks.im>
- Date
- Oct 23, 2026, 12:50 UTC
- Message-ID
- <20261023-pks-rerere-wo-the-repository-v1-6-b6ac0c2e4b81@pks.im>
- In-Reply-To
- <20261023-pks-rerere-wo-the-repository-v1-0-b6ac0c2e4b81@pks.im>
The state of the rerere subsystem is tracked across several global variables. Move them into a struct so that we can easily de-globalize the state.
Note that the lock timeout is only ever used in `setup_rerere()`. So instead of moving it into the new struct, we just keep it as a local variable.
Signed-off-by: Patrick Steinhardt <ps@pks.im> --- rerere.c | 44 +++++++++++++++++++------------------------- rerere.h | 11 +++++++++++ 2 files changed, 30 insertions(+), 25 deletions(-)
diff --git a/rerere.c b/rerere.c index 366797ab7e..23bcb8bc31 100644 --- a/rerere.c +++ b/rerere.c @@ -21,17 +21,15 @@ #include "odb.h" #include "strmap.h" +static struct rerere_cache cache = { + .dirs = STRMAP_INIT, +}; + #define RESOLVED 0 #define PUNTED 1 #define THREE_STAGED 2 void *RERERE_RESOLVED = &RERERE_RESOLVED; -/* automatically update cleanly resolved paths to the index */ -static int rerere_autoupdate; - -/* how long to wait for MERGE_RR.lock, in milliseconds */ -static int rerere_lock_timeout_ms = 1000; - #define RR_HAS_POSTIMAGE 1 #define RR_HAS_PREIMAGE 2 struct rerere_dir { @@ -40,19 +38,17 @@ struct rerere_dir { char name[FLEX_ARRAY]; }; -static struct strmap rerere_dirs = STRMAP_INIT; - static void free_rerere_dirs(void) { struct hashmap_iter iter; struct strmap_entry *ent; - strmap_for_each_entry(&rerere_dirs, &iter, ent) { + strmap_for_each_entry(&cache.dirs, &iter, ent) { struct rerere_dir *rr_dir = ent->value; free(rr_dir->status); free(rr_dir); } - strmap_clear(&rerere_dirs, 0); + strmap_clear(&cache.dirs, 0); } static void free_rerere_id(struct string_list_item *item) @@ -154,13 +150,13 @@ static struct rerere_dir *find_rerere_dir(struct repository *r, const char *hex) { struct rerere_dir *rr_dir; - rr_dir = strmap_get(&rerere_dirs, hex); + rr_dir = strmap_get(&cache.dirs, hex); if (!rr_dir) { FLEX_ALLOC_STR(rr_dir, name, hex); rr_dir->status = NULL; rr_dir->status_nr = 0; rr_dir->status_alloc = 0; - strmap_put(&rerere_dirs, hex, rr_dir); + strmap_put(&cache.dirs, hex, rr_dir); scan_rerere_dir(r, rr_dir); } @@ -241,8 +237,6 @@ static void read_rr(struct repository *r, struct string_list *rr) fclose(in); } -static struct lock_file write_lock; - static int write_rr(struct string_list *rr, int out_fd) { int i; @@ -270,7 +264,7 @@ static int write_rr(struct string_list *rr, int out_fd) strbuf_release(&buf); } - if (commit_lock_file(&write_lock) != 0) + if (commit_lock_file(&cache.write_lock) != 0) die(_("unable to write rerere record")); return 0; } @@ -785,7 +779,7 @@ static void do_rerere_one_path(struct index_state *istate, if (0 <= id->variant && id->variant != variant) remove_variant(istate->repo, id); - if (rerere_autoupdate) + if (cache.autoupdate) string_list_insert(update, path); else fprintf_ln(stderr, @@ -902,27 +896,27 @@ static int is_rerere_enabled(struct repository *r) int setup_rerere(struct repository *r, struct string_list *merge_rr, int flags) { + int lock_timeout_ms = 1000; int fd; if (!is_rerere_enabled(r)) return -1; - repo_config_get_bool(r, "rerere.autoupdate", &rerere_autoupdate); - repo_config_get_int(r, "rerere.locktimeout", &rerere_lock_timeout_ms); + repo_config_get_bool(r, "rerere.autoupdate", &cache.autoupdate); + repo_config_get_int(r, "rerere.locktimeout", &lock_timeout_ms); if (flags & (RERERE_AUTOUPDATE|RERERE_NOAUTOUPDATE)) - rerere_autoupdate = !!(flags & RERERE_AUTOUPDATE); + cache.autoupdate = !!(flags & RERERE_AUTOUPDATE); if ((flags & RERERE_READONLY) && (flags & RERERE_NOWAIT)) BUG("RERERE_NOWAIT does not apply with RERERE_READONLY"); if (flags & RERERE_READONLY) { fd = 0; } else { int lock_flags = LOCK_DIE_ON_ERROR; - int timeout_ms = rerere_lock_timeout_ms; if (flags & RERERE_NOWAIT) { lock_flags = 0; - timeout_ms = 0; + lock_timeout_ms = 0; } /* @@ -930,9 +924,9 @@ int setup_rerere(struct repository *r, struct string_list *merge_rr, int flags) * "git rerere gc" while it prunes rr-cache, so by default * wait for it instead of dying right away. */ - fd = repo_hold_lock_file_for_update_timeout(r, &write_lock, + fd = repo_hold_lock_file_for_update_timeout(r, &cache.write_lock, git_path_merge_rr(r), - lock_flags, timeout_ms); + lock_flags, lock_timeout_ms); if (fd < 0) return -1; } @@ -1369,7 +1363,7 @@ void rerere_gc(struct repository *r, struct string_list *rr, int flags) "rr-cache/%s", to_remove.items[i].string)); string_list_clear(&to_remove, 0); - rollback_lock_file(&write_lock); + rollback_lock_file(&cache.write_lock); strbuf_release(&buf); } @@ -1399,5 +1393,5 @@ void rerere_clear(struct repository *r, struct string_list *merge_rr) strbuf_release(&buf); } unlink_or_warn(git_path_merge_rr(r)); - rollback_lock_file(&write_lock); + rollback_lock_file(&cache.write_lock); } diff --git a/rerere.h b/rerere.h index ee8d97917d..570667d866 100644 --- a/rerere.h +++ b/rerere.h @@ -2,7 +2,9 @@ #define RERERE_H #include "gettext.h" +#include "lockfile.h" #include "string-list.h" +#include "strmap.h" struct pathspec; struct repository; @@ -20,6 +22,15 @@ struct repository; */ extern void *RERERE_RESOLVED; +struct rerere_cache { + /* Automatically update cleanly resolved paths to the index. */ + int autoupdate; + + struct strmap dirs; + + struct lock_file write_lock; +}; + struct rerere_dir; struct rerere_id { struct rerere_dir *collection;
-- 2.56.0.307.g5fe7bd680c.dirty