* Some refs are global to the repository (refs/heads/{*}), while others are * local to the worktree (eg. HEAD, refs/bisect/{*}). We solve this by having * multiple separate databases (ie. multiple reftable/ directories), one for * the shared refs, one for the current worktree refs, and one for each * additional worktree. For reading, we merge the view of both the shared and * the current work
| 217 | * those references in their normalized form. |
| 218 | */ |
| 219 | static int backend_for(struct reftable_backend **out, |
| 220 | struct reftable_ref_store *store, |
| 221 | const char *refname, |
| 222 | const char **rewritten_ref, |
| 223 | int reload) |
| 224 | { |
| 225 | const char *wtname; |
| 226 | int wtname_len; |
| 227 | int ret; |
| 228 | |
| 229 | if (!refname) { |
| 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; |
| 238 | |
| 239 | /* |
| 240 | * We're using a static buffer here so that we don't need to |
| 241 | * allocate the worktree name whenever we look up a reference. |
| 242 | * This could be avoided if the strmap interface knew how to |
| 243 | * handle keys with a length. |
| 244 | */ |
| 245 | strbuf_reset(&wtname_buf); |
| 246 | strbuf_add(&wtname_buf, wtname, wtname_len); |
| 247 | |
| 248 | /* |
| 249 | * There is an edge case here: when the worktree references the |
| 250 | * current worktree, then we set up the stack once via |
| 251 | * `worktree_backends` and once via `worktree_backend`. This is |
| 252 | * wasteful, but in the reading case it shouldn't matter. And |
| 253 | * in the writing case we would notice that the stack is locked |
| 254 | * already and error out when trying to write a reference via |
| 255 | * both stacks. |
| 256 | */ |
| 257 | ret = backend_for_worktree(out, store, wtname_buf.buf); |
| 258 | |
| 259 | goto out; |
| 260 | } |
| 261 | case REF_WORKTREE_CURRENT: |
| 262 | /* |
| 263 | * If there is no worktree stack then we're currently in the |
| 264 | * main worktree. We thus return the main stack in that case. |
| 265 | */ |
| 266 | if (!store->worktree_backend.stack) |
| 267 | *out = &store->main_backend; |
| 268 | else |
| 269 | *out = &store->worktree_backend; |
| 270 | ret = 0; |
| 271 | goto out; |
| 272 | case REF_WORKTREE_MAIN: |
| 273 | case REF_WORKTREE_SHARED: |
| 274 | *out = &store->main_backend; |
| 275 | ret = 0; |
| 276 | goto out; |
no test coverage detected