refs/reftable: extract function to retrieve backend for worktree
Pull out the logic to retrieve a backend for a given worktree. This function will be used in a subsequent commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Jan 12, 2026 at 10:03 UTC
78384e2467c4e457f230e731f26409fa7dd72434
1 file changed
+43
-27
refs/reftable-backend.c
+43
-27
@@ -172,6 +172,37 @@ static struct reftable_ref_store *reftable_be_downcast(struct ref_store *ref_sto
172
return refs;
173
}
174
175
+static int backend_for_worktree(struct reftable_backend **out,
176
+ struct reftable_ref_store *store,
177
+ const char *worktree_name)
178
+{
179
+ struct strbuf worktree_dir = STRBUF_INIT;
180
+ int ret;
181
+
182
+ *out = strmap_get(&store->worktree_backends, worktree_name);
183
+ if (*out) {
184
+ ret = 0;
185
+ goto out;
186
+ }
187
+
188
+ strbuf_addf(&worktree_dir, "%s/worktrees/%s/reftable",
189
+ store->base.repo->commondir, worktree_name);
190
+
191
+ CALLOC_ARRAY(*out, 1);
192
+ store->err = ret = reftable_backend_init(*out, worktree_dir.buf,
193
+ &store->write_options);
194
+ if (ret < 0) {
195
+ free(*out);
196
+ goto out;
197
+ }
198
+
199
+ strmap_put(&store->worktree_backends, worktree_name, *out);
200
+
201
+out:
202
+ strbuf_release(&worktree_dir);
203
+ return ret;
204
+}
205
+
206
/*
207
* Some refs are global to the repository (refs/heads/{*}), while others are
208
* local to the worktree (eg. HEAD, refs/bisect/{*}). We solve this by having
@@ -191,19 +222,19 @@ static int backend_for(struct reftable_backend **out,
222
const char **rewritten_ref,
223
int reload)
224
{
194
- struct reftable_backend *be;
225
const char *wtname;
226
int wtname_len;
227
+ int ret;
228
229
if (!refname) {
199
- be = &store->main_backend;
230
+ *out = &store->main_backend;
231
+ ret = 0;
232
goto out;
233
}
234
235
switch (parse_worktree_ref(refname, &wtname, &wtname_len, rewritten_ref)) {
236
case REF_WORKTREE_OTHER: {
237
static struct strbuf wtname_buf = STRBUF_INIT;
206
- struct strbuf wt_dir = STRBUF_INIT;
238
239
/*
240
* We're using a static buffer here so that we don't need to
@@ -223,20 +254,8 @@ static int backend_for(struct reftable_backend **out,
254
* already and error out when trying to write a reference via
255
* both stacks.
256
*/
226
- be = strmap_get(&store->worktree_backends, wtname_buf.buf);
227
- if (!be) {
228
- strbuf_addf(&wt_dir, "%s/worktrees/%s/reftable",
229
- store->base.repo->commondir, wtname_buf.buf);
257
+ ret = backend_for_worktree(out, store, wtname_buf.buf);
258
231
- CALLOC_ARRAY(be, 1);
232
- store->err = reftable_backend_init(be, wt_dir.buf,
233
- &store->write_options);
234
- assert(store->err != REFTABLE_API_ERROR);
235
-
236
- strmap_put(&store->worktree_backends, wtname_buf.buf, be);
237
- }
238
-
239
- strbuf_release(&wt_dir);
259
goto out;
260
}
261
case REF_WORKTREE_CURRENT:
@@ -245,27 +264,24 @@ static int backend_for(struct reftable_backend **out,
264
* main worktree. We thus return the main stack in that case.
265
*/
266
if (!store->worktree_backend.stack)
248
- be = &store->main_backend;
267
+ *out = &store->main_backend;
268
else
250
- be = &store->worktree_backend;
269
+ *out = &store->worktree_backend;
270
+ ret = 0;
271
goto out;
272
case REF_WORKTREE_MAIN:
273
case REF_WORKTREE_SHARED:
254
- be = &store->main_backend;
274
+ *out = &store->main_backend;
275
+ ret = 0;
276
goto out;
277
default:
278
BUG("unhandled worktree reference type");
279
}
280
281
out:
261
- if (reload) {
262
- int ret = reftable_stack_reload(be->stack);
263
- if (ret)
264
- return ret;
265
- }
266
- *out = be;
267
-
268
- return 0;
282
+ if (reload && !ret)
283
+ ret = reftable_stack_reload((*out)->stack);
284
+ return ret;
285
}
286
287
static int should_write_log(struct reftable_ref_store *refs, const char *refname)