All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Han-Wen Nienhuys via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Han-Wen Nienhuys <hanwenn@gmail.com>
Subject: [PATCH v19 00/20] Reftable support git-core
Date: Mon, 29 Jun 2020 18:56:38 +0000	[thread overview]
Message-ID: <pull.539.v19.git.1593457018.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.539.v18.git.1592862920.gitgitgadget@gmail.com>

This adds the reftable library, and hooks it up as a ref backend. 

Includes testing support, to test: make -C t/ GIT_TEST_REFTABLE=1

Summary 21852 tests pass 556 tests fail

v22

 * worktree support

Han-Wen Nienhuys (18):
  lib-t6000.sh: write tag using git-update-ref
  t3432: use git-reflog to inspect the reflog for HEAD
  checkout: add '\n' to reflog message
  Write pseudorefs through ref backends.
  Make refs_ref_exists public
  Treat BISECT_HEAD as a pseudo ref
  Treat CHERRY_PICK_HEAD as a pseudo ref
  Treat REVERT_HEAD as a pseudo ref
  Move REF_LOG_ONLY to refs-internal.h
  Iterate over the "refs/" namespace in for_each_[raw]ref
  Add .gitattributes for the reftable/ directory
  Add reftable library
  Add standalone build infrastructure for reftable
  Reftable support for git-core
  Hookup unittests for the reftable library.
  Add GIT_DEBUG_REFS debugging mechanism
  Add reftable testing infrastructure
  Add "test-tool dump-reftable" command.

Johannes Schindelin (1):
  vcxproj: adjust for the reftable changes

SZEDER Gábor (1):
  git-prompt: prepare for reftable refs backend

 .../technical/repository-version.txt          |    7 +
 Makefile                                      |   47 +-
 builtin/bisect--helper.c                      |    3 +-
 builtin/checkout.c                            |    5 +-
 builtin/clone.c                               |    4 +-
 builtin/commit.c                              |   34 +-
 builtin/init-db.c                             |   54 +-
 builtin/merge.c                               |    2 +-
 builtin/worktree.c                            |   31 +-
 cache.h                                       |    8 +-
 config.mak.uname                              |    2 +-
 contrib/buildsystems/Generators/Vcxproj.pm    |   11 +-
 contrib/completion/git-prompt.sh              |    7 +-
 git-bisect.sh                                 |    4 +-
 path.c                                        |    2 -
 path.h                                        |    9 +-
 refs.c                                        |  157 +-
 refs.h                                        |   16 +
 refs/debug.c                                  |  416 +++++
 refs/files-backend.c                          |  121 +-
 refs/packed-backend.c                         |   21 +-
 refs/refs-internal.h                          |   32 +
 refs/reftable-backend.c                       | 1497 +++++++++++++++++
 reftable/.gitattributes                       |    1 +
 reftable/BUILD                                |  203 +++
 reftable/LICENSE                              |   31 +
 reftable/README.md                            |   33 +
 reftable/VERSION                              |    1 +
 reftable/WORKSPACE                            |   14 +
 reftable/basics.c                             |  215 +++
 reftable/basics.h                             |   53 +
 reftable/block.c                              |  432 +++++
 reftable/block.h                              |  129 ++
 reftable/block_test.c                         |  157 ++
 reftable/compat.c                             |   98 ++
 reftable/compat.h                             |   48 +
 reftable/constants.h                          |   21 +
 reftable/dump.c                               |  212 +++
 reftable/file.c                               |   95 ++
 reftable/iter.c                               |  242 +++
 reftable/iter.h                               |   72 +
 reftable/merged.c                             |  317 ++++
 reftable/merged.h                             |   43 +
 reftable/merged_test.c                        |  286 ++++
 reftable/pq.c                                 |  115 ++
 reftable/pq.h                                 |   34 +
 reftable/reader.c                             |  744 ++++++++
 reftable/reader.h                             |   65 +
 reftable/record.c                             | 1126 +++++++++++++
 reftable/record.h                             |  143 ++
 reftable/record_test.c                        |  410 +++++
 reftable/refname.c                            |  209 +++
 reftable/refname.h                            |   38 +
 reftable/refname_test.c                       |   99 ++
 reftable/reftable-tests.h                     |   22 +
 reftable/reftable.c                           |  154 ++
 reftable/reftable.h                           |  585 +++++++
 reftable/reftable_test.c                      |  632 +++++++
 reftable/stack.c                              | 1225 ++++++++++++++
 reftable/stack.h                              |   50 +
 reftable/stack_test.c                         |  787 +++++++++
 reftable/strbuf.c                             |  206 +++
 reftable/strbuf.h                             |   88 +
 reftable/strbuf_test.c                        |   39 +
 reftable/system.h                             |   53 +
 reftable/test_framework.c                     |   69 +
 reftable/test_framework.h                     |   64 +
 reftable/tree.c                               |   63 +
 reftable/tree.h                               |   34 +
 reftable/tree_test.c                          |   62 +
 reftable/update.sh                            |   19 +
 reftable/writer.c                             |  663 ++++++++
 reftable/writer.h                             |   60 +
 reftable/zlib-compat.c                        |   92 +
 reftable/zlib.BUILD                           |   36 +
 repository.c                                  |    2 +
 repository.h                                  |    3 +
 sequencer.c                                   |   56 +-
 setup.c                                       |   12 +-
 t/helper/test-reftable.c                      |   20 +
 t/helper/test-tool.c                          |    2 +
 t/helper/test-tool.h                          |    2 +
 t/lib-t6000.sh                                |    5 +-
 t/t0031-reftable.sh                           |  178 ++
 t/t0033-debug-refs.sh                         |   18 +
 t/t1409-avoid-packing-refs.sh                 |    6 +
 t/t1450-fsck.sh                               |    6 +
 t/t3210-pack-refs.sh                          |    6 +
 t/t3432-rebase-fast-forward.sh                |    7 +-
 t/test-lib.sh                                 |    5 +
 wt-status.c                                   |    6 +-
 91 files changed, 13304 insertions(+), 209 deletions(-)
 create mode 100644 refs/debug.c
 create mode 100644 refs/reftable-backend.c
 create mode 100644 reftable/.gitattributes
 create mode 100644 reftable/BUILD
 create mode 100644 reftable/LICENSE
 create mode 100644 reftable/README.md
 create mode 100644 reftable/VERSION
 create mode 100644 reftable/WORKSPACE
 create mode 100644 reftable/basics.c
 create mode 100644 reftable/basics.h
 create mode 100644 reftable/block.c
 create mode 100644 reftable/block.h
 create mode 100644 reftable/block_test.c
 create mode 100644 reftable/compat.c
 create mode 100644 reftable/compat.h
 create mode 100644 reftable/constants.h
 create mode 100644 reftable/dump.c
 create mode 100644 reftable/file.c
 create mode 100644 reftable/iter.c
 create mode 100644 reftable/iter.h
 create mode 100644 reftable/merged.c
 create mode 100644 reftable/merged.h
 create mode 100644 reftable/merged_test.c
 create mode 100644 reftable/pq.c
 create mode 100644 reftable/pq.h
 create mode 100644 reftable/reader.c
 create mode 100644 reftable/reader.h
 create mode 100644 reftable/record.c
 create mode 100644 reftable/record.h
 create mode 100644 reftable/record_test.c
 create mode 100644 reftable/refname.c
 create mode 100644 reftable/refname.h
 create mode 100644 reftable/refname_test.c
 create mode 100644 reftable/reftable-tests.h
 create mode 100644 reftable/reftable.c
 create mode 100644 reftable/reftable.h
 create mode 100644 reftable/reftable_test.c
 create mode 100644 reftable/stack.c
 create mode 100644 reftable/stack.h
 create mode 100644 reftable/stack_test.c
 create mode 100644 reftable/strbuf.c
 create mode 100644 reftable/strbuf.h
 create mode 100644 reftable/strbuf_test.c
 create mode 100644 reftable/system.h
 create mode 100644 reftable/test_framework.c
 create mode 100644 reftable/test_framework.h
 create mode 100644 reftable/tree.c
 create mode 100644 reftable/tree.h
 create mode 100644 reftable/tree_test.c
 create mode 100755 reftable/update.sh
 create mode 100644 reftable/writer.c
 create mode 100644 reftable/writer.h
 create mode 100644 reftable/zlib-compat.c
 create mode 100644 reftable/zlib.BUILD
 create mode 100644 t/helper/test-reftable.c
 create mode 100755 t/t0031-reftable.sh
 create mode 100755 t/t0033-debug-refs.sh


base-commit: b9a2d1a0207fb9ded3fa524f54db3bc322a12cc4
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-539%2Fhanwen%2Freftable-v19
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-539/hanwen/reftable-v19
Pull-Request: https://github.com/gitgitgadget/git/pull/539

Range-diff vs v18:

  1:  b968b795af =  1:  596c316da4 lib-t6000.sh: write tag using git-update-ref
  -:  ---------- >  2:  277da0cf7e t3432: use git-reflog to inspect the reflog for HEAD
  2:  5210225977 =  3:  125695ce92 checkout: add '\n' to reflog message
  3:  15c9dd66e1 =  4:  5715681b3f Write pseudorefs through ref backends.
  4:  a5bce2e3fe =  5:  c8cf2d2ce1 Make refs_ref_exists public
  5:  a29d898907 =  6:  e36b29de79 Treat BISECT_HEAD as a pseudo ref
  6:  11a690d2b8 =  7:  1676df9851 Treat CHERRY_PICK_HEAD as a pseudo ref
  7:  4e52ec0dbc =  8:  0a5f97ea34 Treat REVERT_HEAD as a pseudo ref
  8:  37e350af15 =  9:  9463ed9093 Move REF_LOG_ONLY to refs-internal.h
  9:  468f00eaf6 = 10:  a116aebe11 Iterate over the "refs/" namespace in for_each_[raw]ref
 10:  21febeaa81 = 11:  e4545658ed Add .gitattributes for the reftable/ directory
 11:  3c84f43cfa ! 12:  169f6c7f54 Add reftable library
     @@ reftable/LICENSE (new)
      
       ## reftable/VERSION (new) ##
      @@
     -+d7472cbd1afe6bf3da53e94971b1cc79ce183fa8 Remove outdated bits of the README file
     ++994cc2f626ff626ff04be5240413775f832110fb C: formatting tweaks
      
       ## reftable/basics.c (new) ##
      @@
     @@ reftable/basics.c (new)
      +void parse_names(char *buf, int size, char ***namesp)
      +{
      +	char **names = NULL;
     -+	int names_cap = 0;
     -+	int names_len = 0;
     ++	size_t names_cap = 0;
     ++	size_t names_len = 0;
      +
      +	char *p = buf;
      +	char *end = buf + size;
     @@ reftable/block_test.c (new)
      +		snprintf(name, sizeof(name), "branch%02d", i);
      +		memset(hash, i, sizeof(hash));
      +
     -+		ref.ref_name = name;
     ++		ref.refname = name;
      +		ref.value = hash;
      +		names[i] = xstrdup(name);
      +		n = block_writer_add(&bw, &rec);
     -+		ref.ref_name = NULL;
     ++		ref.refname = NULL;
      +		ref.value = NULL;
      +		assert(n == 0);
      +	}
     @@ reftable/block_test.c (new)
      +		if (r > 0) {
      +			break;
      +		}
     -+		assert_streq(names[j], ref.ref_name);
     ++		assert_streq(names[j], ref.refname);
      +		j++;
      +	}
      +
     @@ reftable/block_test.c (new)
      +		n = block_iter_next(&it, &rec);
      +		assert(n == 0);
      +
     -+		assert_streq(names[i], ref.ref_name);
     ++		assert_streq(names[i], ref.refname);
      +
      +		want.len--;
      +		n = block_reader_seek(&br, &it, &want);
     @@ reftable/block_test.c (new)
      +
      +		n = block_iter_next(&it, &rec);
      +		assert(n == 0);
     -+		assert_streq(names[10 * (i / 10)], ref.ref_name);
     ++		assert_streq(names[10 * (i / 10)], ref.refname);
      +
      +		block_iter_close(&it);
      +	}
     @@ reftable/iter.c (new)
      +			struct reftable_iterator it = { 0 };
      +
      +			err = reftable_table_seek_ref(&fri->tab, &it,
     -+						      ref->ref_name);
     ++						      ref->refname);
      +			if (err == 0) {
      +				err = reftable_iterator_next_ref(&it, ref);
      +			}
     @@ reftable/merged.c (new)
      +}
      +
      +int reftable_new_merged_table(struct reftable_merged_table **dest,
     -+			      struct reftable_reader **stack, int n,
     ++			      struct reftable_table *stack, int n,
      +			      uint32_t hash_id)
      +{
      +	struct reftable_merged_table *m = NULL;
     @@ reftable/merged.c (new)
      +	uint64_t first_min = 0;
      +	int i = 0;
      +	for (i = 0; i < n; i++) {
     -+		struct reftable_reader *r = stack[i];
     -+		if (r->hash_id != hash_id) {
     ++		uint64_t min = reftable_table_min_update_index(&stack[i]);
     ++		uint64_t max = reftable_table_max_update_index(&stack[i]);
     ++
     ++		if (reftable_table_hash_id(&stack[i]) != hash_id) {
      +			return REFTABLE_FORMAT_ERROR;
      +		}
     -+		if (i > 0 && last_max >= reftable_reader_min_update_index(r)) {
     -+			return REFTABLE_FORMAT_ERROR;
     ++		if (i == 0 || min < first_min) {
     ++			first_min = min;
      +		}
     -+		if (i == 0) {
     -+			first_min = reftable_reader_min_update_index(r);
     ++		if (i == 0 || max > last_max) {
     ++			last_max = max;
      +		}
     -+
     -+		last_max = reftable_reader_max_update_index(r);
      +	}
      +
      +	m = (struct reftable_merged_table *)reftable_calloc(
     @@ reftable/merged.c (new)
      +	return 0;
      +}
      +
     -+void reftable_merged_table_close(struct reftable_merged_table *mt)
     -+{
     -+	int i = 0;
     -+	for (i = 0; i < mt->stack_len; i++) {
     -+		reftable_reader_free(mt->stack[i]);
     -+	}
     -+	FREE_AND_NULL(mt->stack);
     -+	mt->stack_len = 0;
     -+}
     -+
      +/* clears the list of subtable, without affecting the readers themselves. */
      +void merged_table_clear(struct reftable_merged_table *mt)
      +{
     @@ reftable/merged.c (new)
      +	int err = 0;
      +	int i = 0;
      +	for (i = 0; i < mt->stack_len && err == 0; i++) {
     -+		int e = reader_seek(mt->stack[i], &iters[n], rec);
     ++		int e = reftable_table_seek_record(&mt->stack[i], &iters[n],
     ++						   rec);
      +		if (e < 0) {
      +			err = e;
      +		}
     @@ reftable/merged.c (new)
      +				   const char *name)
      +{
      +	struct reftable_ref_record ref = {
     -+		.ref_name = (char *)name,
     ++		.refname = (char *)name,
      +	};
      +	struct reftable_record rec = { 0 };
      +	reftable_record_from_ref(&rec, &ref);
     @@ reftable/merged.c (new)
      +				      const char *name, uint64_t update_index)
      +{
      +	struct reftable_log_record log = {
     -+		.ref_name = (char *)name,
     ++		.refname = (char *)name,
      +		.update_index = update_index,
      +	};
      +	struct reftable_record rec = { 0 };
     @@ reftable/merged.c (new)
      +{
      +	uint64_t max = ~((uint64_t)0);
      +	return reftable_merged_table_seek_log_at(mt, it, name, max);
     ++}
     ++
     ++uint32_t reftable_merged_table_hash_id(struct reftable_merged_table *mt)
     ++{
     ++	return mt->hash_id;
      +}
      
       ## reftable/merged.h (new) ##
     @@ reftable/merged.h (new)
      +#include "reftable.h"
      +
      +struct reftable_merged_table {
     -+	struct reftable_reader **stack;
     -+	int stack_len;
     ++	struct reftable_table *stack;
     ++	size_t stack_len;
      +	uint32_t hash_id;
      +	bool suppress_deletions;
      +
     @@ reftable/merged.h (new)
      +struct merged_iter {
      +	struct reftable_iterator *stack;
      +	uint32_t hash_id;
     -+	int stack_len;
     ++	size_t stack_len;
      +	uint8_t typ;
      +	bool suppress_deletions;
      +	struct merged_iter_pqueue pq;
     @@ reftable/merged.h (new)
      +			     struct reftable_iterator *it,
      +			     struct reftable_record *rec);
      +
     ++int reftable_table_seek_record(struct reftable_table *tab,
     ++			       struct reftable_iterator *it,
     ++			       struct reftable_record *rec);
     ++
      +#endif
      
       ## reftable/merged_test.c (new) ##
     @@ reftable/merged_test.c (new)
      +			reftable_new_record(BLOCK_TYPE_REF);
      +		struct pq_entry e = { 0 };
      +
     -+		reftable_record_as_ref(&rec)->ref_name = names[i];
     ++		reftable_record_as_ref(&rec)->refname = names[i];
      +		e.rec = rec;
      +		merged_iter_pqueue_add(&pq, e);
      +		merged_iter_pqueue_check(pq);
     @@ reftable/merged_test.c (new)
      +		merged_iter_pqueue_check(pq);
      +
      +		if (last != NULL) {
     -+			assert(strcmp(last, ref->ref_name) < 0);
     ++			assert(strcmp(last, ref->refname) < 0);
      +		}
     -+		last = ref->ref_name;
     -+		ref->ref_name = NULL;
     ++		last = ref->refname;
     ++		ref->refname = NULL;
      +		reftable_free(ref);
      +	}
      +
     @@ reftable/merged_test.c (new)
      +
      +static struct reftable_merged_table *
      +merged_table_from_records(struct reftable_ref_record **refs,
     -+			  struct reftable_block_source **source, int *sizes,
     ++			  struct reftable_block_source **source,
     ++			  struct reftable_reader ***readers, int *sizes,
      +			  struct strbuf *buf, int n)
      +{
     -+	struct reftable_reader **rd = reftable_calloc(n * sizeof(*rd));
      +	int i = 0;
      +	struct reftable_merged_table *mt = NULL;
      +	int err;
     ++	struct reftable_table *tabs =
     ++		reftable_calloc(n * sizeof(struct reftable_table));
     ++	*readers = reftable_calloc(n * sizeof(struct reftable_reader *));
      +	*source = reftable_calloc(n * sizeof(**source));
      +	for (i = 0; i < n; i++) {
      +		write_test_table(&buf[i], refs[i], sizes[i]);
      +		block_source_from_strbuf(&(*source)[i], &buf[i]);
      +
     -+		err = reftable_new_reader(&rd[i], &(*source)[i], "name");
     ++		err = reftable_new_reader(&(*readers)[i], &(*source)[i],
     ++					  "name");
      +		assert_err(err);
     ++		reftable_table_from_reader(&tabs[i], (*readers)[i]);
      +	}
      +
     -+	err = reftable_new_merged_table(&mt, rd, n, SHA1_ID);
     ++	err = reftable_new_merged_table(&mt, tabs, n, SHA1_ID);
      +	assert_err(err);
      +	return mt;
      +}
      +
     ++static void readers_destroy(struct reftable_reader **readers, size_t n)
     ++{
     ++	int i = 0;
     ++	for (; i < n; i++)
     ++		reftable_reader_free(readers[i]);
     ++	reftable_free(readers);
     ++}
     ++
      +static void test_merged_between(void)
      +{
      +	uint8_t hash1[SHA1_SIZE] = { 1, 2, 3, 0 };
      +
      +	struct reftable_ref_record r1[] = { {
     -+		.ref_name = "b",
     ++		.refname = "b",
      +		.update_index = 1,
      +		.value = hash1,
      +	} };
      +	struct reftable_ref_record r2[] = { {
     -+		.ref_name = "a",
     ++		.refname = "a",
      +		.update_index = 2,
      +	} };
      +
     @@ reftable/merged_test.c (new)
      +	int sizes[] = { 1, 1 };
      +	struct strbuf bufs[2] = { STRBUF_INIT, STRBUF_INIT };
      +	struct reftable_block_source *bs = NULL;
     ++	struct reftable_reader **readers = NULL;
      +	struct reftable_merged_table *mt =
     -+		merged_table_from_records(refs, &bs, sizes, bufs, 2);
     ++		merged_table_from_records(refs, &bs, &readers, sizes, bufs, 2);
      +	int i;
      +	struct reftable_ref_record ref = { 0 };
      +	struct reftable_iterator it = { 0 };
     @@ reftable/merged_test.c (new)
      +	assert_err(err);
      +	assert(ref.update_index == 2);
      +	reftable_ref_record_clear(&ref);
     -+
      +	reftable_iterator_destroy(&it);
     -+	reftable_merged_table_close(mt);
     ++	readers_destroy(readers, 2);
      +	reftable_merged_table_free(mt);
      +	for (i = 0; i < ARRAY_SIZE(bufs); i++) {
      +		strbuf_release(&bufs[i]);
     @@ reftable/merged_test.c (new)
      +	uint8_t hash1[SHA1_SIZE] = { 1 };
      +	uint8_t hash2[SHA1_SIZE] = { 2 };
      +	struct reftable_ref_record r1[] = { {
     -+						    .ref_name = "a",
     ++						    .refname = "a",
      +						    .update_index = 1,
      +						    .value = hash1,
      +					    },
      +					    {
     -+						    .ref_name = "b",
     ++						    .refname = "b",
      +						    .update_index = 1,
      +						    .value = hash1,
      +					    },
      +					    {
     -+						    .ref_name = "c",
     ++						    .refname = "c",
      +						    .update_index = 1,
      +						    .value = hash1,
      +					    } };
      +	struct reftable_ref_record r2[] = { {
     -+		.ref_name = "a",
     ++		.refname = "a",
      +		.update_index = 2,
      +	} };
      +	struct reftable_ref_record r3[] = {
      +		{
     -+			.ref_name = "c",
     ++			.refname = "c",
      +			.update_index = 3,
      +			.value = hash2,
      +		},
      +		{
     -+			.ref_name = "d",
     ++			.refname = "d",
      +			.update_index = 3,
      +			.value = hash1,
      +		},
     @@ reftable/merged_test.c (new)
      +	int sizes[3] = { 3, 1, 2 };
      +	struct strbuf bufs[3] = { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT };
      +	struct reftable_block_source *bs = NULL;
     -+
     ++	struct reftable_reader **readers = NULL;
      +	struct reftable_merged_table *mt =
     -+		merged_table_from_records(refs, &bs, sizes, bufs, 3);
     ++		merged_table_from_records(refs, &bs, &readers, sizes, bufs, 3);
      +
      +	struct reftable_iterator it = { 0 };
      +	int err = reftable_merged_table_seek_ref(mt, &it, "a");
      +	struct reftable_ref_record *out = NULL;
     -+	int len = 0;
     -+	int cap = 0;
     ++	size_t len = 0;
     ++	size_t cap = 0;
      +	int i = 0;
      +
      +	assert_err(err);
     @@ reftable/merged_test.c (new)
      +	for (i = 0; i < 3; i++) {
      +		strbuf_release(&bufs[i]);
      +	}
     -+	reftable_merged_table_close(mt);
     ++	readers_destroy(readers, 3);
      +	reftable_merged_table_free(mt);
      +	reftable_free(bs);
      +}
     @@ reftable/pq.h (new)
      +
      +struct merged_iter_pqueue {
      +	struct pq_entry *heap;
     -+	int len;
     -+	int cap;
     ++	size_t len;
     ++	size_t cap;
      +};
      +
      +struct pq_entry merged_iter_pqueue_top(struct merged_iter_pqueue pq);
     @@ reftable/reader.c (new)
      +			     uint64_t next_off, uint8_t want_typ)
      +{
      +	int32_t guess_block_size = r->block_size ? r->block_size :
     -+						   DEFAULT_BLOCK_SIZE;
     ++							 DEFAULT_BLOCK_SIZE;
      +	struct reftable_block block = { 0 };
      +	uint8_t block_typ = 0;
      +	int err = 0;
     @@ reftable/reader.c (new)
      +			     struct reftable_iterator *it, const char *name)
      +{
      +	struct reftable_ref_record ref = {
     -+		.ref_name = (char *)name,
     ++		.refname = (char *)name,
      +	};
      +	struct reftable_record rec = { 0 };
      +	reftable_record_from_ref(&rec, &ref);
     @@ reftable/reader.c (new)
      +				uint64_t update_index)
      +{
      +	struct reftable_log_record log = {
     -+		.ref_name = (char *)name,
     ++		.refname = (char *)name,
      +		.update_index = update_index,
      +	};
      +	struct reftable_record rec = { 0 };
     @@ reftable/record.c (new)
      +	const struct reftable_ref_record *rec =
      +		(const struct reftable_ref_record *)r;
      +	strbuf_reset(dest);
     -+	strbuf_addstr(dest, rec->ref_name);
     ++	strbuf_addstr(dest, rec->refname);
      +}
      +
      +static void reftable_ref_record_copy_from(void *rec, const void *src_rec,
     @@ reftable/record.c (new)
      +	/* This is simple and correct, but we could probably reuse the hash
      +	   fields. */
      +	reftable_ref_record_clear(ref);
     -+	if (src->ref_name != NULL) {
     -+		ref->ref_name = xstrdup(src->ref_name);
     ++	if (src->refname != NULL) {
     ++		ref->refname = xstrdup(src->refname);
      +	}
      +
      +	if (src->target != NULL) {
     @@ reftable/record.c (new)
      +			       uint32_t hash_id)
      +{
      +	char hex[SHA256_SIZE + 1] = { 0 };
     -+	printf("ref{%s(%" PRIu64 ") ", ref->ref_name, ref->update_index);
     ++	printf("ref{%s(%" PRIu64 ") ", ref->refname, ref->update_index);
      +	if (ref->value != NULL) {
      +		hex_format(hex, ref->value, hash_size(hash_id));
      +		printf("%s", hex);
     @@ reftable/record.c (new)
      +
      +void reftable_ref_record_clear(struct reftable_ref_record *ref)
      +{
     -+	reftable_free(ref->ref_name);
     ++	reftable_free(ref->refname);
      +	reftable_free(ref->target);
      +	reftable_free(ref->target_value);
      +	reftable_free(ref->value);
     @@ reftable/record.c (new)
      +
      +	string_view_consume(&in, n);
      +
     -+	r->ref_name = reftable_realloc(r->ref_name, key.len + 1);
     -+	memcpy(r->ref_name, key.buf, key.len);
     -+	r->ref_name[key.len] = 0;
     ++	r->refname = reftable_realloc(r->refname, key.len + 1);
     ++	memcpy(r->refname, key.buf, key.len);
     ++	r->refname[key.len] = 0;
      +
      +	switch (val_type) {
      +	case 1:
     @@ reftable/record.c (new)
      +{
      +	char hex[SHA256_SIZE + 1] = { 0 };
      +
     -+	printf("log{%s(%" PRIu64 ") %s <%s> %" PRIu64 " %04d\n", log->ref_name,
     ++	printf("log{%s(%" PRIu64 ") %s <%s> %" PRIu64 " %04d\n", log->refname,
      +	       log->update_index, log->name, log->email, log->time,
      +	       log->tz_offset);
      +	hex_format(hex, log->old_hash, hash_size(hash_id));
     @@ reftable/record.c (new)
      +{
      +	const struct reftable_log_record *rec =
      +		(const struct reftable_log_record *)r;
     -+	int len = strlen(rec->ref_name);
     ++	int len = strlen(rec->refname);
      +	uint8_t i64[8];
      +	uint64_t ts = 0;
      +	strbuf_reset(dest);
     -+	strbuf_add(dest, (uint8_t *)rec->ref_name, len + 1);
     ++	strbuf_add(dest, (uint8_t *)rec->refname, len + 1);
      +
      +	ts = (~ts) - rec->update_index;
      +	put_be64(&i64[0], ts);
     @@ reftable/record.c (new)
      +
      +	reftable_log_record_clear(dst);
      +	*dst = *src;
     -+	if (dst->ref_name != NULL) {
     -+		dst->ref_name = xstrdup(dst->ref_name);
     ++	if (dst->refname != NULL) {
     ++		dst->refname = xstrdup(dst->refname);
      +	}
      +	if (dst->email != NULL) {
      +		dst->email = xstrdup(dst->email);
     @@ reftable/record.c (new)
      +
      +void reftable_log_record_clear(struct reftable_log_record *r)
      +{
     -+	reftable_free(r->ref_name);
     ++	reftable_free(r->refname);
      +	reftable_free(r->new_hash);
      +	reftable_free(r->old_hash);
      +	reftable_free(r->name);
     @@ reftable/record.c (new)
      +	if (key.len <= 9 || key.buf[key.len - 9] != 0)
      +		return REFTABLE_FORMAT_ERROR;
      +
     -+	r->ref_name = reftable_realloc(r->ref_name, key.len - 8);
     -+	memcpy(r->ref_name, key.buf, key.len - 8);
     ++	r->refname = reftable_realloc(r->refname, key.len - 8);
     ++	memcpy(r->refname, key.buf, key.len - 8);
      +	ts = get_be64(key.buf + key.len - 8);
      +
      +	r->update_index = (~max) - ts;
     @@ reftable/record.c (new)
      +			       struct reftable_ref_record *b, int hash_size)
      +{
      +	assert(hash_size > 0);
     -+	return 0 == strcmp(a->ref_name, b->ref_name) &&
     ++	return 0 == strcmp(a->refname, b->refname) &&
      +	       a->update_index == b->update_index &&
      +	       hash_equal(a->value, b->value, hash_size) &&
      +	       hash_equal(a->target_value, b->target_value, hash_size) &&
     @@ reftable/record.c (new)
      +
      +int reftable_ref_record_compare_name(const void *a, const void *b)
      +{
     -+	return strcmp(((struct reftable_ref_record *)a)->ref_name,
     -+		      ((struct reftable_ref_record *)b)->ref_name);
     ++	return strcmp(((struct reftable_ref_record *)a)->refname,
     ++		      ((struct reftable_ref_record *)b)->refname);
      +}
      +
      +bool reftable_ref_record_is_deletion(const struct reftable_ref_record *ref)
     @@ reftable/record.c (new)
      +	struct reftable_log_record *la = (struct reftable_log_record *)a;
      +	struct reftable_log_record *lb = (struct reftable_log_record *)b;
      +
     -+	int cmp = strcmp(la->ref_name, lb->ref_name);
     ++	int cmp = strcmp(la->refname, lb->refname);
      +	if (cmp)
      +		return cmp;
      +	if (la->update_index > lb->update_index)
     @@ reftable/record.h (new)
      +*/
      +struct string_view {
      +	uint8_t *buf;
     -+	int len;
     ++	size_t len;
      +};
      +
      +/* Advance `s.buf` by `n`, and decrease length. */
     @@ reftable/record_test.c (new)
      +	for (i = 0; i <= 3; i++) {
      +		struct reftable_ref_record in = { 0 };
      +		struct reftable_ref_record out = {
     -+			.ref_name = xstrdup("old name"),
     ++			.refname = xstrdup("old name"),
      +			.value = reftable_calloc(SHA1_SIZE),
      +			.target_value = reftable_calloc(SHA1_SIZE),
      +			.target = xstrdup("old value"),
     @@ reftable/record_test.c (new)
      +			in.target = xstrdup("target");
      +			break;
      +		}
     -+		in.ref_name = xstrdup("refs/heads/master");
     ++		in.refname = xstrdup("refs/heads/master");
      +
      +		reftable_record_from_ref(&rec, &in);
      +		test_copy(&rec);
     @@ reftable/record_test.c (new)
      +{
      +	struct reftable_log_record in[2] = {
      +		{
     -+			.ref_name = xstrdup("refs/heads/master"),
     ++			.refname = xstrdup("refs/heads/master"),
      +			.update_index = 42,
      +		},
      +		{
     -+			.ref_name = xstrdup("refs/heads/master"),
     ++			.refname = xstrdup("refs/heads/master"),
      +			.update_index = 22,
      +		}
      +	};
     @@ reftable/record_test.c (new)
      +{
      +	struct reftable_log_record in[2] = {
      +		{
     -+			.ref_name = xstrdup("refs/heads/master"),
     ++			.refname = xstrdup("refs/heads/master"),
      +			.old_hash = reftable_malloc(SHA1_SIZE),
      +			.new_hash = reftable_malloc(SHA1_SIZE),
      +			.name = xstrdup("han-wen"),
     @@ reftable/record_test.c (new)
      +			.tz_offset = 100,
      +		},
      +		{
     -+			.ref_name = xstrdup("refs/heads/master"),
     ++			.refname = xstrdup("refs/heads/master"),
      +			.update_index = 22,
      +		}
      +	};
     @@ reftable/record_test.c (new)
      +		};
      +		/* populate out, to check for leaks. */
      +		struct reftable_log_record out = {
     -+			.ref_name = xstrdup("old name"),
     ++			.refname = xstrdup("old name"),
      +			.new_hash = reftable_calloc(SHA1_SIZE),
      +			.old_hash = reftable_calloc(SHA1_SIZE),
      +			.name = xstrdup("old name"),
     @@ reftable/refname.c (new)
      +		if (mod->del_len > 0) {
      +			struct find_arg arg = {
      +				.names = mod->del,
     -+				.want = ref.ref_name,
     ++				.want = ref.refname,
      +			};
      +			int idx = binsearch(mod->del_len, find_name, &arg);
      +			if (idx < mod->del_len &&
     -+			    !strcmp(ref.ref_name, mod->del[idx])) {
     ++			    !strcmp(ref.refname, mod->del[idx])) {
      +				continue;
      +			}
      +		}
      +
     -+		if (strncmp(ref.ref_name, prefix, strlen(prefix))) {
     ++		if (strncmp(ref.refname, prefix, strlen(prefix))) {
      +			err = 1;
      +			goto done;
      +		}
     @@ reftable/refname.c (new)
      +	return err;
      +}
      +
     -+int validate_ref_name(const char *name)
     ++int validate_refname(const char *name)
      +{
      +	while (true) {
      +		char *next = strchr(name, '/');
     @@ reftable/refname.c (new)
      +	int err = 0;
      +	for (; i < sz; i++) {
      +		if (reftable_ref_record_is_deletion(&recs[i])) {
     -+			mod.del[mod.del_len++] = recs[i].ref_name;
     ++			mod.del[mod.del_len++] = recs[i].refname;
      +		} else {
     -+			mod.add[mod.add_len++] = recs[i].ref_name;
     ++			mod.add[mod.add_len++] = recs[i].refname;
      +		}
      +	}
      +
     @@ reftable/refname.c (new)
      +	int err = 0;
      +	int i = 0;
      +	for (; i < mod->add_len; i++) {
     -+		err = validate_ref_name(mod->add[i]);
     ++		err = validate_refname(mod->add[i]);
      +		if (err)
      +			goto done;
      +		strbuf_reset(&slashed);
     @@ reftable/refname.h (new)
      +				     const char *prefix);
      +
      +// 0 = OK.
     -+int validate_ref_name(const char *name);
     ++int validate_refname(const char *name);
      +
      +int validate_ref_record_addition(struct reftable_table tab,
      +				 struct reftable_ref_record *recs, size_t sz);
     @@ reftable/refname_test.c (new)
      +	struct reftable_writer *w =
      +		reftable_new_writer(&strbuf_add_void, &buf, &opts);
      +	struct reftable_ref_record rec = {
     -+		.ref_name = "a/b",
     ++		.refname = "a/b",
      +		.target = "destination", /* make sure it's not a symref. */
      +		.update_index = 1,
      +	};
     @@ reftable/reftable.c (new)
      +#include "merged.h"
      +
      +struct reftable_table_vtable {
     -+	int (*seek)(void *tab, struct reftable_iterator *it,
     -+		    struct reftable_record *);
     ++	int (*seek_record)(void *tab, struct reftable_iterator *it,
     ++			   struct reftable_record *);
     ++	uint32_t (*hash_id)(void *tab);
     ++	uint64_t (*min_update_index)(void *tab);
     ++	uint64_t (*max_update_index)(void *tab);
      +};
      +
      +static int reftable_reader_seek_void(void *tab, struct reftable_iterator *it,
     @@ reftable/reftable.c (new)
      +	return reader_seek((struct reftable_reader *)tab, it, rec);
      +}
      +
     ++static uint32_t reftable_reader_hash_id_void(void *tab)
     ++{
     ++	return reftable_reader_hash_id((struct reftable_reader *)tab);
     ++}
     ++
     ++static uint64_t reftable_reader_min_update_index_void(void *tab)
     ++{
     ++	return reftable_reader_min_update_index((struct reftable_reader *)tab);
     ++}
     ++
     ++static uint64_t reftable_reader_max_update_index_void(void *tab)
     ++{
     ++	return reftable_reader_max_update_index((struct reftable_reader *)tab);
     ++}
     ++
      +static struct reftable_table_vtable reader_vtable = {
     -+	.seek = reftable_reader_seek_void,
     ++	.seek_record = reftable_reader_seek_void,
     ++	.hash_id = reftable_reader_hash_id_void,
     ++	.min_update_index = reftable_reader_min_update_index_void,
     ++	.max_update_index = reftable_reader_max_update_index_void,
      +};
      +
      +static int reftable_merged_table_seek_void(void *tab,
     @@ reftable/reftable.c (new)
      +					rec);
      +}
      +
     ++static uint32_t reftable_merged_table_hash_id_void(void *tab)
     ++{
     ++	return reftable_merged_table_hash_id(
     ++		(struct reftable_merged_table *)tab);
     ++}
     ++
     ++static uint64_t reftable_merged_table_min_update_index_void(void *tab)
     ++{
     ++	return reftable_merged_table_min_update_index(
     ++		(struct reftable_merged_table *)tab);
     ++}
     ++
     ++static uint64_t reftable_merged_table_max_update_index_void(void *tab)
     ++{
     ++	return reftable_merged_table_max_update_index(
     ++		(struct reftable_merged_table *)tab);
     ++}
     ++
      +static struct reftable_table_vtable merged_table_vtable = {
     -+	.seek = reftable_merged_table_seek_void,
     ++	.seek_record = reftable_merged_table_seek_void,
     ++	.hash_id = reftable_merged_table_hash_id_void,
     ++	.min_update_index = reftable_merged_table_min_update_index_void,
     ++	.max_update_index = reftable_merged_table_max_update_index_void,
      +};
      +
      +int reftable_table_seek_ref(struct reftable_table *tab,
      +			    struct reftable_iterator *it, const char *name)
      +{
      +	struct reftable_ref_record ref = {
     -+		.ref_name = (char *)name,
     ++		.refname = (char *)name,
      +	};
      +	struct reftable_record rec = { 0 };
      +	reftable_record_from_ref(&rec, &ref);
     -+	return tab->ops->seek(tab->table_arg, it, &rec);
     ++	return tab->ops->seek_record(tab->table_arg, it, &rec);
      +}
      +
      +void reftable_table_from_reader(struct reftable_table *tab,
     @@ reftable/reftable.c (new)
      +	if (err)
      +		goto done;
      +
     -+	if (strcmp(ref->ref_name, name) ||
     ++	if (strcmp(ref->refname, name) ||
      +	    reftable_ref_record_is_deletion(ref)) {
      +		reftable_ref_record_clear(ref);
      +		err = 1;
     @@ reftable/reftable.c (new)
      +done:
      +	reftable_iterator_destroy(&it);
      +	return err;
     ++}
     ++
     ++int reftable_table_seek_record(struct reftable_table *tab,
     ++			       struct reftable_iterator *it,
     ++			       struct reftable_record *rec)
     ++{
     ++	return tab->ops->seek_record(tab->table_arg, it, rec);
     ++}
     ++
     ++uint64_t reftable_table_max_update_index(struct reftable_table *tab)
     ++{
     ++	return tab->ops->max_update_index(tab->table_arg);
     ++}
     ++
     ++uint64_t reftable_table_min_update_index(struct reftable_table *tab)
     ++{
     ++	return tab->ops->min_update_index(tab->table_arg);
     ++}
     ++
     ++uint32_t reftable_table_hash_id(struct reftable_table *tab)
     ++{
     ++	return tab->ops->hash_id(tab->table_arg);
      +}
      
       ## reftable/reftable.h (new) ##
     @@ reftable/reftable.h (new)
      +
      +/* reftable_ref_record holds a ref database entry target_value */
      +struct reftable_ref_record {
     -+	char *ref_name; /* Name of the ref, malloced. */
     ++	char *refname; /* Name of the ref, malloced. */
      +	uint64_t update_index; /* Logical timestamp at which this value is
      +				  written */
      +	uint8_t *value; /* SHA1, or NULL. malloced. */
     @@ reftable/reftable.h (new)
      +
      +/* reftable_log_record holds a reflog entry */
      +struct reftable_log_record {
     -+	char *ref_name;
     ++	char *refname;
      +	uint64_t update_index; /* logical timestamp of a transactional update.
      +				*/
      +	uint8_t *new_hash;
     @@ reftable/reftable.h (new)
      +	REFTABLE_LOCK_ERROR = -5,
      +
      +	/* Misuse of the API:
     -+	   - on writing a record with NULL ref_name.
     ++	   - on writing a record with NULL refname.
      +	   - on writing a reftable_ref_record outside the table limits
      +	   - on writing a ref or log record before the stack's next_update_index
      +	   - on writing a log record with multiline message with
     @@ reftable/reftable.h (new)
      +/* A merged table is implements seeking/iterating over a stack of tables. */
      +struct reftable_merged_table;
      +
     ++/* A generic reftable; see below. */
     ++struct reftable_table;
     ++
      +/* reftable_new_merged_table creates a new merged table. It takes ownership of
      +   the stack array.
      +*/
      +int reftable_new_merged_table(struct reftable_merged_table **dest,
     -+			      struct reftable_reader **stack, int n,
     ++			      struct reftable_table *stack, int n,
      +			      uint32_t hash_id);
      +
      +/* returns an iterator positioned just before 'name' */
     @@ reftable/reftable.h (new)
      +uint64_t
      +reftable_merged_table_min_update_index(struct reftable_merged_table *mt);
      +
     -+/* closes readers for the merged tables */
     -+void reftable_merged_table_close(struct reftable_merged_table *mt);
     -+
      +/* releases memory for the merged_table */
      +void reftable_merged_table_free(struct reftable_merged_table *m);
      +
     ++/* return the hash ID of the merged table. */
     ++uint32_t reftable_merged_table_hash_id(struct reftable_merged_table *m);
     ++
      +/****************************************************************
      + Generic tables
      +
     @@ reftable/reftable.h (new)
      +
      +void reftable_table_from_reader(struct reftable_table *tab,
      +				struct reftable_reader *reader);
     ++
     ++/* returns the hash ID from a generic reftable_table */
     ++uint32_t reftable_table_hash_id(struct reftable_table *tab);
     ++
     ++/* create a generic table from reftable_merged_table */
      +void reftable_table_from_merged_table(struct reftable_table *tab,
      +				      struct reftable_merged_table *table);
      +
     ++/* returns the max update_index covered by this table. */
     ++uint64_t reftable_table_max_update_index(struct reftable_table *tab);
     ++
     ++/* returns the min update_index covered by this table. */
     ++uint64_t reftable_table_min_update_index(struct reftable_table *tab);
     ++
      +/* convenience function to read a single ref. Returns < 0 for error, 0
      +   for success, and 1 if ref not found. */
      +int reftable_table_read_ref(struct reftable_table *tab, const char *name,
     @@ reftable/reftable_test.c (new)
      +		reftable_new_writer(&strbuf_add_void, &buf, &opts);
      +
      +	struct reftable_ref_record rec = {
     -+		.ref_name = "master",
     ++		.refname = "master",
      +		.update_index = 1,
      +	};
      +	int err;
      +	struct reftable_block_source source = { 0 };
     -+	struct reftable_reader **readers = malloc(sizeof(*readers) * 1);
     ++	struct reftable_reader **readers =
     ++		reftable_calloc(sizeof(*readers) * 1);
     ++	struct reftable_table *tab = reftable_calloc(sizeof(*tab) * 1);
      +	uint32_t hash_id;
      +	struct reftable_reader *rd = NULL;
      +	struct reftable_merged_table *merged = NULL;
     @@ reftable/reftable_test.c (new)
      +	hash_id = reftable_reader_hash_id(rd);
      +	assert(hash_id == SHA1_ID);
      +
     -+	readers[0] = rd;
     -+
     -+	err = reftable_new_merged_table(&merged, readers, 1, SHA1_ID);
     ++	reftable_table_from_reader(&tab[0], rd);
     ++	err = reftable_new_merged_table(&merged, tab, 1, SHA1_ID);
      +	assert_err(err);
      +
     -+	reftable_merged_table_close(merged);
     ++	reader_close(rd);
      +	reftable_merged_table_free(merged);
      +	strbuf_release(&buf);
      +}
     @@ reftable/reftable_test.c (new)
      +
      +		snprintf(name, sizeof(name), "refs/heads/branch%02d", i);
      +
     -+		ref.ref_name = name;
     ++		ref.refname = name;
      +		ref.value = hash;
      +		ref.update_index = update_index;
      +		(*names)[i] = xstrdup(name);
     @@ reftable/reftable_test.c (new)
      +
      +		snprintf(name, sizeof(name), "refs/heads/branch%02d", i);
      +
     -+		log.ref_name = name;
     ++		log.refname = name;
      +		log.new_hash = hash;
      +		log.update_index = update_index;
      +		log.message = "message";
     @@ reftable/reftable_test.c (new)
      +	};
      +	int err;
      +	struct reftable_log_record log = {
     -+		.ref_name = "refs/heads/master",
     ++		.refname = "refs/heads/master",
      +		.name = "Han-Wen Nienhuys",
      +		.email = "hanwen@google.com",
      +		.tz_offset = 100,
     @@ reftable/reftable_test.c (new)
      +		snprintf(name, sizeof(name), "b%02d%0*d", i, 130, 7);
      +		names[i] = xstrdup(name);
      +		puts(name);
     -+		ref.ref_name = name;
     ++		ref.refname = name;
      +		ref.update_index = i;
      +
      +		err = reftable_writer_add_ref(w, &ref);
     @@ reftable/reftable_test.c (new)
      +		set_test_hash(hash1, i);
      +		set_test_hash(hash2, i + 1);
      +
     -+		log.ref_name = names[i];
     ++		log.refname = names[i];
      +		log.update_index = i;
      +		log.old_hash = hash1;
      +		log.new_hash = hash2;
     @@ reftable/reftable_test.c (new)
      +		}
      +
      +		assert_err(err);
     -+		assert_streq(names[i], log.ref_name);
     ++		assert_streq(names[i], log.refname);
      +		assert(i == log.update_index);
      +		i++;
      +		reftable_log_record_clear(&log);
     @@ reftable/reftable_test.c (new)
      +		if (r > 0) {
      +			break;
      +		}
     -+		assert(0 == strcmp(names[j], ref.ref_name));
     ++		assert(0 == strcmp(names[j], ref.refname));
      +		assert(update_index == ref.update_index);
      +
      +		j++;
     @@ reftable/reftable_test.c (new)
      +		assert_err(err);
      +		err = reftable_iterator_next_ref(&it, &ref);
      +		assert_err(err);
     -+		assert(0 == strcmp(names[i], ref.ref_name));
     ++		assert(0 == strcmp(names[i], ref.refname));
      +		assert(i == ref.value[0]);
      +
      +		reftable_ref_record_clear(&ref);
     @@ reftable/reftable_test.c (new)
      +		/* Put the variable part in the start */
      +		snprintf(name, sizeof(name), "br%02d%s", i, fill);
      +		name[40] = 0;
     -+		ref.ref_name = name;
     ++		ref.refname = name;
      +
      +		set_test_hash(hash1, i / 4);
      +		set_test_hash(hash2, 3 + i / 4);
     @@ reftable/reftable_test.c (new)
      +		}
      +
      +		assert(j < want_names_len);
     -+		assert(0 == strcmp(ref.ref_name, want_names[j]));
     ++		assert(0 == strcmp(ref.refname, want_names[j]));
      +		j++;
      +		reftable_ref_record_clear(&ref);
      +	}
     @@ reftable/stack.c (new)
      +void reftable_stack_destroy(struct reftable_stack *st)
      +{
      +	if (st->merged != NULL) {
     -+		reftable_merged_table_close(st->merged);
      +		reftable_merged_table_free(st->merged);
      +		st->merged = NULL;
      +	}
     ++
     ++	if (st->readers != NULL) {
     ++		int i = 0;
     ++		for (i = 0; i < st->readers_len; i++) {
     ++			reftable_reader_free(st->readers[i]);
     ++		}
     ++		st->readers_len = 0;
     ++		FREE_AND_NULL(st->readers);
     ++	}
      +	FREE_AND_NULL(st->list_file);
      +	FREE_AND_NULL(st->reftable_dir);
      +	reftable_free(st);
     @@ reftable/stack.c (new)
      +		reftable_calloc(sizeof(struct reftable_reader *) * cur_len);
      +	int i = 0;
      +	for (i = 0; i < cur_len; i++) {
     -+		cur[i] = st->merged->stack[i];
     ++		cur[i] = st->readers[i];
      +	}
      +	return cur;
      +}
     @@ reftable/stack.c (new)
      +	struct reftable_reader **cur = stack_copy_readers(st, cur_len);
      +	int err = 0;
      +	int names_len = names_length(names);
     -+	struct reftable_reader **new_tables =
     -+		reftable_malloc(sizeof(struct reftable_reader *) * names_len);
     -+	int new_tables_len = 0;
     ++	struct reftable_reader **new_readers =
     ++		reftable_calloc(sizeof(struct reftable_reader *) * names_len);
     ++	struct reftable_table *new_tables =
     ++		reftable_calloc(sizeof(struct reftable_table) * names_len);
     ++	int new_readers_len = 0;
      +	struct reftable_merged_table *new_merged = NULL;
      +	int i;
      +
     @@ reftable/stack.c (new)
      +				goto done;
      +		}
      +
     -+		new_tables[new_tables_len++] = rd;
     ++		new_readers[new_readers_len] = rd;
     ++		reftable_table_from_reader(&new_tables[new_readers_len], rd);
     ++		new_readers_len++;
      +	}
      +
      +	/* success! */
     -+	err = reftable_new_merged_table(&new_merged, new_tables, new_tables_len,
     -+					st->config.hash_id);
     ++	err = reftable_new_merged_table(&new_merged, new_tables,
     ++					new_readers_len, st->config.hash_id);
      +	if (err < 0)
      +		goto done;
      +
      +	new_tables = NULL;
     -+	new_tables_len = 0;
     ++	st->readers_len = new_readers_len;
      +	if (st->merged != NULL) {
      +		merged_table_clear(st->merged);
      +		reftable_merged_table_free(st->merged);
      +	}
     ++	if (st->readers != NULL) {
     ++		reftable_free(st->readers);
     ++	}
     ++	st->readers = new_readers;
     ++	new_readers = NULL;
     ++	new_readers_len = 0;
     ++
      +	new_merged->suppress_deletions = true;
      +	st->merged = new_merged;
     -+
      +	for (i = 0; i < cur_len; i++) {
      +		if (cur[i] != NULL) {
      +			reader_close(cur[i]);
     @@ reftable/stack.c (new)
      +	}
      +
      +done:
     -+	for (i = 0; i < new_tables_len; i++) {
     -+		reader_close(new_tables[i]);
     -+		reftable_reader_free(new_tables[i]);
     ++	for (i = 0; i < new_readers_len; i++) {
     ++		reader_close(new_readers[i]);
     ++		reftable_reader_free(new_readers[i]);
      +	}
     ++	reftable_free(new_readers);
      +	reftable_free(new_tables);
      +	reftable_free(cur);
      +	return err;
     @@ reftable/stack.c (new)
      +	if (err < 0)
      +		return err;
      +
     -+	for (i = 0; i < st->merged->stack_len; i++) {
     ++	for (i = 0; i < st->readers_len; i++) {
      +		if (names[i] == NULL) {
      +			err = 1;
      +			goto done;
      +		}
      +
     -+		if (strcmp(st->merged->stack[i]->name, names[i])) {
     ++		if (strcmp(st->readers[i]->name, names[i])) {
      +			err = 1;
      +			goto done;
      +		}
     @@ reftable/stack.c (new)
      +		goto done;
      +
      +	for (i = 0; i < add->stack->merged->stack_len; i++) {
     -+		strbuf_addstr(&table_list, add->stack->merged->stack[i]->name);
     ++		strbuf_addstr(&table_list, add->stack->readers[i]->name);
      +		strbuf_addstr(&table_list, "\n");
      +	}
      +	for (i = 0; i < add->new_tables_len; i++) {
     @@ reftable/stack.c (new)
      +{
      +	int sz = st->merged->stack_len;
      +	if (sz > 0)
     -+		return reftable_reader_max_update_index(
     -+			       st->merged->stack[sz - 1]) +
     ++		return reftable_reader_max_update_index(st->readers[sz - 1]) +
      +		       1;
      +	return 1;
      +}
     @@ reftable/stack.c (new)
      +	int err = 0;
      +
      +	format_name(&next_name,
     -+		    reftable_reader_min_update_index(st->merged->stack[first]),
     -+		    reftable_reader_max_update_index(st->merged->stack[first]));
     ++		    reftable_reader_min_update_index(st->readers[first]),
     ++		    reftable_reader_max_update_index(st->readers[first]));
      +
      +	strbuf_reset(temp_tab);
      +	strbuf_addstr(temp_tab, st->reftable_dir);
     @@ reftable/stack.c (new)
      +			struct reftable_log_expiry_config *config)
      +{
      +	int subtabs_len = last - first + 1;
     -+	struct reftable_reader **subtabs = reftable_calloc(
     -+		sizeof(struct reftable_reader *) * (last - first + 1));
     ++	struct reftable_table *subtabs = reftable_calloc(
     ++		sizeof(struct reftable_table) * (last - first + 1));
      +	struct reftable_merged_table *mt = NULL;
      +	int err = 0;
      +	struct reftable_iterator it = { 0 };
     @@ reftable/stack.c (new)
      +
      +	int i = 0, j = 0;
      +	for (i = first, j = 0; i <= last; i++) {
     -+		struct reftable_reader *t = st->merged->stack[i];
     -+		subtabs[j++] = t;
     ++		struct reftable_reader *t = st->readers[i];
     ++		reftable_table_from_reader(&subtabs[j++], t);
      +		st->stats.bytes += t->size;
      +	}
     -+	reftable_writer_set_limits(wr,
     -+				   st->merged->stack[first]->min_update_index,
     -+				   st->merged->stack[last]->max_update_index);
     ++	reftable_writer_set_limits(wr, st->readers[first]->min_update_index,
     ++				   st->readers[last]->max_update_index);
      +
      +	err = reftable_new_merged_table(&mt, subtabs, subtabs_len,
      +					st->config.hash_id);
     @@ reftable/stack.c (new)
      +
      +		strbuf_addstr(&subtab_file_name, st->reftable_dir);
      +		strbuf_addstr(&subtab_file_name, "/");
     -+		strbuf_addstr(&subtab_file_name,
     -+			      reader_name(st->merged->stack[i]));
     ++		strbuf_addstr(&subtab_file_name, reader_name(st->readers[i]));
      +
      +		strbuf_reset(&subtab_lock);
      +		strbuf_addbuf(&subtab_lock, &subtab_file_name);
     @@ reftable/stack.c (new)
      +	}
      +	have_lock = true;
      +
     -+	format_name(&new_table_name, st->merged->stack[first]->min_update_index,
     -+		    st->merged->stack[last]->max_update_index);
     ++	format_name(&new_table_name, st->readers[first]->min_update_index,
     ++		    st->readers[last]->max_update_index);
      +	strbuf_addstr(&new_table_name, ".ref");
      +
      +	strbuf_reset(&new_table_path);
     @@ reftable/stack.c (new)
      +	}
      +
      +	for (i = 0; i < first; i++) {
     -+		strbuf_addstr(&ref_list_contents, st->merged->stack[i]->name);
     ++		strbuf_addstr(&ref_list_contents, st->readers[i]->name);
      +		strbuf_addstr(&ref_list_contents, "\n");
      +	}
      +	if (!is_empty_table) {
     @@ reftable/stack.c (new)
      +		strbuf_addstr(&ref_list_contents, "\n");
      +	}
      +	for (i = last + 1; i < st->merged->stack_len; i++) {
     -+		strbuf_addstr(&ref_list_contents, st->merged->stack[i]->name);
     ++		strbuf_addstr(&ref_list_contents, st->readers[i]->name);
      +		strbuf_addstr(&ref_list_contents, "\n");
      +	}
      +
     @@ reftable/stack.c (new)
      +	int overhead = header_size(version) - 1;
      +	int i = 0;
      +	for (i = 0; i < st->merged->stack_len; i++) {
     -+		sizes[i] = st->merged->stack[i]->size - overhead;
     ++		sizes[i] = st->readers[i]->size - overhead;
      +	}
      +	return sizes;
      +}
     @@ reftable/stack.c (new)
      +	if (err)
      +		goto done;
      +
     -+	if (strcmp(log->ref_name, refname) ||
     ++	if (strcmp(log->refname, refname) ||
      +	    reftable_log_record_is_deletion(log)) {
      +		err = 1;
      +		goto done;
     @@ reftable/stack.h (new)
      +
      +	struct reftable_write_options config;
      +
     ++	struct reftable_reader **readers;
     ++	size_t readers_len;
      +	struct reftable_merged_table *merged;
      +	struct reftable_compaction_stats stats;
      +};
     @@ reftable/stack_test.c (new)
      +	struct reftable_stack *st = NULL;
      +	int err;
      +	struct reftable_ref_record ref = {
     -+		.ref_name = "HEAD",
     ++		.refname = "HEAD",
      +		.update_index = 1,
      +		.target = "master",
      +	};
     @@ reftable/stack_test.c (new)
      +	err = reftable_stack_add(st, &write_test_ref, &ref);
      +	assert_err(err);
      +
     -+	err = reftable_stack_read_ref(st, ref.ref_name, &dest);
     ++	err = reftable_stack_read_ref(st, ref.refname, &dest);
      +	assert_err(err);
      +	assert(0 == strcmp("master", dest.target));
      +
     @@ reftable/stack_test.c (new)
      +	char dir[256] = "/tmp/stack_test.XXXXXX";
      +	int err;
      +	struct reftable_ref_record ref1 = {
     -+		.ref_name = "HEAD",
     ++		.refname = "HEAD",
      +		.update_index = 1,
      +		.target = "master",
      +	};
      +	struct reftable_ref_record ref2 = {
     -+		.ref_name = "branch2",
     ++		.refname = "branch2",
      +		.update_index = 2,
      +		.target = "master",
      +	};
     @@ reftable/stack_test.c (new)
      +	struct reftable_addition *add = NULL;
      +
      +	struct reftable_ref_record ref = {
     -+		.ref_name = "HEAD",
     ++		.refname = "HEAD",
      +		.update_index = 1,
      +		.target = "master",
      +	};
     @@ reftable/stack_test.c (new)
      +
      +	reftable_addition_destroy(add);
      +
     -+	err = reftable_stack_read_ref(st, ref.ref_name, &dest);
     ++	err = reftable_stack_read_ref(st, ref.refname, &dest);
      +	assert_err(err);
      +	assert(0 == strcmp("master", dest.target));
      +
     @@ reftable/stack_test.c (new)
      +	char dir[256] = "/tmp/stack_test.XXXXXX";
      +	int i;
      +	struct reftable_ref_record ref = {
     -+		.ref_name = "a/b",
     ++		.refname = "a/b",
      +		.update_index = 1,
      +		.target = "master",
      +	};
     @@ reftable/stack_test.c (new)
      +
      +	for (i = 0; i < ARRAY_SIZE(additions); i++) {
      +		struct reftable_ref_record ref = {
     -+			.ref_name = additions[i],
     ++			.refname = additions[i],
      +			.update_index = 1,
      +			.target = "master",
      +		};
     @@ reftable/stack_test.c (new)
      +	struct reftable_stack *st = NULL;
      +	int err;
      +	struct reftable_ref_record ref1 = {
     -+		.ref_name = "name1",
     ++		.refname = "name1",
      +		.update_index = 1,
      +		.target = "master",
      +	};
      +	struct reftable_ref_record ref2 = {
     -+		.ref_name = "name2",
     ++		.refname = "name2",
      +		.update_index = 1,
      +		.target = "master",
      +	};
     @@ reftable/stack_test.c (new)
      +	for (i = 0; i < N; i++) {
      +		char buf[256];
      +		snprintf(buf, sizeof(buf), "branch%02d", i);
     -+		refs[i].ref_name = xstrdup(buf);
     ++		refs[i].refname = xstrdup(buf);
      +		refs[i].value = reftable_malloc(SHA1_SIZE);
      +		refs[i].update_index = i + 1;
      +		set_test_hash(refs[i].value, i);
      +
     -+		logs[i].ref_name = xstrdup(buf);
     ++		logs[i].refname = xstrdup(buf);
      +		logs[i].update_index = N + i + 1;
      +		logs[i].new_hash = reftable_malloc(SHA1_SIZE);
      +		logs[i].email = xstrdup("identity@invalid");
     @@ reftable/stack_test.c (new)
      +
      +	for (i = 0; i < N; i++) {
      +		struct reftable_ref_record dest = { 0 };
     -+		int err = reftable_stack_read_ref(st, refs[i].ref_name, &dest);
     ++		int err = reftable_stack_read_ref(st, refs[i].refname, &dest);
      +		assert_err(err);
      +		assert(reftable_ref_record_equal(&dest, refs + i, SHA1_SIZE));
      +		reftable_ref_record_clear(&dest);
     @@ reftable/stack_test.c (new)
      +
      +	for (i = 0; i < N; i++) {
      +		struct reftable_log_record dest = { 0 };
     -+		int err = reftable_stack_read_log(st, refs[i].ref_name, &dest);
     ++		int err = reftable_stack_read_log(st, refs[i].refname, &dest);
      +		assert_err(err);
      +		assert(reftable_log_record_equal(&dest, logs + i, SHA1_SIZE));
      +		reftable_log_record_clear(&dest);
     @@ reftable/stack_test.c (new)
      +	uint8_t h1[SHA1_SIZE] = { 0x01 }, h2[SHA1_SIZE] = { 0x02 };
      +
      +	struct reftable_log_record input = {
     -+		.ref_name = "branch",
     ++		.refname = "branch",
      +		.update_index = 1,
      +		.new_hash = h1,
      +		.old_hash = h2,
     @@ reftable/stack_test.c (new)
      +	err = reftable_stack_add(st, &write_test_log, &arg);
      +	assert_err(err);
      +
     -+	err = reftable_stack_read_log(st, input.ref_name, &dest);
     ++	err = reftable_stack_read_log(st, input.refname, &dest);
      +	assert_err(err);
      +	assert(0 == strcmp(dest.message, "one\n"));
      +
     @@ reftable/stack_test.c (new)
      +	arg.update_index = 2;
      +	err = reftable_stack_add(st, &write_test_log, &arg);
      +	assert_err(err);
     -+	err = reftable_stack_read_log(st, input.ref_name, &dest);
     ++	err = reftable_stack_read_log(st, input.refname, &dest);
      +	assert_err(err);
      +	assert(0 == strcmp(dest.message, "two\n"));
      +
     @@ reftable/stack_test.c (new)
      +
      +	for (i = 0; i < N; i++) {
      +		const char *buf = "branch";
     -+		refs[i].ref_name = xstrdup(buf);
     ++		refs[i].refname = xstrdup(buf);
      +		refs[i].update_index = i + 1;
      +		if (i % 2 == 0) {
      +			refs[i].value = reftable_malloc(SHA1_SIZE);
      +			set_test_hash(refs[i].value, i);
      +		}
     -+		logs[i].ref_name = xstrdup(buf);
     ++		logs[i].refname = xstrdup(buf);
      +		/* update_index is part of the key. */
      +		logs[i].update_index = 42;
      +		if (i % 2 == 0) {
     @@ reftable/stack_test.c (new)
      +	int err;
      +
      +	struct reftable_ref_record ref = {
     -+		.ref_name = "master",
     ++		.refname = "master",
      +		.target = "target",
      +		.update_index = 1,
      +	};
     @@ reftable/stack_test.c (new)
      +		char buf[256];
      +		snprintf(buf, sizeof(buf), "branch%02d", i);
      +
     -+		logs[i].ref_name = xstrdup(buf);
     ++		logs[i].refname = xstrdup(buf);
      +		logs[i].update_index = i;
      +		logs[i].time = i;
      +		logs[i].new_hash = reftable_malloc(SHA1_SIZE);
     @@ reftable/stack_test.c (new)
      +	err = reftable_stack_compact_all(st, &expiry);
      +	assert_err(err);
      +
     -+	err = reftable_stack_read_log(st, logs[9].ref_name, &log);
     ++	err = reftable_stack_read_log(st, logs[9].refname, &log);
      +	assert(err == 1);
      +
     -+	err = reftable_stack_read_log(st, logs[11].ref_name, &log);
     ++	err = reftable_stack_read_log(st, logs[11].refname, &log);
      +	assert_err(err);
      +
      +	expiry.min_update_index = 15;
      +	err = reftable_stack_compact_all(st, &expiry);
      +	assert_err(err);
      +
     -+	err = reftable_stack_read_log(st, logs[14].ref_name, &log);
     ++	err = reftable_stack_read_log(st, logs[14].refname, &log);
      +	assert(err == 1);
      +
     -+	err = reftable_stack_read_log(st, logs[16].ref_name, &log);
     ++	err = reftable_stack_read_log(st, logs[16].refname, &log);
      +	assert_err(err);
      +
      +	/* cleanup */
     @@ reftable/stack_test.c (new)
      +	for (i = 0; i < N; i++) {
      +		char name[100];
      +		struct reftable_ref_record ref = {
     -+			.ref_name = name,
     ++			.refname = name,
      +			.update_index = reftable_stack_next_update_index(st),
      +			.target = "master",
      +		};
     @@ reftable/strbuf.h (new)
      +  x = STRBUF_INIT;"
      + */
      +struct strbuf {
     -+	int len;
     -+	int cap;
     ++	size_t len;
     ++	size_t cap;
      +	char *buf;
      +
      +	/* Used to enforce initialization with STRBUF_INIT */
     @@ reftable/writer.c (new)
      +struct obj_index_tree_node {
      +	struct strbuf hash;
      +	uint64_t *offsets;
     -+	int offset_len;
     -+	int offset_cap;
     ++	size_t offset_len;
     ++	size_t offset_cap;
      +};
     ++
      +#define OBJ_INDEX_TREE_NODE_INIT    \
      +	{                           \
      +		.hash = STRBUF_INIT \
     @@ reftable/writer.c (new)
      +	struct reftable_ref_record copy = *ref;
      +	int err = 0;
      +
     -+	if (ref->ref_name == NULL)
     ++	if (ref->refname == NULL)
      +		return REFTABLE_API_ERROR;
      +	if (ref->update_index < w->min_update_index ||
      +	    ref->update_index > w->max_update_index)
     @@ reftable/writer.c (new)
      +	char *input_log_message = log->message;
      +	struct strbuf cleaned_message = STRBUF_INIT;
      +	int err;
     -+	if (log->ref_name == NULL)
     ++	if (log->refname == NULL)
      +		return REFTABLE_API_ERROR;
      +
      +	if (w->block_writer != NULL &&
     @@ reftable/writer.h (new)
      +
      +	/* pending index records for the current section */
      +	struct reftable_index_record *index;
     -+	int index_len;
     -+	int index_cap;
     ++	size_t index_len;
     ++	size_t index_cap;
      +
      +	/*
      +	  tree for use with tsearch; used to populate the 'o' inverse OID
 12:  c92b8d12ec = 13:  d155240b16 Add standalone build infrastructure for reftable
 13:  479fe884e9 ! 14:  073bff7279 Reftable support for git-core
     @@ Commit message
      
          For background, see the previous commit introducing the library.
      
     -    This introduces the refs/reftable-backend.c containing reftable powered ref
     -    storage backend.
     +    This introduces the file refs/reftable-backend.c containing a reftable-powered
     +    ref storage backend.
      
     -    It can be activated by passing --ref-storage=reftable to "git init".
     +    It can be activated by passing --ref-storage=reftable to "git init", or setting
     +    GIT_TEST_REFTABLE in the environment.
      
          Example use: see t/t0031-reftable.sh
      
     @@ Makefile: cocciclean:
      
       ## builtin/clone.c ##
      @@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
     - 		}
       	}
       
     --	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, INIT_DB_QUIET);
     -+	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN,
     + 	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
     +-		INIT_DB_QUIET);
      +		default_ref_storage(), INIT_DB_QUIET);
       
       	if (real_git_dir)
       		git_dir = real_git_dir;
     +@@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
     + 		 * Now that we know what algorithm the remote side is using,
     + 		 * let's set ours to the same thing.
     + 		 */
     +-		initialize_repository_version(hash_algo);
     ++		initialize_repository_version(hash_algo, default_ref_storage());
     + 		repo_set_hash_algo(the_repository, hash_algo);
     + 
     + 		mapped_refs = wanted_peer_refs(refs, &remote->fetch);
      
       ## builtin/init-db.c ##
      @@ builtin/init-db.c: static int needs_work_tree_config(const char *git_dir, const char *work_tree)
     @@ builtin/init-db.c: static int create_default_files(const char *template_path,
       	 * We need to create a "refs" dir in any case so that older
       	 * versions of git can tell that this is a repository.
      @@ builtin/init-db.c: static int create_default_files(const char *template_path,
     - 	 * Create the default symlink from ".git/HEAD" to the "master"
     - 	 * branch, if it does not exist yet.
     + 	 * Point the HEAD symref to the initial branch with if HEAD does
     + 	 * not yet exist.
       	 */
      -	path = git_path_buf(&buf, "HEAD");
      -	reinit = (!access(path, R_OK)
      -		  || readlink(path, junk, sizeof(junk)-1) != -1);
       	if (!reinit) {
     - 		if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
     - 			exit(1);
     + 		char *ref;
     + 
     +@@ builtin/init-db.c: static int create_default_files(const char *template_path,
     + 		free(ref);
       	}
       
      -	initialize_repository_version(fmt->hash_algo);
     @@ builtin/init-db.c: static int create_default_files(const char *template_path,
       	/* Check filemode trustability */
       	path = git_path_buf(&buf, "config");
      @@ builtin/init-db.c: static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash
     - }
       
       int init_db(const char *git_dir, const char *real_git_dir,
     --	    const char *template_dir, int hash, unsigned int flags)
     -+	    const char *template_dir, int hash, const char *ref_storage_format,
     -+	    unsigned int flags)
     + 	    const char *template_dir, int hash, const char *initial_branch,
     +-	    unsigned int flags)
     ++	    const char *ref_storage_format, unsigned int flags)
       {
       	int reinit;
       	int exist_ok = flags & INIT_DB_EXIST_OK;
     @@ builtin/init-db.c: static const char *const init_db_usage[] = {
       	const char *work_tree;
       	const char *template_dir = NULL;
      @@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *prefix)
     - 	const char *object_format = NULL;
     + 	const char *initial_branch = NULL;
       	int hash_algo = GIT_HASH_UNKNOWN;
       	const struct option init_db_options[] = {
      -		OPT_STRING(0, "template", &template_dir, N_("template-directory"),
     @@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *pref
      +			   N_("the ref storage format to use")),
       		OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
       			   N_("separate git dir from working tree")),
     - 		OPT_STRING(0, "object-format", &object_format, N_("hash"),
     + 		OPT_STRING('b', "initial-branch", &initial_branch, N_("name"),
      @@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *prefix)
       	}
       
     @@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *pref
       	UNLEAK(work_tree);
       
       	flags |= INIT_DB_EXIST_OK;
     --	return init_db(git_dir, real_git_dir, template_dir, hash_algo, flags);
     -+	return init_db(git_dir, real_git_dir, template_dir, hash_algo,
     -+		       ref_storage_format, flags);
     + 	return init_db(git_dir, real_git_dir, template_dir, hash_algo,
     +-		       initial_branch, flags);
     ++		       initial_branch, ref_storage_format, flags);
       }
      
     + ## builtin/worktree.c ##
     +@@
     + #include "submodule.h"
     + #include "utf8.h"
     + #include "worktree.h"
     ++#include "../refs/refs-internal.h"
     + 
     + static const char * const worktree_usage[] = {
     + 	N_("git worktree add [<options>] <path> [<commit-ish>]"),
     +@@ builtin/worktree.c: static int add_worktree(const char *path, const char *refname,
     + 	 * worktree.
     + 	 */
     + 	strbuf_reset(&sb);
     +-	strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
     +-	write_file(sb.buf, "%s", oid_to_hex(&null_oid));
     +-	strbuf_reset(&sb);
     ++	if (get_main_ref_store(the_repository)->be == &refs_be_reftable) {
     ++		/* XXX this is cut & paste from reftable_init_db. */
     ++		strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
     ++		write_file(sb.buf, "%s", "ref: refs/heads/.invalid\n");
     ++		strbuf_reset(&sb);
     ++
     ++		strbuf_addf(&sb, "%s/refs", sb_repo.buf);
     ++		safe_create_dir(sb.buf, 1);
     ++		strbuf_reset(&sb);
     ++
     ++		strbuf_addf(&sb, "%s/refs/heads", sb_repo.buf);
     ++		write_file(sb.buf, "this repository uses the reftable format");
     ++		strbuf_reset(&sb);
     ++
     ++		strbuf_addf(&sb, "%s/reftable", sb_repo.buf);
     ++		safe_create_dir(sb.buf, 1);
     ++		strbuf_reset(&sb);
     ++	} else {
     ++		strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
     ++		write_file(sb.buf, "%s", oid_to_hex(&null_oid));
     ++		strbuf_reset(&sb);
     ++	}
     ++
     + 	strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
     + 	write_file(sb.buf, "../..");
     + 
     +
       ## cache.h ##
      @@ cache.h: int path_inside_repo(const char *prefix, const char *path);
     + #define INIT_DB_EXIST_OK 0x0002
       
       int init_db(const char *git_dir, const char *real_git_dir,
     - 	    const char *template_dir, int hash_algo,
     --	    unsigned int flags);
     +-	    const char *template_dir, int hash_algo,
     +-	    const char *initial_branch, unsigned int flags);
      -void initialize_repository_version(int hash_algo);
     ++	    const char *template_dir, int hash_algo, const char *initial_branch,
      +	    const char *ref_storage_format, unsigned int flags);
      +void initialize_repository_version(int hash_algo,
      +				   const char *ref_storage_format);
     @@ cache.h: struct repository_format {
      
       ## refs.c ##
      @@
     - #include "argv-array.h"
       #include "repository.h"
     + #include "sigchain.h"
       
      +const char *default_ref_storage(void)
      +{
     @@ refs.c: struct ref_store *get_main_ref_store(struct repository *r)
      -	r->refs_private = ref_store_init(r->gitdir, REF_STORE_ALL_CAPS);
      +	r->refs_private = ref_store_init(r->gitdir,
      +					 r->ref_storage_format ?
     -+						 r->ref_storage_format :
     -+						 default_ref_storage(),
     ++						       r->ref_storage_format :
     ++						       default_ref_storage(),
      +					 REF_STORE_ALL_CAPS);
       	return r->refs_private;
       }
     @@ refs/refs-internal.h: struct ref_storage_be {
       ## refs/reftable-backend.c (new) ##
      @@
      +#include "../cache.h"
     ++#include "../chdir-notify.h"
      +#include "../config.h"
     -+#include "../refs.h"
     -+#include "refs-internal.h"
      +#include "../iterator.h"
      +#include "../lockfile.h"
     -+#include "../chdir-notify.h"
     -+
     ++#include "../refs.h"
      +#include "../reftable/reftable.h"
     ++#include "../worktree.h"
     ++#include "refs-internal.h"
      +
      +extern struct ref_storage_be refs_be_reftable;
      +
     @@ refs/reftable-backend.c (new)
      +
      +	int err;
      +	char *repo_dir;
     ++
      +	char *reftable_dir;
     -+	struct reftable_stack *stack;
     ++	char *worktree_reftable_dir;
     ++
     ++	struct reftable_stack *main_stack;
     ++	struct reftable_stack *worktree_stack;
      +};
      +
     -+static int reftable_read_raw_ref(struct ref_store *ref_store,
     -+				 const char *refname, struct object_id *oid,
     -+				 struct strbuf *referent, unsigned int *type);
     ++static struct reftable_stack *stack_for(struct git_reftable_ref_store *store,
     ++					const char *refname)
     ++{
     ++	if (store->worktree_stack == NULL)
     ++		return store->main_stack;
     ++
     ++	switch (ref_type(refname)) {
     ++	case REF_TYPE_PER_WORKTREE:
     ++	case REF_TYPE_PSEUDOREF:
     ++	case REF_TYPE_OTHER_PSEUDOREF:
     ++		return store->worktree_stack;
     ++	default:
     ++	case REF_TYPE_MAIN_PSEUDOREF:
     ++	case REF_TYPE_NORMAL:
     ++		return store->main_stack;
     ++	}
     ++}
     ++
     ++static int git_reftable_read_raw_ref(struct ref_store *ref_store,
     ++				     const char *refname, struct object_id *oid,
     ++				     struct strbuf *referent,
     ++				     unsigned int *type);
      +
      +static void clear_reftable_log_record(struct reftable_log_record *log)
      +{
      +	log->old_hash = NULL;
      +	log->new_hash = NULL;
      +	log->message = NULL;
     -+	log->ref_name = NULL;
     ++	log->refname = NULL;
      +	reftable_log_record_clear(log);
      +}
      +
     @@ refs/reftable-backend.c (new)
      +	log->tz_offset = sign * atoi(split.tz_begin);
      +}
      +
     ++static int has_suffix(struct strbuf *b, const char *suffix)
     ++{
     ++	size_t len = strlen(suffix);
     ++
     ++	if (len > b->len) {
     ++		return 0;
     ++	}
     ++
     ++	return 0 == strncmp(b->buf + b->len - len, suffix, len);
     ++}
     ++
     ++static int trim_component(struct strbuf *b)
     ++{
     ++	char *last;
     ++	last = strrchr(b->buf, '/');
     ++	if (!last)
     ++		return -1;
     ++	strbuf_setlen(b, last - b->buf);
     ++	return 0;
     ++}
     ++
     ++static int is_worktree(struct strbuf *b)
     ++{
     ++	if (trim_component(b) < 0) {
     ++		return 0;
     ++	}
     ++	if (!has_suffix(b, "/worktrees")) {
     ++		return 0;
     ++	}
     ++	trim_component(b);
     ++	return 1;
     ++}
     ++
      +static struct ref_store *git_reftable_ref_store_create(const char *path,
      +						       unsigned int store_flags)
      +{
     @@ refs/reftable-backend.c (new)
      +		.hash_id = the_hash_algo->format_id,
      +	};
      +	struct strbuf sb = STRBUF_INIT;
     ++	const char *gitdir = path;
     ++	struct strbuf wt_buf = STRBUF_INIT;
     ++	int wt = 0;
     ++
     ++	strbuf_addstr(&wt_buf, path);
     ++
     ++	/* this is clumsy, but the official worktree functions (eg.
     ++	 * get_worktrees()) function will try to initialize a ref storage
     ++	 * backend, leading to infinite recursion.  */
     ++	wt = is_worktree(&wt_buf);
     ++	if (wt) {
     ++		gitdir = wt_buf.buf;
     ++	}
      +
      +	base_ref_store_init(ref_store, &refs_be_reftable);
      +	refs->store_flags = store_flags;
     -+	refs->repo_dir = xstrdup(path);
     -+	strbuf_addf(&sb, "%s/reftable", path);
     ++	refs->repo_dir = xstrdup(gitdir);
     ++	strbuf_addf(&sb, "%s/reftable", gitdir);
      +	refs->reftable_dir = xstrdup(sb.buf);
      +	strbuf_reset(&sb);
      +
     -+	refs->err = reftable_new_stack(&refs->stack, refs->reftable_dir, cfg);
     ++	refs->err =
     ++		reftable_new_stack(&refs->main_stack, refs->reftable_dir, cfg);
      +	assert(refs->err != REFTABLE_API_ERROR);
     ++
     ++	if (refs->err == 0 && wt) {
     ++		strbuf_addf(&sb, "%s/reftable", path);
     ++		refs->worktree_reftable_dir = xstrdup(sb.buf);
     ++
     ++		refs->err = reftable_new_stack(&refs->worktree_stack,
     ++					       refs->worktree_reftable_dir,
     ++					       cfg);
     ++		assert(refs->err != REFTABLE_API_ERROR);
     ++	}
     ++
      +	strbuf_release(&sb);
     ++	strbuf_release(&wt_buf);
      +	return ref_store;
      +}
      +
     -+static int reftable_init_db(struct ref_store *ref_store, struct strbuf *err)
     ++static int git_reftable_init_db(struct ref_store *ref_store, struct strbuf *err)
      +{
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
      +	struct strbuf sb = STRBUF_INIT;
      +
      +	safe_create_dir(refs->reftable_dir, 1);
     ++	assert(refs->worktree_reftable_dir == NULL);
      +
      +	strbuf_addf(&sb, "%s/HEAD", refs->repo_dir);
      +	write_file(sb.buf, "ref: refs/heads/.invalid");
     @@ refs/reftable-backend.c (new)
      +	struct reftable_ref_record ref;
      +	struct object_id oid;
      +	struct ref_store *ref_store;
     ++
     ++	/* In case we must iterate over 2 stacks, this is non-null. */
     ++	struct reftable_merged_table *merged;
      +	unsigned int flags;
      +	int err;
      +	const char *prefix;
     @@ refs/reftable-backend.c (new)
      +		   a PSEUDOREF, but a PER_WORKTREE, b/c each worktree can have
      +		   its own HEAD.
      +		 */
     -+		ri->base.refname = ri->ref.ref_name;
     ++		ri->base.refname = ri->ref.refname;
      +		if (ri->prefix != NULL &&
     -+		    strncmp(ri->prefix, ri->ref.ref_name, strlen(ri->prefix))) {
     ++		    strncmp(ri->prefix, ri->ref.refname, strlen(ri->prefix))) {
      +			ri->err = 1;
      +			break;
      +		}
     @@ refs/reftable-backend.c (new)
      +		} else if (ri->ref.target != NULL) {
      +			int out_flags = 0;
      +			const char *resolved = refs_resolve_ref_unsafe(
     -+				ri->ref_store, ri->ref.ref_name,
     ++				ri->ref_store, ri->ref.refname,
      +				RESOLVE_REF_READING, &ri->oid, &out_flags);
      +			ri->base.flags = out_flags;
      +			if (resolved == NULL &&
     @@ refs/reftable-backend.c (new)
      +		(struct git_reftable_iterator *)ref_iterator;
      +	reftable_ref_record_clear(&ri->ref);
      +	reftable_iterator_destroy(&ri->iter);
     ++	if (ri->merged) {
     ++		reftable_merged_table_free(ri->merged);
     ++	}
      +	return 0;
      +}
      +
     @@ refs/reftable-backend.c (new)
      +};
      +
      +static struct ref_iterator *
     -+reftable_ref_iterator_begin(struct ref_store *ref_store, const char *prefix,
     -+			    unsigned int flags)
     ++git_reftable_ref_iterator_begin(struct ref_store *ref_store, const char *prefix,
     ++				unsigned int flags)
      +{
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
      +	struct git_reftable_iterator *ri = xcalloc(1, sizeof(*ri));
     -+	struct reftable_merged_table *mt = NULL;
      +
      +	if (refs->err < 0) {
      +		ri->err = refs->err;
     -+	} else {
     -+		mt = reftable_stack_merged_table(refs->stack);
     ++	} else if (refs->worktree_stack == NULL) {
     ++		struct reftable_merged_table *mt =
     ++			reftable_stack_merged_table(refs->main_stack);
      +		ri->err = reftable_merged_table_seek_ref(mt, &ri->iter, prefix);
     ++	} else {
     ++		struct reftable_merged_table *mt1 =
     ++			reftable_stack_merged_table(refs->main_stack);
     ++		struct reftable_merged_table *mt2 =
     ++			reftable_stack_merged_table(refs->worktree_stack);
     ++		struct reftable_table *tabs =
     ++			xcalloc(2, sizeof(struct reftable_table));
     ++		reftable_table_from_merged_table(&tabs[0], mt1);
     ++		reftable_table_from_merged_table(&tabs[1], mt2);
     ++		ri->err = reftable_new_merged_table(&ri->merged, tabs, 2,
     ++						    the_hash_algo->format_id);
     ++		if (ri->err == 0)
     ++			ri->err = reftable_merged_table_seek_ref(
     ++				ri->merged, &ri->iter, prefix);
      +	}
      +
      +	base_ref_iterator_init(&ri->base, &reftable_ref_iterator_vtable, 1);
     @@ refs/reftable-backend.c (new)
      +		struct ref_update *update = transaction->updates[i];
      +		struct object_id old_oid;
      +
     -+		err = reftable_read_raw_ref(ref_store, update->refname,
     -+					    &old_oid, &referent,
     -+					    /* mutate input, like
     -+					       files-backend.c */
     -+					    &update->type);
     ++		err = git_reftable_read_raw_ref(ref_store, update->refname,
     ++						&old_oid, &referent,
     ++						/* mutate input, like
     ++						   files-backend.c */
     ++						&update->type);
      +		if (err < 0 && errno == ENOENT &&
      +		    is_null_oid(&update->old_oid)) {
      +			err = 0;
     @@ refs/reftable-backend.c (new)
      +	return err;
      +}
      +
     -+static int reftable_transaction_prepare(struct ref_store *ref_store,
     -+					struct ref_transaction *transaction,
     -+					struct strbuf *errbuf)
     ++static int git_reftable_transaction_prepare(struct ref_store *ref_store,
     ++					    struct ref_transaction *transaction,
     ++					    struct strbuf *errbuf)
      +{
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
      +	struct reftable_addition *add = NULL;
     ++	struct reftable_stack *stack =
     ++		transaction->nr ?
     ++			      stack_for(refs, transaction->updates[0]->refname) :
     ++			      refs->main_stack;
      +	int err = refs->err;
      +	if (err < 0) {
      +		goto done;
      +	}
      +
     -+	err = reftable_stack_reload(refs->stack);
     ++	err = reftable_stack_reload(stack);
      +	if (err) {
      +		goto done;
      +	}
      +
     -+	err = reftable_stack_new_addition(&add, refs->stack);
     ++	err = reftable_stack_new_addition(&add, stack);
      +	if (err) {
      +		goto done;
      +	}
     @@ refs/reftable-backend.c (new)
      +	return err;
      +}
      +
     -+static int reftable_transaction_abort(struct ref_store *ref_store,
     -+				      struct ref_transaction *transaction,
     -+				      struct strbuf *err)
     ++static int git_reftable_transaction_abort(struct ref_store *ref_store,
     ++					  struct ref_transaction *transaction,
     ++					  struct strbuf *err)
      +{
      +	struct reftable_addition *add =
      +		(struct reftable_addition *)transaction->backend_data;
     @@ refs/reftable-backend.c (new)
      +	struct ref_transaction *transaction = (struct ref_transaction *)arg;
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)transaction->ref_store;
     -+	uint64_t ts = reftable_stack_next_update_index(refs->stack);
     ++	struct reftable_stack *stack =
     ++		stack_for(refs, transaction->updates[0]->refname);
     ++	uint64_t ts = reftable_stack_next_update_index(stack);
      +	int err = 0;
      +	int i = 0;
      +	struct reftable_log_record *logs =
     @@ refs/reftable-backend.c (new)
      +		struct ref_update *u = sorted[i];
      +		struct reftable_log_record *log = &logs[i];
      +		fill_reftable_log_record(log);
     -+		log->ref_name = (char *)u->refname;
     ++		log->refname = (char *)u->refname;
      +		log->old_hash = u->old_oid.hash;
      +		log->new_hash = u->new_oid.hash;
      +		log->update_index = ts;
     @@ refs/reftable-backend.c (new)
      +			struct object_id peeled;
      +
      +			int peel_error = peel_object(&u->new_oid, &peeled);
     -+			ref.ref_name = (char *)u->refname;
     ++			ref.refname = (char *)u->refname;
      +
      +			if (!is_null_oid(&u->new_oid)) {
      +				ref.value = u->new_oid.hash;
     @@ refs/reftable-backend.c (new)
      +	return err;
      +}
      +
     -+static int reftable_transaction_finish(struct ref_store *ref_store,
     -+				       struct ref_transaction *transaction,
     -+				       struct strbuf *errmsg)
     ++static int git_reftable_transaction_finish(struct ref_store *ref_store,
     ++					   struct ref_transaction *transaction,
     ++					   struct strbuf *errmsg)
      +{
      +	struct reftable_addition *add =
      +		(struct reftable_addition *)transaction->backend_data;
     @@ refs/reftable-backend.c (new)
      +			}
      +		}
      +	}
     -+
     -+	err = reftable_addition_add(add, &write_transaction_table, transaction);
     -+	if (err < 0) {
     -+		goto done;
     ++	if (transaction->nr) {
     ++		err = reftable_addition_add(add, &write_transaction_table,
     ++					    transaction);
     ++		if (err < 0) {
     ++			goto done;
     ++		}
      +	}
      +
      +	err = reftable_addition_commit(add);
     @@ refs/reftable-backend.c (new)
      +}
      +
      +static int
     -+reftable_transaction_initial_commit(struct ref_store *ref_store,
     -+				    struct ref_transaction *transaction,
     -+				    struct strbuf *errmsg)
     ++git_reftable_transaction_initial_commit(struct ref_store *ref_store,
     ++					struct ref_transaction *transaction,
     ++					struct strbuf *errmsg)
      +{
     -+	int err = reftable_transaction_prepare(ref_store, transaction, errmsg);
     ++	int err = git_reftable_transaction_prepare(ref_store, transaction,
     ++						   errmsg);
      +	if (err)
      +		return err;
      +
     -+	return reftable_transaction_finish(ref_store, transaction, errmsg);
     ++	return git_reftable_transaction_finish(ref_store, transaction, errmsg);
      +}
      +
      +struct write_pseudoref_arg {
     @@ refs/reftable-backend.c (new)
      +		}
      +	}
      +
     -+	write_ref.ref_name = (char *)arg->pseudoref;
     ++	write_ref.refname = (char *)arg->pseudoref;
      +	write_ref.update_index = ts;
      +	if (!is_null_oid(arg->new_oid))
      +		write_ref.value = (uint8_t *)arg->new_oid->hash;
     @@ refs/reftable-backend.c (new)
      +	return err;
      +}
      +
     -+static int reftable_write_pseudoref(struct ref_store *ref_store,
     -+				    const char *pseudoref,
     -+				    const struct object_id *oid,
     -+				    const struct object_id *old_oid,
     -+				    struct strbuf *errbuf)
     ++static int git_reftable_write_pseudoref(struct ref_store *ref_store,
     ++					const char *pseudoref,
     ++					const struct object_id *oid,
     ++					const struct object_id *old_oid,
     ++					struct strbuf *errbuf)
      +{
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
     ++	struct reftable_stack *stack = stack_for(refs, pseudoref);
      +	struct write_pseudoref_arg arg = {
     -+		.stack = refs->stack,
     ++		.stack = stack,
      +		.pseudoref = pseudoref,
      +		.new_oid = oid,
      +	};
     @@ refs/reftable-backend.c (new)
      +		goto done;
      +	}
      +
     -+	err = reftable_stack_reload(refs->stack);
     ++	err = reftable_stack_reload(stack);
      +	if (err) {
      +		goto done;
      +	}
     -+	err = reftable_stack_new_addition(&add, refs->stack);
     ++	err = reftable_stack_new_addition(&add, stack);
      +	if (err) {
      +		goto done;
      +	}
     @@ refs/reftable-backend.c (new)
      +				     const struct object_id *old_oid)
      +{
      +	struct strbuf errbuf = STRBUF_INIT;
     -+	int ret = reftable_write_pseudoref(ref_store, pseudoref, &null_oid,
     -+					   old_oid, &errbuf);
     ++	int ret = git_reftable_write_pseudoref(ref_store, pseudoref, &null_oid,
     ++					       old_oid, &errbuf);
      +	/* XXX what to do with the error message? */
      +	strbuf_release(&errbuf);
      +	return ret;
     @@ refs/reftable-backend.c (new)
      +	reftable_writer_set_limits(writer, ts, ts);
      +	for (i = 0; i < arg->refnames->nr; i++) {
      +		struct reftable_ref_record ref = {
     -+			.ref_name = (char *)arg->refnames->items[i].string,
     ++			.refname = (char *)arg->refnames->items[i].string,
      +			.update_index = ts,
      +		};
      +		err = reftable_writer_add_ref(writer, &ref);
     @@ refs/reftable-backend.c (new)
      +		log.new_hash = NULL;
      +		log.old_hash = NULL;
      +		log.update_index = ts;
     -+		log.ref_name = (char *)arg->refnames->items[i].string;
     ++		log.refname = (char *)arg->refnames->items[i].string;
      +
     -+		if (reftable_stack_read_ref(arg->stack, log.ref_name,
     ++		if (reftable_stack_read_ref(arg->stack, log.refname,
      +					    &current) == 0) {
      +			log.old_hash = current.value;
      +		}
     @@ refs/reftable-backend.c (new)
      +	return 0;
      +}
      +
     -+static int reftable_delete_refs(struct ref_store *ref_store, const char *msg,
     -+				struct string_list *refnames,
     -+				unsigned int flags)
     ++static int git_reftable_delete_refs(struct ref_store *ref_store,
     ++				    const char *msg,
     ++				    struct string_list *refnames,
     ++				    unsigned int flags)
      +{
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
     ++	struct reftable_stack *stack =
     ++		stack_for(refs, refnames->items[0].string);
      +	struct write_delete_refs_arg arg = {
     -+		.stack = refs->stack,
     ++		.stack = stack,
      +		.refnames = refnames,
      +		.logmsg = msg,
      +		.flags = flags,
     @@ refs/reftable-backend.c (new)
      +	}
      +
      +	string_list_sort(refnames);
     -+	err = reftable_stack_reload(refs->stack);
     ++	err = reftable_stack_reload(stack);
      +	if (err) {
      +		goto done;
      +	}
     -+	err = reftable_stack_add(refs->stack, &write_delete_refs_table, &arg);
     ++	err = reftable_stack_add(stack, &write_delete_refs_table, &arg);
      +done:
      +	assert(err != REFTABLE_API_ERROR);
      +	return err;
      +}
      +
     -+static int reftable_pack_refs(struct ref_store *ref_store, unsigned int flags)
     ++static int git_reftable_pack_refs(struct ref_store *ref_store,
     ++				  unsigned int flags)
      +{
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
     -+	if (refs->err < 0) {
     -+		return refs->err;
     ++	int err = refs->err;
     ++	if (err < 0) {
     ++		return err;
      +	}
     -+	return reftable_stack_compact_all(refs->stack, NULL);
     ++	err = reftable_stack_compact_all(refs->main_stack, NULL);
     ++	if (err == 0 && refs->worktree_stack != NULL)
     ++		err = reftable_stack_compact_all(refs->worktree_stack, NULL);
     ++	return err;
      +}
      +
      +struct write_create_symref_arg {
      +	struct git_reftable_ref_store *refs;
     ++	struct reftable_stack *stack;
      +	const char *refname;
      +	const char *target;
      +	const char *logmsg;
     @@ refs/reftable-backend.c (new)
      +{
      +	struct write_create_symref_arg *create =
      +		(struct write_create_symref_arg *)arg;
     -+	uint64_t ts = reftable_stack_next_update_index(create->refs->stack);
     ++	uint64_t ts = reftable_stack_next_update_index(create->stack);
      +	int err = 0;
      +
      +	struct reftable_ref_record ref = {
     -+		.ref_name = (char *)create->refname,
     ++		.refname = (char *)create->refname,
      +		.target = (char *)create->target,
      +		.update_index = ts,
      +	};
     @@ refs/reftable-backend.c (new)
      +		struct object_id old_oid;
      +
      +		fill_reftable_log_record(&log);
     -+		log.ref_name = (char *)create->refname;
     ++		log.refname = (char *)create->refname;
      +		log.message = (char *)create->logmsg;
      +		log.update_index = ts;
      +		if (refs_resolve_ref_unsafe(
     @@ refs/reftable-backend.c (new)
      +		if (log.old_hash != NULL || log.new_hash != NULL) {
      +			err = reftable_writer_add_log(writer, &log);
      +		}
     -+		log.ref_name = NULL;
     ++		log.refname = NULL;
      +		log.message = NULL;
      +		log.old_hash = NULL;
      +		log.new_hash = NULL;
     @@ refs/reftable-backend.c (new)
      +	return err;
      +}
      +
     -+static int reftable_create_symref(struct ref_store *ref_store,
     -+				  const char *refname, const char *target,
     -+				  const char *logmsg)
     ++static int git_reftable_create_symref(struct ref_store *ref_store,
     ++				      const char *refname, const char *target,
     ++				      const char *logmsg)
      +{
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
     ++	struct reftable_stack *stack = stack_for(refs, refname);
      +	struct write_create_symref_arg arg = { .refs = refs,
     ++					       .stack = stack,
      +					       .refname = refname,
      +					       .target = target,
      +					       .logmsg = logmsg };
     @@ refs/reftable-backend.c (new)
      +	if (err < 0) {
      +		goto done;
      +	}
     -+	err = reftable_stack_reload(refs->stack);
     ++	err = reftable_stack_reload(stack);
      +	if (err) {
      +		goto done;
      +	}
     -+	err = reftable_stack_add(refs->stack, &write_create_symref_table, &arg);
     ++	err = reftable_stack_add(stack, &write_create_symref_table, &arg);
      +done:
      +	assert(err != REFTABLE_API_ERROR);
      +	return err;
     @@ refs/reftable-backend.c (new)
      +		goto done;
      +	}
      +
     -+	free(ref.ref_name);
     -+	ref.ref_name = strdup(arg->newname);
     ++	free(ref.refname);
     ++	ref.refname = strdup(arg->newname);
      +	reftable_writer_set_limits(writer, ts, ts);
      +	ref.update_index = ts;
      +
      +	{
      +		struct reftable_ref_record todo[2] = { { NULL } };
     -+		todo[0].ref_name = (char *)arg->oldname;
     ++		todo[0].refname = (char *)arg->oldname;
      +		todo[0].update_index = ts;
      +		/* leave todo[0] empty */
      +		todo[1] = ref;
     @@ refs/reftable-backend.c (new)
      +		fill_reftable_log_record(&todo[0]);
      +		fill_reftable_log_record(&todo[1]);
      +
     -+		todo[0].ref_name = (char *)arg->oldname;
     ++		todo[0].refname = (char *)arg->oldname;
      +		todo[0].update_index = ts;
      +		todo[0].message = (char *)arg->logmsg;
      +		todo[0].old_hash = ref.value;
      +		todo[0].new_hash = NULL;
      +
     -+		todo[1].ref_name = (char *)arg->newname;
     ++		todo[1].refname = (char *)arg->newname;
      +		todo[1].update_index = ts;
      +		todo[1].old_hash = NULL;
      +		todo[1].new_hash = ref.value;
     @@ refs/reftable-backend.c (new)
      +	return err;
      +}
      +
     -+static int reftable_rename_ref(struct ref_store *ref_store,
     -+			       const char *oldrefname, const char *newrefname,
     -+			       const char *logmsg)
     ++static int git_reftable_rename_ref(struct ref_store *ref_store,
     ++				   const char *oldrefname,
     ++				   const char *newrefname, const char *logmsg)
      +{
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
     ++	struct reftable_stack *stack = stack_for(refs, newrefname);
      +	struct write_rename_arg arg = {
     -+		.stack = refs->stack,
     ++		.stack = stack,
      +		.oldname = oldrefname,
      +		.newname = newrefname,
      +		.logmsg = logmsg,
     @@ refs/reftable-backend.c (new)
      +	if (err < 0) {
      +		goto done;
      +	}
     -+	err = reftable_stack_reload(refs->stack);
     ++	err = reftable_stack_reload(stack);
      +	if (err) {
      +		goto done;
      +	}
      +
     -+	err = reftable_stack_add(refs->stack, &write_rename_table, &arg);
     ++	err = reftable_stack_add(stack, &write_rename_table, &arg);
      +done:
      +	assert(err != REFTABLE_API_ERROR);
      +	return err;
      +}
      +
     -+static int reftable_copy_ref(struct ref_store *ref_store,
     -+			     const char *oldrefname, const char *newrefname,
     -+			     const char *logmsg)
     ++static int git_reftable_copy_ref(struct ref_store *ref_store,
     ++				 const char *oldrefname, const char *newrefname,
     ++				 const char *logmsg)
      +{
      +	BUG("reftable reference store does not support copying references");
      +}
      +
     -+struct reftable_reflog_ref_iterator {
     ++struct git_reftable_reflog_ref_iterator {
      +	struct ref_iterator base;
      +	struct reftable_iterator iter;
      +	struct reftable_log_record log;
      +	struct object_id oid;
     ++
     ++	/* Used when iterating over worktree & main */
     ++	struct reftable_merged_table *merged;
      +	char *last_name;
      +};
      +
      +static int
     -+reftable_reflog_ref_iterator_advance(struct ref_iterator *ref_iterator)
     ++git_reftable_reflog_ref_iterator_advance(struct ref_iterator *ref_iterator)
      +{
     -+	struct reftable_reflog_ref_iterator *ri =
     -+		(struct reftable_reflog_ref_iterator *)ref_iterator;
     ++	struct git_reftable_reflog_ref_iterator *ri =
     ++		(struct git_reftable_reflog_ref_iterator *)ref_iterator;
      +
      +	while (1) {
      +		int err = reftable_iterator_next_log(&ri->iter, &ri->log);
     @@ refs/reftable-backend.c (new)
      +			return ITER_ERROR;
      +		}
      +
     -+		ri->base.refname = ri->log.ref_name;
     ++		ri->base.refname = ri->log.refname;
      +		if (ri->last_name != NULL &&
     -+		    !strcmp(ri->log.ref_name, ri->last_name)) {
     ++		    !strcmp(ri->log.refname, ri->last_name)) {
      +			/* we want the refnames that we have reflogs for, so we
      +			 * skip if we've already produced this name. This could
      +			 * be faster by seeking directly to
     @@ refs/reftable-backend.c (new)
      +		}
      +
      +		free(ri->last_name);
     -+		ri->last_name = xstrdup(ri->log.ref_name);
     ++		ri->last_name = xstrdup(ri->log.refname);
      +		hashcpy(ri->oid.hash, ri->log.new_hash);
      +		return ITER_OK;
      +	}
      +}
      +
     -+static int reftable_reflog_ref_iterator_peel(struct ref_iterator *ref_iterator,
     -+					     struct object_id *peeled)
     ++static int
     ++git_reftable_reflog_ref_iterator_peel(struct ref_iterator *ref_iterator,
     ++				      struct object_id *peeled)
      +{
      +	BUG("not supported.");
      +	return -1;
      +}
      +
     -+static int reftable_reflog_ref_iterator_abort(struct ref_iterator *ref_iterator)
     ++static int
     ++git_reftable_reflog_ref_iterator_abort(struct ref_iterator *ref_iterator)
      +{
     -+	struct reftable_reflog_ref_iterator *ri =
     -+		(struct reftable_reflog_ref_iterator *)ref_iterator;
     ++	struct git_reftable_reflog_ref_iterator *ri =
     ++		(struct git_reftable_reflog_ref_iterator *)ref_iterator;
      +	reftable_log_record_clear(&ri->log);
      +	reftable_iterator_destroy(&ri->iter);
     ++	if (ri->merged)
     ++		reftable_merged_table_free(ri->merged);
      +	return 0;
      +}
      +
     -+static struct ref_iterator_vtable reftable_reflog_ref_iterator_vtable = {
     -+	reftable_reflog_ref_iterator_advance, reftable_reflog_ref_iterator_peel,
     -+	reftable_reflog_ref_iterator_abort
     ++static struct ref_iterator_vtable git_reftable_reflog_ref_iterator_vtable = {
     ++	git_reftable_reflog_ref_iterator_advance,
     ++	git_reftable_reflog_ref_iterator_peel,
     ++	git_reftable_reflog_ref_iterator_abort
      +};
      +
      +static struct ref_iterator *
     -+reftable_reflog_iterator_begin(struct ref_store *ref_store)
     ++git_reftable_reflog_iterator_begin(struct ref_store *ref_store)
      +{
     -+	struct reftable_reflog_ref_iterator *ri = xcalloc(sizeof(*ri), 1);
     ++	struct git_reftable_reflog_ref_iterator *ri = xcalloc(sizeof(*ri), 1);
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
      +
     -+	struct reftable_merged_table *mt =
     -+		reftable_stack_merged_table(refs->stack);
     -+	int err = reftable_merged_table_seek_log(mt, &ri->iter, "");
     -+	if (err < 0) {
     -+		free(ri);
     -+		return NULL;
     ++	if (refs->worktree_stack == NULL) {
     ++		struct reftable_stack *stack = refs->main_stack;
     ++		struct reftable_merged_table *mt =
     ++			reftable_stack_merged_table(stack);
     ++		int err = reftable_merged_table_seek_log(mt, &ri->iter, "");
     ++		if (err < 0) {
     ++			free(ri);
     ++			/* XXX is this allowed? */
     ++			return NULL;
     ++		}
     ++	} else {
     ++		struct reftable_merged_table *mt1 =
     ++			reftable_stack_merged_table(refs->main_stack);
     ++		struct reftable_merged_table *mt2 =
     ++			reftable_stack_merged_table(refs->worktree_stack);
     ++		struct reftable_table *tabs =
     ++			xcalloc(2, sizeof(struct reftable_table));
     ++		int err = 0;
     ++		reftable_table_from_merged_table(&tabs[0], mt1);
     ++		reftable_table_from_merged_table(&tabs[1], mt2);
     ++		err = reftable_new_merged_table(&ri->merged, tabs, 2,
     ++						the_hash_algo->format_id);
     ++		if (err < 0) {
     ++			free(tabs);
     ++			/* XXX see above */
     ++			return NULL;
     ++		}
     ++		err = reftable_merged_table_seek_ref(ri->merged, &ri->iter, "");
     ++		if (err < 0) {
     ++			return NULL;
     ++		}
      +	}
     -+
     -+	base_ref_iterator_init(&ri->base, &reftable_reflog_ref_iterator_vtable,
     -+			       1);
     ++	base_ref_iterator_init(&ri->base,
     ++			       &git_reftable_reflog_ref_iterator_vtable, 1);
      +	ri->base.oid = &ri->oid;
      +
      +	return (struct ref_iterator *)ri;
      +}
      +
     -+static int
     -+reftable_for_each_reflog_ent_newest_first(struct ref_store *ref_store,
     -+					  const char *refname,
     -+					  each_reflog_ent_fn fn, void *cb_data)
     ++static int git_reftable_for_each_reflog_ent_newest_first(
     ++	struct ref_store *ref_store, const char *refname, each_reflog_ent_fn fn,
     ++	void *cb_data)
      +{
      +	struct reftable_iterator it = { NULL };
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
     ++	struct reftable_stack *stack = stack_for(refs, refname);
      +	struct reftable_merged_table *mt = NULL;
      +	int err = 0;
      +	struct reftable_log_record log = { NULL };
     @@ refs/reftable-backend.c (new)
      +		return refs->err;
      +	}
      +
     -+	mt = reftable_stack_merged_table(refs->stack);
     ++	mt = reftable_stack_merged_table(stack);
      +	err = reftable_merged_table_seek_log(mt, &it, refname);
      +	while (err == 0) {
      +		struct object_id old_oid;
     @@ refs/reftable-backend.c (new)
      +			break;
      +		}
      +
     -+		if (strcmp(log.ref_name, refname)) {
     ++		if (strcmp(log.refname, refname)) {
      +			break;
      +		}
      +
     @@ refs/reftable-backend.c (new)
      +	return err;
      +}
      +
     -+static int
     -+reftable_for_each_reflog_ent_oldest_first(struct ref_store *ref_store,
     -+					  const char *refname,
     -+					  each_reflog_ent_fn fn, void *cb_data)
     ++static int git_reftable_for_each_reflog_ent_oldest_first(
     ++	struct ref_store *ref_store, const char *refname, each_reflog_ent_fn fn,
     ++	void *cb_data)
      +{
      +	struct reftable_iterator it = { NULL };
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
     ++	struct reftable_stack *stack = stack_for(refs, refname);
      +	struct reftable_merged_table *mt = NULL;
      +	struct reftable_log_record *logs = NULL;
      +	int cap = 0;
     @@ refs/reftable-backend.c (new)
      +	if (refs->err < 0) {
      +		return refs->err;
      +	}
     -+	mt = reftable_stack_merged_table(refs->stack);
     ++	mt = reftable_stack_merged_table(stack);
      +	err = reftable_merged_table_seek_log(mt, &it, refname);
      +
      +	while (err == 0) {
     @@ refs/reftable-backend.c (new)
      +			break;
      +		}
      +
     -+		if (strcmp(log.ref_name, refname)) {
     ++		if (strcmp(log.refname, refname)) {
      +			break;
      +		}
      +
     @@ refs/reftable-backend.c (new)
      +	return err;
      +}
      +
     -+static int reftable_reflog_exists(struct ref_store *ref_store,
     -+				  const char *refname)
     ++static int git_reftable_reflog_exists(struct ref_store *ref_store,
     ++				      const char *refname)
      +{
      +	/* always exists. */
      +	return 1;
      +}
      +
     -+static int reftable_create_reflog(struct ref_store *ref_store,
     -+				  const char *refname, int force_create,
     -+				  struct strbuf *err)
     ++static int git_reftable_create_reflog(struct ref_store *ref_store,
     ++				      const char *refname, int force_create,
     ++				      struct strbuf *err)
      +{
      +	return 0;
      +}
      +
     -+static int reftable_delete_reflog(struct ref_store *ref_store,
     -+				  const char *refname)
     ++static int git_reftable_delete_reflog(struct ref_store *ref_store,
     ++				      const char *refname)
      +{
      +	return 0;
      +}
      +
      +struct reflog_expiry_arg {
      +	struct git_reftable_ref_store *refs;
     ++	struct reftable_stack *stack;
      +	struct reftable_log_record *tombstones;
      +	int len;
      +	int cap;
     @@ refs/reftable-backend.c (new)
      +			      const char *refname, uint64_t ts)
      +{
      +	struct reftable_log_record tombstone = {
     -+		.ref_name = xstrdup(refname),
     ++		.refname = xstrdup(refname),
      +		.update_index = ts,
      +	};
      +	if (arg->len == arg->cap) {
     @@ refs/reftable-backend.c (new)
      +static int write_reflog_expiry_table(struct reftable_writer *writer, void *argv)
      +{
      +	struct reflog_expiry_arg *arg = (struct reflog_expiry_arg *)argv;
     -+	uint64_t ts = reftable_stack_next_update_index(arg->refs->stack);
     ++	uint64_t ts = reftable_stack_next_update_index(arg->stack);
      +	int i = 0;
      +	reftable_writer_set_limits(writer, ts, ts);
      +	for (i = 0; i < arg->len; i++) {
     @@ refs/reftable-backend.c (new)
      +	return 0;
      +}
      +
     -+static int reftable_reflog_expire(struct ref_store *ref_store,
     -+				  const char *refname,
     -+				  const struct object_id *oid,
     -+				  unsigned int flags,
     -+				  reflog_expiry_prepare_fn prepare_fn,
     -+				  reflog_expiry_should_prune_fn should_prune_fn,
     -+				  reflog_expiry_cleanup_fn cleanup_fn,
     -+				  void *policy_cb_data)
     ++static int
     ++git_reftable_reflog_expire(struct ref_store *ref_store, const char *refname,
     ++			   const struct object_id *oid, unsigned int flags,
     ++			   reflog_expiry_prepare_fn prepare_fn,
     ++			   reflog_expiry_should_prune_fn should_prune_fn,
     ++			   reflog_expiry_cleanup_fn cleanup_fn,
     ++			   void *policy_cb_data)
      +{
      +	/*
      +	  For log expiry, we write tombstones in place of the expired entries,
     @@ refs/reftable-backend.c (new)
      +	  stack, and expiring entries paradoxically takes extra memory.
      +
      +	  This memory is only reclaimed when some operation issues a
     -+	  reftable_pack_refs(), which will compact the entire stack and get rid
     -+	  of deletion entries.
     ++	  git_reftable_pack_refs(), which will compact the entire stack and get
     ++	  rid of deletion entries.
      +
      +	  It would be better if the refs backend supported an API that sets a
      +	  criterion for all refs, passing the criterion to pack_refs().
      +	*/
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
     ++	struct reftable_stack *stack = stack_for(refs, refname);
      +	struct reftable_merged_table *mt = NULL;
      +	struct reflog_expiry_arg arg = {
     ++		.stack = stack,
      +		.refs = refs,
      +	};
      +	struct reftable_log_record log = { NULL };
     @@ refs/reftable-backend.c (new)
      +	if (refs->err < 0) {
      +		return refs->err;
      +	}
     -+	err = reftable_stack_reload(refs->stack);
     ++	err = reftable_stack_reload(stack);
      +	if (err) {
      +		goto done;
      +	}
      +
     -+	mt = reftable_stack_merged_table(refs->stack);
     ++	mt = reftable_stack_merged_table(stack);
      +	err = reftable_merged_table_seek_log(mt, &it, refname);
      +	if (err < 0) {
      +		goto done;
     @@ refs/reftable-backend.c (new)
      +			goto done;
      +		}
      +
     -+		if (err > 0 || strcmp(log.ref_name, refname)) {
     ++		if (err > 0 || strcmp(log.refname, refname)) {
      +			break;
      +		}
      +		hashcpy(ooid.hash, log.old_hash);
     @@ refs/reftable-backend.c (new)
      +			add_log_tombstone(&arg, refname, log.update_index);
      +		}
      +	}
     -+	err = reftable_stack_add(refs->stack, &write_reflog_expiry_table, &arg);
     ++	err = reftable_stack_add(stack, &write_reflog_expiry_table, &arg);
      +
      +done:
      +	assert(err != REFTABLE_API_ERROR);
     @@ refs/reftable-backend.c (new)
      +	return err;
      +}
      +
     -+static int reftable_read_raw_ref(struct ref_store *ref_store,
     -+				 const char *refname, struct object_id *oid,
     -+				 struct strbuf *referent, unsigned int *type)
     ++static int git_reftable_read_raw_ref(struct ref_store *ref_store,
     ++				     const char *refname, struct object_id *oid,
     ++				     struct strbuf *referent,
     ++				     unsigned int *type)
      +{
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
     ++	struct reftable_stack *stack = stack_for(refs, refname);
     ++
      +	struct reftable_ref_record ref = { NULL };
      +	int err = 0;
      +	if (refs->err < 0) {
     @@ refs/reftable-backend.c (new)
      +	/* This is usually not needed, but Git doesn't signal to ref backend if
      +	   a subprocess updated the ref DB.  So we always check.
      +	*/
     -+	err = reftable_stack_reload(refs->stack);
     ++	err = reftable_stack_reload(stack);
      +	if (err) {
      +		goto done;
      +	}
      +
     -+	err = reftable_stack_read_ref(refs->stack, refname, &ref);
     ++	err = reftable_stack_read_ref(stack, refname, &ref);
      +	if (err > 0) {
      +		errno = ENOENT;
      +		err = -1;
     @@ refs/reftable-backend.c (new)
      +	&refs_be_files,
      +	"reftable",
      +	git_reftable_ref_store_create,
     -+	reftable_init_db,
     -+	reftable_transaction_prepare,
     -+	reftable_transaction_finish,
     -+	reftable_transaction_abort,
     -+	reftable_transaction_initial_commit,
     -+
     -+	reftable_pack_refs,
     -+	reftable_create_symref,
     -+	reftable_delete_refs,
     -+	reftable_rename_ref,
     -+	reftable_copy_ref,
     -+
     -+	reftable_write_pseudoref,
     ++	git_reftable_init_db,
     ++	git_reftable_transaction_prepare,
     ++	git_reftable_transaction_finish,
     ++	git_reftable_transaction_abort,
     ++	git_reftable_transaction_initial_commit,
     ++
     ++	git_reftable_pack_refs,
     ++	git_reftable_create_symref,
     ++	git_reftable_delete_refs,
     ++	git_reftable_rename_ref,
     ++	git_reftable_copy_ref,
     ++
     ++	git_reftable_write_pseudoref,
      +	reftable_delete_pseudoref,
      +
     -+	reftable_ref_iterator_begin,
     -+	reftable_read_raw_ref,
     ++	git_reftable_ref_iterator_begin,
     ++	git_reftable_read_raw_ref,
      +
     -+	reftable_reflog_iterator_begin,
     -+	reftable_for_each_reflog_ent_oldest_first,
     -+	reftable_for_each_reflog_ent_newest_first,
     -+	reftable_reflog_exists,
     -+	reftable_create_reflog,
     -+	reftable_delete_reflog,
     -+	reftable_reflog_expire,
     ++	git_reftable_reflog_iterator_begin,
     ++	git_reftable_for_each_reflog_ent_oldest_first,
     ++	git_reftable_for_each_reflog_ent_newest_first,
     ++	git_reftable_reflog_exists,
     ++	git_reftable_create_reflog,
     ++	git_reftable_delete_reflog,
     ++	git_reftable_reflog_expire,
      +};
      
       ## reftable/update.sh ##
     @@ t/t0031-reftable.sh (new)
      +	test -f file2
      +'
      +
     ++test_expect_success 'worktrees' '
     ++	git init --ref-storage=reftable start &&
     ++	(cd start && test_commit file1 && git checkout -b branch1 &&
     ++	git checkout -b branch2 &&
     ++	git worktree add  ../wt
     ++	) &&
     ++	cd wt &&
     ++	git checkout branch1 &&
     ++	git branch
     ++'
     ++
     ++test_expect_success 'worktrees 2' '
     ++	initialize &&
     ++	test_commit file1 &&
     ++	mkdir existing_empty &&
     ++	git worktree add --detach existing_empty master
     ++'
     ++
      +test_done
      +
 14:  eafd8eeefc = 15:  04c86e7395 Hookup unittests for the reftable library.
 15:  46af142f33 ! 16:  c751265705 Add GIT_DEBUG_REFS debugging mechanism
     @@ Makefile: LIB_OBJS += rebase.o
       LIB_OBJS += refs/reftable-backend.o
       LIB_OBJS += refs/iterator.o
      
     + ## builtin/worktree.c ##
     +@@ builtin/worktree.c: static int add_worktree(const char *path, const char *refname,
     + 	 * worktree.
     + 	 */
     + 	strbuf_reset(&sb);
     +-	if (get_main_ref_store(the_repository)->be == &refs_be_reftable) {
     ++
     ++	/* XXX: check GIT_TEST_REFTABLE because GIT_DEBUG_REFS obscures the
     ++	 * instance type. */
     ++	if (get_main_ref_store(the_repository)->be == &refs_be_reftable ||
     ++	    getenv("GIT_TEST_REFTABLE") != NULL) {
     + 		/* XXX this is cut & paste from reftable_init_db. */
     + 		strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
     + 		write_file(sb.buf, "%s", "ref: refs/heads/.invalid\n");
     +
       ## refs.c ##
      @@ refs.c: struct ref_store *get_main_ref_store(struct repository *r)
     - 						 r->ref_storage_format :
     - 						 default_ref_storage(),
     + 						       r->ref_storage_format :
     + 						       default_ref_storage(),
       					 REF_STORE_ALL_CAPS);
      +	if (getenv("GIT_DEBUG_REFS")) {
     -+		r->refs_private = debug_wrap(r->refs_private);
     ++		r->refs_private = debug_wrap(r->gitdir, r->refs_private);
      +	}
       	return r->refs_private;
       }
     @@ refs/debug.c (new)
      +};
      +
      +extern struct ref_storage_be refs_be_debug;
     -+struct ref_store *debug_wrap(struct ref_store *store);
     ++struct ref_store *debug_wrap(const char *gitdir, struct ref_store *store);
      +
     -+struct ref_store *debug_wrap(struct ref_store *store)
     ++struct ref_store *debug_wrap(const char *gitdir, struct ref_store *store)
      +{
      +	struct debug_ref_store *res = malloc(sizeof(struct debug_ref_store));
     ++	fprintf(stderr, "ref_store for %s\n", gitdir);
      +	res->refs = store;
      +	base_ref_store_init((struct ref_store *)res, &refs_be_debug);
      +	return (struct ref_store *)res;
     @@ refs/debug.c (new)
      +	struct debug_ref_iterator *diter =
      +		(struct debug_ref_iterator *)ref_iterator;
      +	int res = diter->iter->vtable->advance(diter->iter);
     -+	fprintf(stderr, "iterator_advance: %s: %d\n", diter->iter->refname,
     -+		res);
     ++	if (res)
     ++		fprintf(stderr, "iterator_advance: %d\n", res);
     ++	else
     ++		fprintf(stderr, "iterator_advance before: %s\n",
     ++			diter->iter->refname);
     ++
      +	diter->base.ordered = diter->iter->ordered;
      +	diter->base.refname = diter->iter->refname;
      +	diter->base.oid = diter->iter->oid;
     @@ refs/refs-internal.h: struct ref_store {
      + * Print out ref operations as they occur. Useful for debugging alternate ref
      + * backends.
      + */
     -+struct ref_store *debug_wrap(struct ref_store *store);
     ++struct ref_store *debug_wrap(const char *gitdir, struct ref_store *store);
      +
       #endif /* REFS_REFS_INTERNAL_H */
      
 16:  5211c64310 = 17:  ef0dd45f07 vcxproj: adjust for the reftable changes
 17:  9724854088 = 18:  d4dc1deae5 git-prompt: prepare for reftable refs backend
 18:  ece1fa1f62 = 19:  5a85abf9c4 Add reftable testing infrastructure
 19:  991abf9e1b = 20:  0ebf7beb95 Add "test-tool dump-reftable" command.

-- 
gitgitgadget

  parent reply	other threads:[~2020-06-29 21:14 UTC|newest]

Thread overview: 409+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-23 19:41 [PATCH 0/5] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-01-23 19:41 ` [PATCH 1/5] setup.c: enable repo detection for reftable Han-Wen Nienhuys via GitGitGadget
2020-01-23 19:41 ` [PATCH 2/5] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-01-23 19:41 ` [PATCH 3/5] Document how ref iterators and symrefs interact Han-Wen Nienhuys via GitGitGadget
2020-01-23 19:41 ` [PATCH 4/5] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-01-23 19:41 ` [PATCH 5/5] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-01-23 21:44 ` [PATCH 0/5] Reftable support git-core Junio C Hamano
2020-01-27 13:52   ` Han-Wen Nienhuys
2020-01-27 13:57     ` Han-Wen Nienhuys
2020-01-23 22:45 ` Stephan Beyer
2020-01-27 13:57   ` Han-Wen Nienhuys
2020-01-27 14:22 ` [PATCH v2 " Han-Wen Nienhuys via GitGitGadget
2020-01-27 14:22   ` [PATCH v2 1/5] setup.c: enable repo detection for reftable Han-Wen Nienhuys via GitGitGadget
2020-01-27 14:22   ` [PATCH v2 2/5] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-01-27 22:28     ` Junio C Hamano
2020-01-28 15:58       ` Han-Wen Nienhuys
2020-01-30  4:19         ` Junio C Hamano
2020-01-27 14:22   ` [PATCH v2 3/5] Document how ref iterators and symrefs interact Han-Wen Nienhuys via GitGitGadget
2020-01-27 22:53     ` Junio C Hamano
2020-01-28 16:07       ` Han-Wen Nienhuys
2020-01-28 19:35         ` Junio C Hamano
2020-01-27 14:22   ` [PATCH v2 4/5] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-01-27 14:22   ` [PATCH v2 5/5] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-01-28  7:31     ` Jeff King
2020-01-28 15:36       ` Martin Fick
2020-01-29  8:12         ` Jeff King
2020-01-29 16:49           ` Martin Fick
2020-01-29 18:40             ` Han-Wen Nienhuys
2020-01-29 19:47               ` Martin Fick
2020-01-29 19:50                 ` Han-Wen Nienhuys
2020-01-30  7:21                   ` Jeff King
2020-02-03 16:39                     ` Han-Wen Nienhuys
2020-02-03 17:05                       ` Jeff King
2020-02-03 17:09                         ` Han-Wen Nienhuys
2020-02-04 18:54                         ` Han-Wen Nienhuys
2020-02-04 20:06                           ` Jeff King
2020-02-04 20:26                             ` Han-Wen Nienhuys
2020-01-29 18:34           ` Junio C Hamano
2020-01-28 15:56       ` Han-Wen Nienhuys
2020-01-29 10:47         ` Jeff King
2020-01-29 18:43           ` Junio C Hamano
2020-01-29 18:53             ` Han-Wen Nienhuys
2020-01-30  7:26             ` Jeff King
2020-02-04 19:06           ` Han-Wen Nienhuys
2020-02-04 19:54             ` Jeff King
2020-02-04 20:22       ` Han-Wen Nienhuys
2020-02-04 22:13         ` Jeff King
2020-02-04 20:27   ` [PATCH v3 0/6] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-02-04 20:27     ` [PATCH v3 1/6] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-02-04 20:27     ` [PATCH v3 2/6] setup.c: enable repo detection for reftable Han-Wen Nienhuys via GitGitGadget
2020-02-04 20:31       ` Han-Wen Nienhuys
2020-02-04 20:27     ` [PATCH v3 3/6] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-02-04 21:29       ` Junio C Hamano
2020-02-05 11:34         ` Han-Wen Nienhuys
2020-02-05 11:42       ` SZEDER Gábor
2020-02-05 12:24         ` Jeff King
2020-02-04 20:27     ` [PATCH v3 4/6] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-02-04 20:27     ` [PATCH v3 5/6] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-02-04 20:27     ` [PATCH v3 6/6] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-02-06 22:55     ` [PATCH v4 0/5] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-02-06 22:55       ` [PATCH v4 1/5] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-02-06 22:55       ` [PATCH v4 2/5] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-02-06 22:55       ` [PATCH v4 3/5] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-02-06 22:55       ` [PATCH v4 4/5] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-02-06 23:07         ` Junio C Hamano
2020-02-07  0:16         ` brian m. carlson
2020-02-10 13:16           ` Han-Wen Nienhuys
2020-02-11  0:05             ` brian m. carlson
2020-02-11 14:20               ` Han-Wen Nienhuys
2020-02-11 16:31                 ` Junio C Hamano
2020-02-11 16:40                   ` Han-Wen Nienhuys
2020-02-11 23:40                     ` brian m. carlson
2020-02-18  9:25                       ` Han-Wen Nienhuys
2020-02-11 16:46                   ` Han-Wen Nienhuys
2020-02-20 17:20                     ` Jonathan Nieder
2020-02-06 22:55       ` [PATCH v4 5/5] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-02-06 23:49         ` brian m. carlson
2020-02-10 13:18           ` Han-Wen Nienhuys
2020-02-06 23:31       ` [PATCH v4 0/5] Reftable support git-core brian m. carlson
2020-02-10 14:14       ` [PATCH v5 " Han-Wen Nienhuys via GitGitGadget
2020-02-10 14:14         ` [PATCH v5 1/5] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-02-10 14:14         ` [PATCH v5 2/5] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-02-10 14:14         ` [PATCH v5 3/5] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-02-10 14:14         ` [PATCH v5 4/5] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-02-10 14:14         ` [PATCH v5 5/5] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-02-18  8:43         ` [PATCH v6 0/5] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-02-18  8:43           ` [PATCH v6 1/5] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-02-18  8:43           ` [PATCH v6 2/5] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-02-18  8:43           ` [PATCH v6 3/5] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-02-18  8:43           ` [PATCH v6 4/5] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-02-18 21:11             ` Junio C Hamano
2020-02-19  6:55               ` Jeff King
2020-02-19 17:00                 ` Han-Wen Nienhuys
2020-02-18  8:43           ` [PATCH v6 5/5] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-02-18 21:05           ` [PATCH v6 0/5] Reftable support git-core Junio C Hamano
2020-02-19 16:59             ` Han-Wen Nienhuys
2020-02-19 17:02               ` Junio C Hamano
2020-02-19 17:21                 ` Han-Wen Nienhuys
2020-02-19 18:10                   ` Junio C Hamano
2020-02-19 19:14                     ` Han-Wen Nienhuys
2020-02-19 20:09                       ` Junio C Hamano
2020-02-20 11:19                     ` Jeff King
2020-02-21  6:40           ` Jonathan Nieder
2020-02-26 17:16             ` Han-Wen Nienhuys
2020-02-26 20:04               ` Junio C Hamano
2020-02-27  0:01               ` brian m. carlson
     [not found]             ` <CAFQ2z_NQn9O3kFmHk8Cr31FY66ToU4bUdE=asHUfN++zBG+SPw@mail.gmail.com>
2020-02-26 17:41               ` Jonathan Nieder
2020-02-26 17:54                 ` Han-Wen Nienhuys
2020-02-26  8:49           ` [PATCH v7 0/6] " Han-Wen Nienhuys via GitGitGadget
2020-02-26  8:49             ` [PATCH v7 1/6] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-02-26  8:49             ` [PATCH v7 2/6] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-02-26  8:49             ` [PATCH v7 3/6] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-02-26  8:49             ` [PATCH v7 4/6] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-02-26  8:49             ` [PATCH v7 5/6] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-02-26  8:49             ` [PATCH v7 6/6] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-02-26 18:12               ` Junio C Hamano
2020-02-26 18:59                 ` Han-Wen Nienhuys
2020-02-26 19:59                   ` Junio C Hamano
2020-02-27 16:03                     ` Han-Wen Nienhuys
2020-02-27 16:23                       ` Junio C Hamano
2020-02-27 17:56                         ` Han-Wen Nienhuys
2020-02-26 21:31               ` Junio C Hamano
2020-02-27 16:01                 ` Han-Wen Nienhuys
2020-02-27 16:26                   ` Junio C Hamano
2020-02-26 17:35             ` [PATCH v7 0/6] Reftable support git-core Junio C Hamano
2020-03-24  6:06             ` Jonathan Nieder
2020-04-01 11:28             ` [PATCH v8 0/9] " Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28               ` [PATCH v8 1/9] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28               ` [PATCH v8 2/9] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28               ` [PATCH v8 3/9] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28               ` [PATCH v8 4/9] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28               ` [PATCH v8 5/9] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-04-01 11:28               ` [PATCH v8 6/9] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28               ` [PATCH v8 7/9] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28               ` [PATCH v8 8/9] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28               ` [PATCH v8 9/9] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-04-15 23:29               ` [PATCH v8 0/9] Reftable support git-core Junio C Hamano
2020-04-18  3:22                 ` Danh Doan
2020-04-20 21:14               ` [PATCH v9 00/10] " Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14                 ` [PATCH v9 01/10] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14                 ` [PATCH v9 02/10] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14                 ` [PATCH v9 03/10] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14                 ` [PATCH v9 04/10] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14                 ` [PATCH v9 05/10] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14                 ` [PATCH v9 06/10] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-04-20 21:14                 ` [PATCH v9 07/10] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14                 ` [PATCH v9 08/10] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14                 ` [PATCH v9 09/10] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-04-20 22:06                   ` Junio C Hamano
2020-04-21 19:04                     ` Han-Wen Nienhuys
2020-04-22 17:35                     ` Johannes Schindelin
2020-04-20 21:14                 ` [PATCH v9 10/10] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-04-21 20:13                 ` [PATCH v9 00/10] Reftable support git-core Junio C Hamano
2020-04-23 21:27                   ` Han-Wen Nienhuys
2020-04-23 21:43                     ` Junio C Hamano
2020-04-23 21:52                       ` Junio C Hamano
2020-04-25 13:58                         ` Johannes Schindelin
2020-04-27 20:13                 ` [PATCH v10 00/12] " Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 01/12] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 02/12] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-04-30 21:17                     ` Emily Shaffer
2020-05-04 18:03                       ` Han-Wen Nienhuys
2020-05-05 18:26                         ` Pseudo ref handling (was Re: [PATCH v10 02/12] Iterate over the "refs/" namespace in for_each_[raw]ref) Han-Wen Nienhuys
2020-04-27 20:13                   ` [PATCH v10 03/12] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-04-30 21:24                     ` Emily Shaffer
2020-04-30 21:49                       ` Junio C Hamano
2020-05-04 18:10                       ` Han-Wen Nienhuys
2020-04-27 20:13                   ` [PATCH v10 04/12] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 05/12] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 06/12] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 07/12] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 08/12] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 09/12] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-04-28 14:55                     ` Danh Doan
2020-04-28 15:29                       ` Junio C Hamano
2020-04-28 15:31                         ` Junio C Hamano
2020-04-28 20:21                       ` Han-Wen Nienhuys
2020-04-28 20:23                         ` Han-Wen Nienhuys
2020-04-27 20:13                   ` [PATCH v10 10/12] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 11/12] Add some reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 12/12] t: use update-ref and show-ref to reading/writing refs Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                   ` [PATCH v11 00/12] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 01/12] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 02/12] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 03/12] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 04/12] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 05/12] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 06/12] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 07/12] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 08/12] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 09/12] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 10/12] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 11/12] Add some reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 12/12] t: use update-ref and show-ref to reading/writing refs Han-Wen Nienhuys via GitGitGadget
2020-05-06  4:29                     ` [PATCH v11 00/12] Reftable support git-core Junio C Hamano
2020-05-07  9:59                     ` [PATCH v12 " Han-Wen Nienhuys via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 01/12] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-05-08 18:54                         ` Junio C Hamano
2020-05-07  9:59                       ` [PATCH v12 02/12] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-08 18:54                         ` Junio C Hamano
2020-05-11 11:41                           ` Han-Wen Nienhuys
2020-05-07  9:59                       ` [PATCH v12 03/12] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-05-08 18:58                         ` Junio C Hamano
2020-05-11 11:42                           ` Han-Wen Nienhuys
2020-05-11 14:49                             ` Junio C Hamano
2020-05-11 15:11                               ` Han-Wen Nienhuys
2020-05-07  9:59                       ` [PATCH v12 04/12] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 05/12] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 06/12] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-05-08 19:59                         ` Junio C Hamano
2020-05-07  9:59                       ` [PATCH v12 07/12] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 08/12] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 09/12] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 10/12] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 11/12] t: use update-ref and show-ref to reading/writing refs Han-Wen Nienhuys via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 12/12] Add some reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46                       ` [PATCH v13 00/13] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46                         ` [PATCH v13 01/13] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-05-18 23:31                           ` Junio C Hamano
2020-05-11 19:46                         ` [PATCH v13 02/13] t: use update-ref and show-ref to reading/writing refs Han-Wen Nienhuys via GitGitGadget
2020-05-18 23:34                           ` Junio C Hamano
2020-05-11 19:46                         ` [PATCH v13 03/13] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-05-18 23:43                           ` Junio C Hamano
2020-05-11 19:46                         ` [PATCH v13 04/13] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-05-19 22:00                           ` Junio C Hamano
2020-05-20 16:06                             ` Han-Wen Nienhuys
2020-05-20 17:20                               ` Han-Wen Nienhuys
2020-05-20 17:25                                 ` Han-Wen Nienhuys
2020-05-20 17:33                                   ` Junio C Hamano
2020-05-20 18:52                             ` Jonathan Nieder
2020-05-11 19:46                         ` [PATCH v13 05/13] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-05-19 22:01                           ` Junio C Hamano
2020-05-11 19:46                         ` [PATCH v13 06/13] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-05-19 22:32                           ` Junio C Hamano
2020-05-20 12:38                             ` Han-Wen Nienhuys
2020-05-20 14:40                               ` Junio C Hamano
2020-05-11 19:46                         ` [PATCH v13 07/13] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-05-12 10:22                           ` Phillip Wood
2020-05-12 16:48                             ` Han-Wen Nienhuys
2020-05-13 10:06                               ` Phillip Wood
2020-05-13 18:10                                 ` Phillip Wood
2020-05-11 19:46                         ` [PATCH v13 08/13] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46                         ` [PATCH v13 09/13] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46                         ` [PATCH v13 10/13] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46                         ` [PATCH v13 11/13] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-13 19:55                           ` Junio C Hamano
2020-05-11 19:46                         ` [PATCH v13 12/13] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-11 19:46                         ` [PATCH v13 13/13] Add some reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-13 19:57                           ` Junio C Hamano
2020-05-19 13:54                             ` Han-Wen Nienhuys
2020-05-19 15:21                               ` Junio C Hamano
2020-05-12  0:41                         ` [PATCH v13 00/13] Reftable support git-core Junio C Hamano
2020-05-12  7:49                           ` Han-Wen Nienhuys
2020-05-13 21:21                             ` Junio C Hamano
2020-05-18 20:31                         ` [PATCH v14 0/9] " Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 1/9] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 2/9] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 3/9] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 4/9] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 5/9] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 6/9] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 7/9] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 8/9] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 9/9] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                           ` [PATCH v15 00/13] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 01/13] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 02/13] Make refs_ref_exists public Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 03/13] Treat BISECT_HEAD as a pseudo ref Han-Wen Nienhuys via GitGitGadget
2020-05-28 20:52                               ` Junio C Hamano
2020-05-28 19:46                             ` [PATCH v15 04/13] Treat CHERRY_PICK_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 05/13] Treat REVERT_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 06/13] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 07/13] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 08/13] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 09/13] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 10/13] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 11/13] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 12/13] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 13/13] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-28 20:15                             ` [PATCH v15 00/13] Reftable support git-core Junio C Hamano
2020-05-28 21:21                             ` Junio C Hamano
2020-06-05 18:03                             ` [PATCH v16 00/14] " Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 01/14] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-06-09 10:16                                 ` Phillip Wood
2020-06-05 18:03                               ` [PATCH v16 02/14] Make refs_ref_exists public Han-Wen Nienhuys via GitGitGadget
2020-06-09 10:36                                 ` Phillip Wood
2020-06-10 18:05                                   ` Han-Wen Nienhuys
2020-06-11 14:59                                     ` Phillip Wood
2020-06-12  9:51                                       ` Phillip Wood
2020-06-15 11:32                                         ` Han-Wen Nienhuys
2020-06-05 18:03                               ` [PATCH v16 03/14] Treat BISECT_HEAD as a pseudo ref Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 04/14] Treat CHERRY_PICK_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 05/14] Treat REVERT_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 06/14] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 07/14] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 08/14] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 09/14] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 10/14] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 11/14] Hookup unittests for the reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-08 19:39                                 ` Junio C Hamano
2020-06-09 17:22                                   ` [PATCH] Fixup! Add t/helper/test-reftable.c hanwen
2020-06-09 20:45                                     ` Junio C Hamano
2020-06-05 18:03                               ` [PATCH v16 12/14] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 13/14] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 14/14] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-06-09 23:14                               ` [PATCH v16 00/14] Reftable support git-core Junio C Hamano
2020-06-10  6:56                                 ` Han-Wen Nienhuys
2020-06-10 17:09                                   ` Junio C Hamano
2020-06-10 17:38                                     ` Junio C Hamano
2020-06-10 18:59                                     ` Johannes Schindelin
2020-06-10 19:04                                       ` Han-Wen Nienhuys
2020-06-10 19:20                                         ` Johannes Schindelin
2020-06-10 16:57                                 ` Han-Wen Nienhuys
2020-06-16 19:20                               ` [PATCH v17 00/17] " Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 01/17] lib-t6000.sh: write tag using git-update-ref Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 02/17] checkout: add '\n' to reflog message Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 03/17] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 04/17] Make refs_ref_exists public Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 05/17] Treat BISECT_HEAD as a pseudo ref Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 06/17] Treat CHERRY_PICK_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 07/17] Treat REVERT_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 08/17] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 09/17] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 10/17] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 11/17] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 12/17] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-06-19 14:24                                   ` SZEDER Gábor
2020-06-16 19:20                                 ` [PATCH v17 13/17] Hookup unittests for the reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 14/17] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 15/17] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 16/17] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-06-19 16:03                                   ` SZEDER Gábor
2020-06-16 19:20                                 ` [PATCH v17 17/17] Add "test-tool dump-reftable" command Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                 ` [PATCH v18 00/19] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 01/19] lib-t6000.sh: write tag using git-update-ref Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 02/19] checkout: add '\n' to reflog message Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 03/19] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 04/19] Make refs_ref_exists public Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 05/19] Treat BISECT_HEAD as a pseudo ref Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 06/19] Treat CHERRY_PICK_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 07/19] Treat REVERT_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 08/19] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 09/19] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 10/19] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 11/19] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 12/19] Add standalone build infrastructure for reftable Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 13/19] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 14/19] Hookup unittests for the reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 15/19] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 16/19] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 17/19] git-prompt: prepare for reftable refs backend SZEDER Gábor via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 18/19] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 19/19] Add "test-tool dump-reftable" command Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                   ` Han-Wen Nienhuys via GitGitGadget [this message]
2020-06-29 18:56                                     ` [PATCH v19 01/20] lib-t6000.sh: write tag using git-update-ref Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 02/20] t3432: use git-reflog to inspect the reflog for HEAD Han-Wen Nienhuys via GitGitGadget
2020-06-30 15:23                                       ` Denton Liu
2020-06-29 18:56                                     ` [PATCH v19 03/20] checkout: add '\n' to reflog message Han-Wen Nienhuys via GitGitGadget
2020-06-29 20:07                                       ` Junio C Hamano
2020-06-30  8:30                                         ` Han-Wen Nienhuys
2020-06-30 23:58                                           ` Junio C Hamano
2020-07-01 16:56                                             ` Han-Wen Nienhuys
2020-07-01 20:22                                               ` Re* " Junio C Hamano
2020-07-06 15:56                                                 ` Han-Wen Nienhuys
2020-07-06 18:53                                                   ` Junio C Hamano
2020-06-29 18:56                                     ` [PATCH v19 04/20] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 05/20] Make refs_ref_exists public Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 06/20] Treat BISECT_HEAD as a pseudo ref Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 07/20] Treat CHERRY_PICK_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 08/20] Treat REVERT_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 09/20] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 10/20] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 11/20] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 12/20] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 13/20] Add standalone build infrastructure for reftable Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 14/20] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 15/20] Hookup unittests for the reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 16/20] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 17/20] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 18/20] git-prompt: prepare for reftable refs backend SZEDER Gábor via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 19/20] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                     ` [PATCH v19 20/20] Add "test-tool dump-reftable" command Han-Wen Nienhuys via GitGitGadget
2020-06-29 22:54                                     ` [PATCH v19 00/20] Reftable support git-core Junio C Hamano
2020-06-30  9:28                                       ` Han-Wen Nienhuys
2020-07-01  0:03                                         ` Junio C Hamano
2020-07-01 10:16                                           ` Han-Wen Nienhuys
2020-07-01 20:56                                             ` Junio C Hamano
2020-07-31 15:26                                     ` [PATCH v20 00/21] " Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:26                                       ` [PATCH v20 01/21] refs: add \t to reflog in the files backend Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:26                                       ` [PATCH v20 02/21] Split off reading loose ref data in separate function Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:26                                       ` [PATCH v20 03/21] t1400: use git rev-parse for testing PSEUDOREF existence Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 04/21] Modify pseudo refs through ref backend storage Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 05/21] Make HEAD a PSEUDOREF rather than PER_WORKTREE Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 06/21] Make refs_ref_exists public Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 07/21] Treat CHERRY_PICK_HEAD as a pseudo ref Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 08/21] Treat REVERT_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 09/21] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 10/21] Iteration over entire ref namespace is iterating over "refs/" Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 11/21] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 12/21] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 13/21] Add standalone build infrastructure for reftable Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 14/21] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 15/21] Read FETCH_HEAD as loose ref Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 16/21] Hookup unittests for the reftable library Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 17/21] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 18/21] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 19/21] git-prompt: prepare for reftable refs backend SZEDER Gábor via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 20/21] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-07-31 15:27                                       ` [PATCH v20 21/21] Add "test-tool dump-reftable" command Han-Wen Nienhuys via GitGitGadget

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=pull.539.v19.git.1593457018.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=hanwenn@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.