Subject: [PATCH v2 00/16] refs: drop all references to `the_repository`

From: Patrick Steinhardt <[email-masked]>
Date: Fri, 17 May 2024 10:18:10 +0200

Hi,

this is the second version of my patch series that removes all
references to `the_repository` and `the_hash_algo` in the refs
interfaces.

Changes compared to v1:

  - Fix duplicate word in commit message.

  - Rename `ref_store_create()` to `ref_store_create_on_disk()`.

  - Add a trace when calling `debug_release()`.

  - Add a note in patch 5 that the newly added reference to
    `the_repository` in `resolved_gitlink_ref()` gets fixed in the
    following patch.

  - Fix unsetting the worktree stack in `reftable_be_release()`.

Thanks!

Patrick

Patrick Steinhardt (16):
  refs: adjust names for `init` and `init_db` callbacks
  refs: rename `init_db` callback to avoid confusion
  refs: implement releasing ref storages
  refs: track ref stores via strmap
  refs: pass repo when retrieving submodule ref store
  refs: refactor `resolve_gitlink_ref()` to accept a repository
  refs: retrieve worktree ref stores via associated repository
  refs: convert iteration over replace refs to accept ref store
  refs: pass ref store when detecting dangling symrefs
  refs: move object peeling into "object.c"
  refs: pass repo when peeling objects
  refs: drop `git_default_branch_name()`
  refs: remove `dwim_log()`
  refs/files: use correct repository
  refs/files: remove references to `the_hash_algo`
  refs/packed: remove references to `the_hash_algo`

 attr.c                      |   3 +-
 builtin/clone.c             |   5 +-
 builtin/describe.c          |   2 +-
 builtin/fetch.c             |   3 +-
 builtin/gc.c                |   2 +-
 builtin/pack-objects.c      |   6 +-
 builtin/reflog.c            |   2 +-
 builtin/remote.c            |   3 +-
 builtin/repack.c            |   2 +-
 builtin/replace.c           |  13 +-
 builtin/show-ref.c          |   2 +-
 builtin/submodule--helper.c |  14 +-
 builtin/update-index.c      |   5 +-
 builtin/var.c               |   2 +-
 builtin/worktree.c          |   2 +-
 combine-diff.c              |   3 +-
 commit-graph.c              |   2 +-
 diff-lib.c                  |   3 +-
 dir.c                       |   3 +-
 ls-refs.c                   |   2 +-
 midx-write.c                |   2 +-
 object-file.c               |   2 +-
 object.c                    |  23 ++++
 object.h                    |  35 +++++
 read-cache.c                |   5 +-
 ref-filter.c                |   2 +-
 reflog-walk.c               |   4 +-
 reflog.c                    |   2 +-
 refs.c                      | 266 ++++++++++--------------------------
 refs.h                      |  51 +++----
 refs/debug.c                |  16 ++-
 refs/files-backend.c        |  59 ++++----
 refs/iterator.c             |   6 +-
 refs/packed-backend.c       |  67 +++++----
 refs/packed-backend.h       |   6 +-
 refs/ref-cache.c            |   5 +-
 refs/refs-internal.h        |  54 ++------
 refs/reftable-backend.c     |  39 +++++-
 remote.c                    |  12 +-
 replace-object.c            |  10 +-
 repository.c                |  12 ++
 repository.h                |  14 ++
 setup.c                     |   7 +-
 submodule.c                 |   3 +-
 t/helper/test-reach.c       |   2 +-
 t/helper/test-ref-store.c   |   2 +-
 tag.c                       |   4 +-
 tag.h                       |   2 +-
 unpack-trees.c              |   3 +-
 upload-pack.c               |   2 +-
 worktree.c                  |   2 +
 worktree.h                  |   2 +
 52 files changed, 408 insertions(+), 392 deletions(-)

Range-diff against v1:
 1:  360d034746 !  1:  4225a6928a refs: adjust names for `init` and `init_db` callbacks
    @@ Metadata
      ## Commit message ##
         refs: adjust names for `init` and `init_db` callbacks
     
    -    The names of the functions that implement the the `init` and `init_db`
    +    The names of the functions that implement the `init` and `init_db`
         callbacks in the "files" and "packed" backends do not match the names of
         the callbacks, which is inconsistent. Rename them so that they match,
         which makes it easier to discover their respective implementations.
 2:  3cc2b4e550 !  2:  050fb24e58 refs: rename `init_db` callback to avoid confusion
    @@ Commit message
         refs: rename `init_db` callback to avoid confusion
     
         Reference backends have two callbacks `init` and `init_db`. The
    -    similarity of these two callbacks has repeatedly tripped myself whenever
    -    I was looking at those, where I always had to look up which of them does
    +    similarity of these two callbacks has repeatedly confused me whenever I
    +    was looking at them, where I always had to look up which of them does
         what.
     
    -    Rename the `init_db` callback to `create`, which should hopefully be
    -    clearer.
    +    Rename the `init_db` callback to `create_on_disk`, which should
    +    hopefully be clearer.
     
         Signed-off-by: Patrick Steinhardt <[email-masked]>
     
    @@ builtin/worktree.c: static int add_worktree(const char *path, const char *refnam
      	wt_refs = get_worktree_ref_store(wt);
      
     -	ret = refs_init_db(wt_refs, REFS_INIT_DB_IS_WORKTREE, &sb);
    -+	ret = ref_store_create(wt_refs, REF_STORE_CREATE_IS_WORKTREE, &sb);
    ++	ret = ref_store_create_on_disk(wt_refs, REF_STORE_CREATE_ON_DISK_IS_WORKTREE, &sb);
      	if (ret)
      		goto done;
      
    @@ refs.c: const char *refs_resolve_ref_unsafe(struct ref_store *refs,
      
      /* backend functions */
     -int refs_init_db(struct ref_store *refs, int flags, struct strbuf *err)
    -+int ref_store_create(struct ref_store *refs, int flags, struct strbuf *err)
    ++int ref_store_create_on_disk(struct ref_store *refs, int flags, struct strbuf *err)
      {
     -	return refs->be->init_db(refs, flags, err);
    -+	return refs->be->create(refs, flags, err);
    ++	return refs->be->create_on_disk(refs, flags, err);
      }
      
      int resolve_gitlink_ref(const char *submodule, const char *refname,
    @@ refs.h: int should_autocreate_reflog(const char *refname);
      int is_branch(const char *refname);
      
     -#define REFS_INIT_DB_IS_WORKTREE (1 << 0)
    -+#define REF_STORE_CREATE_IS_WORKTREE (1 << 0)
    ++#define REF_STORE_CREATE_ON_DISK_IS_WORKTREE (1 << 0)
      
     -int refs_init_db(struct ref_store *refs, int flags, struct strbuf *err);
    -+int ref_store_create(struct ref_store *refs, int flags, struct strbuf *err);
    ++int ref_store_create_on_disk(struct ref_store *refs, int flags, struct strbuf *err);
      
      /*
       * Return the peeled value of the oid currently being iterated via
    @@ refs/debug.c: struct ref_store *maybe_debug_wrap_ref_store(const char *gitdir, s
      }
      
     -static int debug_init_db(struct ref_store *refs, int flags, struct strbuf *err)
    -+static int debug_create(struct ref_store *refs, int flags, struct strbuf *err)
    ++static int debug_create_on_disk(struct ref_store *refs, int flags, struct strbuf *err)
      {
      	struct debug_ref_store *drefs = (struct debug_ref_store *)refs;
     -	int res = drefs->refs->be->init_db(drefs->refs, flags, err);
     -	trace_printf_key(&trace_refs, "init_db: %d\n", res);
    -+	int res = drefs->refs->be->create(drefs->refs, flags, err);
    -+	trace_printf_key(&trace_refs, "create: %d\n", res);
    ++	int res = drefs->refs->be->create_on_disk(drefs->refs, flags, err);
    ++	trace_printf_key(&trace_refs, "create_on_disk: %d\n", res);
      	return res;
      }
      
    @@ refs/debug.c: static int debug_reflog_expire(struct ref_store *ref_store, const
      	.name = "debug",
      	.init = NULL,
     -	.init_db = debug_init_db,
    -+	.create = debug_create,
    ++	.create_on_disk = debug_create_on_disk,
      
      	/*
      	 * None of these should be NULL. If the "files" backend (in
    @@ refs/files-backend.c: static int files_reflog_expire(struct ref_store *ref_store
     -static int files_init_db(struct ref_store *ref_store,
     -			 int flags,
     -			 struct strbuf *err UNUSED)
    -+static int files_ref_store_create(struct ref_store *ref_store,
    -+				  int flags,
    -+				  struct strbuf *err UNUSED)
    ++static int files_ref_store_create_on_disk(struct ref_store *ref_store,
    ++					  int flags,
    ++					  struct strbuf *err UNUSED)
      {
      	struct files_ref_store *refs =
     -		files_downcast(ref_store, REF_STORE_WRITE, "init_db");
    @@ refs/files-backend.c: static int files_init_db(struct ref_store *ref_store,
      	 * a worktree ref store.
      	 */
     -	if (!(flags & REFS_INIT_DB_IS_WORKTREE)) {
    -+	if (!(flags & REF_STORE_CREATE_IS_WORKTREE)) {
    ++	if (!(flags & REF_STORE_CREATE_ON_DISK_IS_WORKTREE)) {
      		/*
      		 * Create .git/refs/{heads,tags}
      		 */
    @@ refs/files-backend.c: static int files_init_db(struct ref_store *ref_store,
      	.name = "files",
      	.init = files_ref_store_init,
     -	.init_db = files_init_db,
    -+	.create = files_ref_store_create,
    ++	.create_on_disk = files_ref_store_create_on_disk,
      	.transaction_prepare = files_transaction_prepare,
      	.transaction_finish = files_transaction_finish,
      	.transaction_abort = files_transaction_abort,
    @@ refs/packed-backend.c: int packed_refs_is_locked(struct ref_store *ref_store)
     -static int packed_ref_store_init_db(struct ref_store *ref_store UNUSED,
     -				    int flags UNUSED,
     -				    struct strbuf *err UNUSED)
    -+static int packed_ref_store_create(struct ref_store *ref_store UNUSED,
    -+				   int flags UNUSED,
    -+				   struct strbuf *err UNUSED)
    ++static int packed_ref_store_create_on_disk(struct ref_store *ref_store UNUSED,
    ++					   int flags UNUSED,
    ++					   struct strbuf *err UNUSED)
      {
      	/* Nothing to do. */
      	return 0;
    @@ refs/packed-backend.c: static struct ref_iterator *packed_reflog_iterator_begin(
      	.name = "packed",
      	.init = packed_ref_store_init,
     -	.init_db = packed_ref_store_init_db,
    -+	.create = packed_ref_store_create,
    ++	.create_on_disk = packed_ref_store_create_on_disk,
      	.transaction_prepare = packed_transaction_prepare,
      	.transaction_finish = packed_transaction_finish,
      	.transaction_abort = packed_transaction_abort,
    @@ refs/refs-internal.h: typedef struct ref_store *ref_store_init_fn(struct reposit
     -typedef int ref_init_db_fn(struct ref_store *refs,
     -			   int flags,
     -			   struct strbuf *err);
    -+typedef int ref_store_create_fn(struct ref_store *refs,
    -+				int flags,
    -+				struct strbuf *err);
    ++typedef int ref_store_create_on_disk_fn(struct ref_store *refs,
    ++					int flags,
    ++					struct strbuf *err);
      
      typedef int ref_transaction_prepare_fn(struct ref_store *refs,
      				       struct ref_transaction *transaction,
    @@ refs/refs-internal.h: typedef int read_symbolic_ref_fn(struct ref_store *ref_sto
      	const char *name;
      	ref_store_init_fn *init;
     -	ref_init_db_fn *init_db;
    -+	ref_store_create_fn *create;
    ++	ref_store_create_on_disk_fn *create_on_disk;
      
      	ref_transaction_prepare_fn *transaction_prepare;
      	ref_transaction_finish_fn *transaction_finish;
    @@ refs/reftable-backend.c: static struct ref_store *reftable_be_init(struct reposi
     -static int reftable_be_init_db(struct ref_store *ref_store,
     -			       int flags UNUSED,
     -			       struct strbuf *err UNUSED)
    -+static int reftable_be_create(struct ref_store *ref_store,
    -+			      int flags UNUSED,
    -+			      struct strbuf *err UNUSED)
    ++static int reftable_be_create_on_disk(struct ref_store *ref_store,
    ++				      int flags UNUSED,
    ++				      struct strbuf *err UNUSED)
      {
      	struct reftable_ref_store *refs =
     -		reftable_be_downcast(ref_store, REF_STORE_WRITE, "init_db");
    @@ refs/reftable-backend.c: static int reftable_be_reflog_expire(struct ref_store *
      	.name = "reftable",
      	.init = reftable_be_init,
     -	.init_db = reftable_be_init_db,
    -+	.create = reftable_be_create,
    ++	.create_on_disk = reftable_be_create_on_disk,
      	.transaction_prepare = reftable_be_transaction_prepare,
      	.transaction_finish = reftable_be_transaction_finish,
      	.transaction_abort = reftable_be_transaction_abort,
    @@ setup.c: void create_reference_database(unsigned int ref_storage_format,
      
      	repo_set_ref_storage_format(the_repository, ref_storage_format);
     -	if (refs_init_db(get_main_ref_store(the_repository), 0, &err))
    -+	if (ref_store_create(get_main_ref_store(the_repository), 0, &err))
    ++	if (ref_store_create_on_disk(get_main_ref_store(the_repository), 0, &err))
      		die("failed to set up refs db: %s", err.buf);
      
      	/*
 3:  282fbe35a7 !  3:  4beecb0944 refs: implement releasing ref storages
    @@ refs.c: static struct ref_store *ref_store_init(struct repository *repo,
      ## refs.h ##
     @@ refs.h: int is_branch(const char *refname);
      
    - int ref_store_create(struct ref_store *refs, int flags, struct strbuf *err);
    + int ref_store_create_on_disk(struct ref_store *refs, int flags, struct strbuf *err);
      
     +/*
     + * Release all memory and resources associated with the ref store.
    @@ refs/debug.c: struct ref_store *maybe_debug_wrap_ref_store(const char *gitdir, s
     +{
     +	struct debug_ref_store *drefs = (struct debug_ref_store *)refs;
     +	drefs->refs->be->release(drefs->refs);
    ++	trace_printf_key(&trace_refs, "release\n");
     +}
     +
    - static int debug_create(struct ref_store *refs, int flags, struct strbuf *err)
    + static int debug_create_on_disk(struct ref_store *refs, int flags, struct strbuf *err)
      {
      	struct debug_ref_store *drefs = (struct debug_ref_store *)refs;
     @@ refs/debug.c: static int debug_reflog_expire(struct ref_store *ref_store, const char *refname,
    @@ refs/debug.c: static int debug_reflog_expire(struct ref_store *ref_store, const
      	.name = "debug",
      	.init = NULL,
     +	.release = debug_release,
    - 	.create = debug_create,
    + 	.create_on_disk = debug_create_on_disk,
      
      	/*
     
    @@ refs/files-backend.c: static struct files_ref_store *files_downcast(struct ref_s
      static void files_reflog_path(struct files_ref_store *refs,
      			      struct strbuf *sb,
      			      const char *refname)
    -@@ refs/files-backend.c: static int files_ref_store_create(struct ref_store *ref_store,
    +@@ refs/files-backend.c: static int files_ref_store_create_on_disk(struct ref_store *ref_store,
      struct ref_storage_be refs_be_files = {
      	.name = "files",
      	.init = files_ref_store_init,
     +	.release = files_ref_store_release,
    - 	.create = files_ref_store_create,
    + 	.create_on_disk = files_ref_store_create_on_disk,
    ++
      	.transaction_prepare = files_transaction_prepare,
      	.transaction_finish = files_transaction_finish,
    + 	.transaction_abort = files_transaction_abort,
     
      ## refs/packed-backend.c ##
     @@ refs/packed-backend.c: static void clear_snapshot(struct packed_ref_store *refs)
    @@ refs/packed-backend.c: static struct ref_iterator *packed_reflog_iterator_begin(
      	.name = "packed",
      	.init = packed_ref_store_init,
     +	.release = packed_ref_store_release,
    - 	.create = packed_ref_store_create,
    + 	.create_on_disk = packed_ref_store_create_on_disk,
    ++
      	.transaction_prepare = packed_transaction_prepare,
      	.transaction_finish = packed_transaction_finish,
    + 	.transaction_abort = packed_transaction_abort,
     
      ## refs/refs-internal.h ##
    -@@ refs/refs-internal.h: typedef struct ref_store *ref_store_init_fn(struct repository *repo,
    +@@ refs/refs-internal.h: struct ref_store;
    + typedef struct ref_store *ref_store_init_fn(struct repository *repo,
      					    const char *gitdir,
      					    unsigned int flags);
    - 
     +/*
     + * Release all memory and resources associated with the ref store.
     + */
     +typedef void ref_store_release_fn(struct ref_store *refs);
    -+
    - typedef int ref_store_create_fn(struct ref_store *refs,
    - 				int flags,
    - 				struct strbuf *err);
    + 
    + typedef int ref_store_create_on_disk_fn(struct ref_store *refs,
    + 					int flags,
     @@ refs/refs-internal.h: typedef int read_symbolic_ref_fn(struct ref_store *ref_store, const char *refnam
      struct ref_storage_be {
      	const char *name;
      	ref_store_init_fn *init;
     +	ref_store_release_fn *release;
    - 	ref_store_create_fn *create;
    + 	ref_store_create_on_disk_fn *create_on_disk;
      
      	ref_transaction_prepare_fn *transaction_prepare;
     
    @@ refs/reftable-backend.c: static struct ref_store *reftable_be_init(struct reposi
     +
     +	if (refs->worktree_stack) {
     +		reftable_stack_destroy(refs->worktree_stack);
    -+		refs->main_stack = NULL;
    ++		refs->worktree_stack = NULL;
     +	}
     +
     +	strmap_for_each_entry(&refs->worktree_stacks, &iter, entry)
    @@ refs/reftable-backend.c: static struct ref_store *reftable_be_init(struct reposi
     +	strmap_clear(&refs->worktree_stacks, 0);
     +}
     +
    - static int reftable_be_create(struct ref_store *ref_store,
    - 			      int flags UNUSED,
    - 			      struct strbuf *err UNUSED)
    + static int reftable_be_create_on_disk(struct ref_store *ref_store,
    + 				      int flags UNUSED,
    + 				      struct strbuf *err UNUSED)
     @@ refs/reftable-backend.c: static int reftable_be_reflog_expire(struct ref_store *ref_store,
      struct ref_storage_be refs_be_reftable = {
      	.name = "reftable",
      	.init = reftable_be_init,
     +	.release = reftable_be_release,
    - 	.create = reftable_be_create,
    + 	.create_on_disk = reftable_be_create_on_disk,
    ++
      	.transaction_prepare = reftable_be_transaction_prepare,
      	.transaction_finish = reftable_be_transaction_finish,
    + 	.transaction_abort = reftable_be_transaction_abort,
 4:  52798936a2 =  4:  9ca54a12e8 refs: track ref stores via strmap
 5:  1d48289809 !  5:  d7f8b2f40d refs: pass repo when retrieving submodule ref store
    @@ Commit message
         move the global map into `struct repository`. Like this it becomes
         possible to look up submodule ref stores for arbitrary repositories.
     
    +    Note that this also adds a new reference to `the_repository` in
    +    `resolve_gitlink_ref()`, which is part of the refs interfaces. This will
    +    get adjusted in the next patch.
    +
         Signed-off-by: Patrick Steinhardt <[email-masked]>
     
      ## builtin/submodule--helper.c ##
 6:  7b4ea1ffd2 !  6:  a8593b16a6 refs: refactor `resolve_gitlink_ref()` to accept a repository
    @@ read-cache.c: int add_to_index(struct index_state *istate, const char *path, str
      			namelen--;
     
      ## refs.c ##
    -@@ refs.c: int ref_store_create(struct ref_store *refs, int flags, struct strbuf *err)
    - 	return refs->be->create(refs, flags, err);
    +@@ refs.c: int ref_store_create_on_disk(struct ref_store *refs, int flags, struct strbuf *e
    + 	return refs->be->create_on_disk(refs, flags, err);
      }
      
     -int resolve_gitlink_ref(const char *submodule, const char *refname,
 7:  4d55dbbceb =  7:  977f3a8510 refs: retrieve worktree ref stores via associated repository
 8:  160e64e42a =  8:  5306122d58 refs: convert iteration over replace refs to accept ref store
 9:  50c5d72c6a =  9:  423d7b3fb6 refs: pass ref store when detecting dangling symrefs
10:  f03626ac00 = 10:  3c6f814158 refs: move object peeling into "object.c"
11:  eb60ce5771 = 11:  272cd49357 refs: pass repo when peeling objects
12:  09ca848e7d = 12:  e02e76701f refs: drop `git_default_branch_name()`
13:  da10714a45 = 13:  afa9184884 refs: remove `dwim_log()`
14:  7ce6b7454d = 14:  c1a2dc4e69 refs/files: use correct repository
15:  ab0c793739 = 15:  20c2bb4cbb refs/files: remove references to `the_hash_algo`
16:  9cd554166f = 16:  5ebe81d8c3 refs/packed: remove references to `the_hash_algo`
-- 
2.45.1.190.g19fe900cfc.dirty