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 v15 00/13] Reftable support git-core
Date: Thu, 28 May 2020 19:46:36 +0000	[thread overview]
Message-ID: <pull.539.v15.git.1590695209.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.539.v14.git.1589833884.gitgitgadget@gmail.com>

This adds the reftable library, and hooks it up as a ref backend. Based on
hn/refs-cleanup.

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

Summary 20479 tests pass 1299 tests fail

Some issues:

 * many tests inspect .git/{logs,heads}/ directly.
 * worktrees broken. 
 * Rebase/cherry-pick still largely broken

v17

 * many style tweaks in reftable/
 * fix rebase
 * GIT_DEBUG_REFS support.

v18

 * fix pseudo ref usage

Han-Wen Nienhuys (12):
  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
  Reftable support for git-core
  Add GIT_DEBUG_REFS debugging mechanism
  Add reftable testing infrastructure

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

 .../technical/repository-version.txt          |    7 +
 Makefile                                      |   28 +-
 builtin/bisect--helper.c                      |    3 +-
 builtin/clone.c                               |    3 +-
 builtin/commit.c                              |   34 +-
 builtin/init-db.c                             |   56 +-
 builtin/merge.c                               |    2 +-
 cache.h                                       |    6 +-
 config.mak.uname                              |    2 +-
 contrib/buildsystems/Generators/Vcxproj.pm    |   11 +-
 git-bisect.sh                                 |    4 +-
 path.c                                        |    2 -
 path.h                                        |    9 +-
 refs.c                                        |  157 +-
 refs.h                                        |   16 +
 refs/debug.c                                  |  309 ++++
 refs/files-backend.c                          |  121 +-
 refs/packed-backend.c                         |   21 +-
 refs/refs-internal.h                          |   26 +
 refs/reftable-backend.c                       | 1332 +++++++++++++++++
 reftable/.gitattributes                       |    1 +
 reftable/LICENSE                              |   31 +
 reftable/README.md                            |   11 +
 reftable/VERSION                              |    8 +
 reftable/basics.c                             |  215 +++
 reftable/basics.h                             |   53 +
 reftable/block.c                              |  433 ++++++
 reftable/block.h                              |  129 ++
 reftable/constants.h                          |   21 +
 reftable/file.c                               |   95 ++
 reftable/iter.c                               |  243 +++
 reftable/iter.h                               |   72 +
 reftable/merged.c                             |  320 ++++
 reftable/merged.h                             |   39 +
 reftable/pq.c                                 |  113 ++
 reftable/pq.h                                 |   34 +
 reftable/reader.c                             |  742 +++++++++
 reftable/reader.h                             |   65 +
 reftable/record.c                             | 1113 ++++++++++++++
 reftable/record.h                             |  128 ++
 reftable/refname.c                            |  209 +++
 reftable/refname.h                            |   38 +
 reftable/reftable.c                           |   90 ++
 reftable/reftable.h                           |  564 +++++++
 reftable/slice.c                              |  247 +++
 reftable/slice.h                              |   87 ++
 reftable/stack.c                              | 1207 +++++++++++++++
 reftable/stack.h                              |   48 +
 reftable/system.h                             |   54 +
 reftable/tree.c                               |   63 +
 reftable/tree.h                               |   34 +
 reftable/update.sh                            |   24 +
 reftable/writer.c                             |  644 ++++++++
 reftable/writer.h                             |   60 +
 reftable/zlib-compat.c                        |   92 ++
 repository.c                                  |    2 +
 repository.h                                  |    3 +
 sequencer.c                                   |   56 +-
 setup.c                                       |   12 +-
 t/t0031-reftable.sh                           |  142 ++
 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/t9903-bash-prompt.sh                        |    6 +
 t/test-lib.sh                                 |    5 +
 wt-status.c                                   |    6 +-
 67 files changed, 9550 insertions(+), 194 deletions(-)
 create mode 100644 refs/debug.c
 create mode 100644 refs/reftable-backend.c
 create mode 100644 reftable/.gitattributes
 create mode 100644 reftable/LICENSE
 create mode 100644 reftable/README.md
 create mode 100644 reftable/VERSION
 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/constants.h
 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/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/refname.c
 create mode 100644 reftable/refname.h
 create mode 100644 reftable/reftable.c
 create mode 100644 reftable/reftable.h
 create mode 100644 reftable/slice.c
 create mode 100644 reftable/slice.h
 create mode 100644 reftable/stack.c
 create mode 100644 reftable/stack.h
 create mode 100644 reftable/system.h
 create mode 100644 reftable/tree.c
 create mode 100644 reftable/tree.h
 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 100755 t/t0031-reftable.sh
 create mode 100755 t/t0033-debug-refs.sh


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

Range-diff vs v14:

  1:  46d04f6740e !  1:  9bb64f748dc Write pseudorefs through ref backends.
     @@ Commit message
          CHERRY_PICK_HEAD, etc.
      
          These refs have always been read through the ref backends, but they were written
     -    in a one-off routine that wrote a object ID or symref directly wrote into
     +    in a one-off routine that wrote an object ID or symref directly into
          .git/<pseudo_ref_name>.
      
          This causes problems when introducing a new ref storage backend. To remedy this,
     @@ Commit message
          Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
      
       ## refs.c ##
     +@@ refs.c: int ref_exists(const char *refname)
     + 	return refs_ref_exists(get_main_ref_store(the_repository), refname);
     + }
     + 
     ++int delete_pseudoref(const char *pseudoref, const struct object_id *old_oid)
     ++{
     ++	return refs_delete_pseudoref(get_main_ref_store(the_repository),
     ++				     pseudoref, old_oid);
     ++}
     ++
     + static int filter_refs(const char *refname, const struct object_id *oid,
     + 			   int flags, void *data)
     + {
      @@ refs.c: long get_files_ref_lock_timeout_ms(void)
       	return timeout_ms;
       }
     @@ refs.c: int refs_delete_ref(struct ref_store *refs, const char *msg,
       	if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
       		assert(refs == get_main_ref_store(the_repository));
      -		return delete_pseudoref(refname, old_oid);
     -+		return ref_store_delete_pseudoref(refs, refname, old_oid);
     ++		return refs_delete_pseudoref(refs, refname, old_oid);
       	}
       
       	transaction = ref_store_transaction_begin(refs, &err);
     @@ refs.c: int refs_update_ref(struct ref_store *refs, const char *msg,
       	if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
       		assert(refs == get_main_ref_store(the_repository));
      -		ret = write_pseudoref(refname, new_oid, old_oid, &err);
     -+		ret = ref_store_write_pseudoref(refs, refname, new_oid, old_oid,
     -+						&err);
     ++		ret = refs_write_pseudoref(refs, refname, new_oid, old_oid,
     ++					   &err);
       	} else {
       		t = ref_store_transaction_begin(refs, &err);
       		if (!t ||
     @@ refs.c: int head_ref(each_ref_fn fn, void *cb_data)
       	return refs_head_ref(get_main_ref_store(the_repository), fn, cb_data);
       }
       
     -+int ref_store_write_pseudoref(struct ref_store *refs, const char *pseudoref,
     -+			      const struct object_id *oid,
     -+			      const struct object_id *old_oid,
     -+			      struct strbuf *err)
     ++int refs_write_pseudoref(struct ref_store *refs, const char *pseudoref,
     ++			 const struct object_id *oid,
     ++			 const struct object_id *old_oid, struct strbuf *err)
      +{
      +	return refs->be->write_pseudoref(refs, pseudoref, oid, old_oid, err);
      +}
      +
     -+int ref_store_delete_pseudoref(struct ref_store *refs, const char *pseudoref,
     -+			       const struct object_id *old_oid)
     ++int refs_delete_pseudoref(struct ref_store *refs, const char *pseudoref,
     ++			  const struct object_id *old_oid)
      +{
      +	return refs->be->delete_pseudoref(refs, pseudoref, old_oid);
      +}
     @@ refs.h: int update_ref(const char *msg, const char *refname,
      +   and deletion as they cannot take part in normal transactional updates.
      +   Pseudorefs should only be written for the main repository.
      +*/
     -+int ref_store_write_pseudoref(struct ref_store *refs, const char *pseudoref,
     -+			      const struct object_id *oid,
     -+			      const struct object_id *old_oid,
     -+			      struct strbuf *err);
     -+int ref_store_delete_pseudoref(struct ref_store *refs, const char *pseudoref,
     -+			       const struct object_id *old_oid);
     ++int refs_write_pseudoref(struct ref_store *refs, const char *pseudoref,
     ++			 const struct object_id *oid,
     ++			 const struct object_id *old_oid, struct strbuf *err);
     ++int refs_delete_pseudoref(struct ref_store *refs, const char *pseudoref,
     ++			  const struct object_id *old_oid);
     ++int delete_pseudoref(const char *pseudoref, const struct object_id *old_oid);
      +
       int parse_hide_refs_config(const char *var, const char *value, const char *);
       
  -:  ----------- >  2:  d489806907b Make refs_ref_exists public
  -:  ----------- >  3:  60a82678a1b Treat BISECT_HEAD as a pseudo ref
  -:  ----------- >  4:  1a925f5671a Treat CHERRY_PICK_HEAD as a pseudo ref
  -:  ----------- >  5:  8f2ebf65b90 Treat REVERT_HEAD as a pseudo ref
  2:  c650f7e4345 =  6:  e0e1e3a558d Move REF_LOG_ONLY to refs-internal.h
  3:  0c953fce52a =  7:  27a980d1d9d Iterate over the "refs/" namespace in for_each_[raw]ref
  4:  206b7d329f8 =  8:  dcbd000e7f7 Add .gitattributes for the reftable/ directory
  5:  9a8e504a1d0 !  9:  718b646a54e Add reftable library
     @@ reftable/README.md (new)
      
       ## reftable/VERSION (new) ##
      @@
     -+commit bad78b6de70700933a2f93ebadaa37a5e852d9ea
     ++commit fe15c65dd95b6a13de92b4baf711e50338ef20ae
      +Author: Han-Wen Nienhuys <hanwen@google.com>
     -+Date:   Mon May 18 20:12:57 2020 +0200
     ++Date:   Thu May 28 19:28:24 2020 +0200
      +
     -+    C: get rid of inner blocks for local scoping
     ++    C: add 'canary' to struct slice
     ++    
     ++    This enforces that all slices are initialized explicitly with
     ++    SLICE_INIT, for future compatibility with git's strbuf.
      
       ## reftable/basics.c (new) ##
      @@
     @@ reftable/block.c (new)
      +	bw->entries = 0;
      +	bw->restart_len = 0;
      +	bw->last_key.len = 0;
     ++	bw->last_key.canary = SLICE_CANARY;
      +}
      +
      +byte block_writer_type(struct block_writer *bw)
     @@ reftable/block.c (new)
      +   success */
      +int block_writer_add(struct block_writer *w, struct reftable_record *rec)
      +{
     -+	struct slice empty = { 0 };
     ++	struct slice empty = SLICE_INIT;
      +	struct slice last = w->entries % w->restart_interval == 0 ? empty :
      +								    w->last_key;
      +	struct slice out = {
      +		.buf = w->buf + w->next,
      +		.len = w->block_size - w->next,
     ++		.canary = SLICE_CANARY,
      +	};
      +
      +	struct slice start = out;
      +
      +	bool restart = false;
     -+	struct slice key = { 0 };
     ++	struct slice key = SLICE_INIT;
      +	int n = 0;
      +
      +	reftable_record_key(rec, &key);
      +	n = reftable_encode_key(&restart, out, last, key,
      +				reftable_record_val_type(rec));
     -+	if (n < 0) {
     -+		goto err;
     -+	}
     ++	if (n < 0)
     ++		goto done;
      +	slice_consume(&out, n);
      +
      +	n = reftable_record_encode(rec, out, w->hash_size);
     -+	if (n < 0) {
     -+		goto err;
     -+	}
     ++	if (n < 0)
     ++		goto done;
      +	slice_consume(&out, n);
      +
      +	if (block_writer_register_restart(w, start.len - out.len, restart,
     -+					  key) < 0) {
     -+		goto err;
     -+	}
     ++					  key) < 0)
     ++		goto done;
      +
      +	slice_release(&key);
      +	return 0;
      +
     -+err:
     ++done:
      +	slice_release(&key);
      +	return -1;
      +}
     @@ reftable/block.c (new)
      +	if (restart) {
      +		rlen++;
      +	}
     -+	if (2 + 3 * rlen + n > w->block_size - w->next) {
     ++	if (2 + 3 * rlen + n > w->block_size - w->next)
      +		return -1;
     -+	}
      +	if (restart) {
      +		if (w->restart_len == w->restart_cap) {
      +			w->restart_cap = w->restart_cap * 2 + 1;
     @@ reftable/block.c (new)
      +	}
      +
      +	w->next += n;
     ++
      +	slice_copy(&w->last_key, key);
      +	w->entries++;
      +	return 0;
     @@ reftable/block.c (new)
      +
      +	if (block_writer_type(w) == BLOCK_TYPE_LOG) {
      +		int block_header_skip = 4 + w->header_off;
     -+		struct slice compressed = { 0 };
     ++		struct slice compressed = SLICE_INIT;
      +		int zresult = 0;
      +		uLongf src_len = w->next - block_header_skip;
      +		slice_resize(&compressed, src_len);
     @@ reftable/block.c (new)
      +	byte typ = block->data[header_off];
      +	uint32_t sz = get_be24(block->data + header_off + 1);
      +
     -+	if (!reftable_is_block_type(typ)) {
     ++	uint16_t restart_count = 0;
     ++	uint32_t restart_start = 0;
     ++	byte *restart_bytes = NULL;
     ++
     ++	if (!reftable_is_block_type(typ))
      +		return REFTABLE_FORMAT_ERROR;
     -+	}
      +
      +	if (typ == BLOCK_TYPE_LOG) {
     -+		struct slice uncompressed = { 0 };
     ++		struct slice uncompressed = SLICE_INIT;
      +		int block_header_skip = 4 + header_off;
      +		uLongf dst_len = sz - block_header_skip; /* total size of dest
      +							    buffer. */
     @@ reftable/block.c (new)
      +			return REFTABLE_ZLIB_ERROR;
      +		}
      +
     -+		if (dst_len + block_header_skip != sz) {
     ++		if (dst_len + block_header_skip != sz)
      +			return REFTABLE_FORMAT_ERROR;
     -+		}
      +
      +		/* We're done with the input data. */
      +		reftable_block_done(block);
     @@ reftable/block.c (new)
      +		full_block_size = sz;
      +	}
      +
     -+	{
     -+		uint16_t restart_count = get_be16(block->data + sz - 2);
     -+		uint32_t restart_start = sz - 2 - 3 * restart_count;
     ++	restart_count = get_be16(block->data + sz - 2);
     ++	restart_start = sz - 2 - 3 * restart_count;
     ++	restart_bytes = block->data + restart_start;
      +
     -+		byte *restart_bytes = block->data + restart_start;
     ++	/* transfer ownership. */
     ++	br->block = *block;
     ++	block->data = NULL;
     ++	block->len = 0;
      +
     -+		/* transfer ownership. */
     -+		br->block = *block;
     -+		block->data = NULL;
     -+		block->len = 0;
     -+
     -+		br->hash_size = hash_size;
     -+		br->block_len = restart_start;
     -+		br->full_block_size = full_block_size;
     -+		br->header_off = header_off;
     -+		br->restart_count = restart_count;
     -+		br->restart_bytes = restart_bytes;
     -+	}
     ++	br->hash_size = hash_size;
     ++	br->block_len = restart_start;
     ++	br->full_block_size = full_block_size;
     ++	br->header_off = header_off;
     ++	br->restart_count = restart_count;
     ++	br->restart_bytes = restart_bytes;
      +
      +	return 0;
      +}
     @@ reftable/block.c (new)
      +	struct slice in = {
      +		.buf = a->r->block.data + off,
      +		.len = a->r->block_len - off,
     ++		.canary = SLICE_CANARY,
      +	};
      +
      +	/* the restart key is verbatim in the block, so this could avoid the
      +	   alloc for decoding the key */
     -+	struct slice rkey = { 0 };
     -+	struct slice last_key = { 0 };
     ++	struct slice rkey = SLICE_INIT;
     ++	struct slice last_key = SLICE_INIT;
      +	byte unused_extra;
      +	int n = reftable_decode_key(&rkey, &unused_extra, last_key, in);
     ++	int result;
      +	if (n < 0) {
      +		a->error = 1;
      +		return -1;
      +	}
      +
     -+	{
     -+		int result = slice_cmp(a->key, rkey);
     -+		slice_release(&rkey);
     -+		return result;
     -+	}
     ++	result = slice_cmp(a->key, rkey);
     ++	slice_release(&rkey);
     ++	return result;
      +}
      +
      +void block_iter_copy_from(struct block_iter *dest, struct block_iter *src)
     @@ reftable/block.c (new)
      +	struct slice in = {
      +		.buf = it->br->block.data + it->next_off,
      +		.len = it->br->block_len - it->next_off,
     ++		.canary = SLICE_CANARY,
      +	};
      +	struct slice start = in;
     -+	struct slice key = { 0 };
     ++	struct slice key = SLICE_INIT;
      +	byte extra = 0;
      +	int n = 0;
      +
     -+	if (it->next_off >= it->br->block_len) {
     ++	if (it->next_off >= it->br->block_len)
      +		return 1;
     -+	}
      +
      +	n = reftable_decode_key(&key, &extra, it->last_key, in);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return -1;
     -+	}
      +
      +	slice_consume(&in, n);
      +	n = reftable_record_decode(rec, key, extra, in, it->br->hash_size);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return -1;
     -+	}
      +	slice_consume(&in, n);
      +
      +	slice_copy(&it->last_key, key);
     @@ reftable/block.c (new)
      +
      +int block_reader_first_key(struct block_reader *br, struct slice *key)
      +{
     -+	struct slice empty = { 0 };
     ++	struct slice empty = SLICE_INIT;
      +	int off = br->header_off + 4;
      +	struct slice in = {
      +		.buf = br->block.data + off,
      +		.len = br->block_len - off,
     ++		.canary = SLICE_CANARY,
      +	};
      +
      +	byte extra = 0;
      +	int n = reftable_decode_key(key, &extra, empty, in);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return n;
     -+	}
     ++
      +	return 0;
      +}
      +
     @@ reftable/block.c (new)
      +		.r = br,
      +	};
      +	struct reftable_record rec = reftable_new_record(block_reader_type(br));
     -+	struct slice key = { 0 };
     ++	struct slice key = SLICE_INIT;
      +	int err = 0;
     -+	struct block_iter next = { 0 };
     ++	struct block_iter next = {
     ++		.last_key = SLICE_INIT,
     ++	};
      +
      +	int i = binsearch(br->restart_count, &restart_key_less, &args);
      +	if (args.error) {
      +		err = REFTABLE_FORMAT_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	it->br = br;
     @@ reftable/block.c (new)
      +	while (true) {
      +		block_iter_copy_from(&next, it);
      +		err = block_iter_next(&next, &rec);
     -+		if (err < 0) {
     -+			goto exit;
     -+		}
     ++		if (err < 0)
     ++			goto done;
      +
      +		reftable_record_key(&rec, &key);
      +		if (err > 0 || slice_cmp(key, want) >= 0) {
      +			err = 0;
     -+			goto exit;
     ++			goto done;
      +		}
      +
      +		block_iter_copy_from(it, &next);
      +	}
      +
     -+exit:
     ++done:
      +	slice_release(&key);
      +	slice_release(&next.last_key);
      +	reftable_record_destroy(&rec);
     @@ reftable/block.h (new)
      +	struct slice last_key;
      +};
      +
     -+/* initializes a block reader */
     ++/* initializes a block reader. */
      +int block_reader_init(struct block_reader *br, struct reftable_block *bl,
      +		      uint32_t header_off, uint32_t table_block_size,
      +		      int hash_size);
     @@ reftable/file.c (new)
      +	struct file_block_source *b = (struct file_block_source *)v;
      +	assert(off + size <= b->size);
      +	dest->data = reftable_malloc(size);
     -+	if (pread(b->fd, dest->data, size, off) != size) {
     ++	if (pread(b->fd, dest->data, size, off) != size)
      +		return -1;
     -+	}
      +	dest->len = size;
      +	return size;
      +}
     @@ reftable/file.c (new)
      +	}
      +
      +	err = fstat(fd, &st);
     -+	if (err < 0) {
     ++	if (err < 0)
      +		return -1;
     -+	}
      +
      +	p = reftable_calloc(sizeof(struct file_block_source));
      +	p->size = st.st_size;
     @@ reftable/iter.c (new)
      +
      +static int indexed_table_ref_iter_next_block(struct indexed_table_ref_iter *it)
      +{
     ++	uint64_t off;
     ++	int err = 0;
      +	if (it->offset_idx == it->offset_len) {
      +		it->finished = true;
      +		return 1;
     @@ reftable/iter.c (new)
      +
      +	reftable_block_done(&it->block_reader.block);
      +
     -+	{
     -+		uint64_t off = it->offsets[it->offset_idx++];
     -+		int err = reader_init_block_reader(it->r, &it->block_reader,
     -+						   off, BLOCK_TYPE_REF);
     -+		if (err < 0) {
     -+			return err;
     -+		}
     -+		if (err > 0) {
     -+			/* indexed block does not exist. */
     -+			return REFTABLE_FORMAT_ERROR;
     -+		}
     ++	off = it->offsets[it->offset_idx++];
     ++	err = reader_init_block_reader(it->r, &it->block_reader, off,
     ++				       BLOCK_TYPE_REF);
     ++	if (err < 0) {
     ++		return err;
     ++	}
     ++	if (err > 0) {
     ++		/* indexed block does not exist. */
     ++		return REFTABLE_FORMAT_ERROR;
      +	}
      +	block_reader_start(&it->block_reader, &it->cur);
      +	return 0;
     @@ reftable/iter.c (new)
      +			       struct reftable_reader *r, byte *oid,
      +			       int oid_len, uint64_t *offsets, int offset_len)
      +{
     ++	struct indexed_table_ref_iter empty = INDEXED_TABLE_REF_ITER_INIT;
      +	struct indexed_table_ref_iter *itr =
      +		reftable_calloc(sizeof(struct indexed_table_ref_iter));
      +	int err = 0;
      +
     ++	*itr = empty;
      +	itr->r = r;
      +	slice_resize(&itr->oid, oid_len);
      +	memcpy(itr->oid.buf, oid, oid_len);
     @@ reftable/iter.h (new)
      +	struct slice oid;
      +	struct reftable_iterator it;
      +};
     ++#define FILTERING_REF_ITERATOR_INIT \
     ++	{                           \
     ++		.oid = SLICE_INIT   \
     ++	}
      +
      +void iterator_from_filtering_ref_iterator(struct reftable_iterator *,
      +					  struct filtering_ref_iterator *);
     @@ reftable/iter.h (new)
      +	bool finished;
      +};
      +
     ++#define INDEXED_TABLE_REF_ITER_INIT                                   \
     ++	{                                                             \
     ++		.cur = { .last_key = SLICE_INIT }, .oid = SLICE_INIT, \
     ++	}
     ++
      +void iterator_from_indexed_table_ref_iter(struct reftable_iterator *it,
      +					  struct indexed_table_ref_iter *itr);
      +int new_indexed_table_ref_iter(struct indexed_table_ref_iter **dest,
     @@ reftable/merged.c (new)
      +		.index = idx,
      +	};
      +	int err = iterator_next(&mi->stack[idx], &rec);
     -+	if (err < 0) {
     ++	if (err < 0)
      +		return err;
     -+	}
      +
      +	if (err > 0) {
      +		reftable_iterator_destroy(&mi->stack[idx]);
     @@ reftable/merged.c (new)
      +
      +static int merged_iter_advance_subiter(struct merged_iter *mi, size_t idx)
      +{
     -+	if (iterator_is_null(&mi->stack[idx])) {
     ++	if (iterator_is_null(&mi->stack[idx]))
      +		return 0;
     -+	}
      +	return merged_iter_advance_nonnull_subiter(mi, idx);
      +}
      +
      +static int merged_iter_next_entry(struct merged_iter *mi,
      +				  struct reftable_record *rec)
      +{
     -+	struct slice entry_key = { 0 };
     ++	struct slice entry_key = SLICE_INIT;
      +	struct pq_entry entry = { 0 };
      +	int err = 0;
      +
     -+	if (merged_iter_pqueue_is_empty(mi->pq)) {
     ++	if (merged_iter_pqueue_is_empty(mi->pq))
      +		return 1;
     -+	}
      +
      +	entry = merged_iter_pqueue_remove(&mi->pq);
      +	err = merged_iter_advance_subiter(mi, entry.index);
     -+	if (err < 0) {
     ++	if (err < 0)
      +		return err;
     -+	}
      +
      +	/*
      +	  One can also use reftable as datacenter-local storage, where the ref
     @@ reftable/merged.c (new)
      +	reftable_record_key(&entry.rec, &entry_key);
      +	while (!merged_iter_pqueue_is_empty(mi->pq)) {
      +		struct pq_entry top = merged_iter_pqueue_top(mi->pq);
     -+		struct slice k = { 0 };
     ++		struct slice k = SLICE_INIT;
      +		int err = 0, cmp = 0;
      +
      +		reftable_record_key(&top.rec, &k);
     @@ reftable/merged.c (new)
      +static int merged_iter_next_void(void *p, struct reftable_record *rec)
      +{
      +	struct merged_iter *mi = (struct merged_iter *)p;
     -+	if (merged_iter_pqueue_is_empty(mi->pq)) {
     ++	if (merged_iter_pqueue_is_empty(mi->pq))
      +		return 1;
     -+	}
      +
      +	return merged_iter_next(mi, rec);
      +}
     @@ reftable/merged.c (new)
      +	if (err < 0) {
      +		merged_iter_close(&merged);
      +		return err;
     -+	}
     -+
     -+	{
     ++	} else {
      +		struct merged_iter *p =
      +			reftable_malloc(sizeof(struct merged_iter));
      +		*p = merged;
     @@ reftable/pq.c (new)
      +
      +int pq_less(struct pq_entry a, struct pq_entry b)
      +{
     -+	struct slice ak = { 0 };
     -+	struct slice bk = { 0 };
     ++	struct slice ak = SLICE_INIT;
     ++	struct slice bk = SLICE_INIT;
      +	int cmp = 0;
      +	reftable_record_key(&a.rec, &ak);
      +	reftable_record_key(&b.rec, &bk);
     @@ reftable/pq.c (new)
      +	slice_release(&ak);
      +	slice_release(&bk);
      +
     -+	if (cmp == 0) {
     ++	if (cmp == 0)
      +		return a.index > b.index;
     -+	}
      +
      +	return cmp < 0;
      +}
     @@ reftable/reader.c (new)
      +			    struct reftable_block *dest, uint64_t off,
      +			    uint32_t sz)
      +{
     -+	if (off >= r->size) {
     ++	if (off >= r->size)
      +		return 0;
     -+	}
      +
      +	if (off + sz > r->size) {
      +		sz = r->size - off;
     @@ reftable/reader.c (new)
      +
      +	if (memcmp(f, "REFT", 4)) {
      +		err = REFTABLE_FORMAT_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +	f += 4;
      +
      +	if (memcmp(footer, header, header_size(r->version))) {
      +		err = REFTABLE_FORMAT_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	f++;
     @@ reftable/reader.c (new)
      +			break;
      +		default:
      +			err = REFTABLE_FORMAT_ERROR;
     -+			goto exit;
     ++			goto done;
      +		}
      +		f += 4;
      +	}
     @@ reftable/reader.c (new)
      +	f += 4;
      +	if (computed_crc != file_crc) {
      +		err = REFTABLE_FORMAT_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	first_block_typ = header[header_size(r->version)];
     @@ reftable/reader.c (new)
      +				  r->log_offsets.offset > 0);
      +	r->obj_offsets.present = r->obj_offsets.offset > 0;
      +	err = 0;
     -+exit:
     ++done:
      +	return err;
      +}
      +
     @@ reftable/reader.c (new)
      +	err = block_source_read_block(source, &header, 0, header_size(2) + 1);
      +	if (err != header_size(2) + 1) {
      +		err = REFTABLE_IO_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	if (memcmp(header.data, "REFT", 4)) {
      +		err = REFTABLE_FORMAT_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +	r->version = header.data[4];
      +	if (r->version != 1 && r->version != 2) {
      +		err = REFTABLE_FORMAT_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	r->size = block_source_size(source) - footer_size(r->version);
     @@ reftable/reader.c (new)
      +				      footer_size(r->version));
      +	if (err != footer_size(r->version)) {
      +		err = REFTABLE_IO_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	err = parse_footer(r, footer.data, header.data);
     -+exit:
     ++done:
      +	reftable_block_done(&footer);
      +	reftable_block_done(&header);
      +	return err;
     @@ reftable/reader.c (new)
      +	struct block_iter bi;
      +	bool finished;
      +};
     ++#define TABLE_ITER_INIT                         \
     ++	{                                       \
     ++		.bi = {.last_key = SLICE_INIT } \
     ++	}
      +
      +static void table_iter_copy_from(struct table_iter *dest,
      +				 struct table_iter *src)
     @@ reftable/reader.c (new)
      +	uint32_t header_off = next_off ? 0 : header_size(r->version);
      +	int32_t block_size = 0;
      +
     -+	if (next_off >= r->size) {
     ++	if (next_off >= r->size)
      +		return 1;
     -+	}
      +
      +	err = reader_get_block(r, &block, next_off, guess_block_size);
     -+	if (err < 0) {
     ++	if (err < 0)
      +		return err;
     -+	}
      +
      +	block_size = extract_block_size(block.data, &block_typ, next_off,
      +					r->version);
     -+	if (block_size < 0) {
     ++	if (block_size < 0)
      +		return block_size;
     -+	}
      +
      +	if (want_typ != BLOCK_TYPE_ANY && block_typ != want_typ) {
      +		reftable_block_done(&block);
     @@ reftable/reader.c (new)
      +		dest->finished = true;
      +		return 1;
      +	}
     -+	if (err != 0) {
     ++	if (err != 0)
      +		return err;
     -+	}
     -+
     -+	{
     ++	else {
      +		struct block_reader *brp =
      +			reftable_malloc(sizeof(struct block_reader));
      +		*brp = br;
     @@ reftable/reader.c (new)
      +
      +static int table_iter_next(struct table_iter *ti, struct reftable_record *rec)
      +{
     -+	if (reftable_record_type(rec) != ti->typ) {
     ++	if (reftable_record_type(rec) != ti->typ)
      +		return REFTABLE_API_ERROR;
     -+	}
      +
      +	while (true) {
     -+		struct table_iter next = { 0 };
     ++		struct table_iter next = TABLE_ITER_INIT;
      +		int err = 0;
      +		if (ti->finished) {
      +			return 1;
     @@ reftable/reader.c (new)
      +	struct block_reader *brp = NULL;
      +
      +	int err = reader_init_block_reader(r, &br, off, typ);
     -+	if (err != 0) {
     ++	if (err != 0)
      +		return err;
     -+	}
      +
      +	brp = reftable_malloc(sizeof(struct block_reader));
      +	*brp = br;
     @@ reftable/reader.c (new)
      +{
      +	struct reftable_record rec =
      +		reftable_new_record(reftable_record_type(want));
     -+	struct slice want_key = { 0 };
     -+	struct slice got_key = { 0 };
     -+	struct table_iter next = { 0 };
     ++	struct slice want_key = SLICE_INIT;
     ++	struct slice got_key = SLICE_INIT;
     ++	struct table_iter next = TABLE_ITER_INIT;
      +	int err = -1;
     ++
      +	reftable_record_key(want, &want_key);
      +
      +	while (true) {
      +		err = table_iter_next_block(&next, ti);
     -+		if (err < 0) {
     -+			goto exit;
     -+		}
     ++		if (err < 0)
     ++			goto done;
      +
      +		if (err > 0) {
      +			break;
      +		}
      +
      +		err = block_reader_first_key(next.bi.br, &got_key);
     -+		if (err < 0) {
     -+			goto exit;
     -+		}
     -+		{
     -+			int cmp = slice_cmp(got_key, want_key);
     -+			if (cmp > 0) {
     -+				table_iter_block_done(&next);
     -+				break;
     -+			}
     ++		if (err < 0)
     ++			goto done;
     ++
     ++		if (slice_cmp(got_key, want_key) > 0) {
     ++			table_iter_block_done(&next);
     ++			break;
      +		}
      +
      +		table_iter_block_done(ti);
     @@ reftable/reader.c (new)
      +	}
      +
      +	err = block_iter_seek(&ti->bi, want_key);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +	err = 0;
      +
     -+exit:
     ++done:
      +	block_iter_close(&next.bi);
      +	reftable_record_destroy(&rec);
      +	slice_release(&want_key);
     @@ reftable/reader.c (new)
      +			       struct reftable_iterator *it,
      +			       struct reftable_record *rec)
      +{
     -+	struct reftable_index_record want_index = { 0 };
     ++	struct reftable_index_record want_index = { .last_key = SLICE_INIT };
      +	struct reftable_record want_index_rec = { 0 };
     -+	struct reftable_index_record index_result = { 0 };
     ++	struct reftable_index_record index_result = { .last_key = SLICE_INIT };
      +	struct reftable_record index_result_rec = { 0 };
     -+	struct table_iter index_iter = { 0 };
     -+	struct table_iter next = { 0 };
     ++	struct table_iter index_iter = TABLE_ITER_INIT;
     ++	struct table_iter next = TABLE_ITER_INIT;
      +	int err = 0;
      +
      +	reftable_record_key(rec, &want_index.last_key);
     @@ reftable/reader.c (new)
      +	reftable_record_from_index(&index_result_rec, &index_result);
      +
      +	err = reader_start(r, &index_iter, reftable_record_type(rec), true);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	err = reader_seek_linear(r, &index_iter, &want_index_rec);
      +	while (true) {
      +		err = table_iter_next(&index_iter, &index_result_rec);
      +		table_iter_block_done(&index_iter);
     -+		if (err != 0) {
     -+			goto exit;
     -+		}
     ++		if (err != 0)
     ++			goto done;
      +
      +		err = reader_table_iter_at(r, &next, index_result.offset, 0);
     -+		if (err != 0) {
     -+			goto exit;
     -+		}
     ++		if (err != 0)
     ++			goto done;
      +
      +		err = block_iter_seek(&next.bi, want_index.last_key);
     -+		if (err < 0) {
     -+			goto exit;
     -+		}
     ++		if (err < 0)
     ++			goto done;
      +
      +		if (next.typ == reftable_record_type(rec)) {
      +			err = 0;
     @@ reftable/reader.c (new)
      +	}
      +
      +	if (err == 0) {
     ++		struct table_iter empty = TABLE_ITER_INIT;
      +		struct table_iter *malloced =
      +			reftable_calloc(sizeof(struct table_iter));
     ++		*malloced = empty;
      +		table_iter_copy_from(malloced, &next);
      +		iterator_from_table_iter(it, malloced);
      +	}
     -+exit:
     ++done:
      +	block_iter_close(&next.bi);
      +	table_iter_close(&index_iter);
      +	reftable_record_clear(&want_index_rec);
     @@ reftable/reader.c (new)
      +	struct reftable_reader_offsets *offs =
      +		reader_offsets_for(r, reftable_record_type(rec));
      +	uint64_t idx = offs->index_offset;
     -+	struct table_iter ti = { 0 };
     ++	struct table_iter ti = TABLE_ITER_INIT;
      +	int err = 0;
     -+	if (idx > 0) {
     ++	if (idx > 0)
      +		return reader_seek_indexed(r, it, rec);
     -+	}
      +
      +	err = reader_start(r, &ti, reftable_record_type(rec), false);
     -+	if (err < 0) {
     ++	if (err < 0)
      +		return err;
     -+	}
      +	err = reader_seek_linear(r, &ti, rec);
     -+	if (err < 0) {
     ++	if (err < 0)
      +		return err;
     -+	}
     -+
     -+	{
     ++	else {
      +		struct table_iter *p =
      +			reftable_malloc(sizeof(struct table_iter));
      +		*p = ti;
     @@ reftable/reader.c (new)
      +	/* Look through the reverse index. */
      +	reftable_record_from_obj(&want_rec, &want);
      +	err = reader_seek(r, &oit, &want_rec);
     -+	if (err != 0) {
     -+		goto exit;
     -+	}
     ++	if (err != 0)
     ++		goto done;
      +
      +	/* read out the reftable_obj_record */
      +	reftable_record_from_obj(&got_rec, &got);
      +	err = iterator_next(&oit, &got_rec);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	if (err > 0 ||
      +	    memcmp(want.hash_prefix, got.hash_prefix, r->object_id_len)) {
      +		/* didn't find it; return empty iterator */
      +		iterator_set_empty(it);
      +		err = 0;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	err = new_indexed_table_ref_iter(&itr, r, oid, hash_size(r->hash_id),
      +					 got.offsets, got.offset_len);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +	got.offsets = NULL;
      +	iterator_from_indexed_table_ref_iter(it, itr);
      +
     -+exit:
     ++done:
      +	reftable_iterator_destroy(&oit);
      +	reftable_record_clear(&got_rec);
      +	return err;
     @@ reftable/reader.c (new)
      +					      struct reftable_iterator *it,
      +					      byte *oid)
      +{
     ++	struct table_iter ti_empty = TABLE_ITER_INIT;
      +	struct table_iter *ti = reftable_calloc(sizeof(struct table_iter));
      +	struct filtering_ref_iterator *filter = NULL;
     ++	struct filtering_ref_iterator empty = FILTERING_REF_ITERATOR_INIT;
      +	int oid_len = hash_size(r->hash_id);
     -+	int err = reader_start(r, ti, BLOCK_TYPE_REF, false);
     ++	int err;
     ++
     ++	*ti = ti_empty;
     ++	err = reader_start(r, ti, BLOCK_TYPE_REF, false);
      +	if (err < 0) {
      +		reftable_free(ti);
      +		return err;
      +	}
      +
     -+	filter = reftable_calloc(sizeof(struct filtering_ref_iterator));
     ++	filter = reftable_malloc(sizeof(struct filtering_ref_iterator));
     ++	*filter = empty;
      +	slice_resize(&filter->oid, oid_len);
      +	memcpy(filter->oid.buf, oid, oid_len);
      +	reftable_table_from_reader(&filter->tab, r);
     @@ reftable/reader.c (new)
      +int reftable_reader_refs_for(struct reftable_reader *r,
      +			     struct reftable_iterator *it, byte *oid)
      +{
     -+	if (r->obj_offsets.present) {
     ++	if (r->obj_offsets.present)
      +		return reftable_reader_refs_for_indexed(r, it, oid);
     -+	}
      +	return reftable_reader_refs_for_unindexed(r, it, oid);
      +}
      +
     @@ reftable/record.c (new)
      +	int ptr = 0;
      +	uint64_t val;
      +
     -+	if (in.len == 0) {
     ++	if (in.len == 0)
      +		return -1;
     -+	}
      +	val = in.buf[ptr] & 0x7f;
      +
      +	while (in.buf[ptr] & 0x80) {
     @@ reftable/record.c (new)
      +	}
      +
      +	n = sizeof(buf) - i - 1;
     -+	if (dest.len < n) {
     ++	if (dest.len < n)
      +		return -1;
     -+	}
      +	memcpy(dest.buf, &buf[i + 1], n);
      +	return n;
      +}
     @@ reftable/record.c (new)
      +	int start_len = in.len;
      +	uint64_t tsize = 0;
      +	int n = get_var_int(&tsize, in);
     -+	if (n <= 0) {
     ++	if (n <= 0)
      +		return -1;
     -+	}
      +	slice_consume(&in, n);
     -+	if (in.len < tsize) {
     ++	if (in.len < tsize)
      +		return -1;
     -+	}
      +
      +	slice_resize(dest, tsize + 1);
      +	dest->buf[tsize] = 0;
     @@ reftable/record.c (new)
      +	struct slice start = s;
      +	int l = strlen(str);
      +	int n = put_var_int(s, l);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return -1;
     -+	}
      +	slice_consume(&s, n);
     -+	if (s.len < l) {
     ++	if (s.len < l)
      +		return -1;
     -+	}
      +	memcpy(s.buf, str, l);
      +	slice_consume(&s, l);
      +
     @@ reftable/record.c (new)
      +	int prefix_len = common_prefix_size(prev_key, key);
      +	uint64_t suffix_len = key.len - prefix_len;
      +	int n = put_var_int(dest, (uint64_t)prefix_len);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return -1;
     -+	}
      +	slice_consume(&dest, n);
      +
      +	*restart = (prefix_len == 0);
      +
      +	n = put_var_int(dest, suffix_len << 3 | (uint64_t)extra);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return -1;
     -+	}
      +	slice_consume(&dest, n);
      +
     -+	if (dest.len < suffix_len) {
     ++	if (dest.len < suffix_len)
      +		return -1;
     -+	}
      +	memcpy(dest.buf, key.buf + prefix_len, suffix_len);
      +	slice_consume(&dest, suffix_len);
      +
     @@ reftable/record.c (new)
      +	uint64_t prefix_len = 0;
      +	uint64_t suffix_len = 0;
      +	int n = get_var_int(&prefix_len, in);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return -1;
     -+	}
      +	slice_consume(&in, n);
      +
     -+	if (prefix_len > last_key.len) {
     ++	if (prefix_len > last_key.len)
      +		return -1;
     -+	}
      +
      +	n = get_var_int(&suffix_len, in);
     -+	if (n <= 0) {
     ++	if (n <= 0)
      +		return -1;
     -+	}
      +	slice_consume(&in, n);
      +
      +	*extra = (byte)(suffix_len & 0x7);
      +	suffix_len >>= 3;
      +
     -+	if (in.len < suffix_len) {
     ++	if (in.len < suffix_len)
      +		return -1;
     -+	}
      +
      +	slice_resize(key, suffix_len + prefix_len);
      +	memcpy(key->buf, last_key.buf, prefix_len);
     @@ reftable/record.c (new)
      +
      +static char hexdigit(int c)
      +{
     -+	if (c <= 9) {
     ++	if (c <= 9)
      +		return '0' + c;
     -+	}
      +	return 'a' + (c - 10);
      +}
      +
     @@ reftable/record.c (new)
      +		} else {
      +			return 1;
      +		}
     -+	} else if (r->target != NULL) {
     ++	} else if (r->target != NULL)
      +		return 3;
     -+	}
      +	return 0;
      +}
      +
     @@ reftable/record.c (new)
      +	struct slice start = s;
      +	int n = put_var_int(s, r->update_index);
      +	assert(hash_size > 0);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return -1;
     -+	}
      +	slice_consume(&s, n);
      +
      +	if (r->value != NULL) {
     @@ reftable/record.c (new)
      +	bool seen_target = false;
      +
      +	int n = get_var_int(&r->update_index, in);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return n;
     -+	}
      +	assert(hash_size > 0);
      +
      +	slice_consume(&in, n);
     @@ reftable/record.c (new)
      +		slice_consume(&in, hash_size);
      +		break;
      +	case 3: {
     -+		struct slice dest = { 0 };
     ++		struct slice dest = SLICE_INIT;
      +		int n = decode_string(&dest, in);
      +		if (n < 0) {
      +			return -1;
     @@ reftable/record.c (new)
      +	struct reftable_obj_record *obj = (struct reftable_obj_record *)rec;
      +	const struct reftable_obj_record *src =
      +		(const struct reftable_obj_record *)src_rec;
     ++	int olen;
      +
      +	reftable_obj_record_clear(obj);
      +	*obj = *src;
      +	obj->hash_prefix = reftable_malloc(obj->hash_prefix_len);
      +	memcpy(obj->hash_prefix, src->hash_prefix, obj->hash_prefix_len);
      +
     -+	{
     -+		int olen = obj->offset_len * sizeof(uint64_t);
     -+		obj->offsets = reftable_malloc(olen);
     -+		memcpy(obj->offsets, src->offsets, olen);
     -+	}
     ++	olen = obj->offset_len * sizeof(uint64_t);
     ++	obj->offsets = reftable_malloc(olen);
     ++	memcpy(obj->offsets, src->offsets, olen);
      +}
      +
      +static byte reftable_obj_record_val_type(const void *rec)
      +{
      +	struct reftable_obj_record *r = (struct reftable_obj_record *)rec;
     -+	if (r->offset_len > 0 && r->offset_len < 8) {
     ++	if (r->offset_len > 0 && r->offset_len < 8)
      +		return r->offset_len;
     -+	}
      +	return 0;
      +}
      +
     @@ reftable/record.c (new)
      +		}
      +		slice_consume(&s, n);
      +	}
     -+	if (r->offset_len == 0) {
     ++	if (r->offset_len == 0)
      +		return start.len - s.len;
     -+	}
      +	n = put_var_int(s, r->offsets[0]);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return -1;
     -+	}
      +	slice_consume(&s, n);
      +
      +	last = r->offsets[0];
     @@ reftable/record.c (new)
      +
      +	r->offsets = NULL;
      +	r->offset_len = 0;
     -+	if (count == 0) {
     ++	if (count == 0)
      +		return start.len - in.len;
     -+	}
      +
      +	r->offsets = reftable_malloc(count * sizeof(uint64_t));
      +	r->offset_len = count;
      +
      +	n = get_var_int(&r->offsets[0], in);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return n;
     -+	}
      +	slice_consume(&in, n);
      +
      +	last = r->offsets[0];
     @@ reftable/record.c (new)
      +	int n = 0;
      +	byte *oldh = r->old_hash;
      +	byte *newh = r->new_hash;
     -+	if (reftable_log_record_is_deletion(r)) {
     ++	if (reftable_log_record_is_deletion(r))
      +		return 0;
     -+	}
      +
      +	if (oldh == NULL) {
      +		oldh = zero;
     @@ reftable/record.c (new)
      +		newh = zero;
      +	}
      +
     -+	if (s.len < 2 * hash_size) {
     ++	if (s.len < 2 * hash_size)
      +		return -1;
     -+	}
      +
      +	memcpy(s.buf, oldh, hash_size);
      +	memcpy(s.buf + hash_size, newh, hash_size);
      +	slice_consume(&s, 2 * hash_size);
      +
      +	n = encode_string(r->name ? r->name : "", s);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return -1;
     -+	}
      +	slice_consume(&s, n);
      +
      +	n = encode_string(r->email ? r->email : "", s);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return -1;
     -+	}
      +	slice_consume(&s, n);
      +
      +	n = put_var_int(s, r->time);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return -1;
     -+	}
      +	slice_consume(&s, n);
      +
     -+	if (s.len < 2) {
     ++	if (s.len < 2)
      +		return -1;
     -+	}
      +
      +	put_be16(s.buf, r->tz_offset);
      +	slice_consume(&s, 2);
      +
      +	n = encode_string(r->message ? r->message : "", s);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return -1;
     -+	}
      +	slice_consume(&s, n);
      +
      +	return start.len - s.len;
     @@ reftable/record.c (new)
      +	struct reftable_log_record *r = (struct reftable_log_record *)rec;
      +	uint64_t max = 0;
      +	uint64_t ts = 0;
     -+	struct slice dest = { 0 };
     ++	struct slice dest = SLICE_INIT;
      +	int n;
      +
     -+	if (key.len <= 9 || key.buf[key.len - 9] != 0) {
     ++	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);
     @@ reftable/record.c (new)
      +		return 0;
      +	}
      +
     -+	if (in.len < 2 * hash_size) {
     ++	if (in.len < 2 * hash_size)
      +		return REFTABLE_FORMAT_ERROR;
     -+	}
      +
      +	r->old_hash = reftable_realloc(r->old_hash, hash_size);
      +	r->new_hash = reftable_realloc(r->new_hash, hash_size);
     @@ reftable/record.c (new)
      +	slice_consume(&in, 2 * hash_size);
      +
      +	n = decode_string(&dest, in);
     -+	if (n < 0) {
     -+		goto error;
     -+	}
     ++	if (n < 0)
     ++		goto done;
      +	slice_consume(&in, n);
      +
      +	r->name = reftable_realloc(r->name, dest.len + 1);
     @@ reftable/record.c (new)
      +
      +	slice_resize(&dest, 0);
      +	n = decode_string(&dest, in);
     -+	if (n < 0) {
     -+		goto error;
     -+	}
     ++	if (n < 0)
     ++		goto done;
      +	slice_consume(&in, n);
      +
      +	r->email = reftable_realloc(r->email, dest.len + 1);
     @@ reftable/record.c (new)
      +
      +	ts = 0;
      +	n = get_var_int(&ts, in);
     -+	if (n < 0) {
     -+		goto error;
     -+	}
     ++	if (n < 0)
     ++		goto done;
      +	slice_consume(&in, n);
      +	r->time = ts;
     -+	if (in.len < 2) {
     -+		goto error;
     -+	}
     ++	if (in.len < 2)
     ++		goto done;
      +
      +	r->tz_offset = get_be16(in.buf);
      +	slice_consume(&in, 2);
      +
      +	slice_resize(&dest, 0);
      +	n = decode_string(&dest, in);
     -+	if (n < 0) {
     -+		goto error;
     -+	}
     ++	if (n < 0)
     ++		goto done;
      +	slice_consume(&in, n);
      +
      +	r->message = reftable_realloc(r->message, dest.len + 1);
     @@ reftable/record.c (new)
      +	slice_release(&dest);
      +	return start.len - in.len;
      +
     -+error:
     ++done:
      +	slice_release(&dest);
      +	return REFTABLE_FORMAT_ERROR;
      +}
     @@ reftable/record.c (new)
      +static bool null_streq(char *a, char *b)
      +{
      +	char *empty = "";
     -+	if (a == NULL) {
     ++	if (a == NULL)
      +		a = empty;
     -+	}
     -+	if (b == NULL) {
     ++
     ++	if (b == NULL)
      +		b = empty;
     -+	}
     ++
      +	return 0 == strcmp(a, b);
      +}
      +
      +static bool zero_hash_eq(byte *a, byte *b, int sz)
      +{
     -+	if (a == NULL) {
     ++	if (a == NULL)
      +		a = zero;
     -+	}
     -+	if (b == NULL) {
     ++
     ++	if (b == NULL)
      +		b = zero;
     -+	}
     ++
      +	return !memcmp(a, b, sz);
      +}
      +
     @@ reftable/record.c (new)
      +		return rec;
      +	}
      +	case BLOCK_TYPE_INDEX: {
     ++		struct reftable_index_record empty = { .last_key = SLICE_INIT };
      +		struct reftable_index_record *r =
      +			reftable_calloc(sizeof(struct reftable_index_record));
     ++		*r = empty;
      +		reftable_record_from_index(&rec, r);
      +		return rec;
      +	}
     @@ reftable/record.c (new)
      +	struct slice start = out;
      +
      +	int n = put_var_int(out, r->offset);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return n;
     -+	}
      +
      +	slice_consume(&out, n);
      +
     @@ reftable/record.c (new)
      +	slice_copy(&r->last_key, key);
      +
      +	n = get_var_int(&r->offset, in);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return n;
     -+	}
      +
      +	slice_consume(&in, n);
      +	return start.len - in.len;
     @@ reftable/record.c (new)
      +
      +static bool hash_equal(byte *a, byte *b, int hash_size)
      +{
     -+	if (a != NULL && b != NULL) {
     ++	if (a != NULL && b != NULL)
      +		return !memcmp(a, b, hash_size);
     -+	}
      +
      +	return a == b;
      +}
      +
      +static bool str_equal(char *a, char *b)
      +{
     -+	if (a != NULL && b != NULL) {
     ++	if (a != NULL && b != NULL)
      +		return 0 == strcmp(a, b);
     -+	}
      +
      +	return a == b;
      +}
     @@ reftable/record.c (new)
      +	struct reftable_log_record *lb = (struct reftable_log_record *)b;
      +
      +	int cmp = strcmp(la->ref_name, lb->ref_name);
     -+	if (cmp) {
     ++	if (cmp)
      +		return cmp;
     -+	}
     -+	if (la->update_index > lb->update_index) {
     ++	if (la->update_index > lb->update_index)
      +		return -1;
     -+	}
      +	return (la->update_index < lb->update_index) ? 1 : 0;
      +}
      +
     @@ reftable/refname.c (new)
      +		};
      +		int idx = binsearch(mod->add_len, find_name, &arg);
      +		if (idx < mod->add_len &&
     -+		    !strncmp(prefix, mod->add[idx], strlen(prefix))) {
     -+			goto exit;
     -+		}
     ++		    !strncmp(prefix, mod->add[idx], strlen(prefix)))
     ++			goto done;
      +	}
      +	err = reftable_table_seek_ref(&mod->tab, &it, prefix);
     -+	if (err) {
     -+		goto exit;
     -+	}
     ++	if (err)
     ++		goto done;
      +
      +	while (true) {
      +		err = reftable_iterator_next_ref(&it, &ref);
     -+		if (err) {
     -+			goto exit;
     -+		}
     ++		if (err)
     ++			goto done;
      +
      +		if (mod->del_len > 0) {
      +			struct find_arg arg = {
     @@ reftable/refname.c (new)
      +
      +		if (strncmp(ref.ref_name, prefix, strlen(prefix))) {
      +			err = 1;
     -+			goto exit;
     ++			goto done;
      +		}
      +		err = 0;
     -+		goto exit;
     ++		goto done;
      +	}
      +
     -+exit:
     ++done:
      +	reftable_ref_record_clear(&ref);
      +	reftable_iterator_destroy(&it);
      +	return err;
     @@ reftable/refname.c (new)
      +
      +int modification_validate(struct modification *mod)
      +{
     -+	struct slice slashed = { 0 };
     ++	struct slice slashed = SLICE_INIT;
      +	int err = 0;
      +	int i = 0;
      +	for (; i < mod->add_len; i++) {
      +		err = validate_ref_name(mod->add[i]);
     -+		if (err) {
     -+			goto exit;
     -+		}
     ++		if (err)
     ++			goto done;
      +		slice_set_string(&slashed, mod->add[i]);
      +		slice_addstr(&slashed, "/");
      +
     @@ reftable/refname.c (new)
      +			mod, slice_as_string(&slashed));
      +		if (err == 0) {
      +			err = REFTABLE_NAME_CONFLICT;
     -+			goto exit;
     -+		}
     -+		if (err < 0) {
     -+			goto exit;
     ++			goto done;
      +		}
     ++		if (err < 0)
     ++			goto done;
      +
      +		slice_set_string(&slashed, mod->add[i]);
      +		while (slashed.len) {
     @@ reftable/refname.c (new)
      +						   slice_as_string(&slashed));
      +			if (err == 0) {
      +				err = REFTABLE_NAME_CONFLICT;
     -+				goto exit;
     -+			}
     -+			if (err < 0) {
     -+				goto exit;
     ++				goto done;
      +			}
     ++			if (err < 0)
     ++				goto done;
      +		}
      +	}
      +	err = 0;
     -+exit:
     ++done:
      +	slice_release(&slashed);
      +	return err;
      +}
     @@ reftable/reftable.c (new)
      +{
      +	struct reftable_iterator it = { 0 };
      +	int err = reftable_table_seek_ref(tab, &it, name);
     -+	if (err) {
     -+		goto exit;
     -+	}
     ++	if (err)
     ++		goto done;
      +
      +	err = reftable_iterator_next_ref(&it, ref);
     -+	if (err) {
     -+		goto exit;
     -+	}
     ++	if (err)
     ++		goto done;
      +
      +	if (strcmp(ref->ref_name, name) ||
      +	    reftable_ref_record_is_deletion(ref)) {
      +		reftable_ref_record_clear(ref);
      +		err = 1;
     -+		goto exit;
     ++		goto done;
      +	}
      +
     -+exit:
     ++done:
      +	reftable_iterator_destroy(&it);
      +	return err;
      +}
     @@ reftable/slice.c (new)
      +
      +#include "reftable.h"
      +
     ++struct slice reftable_empty_slice = SLICE_INIT;
     ++
      +void slice_set_string(struct slice *s, const char *str)
      +{
     ++	int l;
      +	if (str == NULL) {
      +		s->len = 0;
      +		return;
      +	}
     ++	assert(s->canary == SLICE_CANARY);
      +
     -+	{
     -+		int l = strlen(str);
     -+		l++; /* \0 */
     -+		slice_resize(s, l);
     -+		memcpy(s->buf, str, l);
     -+		s->len = l - 1;
     -+	}
     ++	l = strlen(str);
     ++	l++; /* \0 */
     ++	slice_resize(s, l);
     ++	memcpy(s->buf, str, l);
     ++	s->len = l - 1;
     ++}
     ++
     ++void slice_init(struct slice *s)
     ++{
     ++	struct slice empty = SLICE_INIT;
     ++	*s = empty;
      +}
      +
      +void slice_resize(struct slice *s, int l)
      +{
     ++	assert(s->canary == SLICE_CANARY);
      +	if (s->cap < l) {
      +		int c = s->cap * 2;
      +		if (c < l) {
     @@ reftable/slice.c (new)
      +{
      +	int l1 = d->len;
      +	int l2 = strlen(s);
     ++	assert(d->canary == SLICE_CANARY);
      +
      +	slice_resize(d, l2 + l1);
      +	memcpy(d->buf + l1, s, l2);
     @@ reftable/slice.c (new)
      +void slice_addbuf(struct slice *s, struct slice a)
      +{
      +	int end = s->len;
     ++	assert(s->canary == SLICE_CANARY);
      +	slice_resize(s, s->len + a.len);
      +	memcpy(s->buf + end, a.buf, a.len);
      +}
      +
      +void slice_consume(struct slice *s, int n)
      +{
     ++	assert(s->canary == SLICE_CANARY);
      +	s->buf += n;
      +	s->len -= n;
      +}
     @@ reftable/slice.c (new)
      +byte *slice_detach(struct slice *s)
      +{
      +	byte *p = s->buf;
     ++	assert(s->canary == SLICE_CANARY);
      +	s->buf = NULL;
      +	s->cap = 0;
      +	s->len = 0;
     @@ reftable/slice.c (new)
      +
      +void slice_release(struct slice *s)
      +{
     ++	assert(s->canary == SLICE_CANARY);
      +	reftable_free(slice_detach(s));
      +}
      +
      +void slice_copy(struct slice *dest, struct slice src)
      +{
     ++	assert(dest->canary == SLICE_CANARY);
     ++	assert(src.canary == SLICE_CANARY);
      +	slice_resize(dest, src.len);
      +	memcpy(dest->buf, src.buf, src.len);
      +}
     @@ reftable/slice.c (new)
      +   a \0 is added at the end. */
      +const char *slice_as_string(struct slice *s)
      +{
     ++	assert(s->canary == SLICE_CANARY);
      +	if (s->cap == s->len) {
      +		int l = s->len;
      +		slice_resize(s, l + 1);
     @@ reftable/slice.c (new)
      +/* return a newly malloced string for this slice */
      +char *slice_to_string(struct slice in)
      +{
     -+	struct slice s = { 0 };
     ++	struct slice s = SLICE_INIT;
     ++	assert(in.canary == SLICE_CANARY);
      +	slice_resize(&s, in.len + 1);
      +	s.buf[in.len] = 0;
      +	memcpy(s.buf, in.buf, in.len);
     @@ reftable/slice.c (new)
      +
      +bool slice_equal(struct slice a, struct slice b)
      +{
     -+	if (a.len != b.len) {
     ++	assert(a.canary == SLICE_CANARY);
     ++	assert(b.canary == SLICE_CANARY);
     ++	if (a.len != b.len)
      +		return 0;
     -+	}
      +	return memcmp(a.buf, b.buf, a.len) == 0;
      +}
      +
     @@ reftable/slice.c (new)
      +{
      +	int min = a.len < b.len ? a.len : b.len;
      +	int res = memcmp(a.buf, b.buf, min);
     -+	if (res != 0) {
     ++	assert(a.canary == SLICE_CANARY);
     ++	assert(b.canary == SLICE_CANARY);
     ++	if (res != 0)
      +		return res;
     -+	}
     -+	if (a.len < b.len) {
     ++	if (a.len < b.len)
      +		return -1;
     -+	} else if (a.len > b.len) {
     ++	else if (a.len > b.len)
      +		return 1;
     -+	} else {
     ++	else
      +		return 0;
     -+	}
      +}
      +
      +int slice_add(struct slice *b, byte *data, size_t sz)
      +{
     ++	assert(b->canary == SLICE_CANARY);
      +	if (b->len + sz > b->cap) {
      +		int newcap = 2 * b->cap + 1;
      +		if (newcap < b->len + sz) {
     @@ reftable/slice.c (new)
      +int common_prefix_size(struct slice a, struct slice b)
      +{
      +	int p = 0;
     ++	assert(a.canary == SLICE_CANARY);
     ++	assert(b.canary == SLICE_CANARY);
      +	while (p < a.len && p < b.len) {
      +		if (a.buf[p] != b.buf[p]) {
      +			break;
     @@ reftable/slice.h (new)
      +	int len;
      +	int cap;
      +	byte *buf;
     ++	byte canary;
      +};
     ++#define SLICE_CANARY 0x42
     ++#define SLICE_INIT                       \
     ++	{                                \
     ++		0, 0, NULL, SLICE_CANARY \
     ++	}
     ++extern struct slice reftable_empty_slice;
      +
      +void slice_set_string(struct slice *dest, const char *src);
      +void slice_addstr(struct slice *dest, const char *src);
     @@ reftable/slice.h (new)
      +/* Return a malloced string for `src` */
      +char *slice_to_string(struct slice src);
      +
     ++/* Initializes a slice. Accepts a slice with random garbage. */
     ++void slice_init(struct slice *slice);
     ++
      +/* Ensure that `buf` is \0 terminated. */
      +const char *slice_as_string(struct slice *src);
      +
     @@ reftable/stack.c (new)
      +{
      +	struct reftable_stack *p =
      +		reftable_calloc(sizeof(struct reftable_stack));
     -+	struct slice list_file_name = { 0 };
     ++	struct slice list_file_name = SLICE_INIT;
      +	int err = 0;
      +
      +	if (config.hash_id == 0) {
     @@ reftable/stack.c (new)
      +	int err = 0;
      +	if (size < 0) {
      +		err = REFTABLE_IO_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +	err = lseek(fd, 0, SEEK_SET);
      +	if (err < 0) {
      +		err = REFTABLE_IO_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	buf = reftable_malloc(size + 1);
      +	if (read(fd, buf, size) != size) {
      +		err = REFTABLE_IO_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +	buf[size] = 0;
      +
      +	parse_names(buf, size, namesp);
      +
     -+exit:
     ++done:
      +	reftable_free(buf);
      +	return err;
      +}
     @@ reftable/stack.c (new)
      +	int new_tables_len = 0;
      +	struct reftable_merged_table *new_merged = NULL;
      +	int i;
     -+	struct slice table_path = { 0 };
     ++	struct slice table_path = SLICE_INIT;
      +
      +	while (*names) {
      +		struct reftable_reader *rd = NULL;
     @@ reftable/stack.c (new)
      +
      +			err = reftable_block_source_from_file(
      +				&src, slice_as_string(&table_path));
     -+			if (err < 0) {
     -+				goto exit;
     -+			}
     ++			if (err < 0)
     ++				goto done;
      +
      +			err = reftable_new_reader(&rd, &src, name);
     -+			if (err < 0) {
     -+				goto exit;
     -+			}
     ++			if (err < 0)
     ++				goto done;
      +		}
      +
      +		new_tables[new_tables_len++] = rd;
     @@ reftable/stack.c (new)
      +	/* success! */
      +	err = reftable_new_merged_table(&new_merged, new_tables, new_tables_len,
      +					st->config.hash_id);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	new_tables = NULL;
      +	new_tables_len = 0;
     @@ reftable/stack.c (new)
      +		}
      +	}
      +
     -+exit:
     ++done:
      +	slice_release(&table_path);
      +	for (i = 0; i < new_tables_len; i++) {
      +		reader_close(new_tables[i]);
     @@ reftable/stack.c (new)
      +	time_t diff = a->tv_sec - b->tv_sec;
      +	int udiff = a->tv_usec - b->tv_usec;
      +
     -+	if (diff != 0) {
     ++	if (diff != 0)
      +		return diff;
     -+	}
      +
      +	return udiff;
      +}
     @@ reftable/stack.c (new)
      +	int err = gettimeofday(&deadline, NULL);
      +	int64_t delay = 0;
      +	int tries = 0;
     -+	if (err < 0) {
     ++	if (err < 0)
      +		return err;
     -+	}
      +
      +	deadline.tv_sec += 3;
      +	while (true) {
     @@ reftable/stack.c (new)
      +	char **names = NULL;
      +	int err = read_lines(st->list_file, &names);
      +	int i = 0;
     -+	if (err < 0) {
     ++	if (err < 0)
      +		return err;
     -+	}
      +
      +	for (i = 0; i < st->merged->stack_len; i++) {
      +		if (names[i] == NULL) {
      +			err = 1;
     -+			goto exit;
     ++			goto done;
      +		}
      +
      +		if (strcmp(st->merged->stack[i]->name, names[i])) {
      +			err = 1;
     -+			goto exit;
     ++			goto done;
      +		}
      +	}
      +
      +	if (names[st->merged->stack_len] != NULL) {
      +		err = 1;
     -+		goto exit;
     ++		goto done;
      +	}
      +
     -+exit:
     ++done:
      +	free_names(names);
      +	return err;
      +}
     @@ reftable/stack.c (new)
      +int reftable_stack_reload(struct reftable_stack *st)
      +{
      +	int err = stack_uptodate(st);
     -+	if (err > 0) {
     ++	if (err > 0)
      +		return reftable_stack_reload_maybe_reuse(st, true);
     -+	}
      +	return err;
      +}
      +
     @@ reftable/stack.c (new)
      +		return err;
      +	}
      +
     -+	if (!st->disable_auto_compact) {
     ++	if (!st->disable_auto_compact)
      +		return reftable_stack_auto_compact(st);
     -+	}
      +
      +	return 0;
      +}
     @@ reftable/stack.c (new)
      +	uint64_t next_update_index;
      +};
      +
     ++#define REFTABLE_ADDITION_INIT               \
     ++	{                                    \
     ++		.lock_file_name = SLICE_INIT \
     ++	}
     ++
      +static int reftable_stack_init_addition(struct reftable_addition *add,
      +					struct reftable_stack *st)
      +{
     @@ reftable/stack.c (new)
      +		} else {
      +			err = REFTABLE_IO_ERROR;
      +		}
     -+		goto exit;
     ++		goto done;
      +	}
      +	err = stack_uptodate(st);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	if (err > 1) {
      +		err = REFTABLE_LOCK_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	add->next_update_index = reftable_stack_next_update_index(st);
     -+exit:
     ++done:
      +	if (err) {
      +		reftable_addition_close(add);
      +	}
     @@ reftable/stack.c (new)
      +void reftable_addition_close(struct reftable_addition *add)
      +{
      +	int i = 0;
     -+	struct slice nm = { 0 };
     ++	struct slice nm = SLICE_INIT;
      +	for (i = 0; i < add->new_tables_len; i++) {
      +		slice_set_string(&nm, add->stack->list_file);
      +		slice_addstr(&nm, "/");
     @@ reftable/stack.c (new)
      +
      +int reftable_addition_commit(struct reftable_addition *add)
      +{
     -+	struct slice table_list = { 0 };
     ++	struct slice table_list = SLICE_INIT;
      +	int i = 0;
      +	int err = 0;
     -+	if (add->new_tables_len == 0) {
     -+		goto exit;
     -+	}
     ++	if (add->new_tables_len == 0)
     ++		goto done;
      +
      +	for (i = 0; i < add->stack->merged->stack_len; i++) {
      +		slice_addstr(&table_list, add->stack->merged->stack[i]->name);
     @@ reftable/stack.c (new)
      +	slice_release(&table_list);
      +	if (err < 0) {
      +		err = REFTABLE_IO_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	err = close(add->lock_file_fd);
      +	add->lock_file_fd = 0;
      +	if (err < 0) {
      +		err = REFTABLE_IO_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	err = rename(slice_as_string(&add->lock_file_name),
      +		     add->stack->list_file);
      +	if (err < 0) {
      +		err = REFTABLE_IO_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	err = reftable_stack_reload(add->stack);
      +
     -+exit:
     ++done:
      +	reftable_addition_close(add);
      +	return err;
      +}
     @@ reftable/stack.c (new)
      +				struct reftable_stack *st)
      +{
      +	int err = 0;
     ++	struct reftable_addition empty = REFTABLE_ADDITION_INIT;
      +	*dest = reftable_calloc(sizeof(**dest));
     ++	**dest = empty;
      +	err = reftable_stack_init_addition(*dest, st);
      +	if (err) {
      +		reftable_free(*dest);
     @@ reftable/stack.c (new)
      +		  int (*write_table)(struct reftable_writer *wr, void *arg),
      +		  void *arg)
      +{
     -+	struct reftable_addition add = { 0 };
     ++	struct reftable_addition add = REFTABLE_ADDITION_INIT;
      +	int err = reftable_stack_init_addition(&add, st);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +	if (err > 0) {
      +		err = REFTABLE_LOCK_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	err = reftable_addition_add(&add, write_table, arg);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	err = reftable_addition_commit(&add);
     -+exit:
     ++done:
      +	reftable_addition_close(&add);
      +	return err;
      +}
     @@ reftable/stack.c (new)
      +					     void *arg),
      +			  void *arg)
      +{
     -+	struct slice temp_tab_file_name = { 0 };
     -+	struct slice tab_file_name = { 0 };
     -+	struct slice next_name = { 0 };
     ++	struct slice temp_tab_file_name = SLICE_INIT;
     ++	struct slice tab_file_name = SLICE_INIT;
     ++	struct slice next_name = SLICE_INIT;
      +	struct reftable_writer *wr = NULL;
      +	int err = 0;
      +	int tab_fd = 0;
     @@ reftable/stack.c (new)
      +	tab_fd = mkstemp((char *)slice_as_string(&temp_tab_file_name));
      +	if (tab_fd < 0) {
      +		err = REFTABLE_IO_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	wr = reftable_new_writer(reftable_fd_write, &tab_fd,
      +				 &add->stack->config);
      +	err = write_table(wr, arg);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	err = reftable_writer_close(wr);
      +	if (err == REFTABLE_EMPTY_TABLE_ERROR) {
      +		err = 0;
     -+		goto exit;
     -+	}
     -+	if (err < 0) {
     -+		goto exit;
     ++		goto done;
      +	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	err = close(tab_fd);
      +	tab_fd = 0;
      +	if (err < 0) {
      +		err = REFTABLE_IO_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	err = stack_check_addition(add->stack,
      +				   slice_as_string(&temp_tab_file_name));
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	if (wr->min_update_index < add->next_update_index) {
      +		err = REFTABLE_API_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	format_name(&next_name, wr->min_update_index, wr->max_update_index);
     @@ reftable/stack.c (new)
      +		     slice_as_string(&tab_file_name));
      +	if (err < 0) {
      +		err = REFTABLE_IO_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	add->new_tables = reftable_realloc(add->new_tables,
     @@ reftable/stack.c (new)
      +						   (add->new_tables_len + 1));
      +	add->new_tables[add->new_tables_len] = slice_to_string(next_name);
      +	add->new_tables_len++;
     -+exit:
     ++done:
      +	if (tab_fd > 0) {
      +		close(tab_fd);
      +		tab_fd = 0;
     @@ reftable/stack.c (new)
      +uint64_t reftable_stack_next_update_index(struct reftable_stack *st)
      +{
      +	int sz = st->merged->stack_len;
     -+	if (sz > 0) {
     ++	if (sz > 0)
      +		return reftable_reader_max_update_index(
      +			       st->merged->stack[sz - 1]) +
      +		       1;
     -+	}
      +	return 1;
      +}
      +
     @@ reftable/stack.c (new)
      +				struct slice *temp_tab,
      +				struct reftable_log_expiry_config *config)
      +{
     -+	struct slice next_name = { 0 };
     ++	struct slice next_name = SLICE_INIT;
      +	int tab_fd = -1;
      +	struct reftable_writer *wr = NULL;
      +	int err = 0;
     @@ reftable/stack.c (new)
      +	wr = reftable_new_writer(reftable_fd_write, &tab_fd, &st->config);
      +
      +	err = stack_write_compact(st, wr, first, last, config);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +	err = reftable_writer_close(wr);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	err = close(tab_fd);
      +	tab_fd = 0;
      +
     -+exit:
     ++done:
      +	reftable_writer_free(wr);
      +	if (tab_fd > 0) {
      +		close(tab_fd);
     @@ reftable/stack.c (new)
      +					st->config.hash_id);
      +	if (err < 0) {
      +		reftable_free(subtabs);
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	err = reftable_merged_table_seek_ref(mt, &it, "");
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	while (true) {
      +		err = reftable_iterator_next_ref(&it, &ref);
     @@ reftable/stack.c (new)
      +	reftable_iterator_destroy(&it);
      +
      +	err = reftable_merged_table_seek_log(mt, &it, "");
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	while (true) {
      +		err = reftable_iterator_next_log(&it, &log);
     @@ reftable/stack.c (new)
      +		entries++;
      +	}
      +
     -+exit:
     ++done:
      +	reftable_iterator_destroy(&it);
      +	if (mt != NULL) {
      +		merged_table_clear(mt);
     @@ reftable/stack.c (new)
      +static int stack_compact_range(struct reftable_stack *st, int first, int last,
      +			       struct reftable_log_expiry_config *expiry)
      +{
     -+	struct slice temp_tab_file_name = { 0 };
     -+	struct slice new_table_name = { 0 };
     -+	struct slice lock_file_name = { 0 };
     -+	struct slice ref_list_contents = { 0 };
     -+	struct slice new_table_path = { 0 };
     ++	struct slice temp_tab_file_name = SLICE_INIT;
     ++	struct slice new_table_name = SLICE_INIT;
     ++	struct slice lock_file_name = SLICE_INIT;
     ++	struct slice ref_list_contents = SLICE_INIT;
     ++	struct slice new_table_path = SLICE_INIT;
      +	int err = 0;
      +	bool have_lock = false;
      +	int lock_file_fd = 0;
     @@ reftable/stack.c (new)
      +
      +	if (first > last || (expiry == NULL && first == last)) {
      +		err = 0;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	st->stats.attempts++;
     @@ reftable/stack.c (new)
      +		} else {
      +			err = REFTABLE_IO_ERROR;
      +		}
     -+		goto exit;
     ++		goto done;
      +	}
      +	/* Don't want to write to the lock for now.  */
      +	close(lock_file_fd);
     @@ reftable/stack.c (new)
      +
      +	have_lock = true;
      +	err = stack_uptodate(st);
     -+	if (err != 0) {
     -+		goto exit;
     -+	}
     ++	if (err != 0)
     ++		goto done;
      +
      +	for (i = first, j = 0; i <= last; i++) {
     -+		struct slice subtab_file_name = { 0 };
     -+		struct slice subtab_lock = { 0 };
     ++		struct slice subtab_file_name = SLICE_INIT;
     ++		struct slice subtab_lock = SLICE_INIT;
     ++		int sublock_file_fd = -1;
     ++
      +		slice_set_string(&subtab_file_name, st->reftable_dir);
      +		slice_addstr(&subtab_file_name, "/");
      +		slice_addstr(&subtab_file_name,
     @@ reftable/stack.c (new)
      +		slice_copy(&subtab_lock, subtab_file_name);
      +		slice_addstr(&subtab_lock, ".lock");
      +
     -+		{
     -+			int sublock_file_fd =
     -+				open(slice_as_string(&subtab_lock),
     -+				     O_EXCL | O_CREAT | O_WRONLY, 0644);
     -+			if (sublock_file_fd > 0) {
     -+				close(sublock_file_fd);
     -+			} else if (sublock_file_fd < 0) {
     -+				if (errno == EEXIST) {
     -+					err = 1;
     -+				} else {
     -+					err = REFTABLE_IO_ERROR;
     -+				}
     ++		sublock_file_fd = open(slice_as_string(&subtab_lock),
     ++				       O_EXCL | O_CREAT | O_WRONLY, 0644);
     ++		if (sublock_file_fd > 0) {
     ++			close(sublock_file_fd);
     ++		} else if (sublock_file_fd < 0) {
     ++			if (errno == EEXIST) {
     ++				err = 1;
     ++			} else {
     ++				err = REFTABLE_IO_ERROR;
      +			}
      +		}
      +
     @@ reftable/stack.c (new)
      +			(char *)slice_as_string(&subtab_file_name);
      +		j++;
      +
     -+		if (err != 0) {
     -+			goto exit;
     -+		}
     ++		if (err != 0)
     ++			goto done;
      +	}
      +
      +	err = unlink(slice_as_string(&lock_file_name));
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +	have_lock = false;
      +
      +	err = stack_compact_locked(st, first, last, &temp_tab_file_name,
     @@ reftable/stack.c (new)
      +	if (is_empty_table) {
      +		err = 0;
      +	}
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	lock_file_fd = open(slice_as_string(&lock_file_name),
      +			    O_EXCL | O_CREAT | O_WRONLY, 0644);
     @@ reftable/stack.c (new)
      +		} else {
      +			err = REFTABLE_IO_ERROR;
      +		}
     -+		goto exit;
     ++		goto done;
      +	}
      +	have_lock = true;
      +
     @@ reftable/stack.c (new)
      +			     slice_as_string(&new_table_path));
      +		if (err < 0) {
      +			err = REFTABLE_IO_ERROR;
     -+			goto exit;
     ++			goto done;
      +		}
      +	}
      +
     @@ reftable/stack.c (new)
      +	if (err < 0) {
      +		err = REFTABLE_IO_ERROR;
      +		unlink(slice_as_string(&new_table_path));
     -+		goto exit;
     ++		goto done;
      +	}
      +	err = close(lock_file_fd);
      +	lock_file_fd = 0;
      +	if (err < 0) {
      +		err = REFTABLE_IO_ERROR;
      +		unlink(slice_as_string(&new_table_path));
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	err = rename(slice_as_string(&lock_file_name), st->list_file);
      +	if (err < 0) {
      +		err = REFTABLE_IO_ERROR;
      +		unlink(slice_as_string(&new_table_path));
     -+		goto exit;
     ++		goto done;
      +	}
      +	have_lock = false;
      +
     @@ reftable/stack.c (new)
      +		listp++;
      +	}
      +
     -+exit:
     ++done:
      +	free_names(delete_on_success);
      +
      +	listp = subtable_locks;
     @@ reftable/stack.c (new)
      +int fastlog2(uint64_t sz)
      +{
      +	int l = 0;
     -+	if (sz == 0) {
     ++	if (sz == 0)
      +		return 0;
     -+	}
      +	for (; sz; sz /= 2) {
      +		l++;
      +	}
     @@ reftable/stack.c (new)
      +	struct segment seg =
      +		suggest_compaction_segment(sizes, st->merged->stack_len);
      +	reftable_free(sizes);
     -+	if (segment_size(&seg) > 0) {
     ++	if (segment_size(&seg) > 0)
      +		return stack_compact_range_stats(st, seg.start, seg.end - 1,
      +						 NULL);
     -+	}
      +
      +	return 0;
      +}
     @@ reftable/stack.c (new)
      +	struct reftable_iterator it = { 0 };
      +	struct reftable_merged_table *mt = reftable_stack_merged_table(st);
      +	int err = reftable_merged_table_seek_log(mt, &it, refname);
     -+	if (err) {
     -+		goto exit;
     -+	}
     ++	if (err)
     ++		goto done;
      +
      +	err = reftable_iterator_next_log(&it, log);
     -+	if (err) {
     -+		goto exit;
     -+	}
     ++	if (err)
     ++		goto done;
      +
      +	if (strcmp(log->ref_name, refname) ||
      +	    reftable_log_record_is_deletion(log)) {
      +		err = 1;
     -+		goto exit;
     ++		goto done;
      +	}
      +
     -+exit:
     ++done:
      +	if (err) {
      +		reftable_log_record_clear(log);
      +	}
     @@ reftable/stack.c (new)
      +	int len = 0;
      +	int i = 0;
      +
     -+	if (st->config.skip_name_check) {
     ++	if (st->config.skip_name_check)
      +		return 0;
     -+	}
      +
      +	err = reftable_block_source_from_file(&src, new_tab_name);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	err = reftable_new_reader(&rd, &src, new_tab_name);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	err = reftable_reader_seek_ref(rd, &it, "");
      +	if (err > 0) {
      +		err = 0;
     -+		goto exit;
     -+	}
     -+	if (err < 0) {
     -+		goto exit;
     ++		goto done;
      +	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	while (true) {
      +		struct reftable_ref_record ref = { 0 };
     @@ reftable/stack.c (new)
      +		if (err > 0) {
      +			break;
      +		}
     -+		if (err < 0) {
     -+			goto exit;
     -+		}
     ++		if (err < 0)
     ++			goto done;
      +
      +		if (len >= cap) {
      +			cap = 2 * cap + 1;
     @@ reftable/stack.c (new)
      +
      +	err = validate_ref_record_addition(tab, refs, len);
      +
     -+exit:
     ++done:
      +	for (i = 0; i < len; i++) {
      +		reftable_ref_record_clear(&refs[i]);
      +	}
     @@ reftable/tree.c (new)
      +	}
      +
      +	res = compare(key, (*rootp)->key);
     -+	if (res < 0) {
     ++	if (res < 0)
      +		return tree_search(key, &(*rootp)->left, compare, insert);
     -+	} else if (res > 0) {
     ++	else if (res > 0)
      +		return tree_search(key, &(*rootp)->right, compare, insert);
     -+	}
      +	return *rootp;
      +}
      +
     @@ reftable/writer.c (new)
      +	if (w->pending_padding > 0) {
      +		byte *zeroed = reftable_calloc(w->pending_padding);
      +		int n = w->write(w->write_arg, zeroed, w->pending_padding);
     -+		if (n < 0) {
     ++		if (n < 0)
      +			return n;
     -+		}
      +
      +		w->pending_padding = 0;
      +		reftable_free(zeroed);
     @@ reftable/writer.c (new)
      +
      +	w->pending_padding = padding;
      +	n = w->write(w->write_arg, data, len);
     -+	if (n < 0) {
     ++	if (n < 0)
      +		return n;
     -+	}
      +	n += padding;
      +	return 0;
      +}
     @@ reftable/writer.c (new)
      +		block_start = header_size(writer_version(w));
      +	}
      +
     ++	slice_release(&w->last_key);
      +	block_writer_init(&w->block_writer_data, typ, w->block,
      +			  w->opts.block_size, block_start,
      +			  hash_size(w->opts.hash_id));
     @@ reftable/writer.c (new)
      +{
      +	struct reftable_writer *wp =
      +		reftable_calloc(sizeof(struct reftable_writer));
     ++	slice_init(&wp->block_writer_data.last_key);
      +	options_set_defaults(opts);
      +	if (opts->block_size >= (1 << 24)) {
      +		/* TODO - error return? */
      +		abort();
      +	}
     ++	wp->last_key = reftable_empty_slice;
      +	wp->block = reftable_calloc(opts->block_size);
      +	wp->write = writer_func;
      +	wp->write_arg = writer_arg;
     @@ reftable/writer.c (new)
      +	int offset_len;
      +	int offset_cap;
      +};
     ++#define OBJ_INDEX_TREE_NODE_INIT   \
     ++	{                          \
     ++		.hash = SLICE_INIT \
     ++	}
      +
      +static int obj_index_tree_node_compare(const void *a, const void *b)
      +{
     @@ reftable/writer.c (new)
      +					     &obj_index_tree_node_compare, 0);
      +	struct obj_index_tree_node *key = NULL;
      +	if (node == NULL) {
     -+		key = reftable_calloc(sizeof(struct obj_index_tree_node));
     ++		struct obj_index_tree_node empty = OBJ_INDEX_TREE_NODE_INIT;
     ++		key = reftable_malloc(sizeof(struct obj_index_tree_node));
     ++		*key = empty;
     ++
      +		slice_copy(&key->hash, hash);
      +		tree_search((void *)key, &w->obj_index_tree,
      +			    &obj_index_tree_node_compare, 1);
     @@ reftable/writer.c (new)
      +			     struct reftable_record *rec)
      +{
      +	int result = -1;
     -+	struct slice key = { 0 };
     ++	struct slice key = SLICE_INIT;
      +	int err = 0;
      +	reftable_record_key(rec, &key);
     -+	if (slice_cmp(w->last_key, key) >= 0) {
     -+		goto exit;
     -+	}
     ++	if (slice_cmp(w->last_key, key) >= 0)
     ++		goto done;
      +
      +	slice_copy(&w->last_key, key);
      +	if (w->block_writer == NULL) {
     @@ reftable/writer.c (new)
      +
      +	if (block_writer_add(w->block_writer, rec) == 0) {
      +		result = 0;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	err = writer_flush_block(w);
      +	if (err < 0) {
      +		result = err;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	writer_reinit_block_writer(w, reftable_record_type(rec));
      +	err = block_writer_add(w->block_writer, rec);
      +	if (err < 0) {
      +		result = err;
     -+		goto exit;
     ++		goto done;
      +	}
      +
      +	result = 0;
     -+exit:
     ++done:
      +	slice_release(&key);
      +	return result;
      +}
     @@ reftable/writer.c (new)
      +	struct reftable_ref_record copy = *ref;
      +	int err = 0;
      +
     -+	if (ref->ref_name == NULL) {
     ++	if (ref->ref_name == NULL)
      +		return REFTABLE_API_ERROR;
     -+	}
      +	if (ref->update_index < w->min_update_index ||
     -+	    ref->update_index > w->max_update_index) {
     ++	    ref->update_index > w->max_update_index)
      +		return REFTABLE_API_ERROR;
     -+	}
      +
      +	reftable_record_from_ref(&rec, &copy);
      +	copy.update_index -= w->min_update_index;
      +	err = writer_add_record(w, &rec);
     -+	if (err < 0) {
     ++	if (err < 0)
      +		return err;
     -+	}
      +
      +	if (!w->opts.skip_index_objects && ref->value != NULL) {
      +		struct slice h = {
      +			.buf = ref->value,
      +			.len = hash_size(w->opts.hash_id),
     ++			.canary = SLICE_CANARY,
      +		};
      +
      +		writer_index_hash(w, h);
      +	}
     ++
      +	if (!w->opts.skip_index_objects && ref->target_value != NULL) {
      +		struct slice h = {
      +			.buf = ref->target_value,
      +			.len = hash_size(w->opts.hash_id),
     ++			.canary = SLICE_CANARY,
      +		};
      +		writer_index_hash(w, h);
      +	}
     @@ reftable/writer.c (new)
      +{
      +	struct reftable_record rec = { 0 };
      +	int err;
     -+	if (log->ref_name == NULL) {
     ++	if (log->ref_name == NULL)
      +		return REFTABLE_API_ERROR;
     -+	}
      +
      +	if (w->block_writer != NULL &&
      +	    block_writer_type(w->block_writer) == BLOCK_TYPE_REF) {
      +		int err = writer_finish_public_section(w);
     -+		if (err < 0) {
     ++		if (err < 0)
      +			return err;
     -+		}
      +	}
      +
      +	w->next -= w->pending_padding;
     @@ reftable/writer.c (new)
      +	int err = writer_flush_block(w);
      +	int i = 0;
      +	struct reftable_block_stats *bstats = NULL;
     -+	if (err < 0) {
     ++	if (err < 0)
      +		return err;
     -+	}
      +
      +	while (w->index_len > threshold) {
      +		struct reftable_index_record *idx = NULL;
     @@ reftable/writer.c (new)
      +				continue;
      +			}
      +
     -+			{
     -+				int err = writer_flush_block(w);
     -+				if (err < 0) {
     -+					return err;
     -+				}
     -+			}
     ++			err = writer_flush_block(w);
     ++			if (err < 0)
     ++				return err;
      +
      +			writer_reinit_block_writer(w, BLOCK_TYPE_INDEX);
      +
     @@ reftable/writer.c (new)
      +	writer_clear_index(w);
      +
      +	err = writer_flush_block(w);
     -+	if (err < 0) {
     ++	if (err < 0)
      +		return err;
     -+	}
      +
      +	bstats = writer_reftable_block_stats(w, typ);
      +	bstats->index_blocks = w->stats.idx_stats.blocks - before_blocks;
     @@ reftable/writer.c (new)
      +		.offset_len = entry->offset_len,
      +	};
      +	struct reftable_record rec = { 0 };
     -+	if (arg->err < 0) {
     -+		goto exit;
     -+	}
     ++	if (arg->err < 0)
     ++		goto done;
      +
      +	reftable_record_from_obj(&rec, &obj_rec);
      +	arg->err = block_writer_add(arg->w->block_writer, &rec);
     -+	if (arg->err == 0) {
     -+		goto exit;
     -+	}
     ++	if (arg->err == 0)
     ++		goto done;
      +
      +	arg->err = writer_flush_block(arg->w);
     -+	if (arg->err < 0) {
     -+		goto exit;
     -+	}
     ++	if (arg->err < 0)
     ++		goto done;
      +
      +	writer_reinit_block_writer(arg->w, BLOCK_TYPE_OBJ);
      +	arg->err = block_writer_add(arg->w->block_writer, &rec);
     -+	if (arg->err == 0) {
     -+		goto exit;
     -+	}
     ++	if (arg->err == 0)
     ++		goto done;
      +	obj_rec.offset_len = 0;
      +	arg->err = block_writer_add(arg->w->block_writer, &rec);
      +
      +	/* Should be able to write into a fresh block. */
      +	assert(arg->err == 0);
      +
     -+exit:;
     ++done:;
      +}
      +
      +static void object_record_free(void *void_arg, void *key)
     @@ reftable/writer.c (new)
      +		infix_walk(w->obj_index_tree, &write_object_record, &closure);
      +	}
      +
     -+	if (closure.err < 0) {
     ++	if (closure.err < 0)
      +		return closure.err;
     -+	}
      +	return writer_finish_section(w);
      +}
      +
     @@ reftable/writer.c (new)
      +	byte typ = 0;
      +	int err = 0;
      +
     -+	if (w->block_writer == NULL) {
     ++	if (w->block_writer == NULL)
      +		return 0;
     -+	}
      +
      +	typ = block_writer_type(w->block_writer);
      +	err = writer_finish_section(w);
     -+	if (err < 0) {
     ++	if (err < 0)
      +		return err;
     -+	}
      +	if (typ == BLOCK_TYPE_REF && !w->opts.skip_index_objects &&
      +	    w->stats.ref_stats.index_blocks > 0) {
      +		err = writer_dump_object_index(w);
     -+		if (err < 0) {
     ++		if (err < 0)
      +			return err;
     -+		}
      +	}
      +
      +	if (w->obj_index_tree != NULL) {
     @@ reftable/writer.c (new)
      +	byte *p = footer;
      +	int err = writer_finish_public_section(w);
      +	int empty_table = w->next == 0;
     -+	if (err != 0) {
     -+		goto exit;
     -+	}
     ++	if (err != 0)
     ++		goto done;
      +	w->pending_padding = 0;
      +	if (empty_table) {
      +		/* Empty tables need a header anyway. */
      +		byte header[28];
      +		int n = writer_write_header(w, header);
      +		err = padded_write(w, header, n, 0);
     -+		if (err < 0) {
     -+			goto exit;
     -+		}
     ++		if (err < 0)
     ++			goto done;
      +	}
      +
      +	p += writer_write_header(w, footer);
     @@ reftable/writer.c (new)
      +	p += 4;
      +
      +	err = padded_write(w, footer, footer_size(writer_version(w)), 0);
     -+	if (err < 0) {
     -+		goto exit;
     -+	}
     ++	if (err < 0)
     ++		goto done;
      +
      +	if (empty_table) {
      +		err = REFTABLE_EMPTY_TABLE_ERROR;
     -+		goto exit;
     ++		goto done;
      +	}
      +
     -+exit:
     ++done:
      +	/* free up memory. */
      +	block_writer_clear(&w->block_writer_data);
      +	writer_clear_index(w);
     @@ reftable/writer.c (new)
      +	int raw_bytes = block_writer_finish(w->block_writer);
      +	int padding = 0;
      +	int err = 0;
     -+	struct reftable_index_record ir = { 0 };
     -+	if (raw_bytes < 0) {
     ++	struct reftable_index_record ir = { .last_key = SLICE_INIT };
     ++	if (raw_bytes < 0)
      +		return raw_bytes;
     -+	}
      +
      +	if (!w->opts.unpadded && typ != BLOCK_TYPE_LOG) {
      +		padding = w->opts.block_size - raw_bytes;
     @@ reftable/writer.c (new)
      +	}
      +
      +	err = padded_write(w, w->block, raw_bytes, padding);
     -+	if (err < 0) {
     ++	if (err < 0)
      +		return err;
     -+	}
      +
      +	if (w->index_cap == w->index_len) {
      +		w->index_cap = 2 * w->index_cap + 1;
     @@ reftable/writer.c (new)
      +
      +int writer_flush_block(struct reftable_writer *w)
      +{
     -+	if (w->block_writer == NULL) {
     ++	if (w->block_writer == NULL)
      +		return 0;
     -+	}
     -+	if (w->block_writer->entries == 0) {
     ++	if (w->block_writer->entries == 0)
      +		return 0;
     -+	}
      +	return writer_flush_nonempty_block(w);
      +}
      +
  6:  865c2c4567a ! 10:  a86c3753717 Reftable support for git-core
     @@ Commit message
      
          TODO:
      
     -    * Resolve spots marked with XXX
     +    * Fix worktree commands
     +
     +    * Spots marked XXX
      
          Example use: see t/t0031-reftable.sh
      
     @@ refs/reftable-backend.c (new)
      +	strbuf_reset(&sb);
      +
      +	refs->err = reftable_new_stack(&refs->stack, refs->reftable_dir, cfg);
     ++	assert(refs->err != REFTABLE_API_ERROR);
      +	strbuf_release(&sb);
      +	return ref_store;
      +}
     @@ refs/reftable-backend.c (new)
      +	}
      +
      +done:
     ++	assert(err != REFTABLE_API_ERROR);
      +	strbuf_release(&referent);
      +	return err;
      +}
     @@ refs/reftable-backend.c (new)
      +	transaction->state = REF_TRANSACTION_PREPARED;
      +
      +done:
     ++	assert(err != REFTABLE_API_ERROR);
      +	if (err < 0) {
      +		transaction->state = REF_TRANSACTION_CLOSED;
      +		strbuf_addf(errbuf, "reftable: transaction prepare: %s",
     @@ refs/reftable-backend.c (new)
      +	}
      +
      +done:
     ++	assert(err != REFTABLE_API_ERROR);
      +	free(logs);
      +	free(sorted);
      +	return err;
     @@ refs/reftable-backend.c (new)
      +	err = reftable_addition_commit(add);
      +
      +done:
     ++	assert(err != REFTABLE_API_ERROR);
      +	reftable_addition_destroy(add);
      +	transaction->state = REF_TRANSACTION_CLOSED;
      +	transaction->backend_data = NULL;
     @@ refs/reftable-backend.c (new)
      +				    struct ref_transaction *transaction,
      +				    struct strbuf *errmsg)
      +{
     ++	int err = reftable_transaction_prepare(ref_store, transaction, errmsg);
     ++	if (err)
     ++		return err;
     ++
      +	return reftable_transaction_finish(ref_store, transaction, errmsg);
      +}
      +
     @@ refs/reftable-backend.c (new)
      +
      +	err = reftable_writer_add_ref(writer, &write_ref);
      +done:
     ++	assert(err != REFTABLE_API_ERROR);
      +	reftable_ref_record_clear(&read_ref);
      +	return err;
      +}
     @@ refs/reftable-backend.c (new)
      +	}
      +
      +done:
     ++	assert(err != REFTABLE_API_ERROR);
      +	reftable_addition_destroy(add);
      +	return err;
      +}
     @@ refs/reftable-backend.c (new)
      +	if (err < 0) {
      +		goto done;
      +	}
     ++
     ++	string_list_sort(refnames);
      +	err = reftable_stack_reload(refs->stack);
      +	if (err) {
      +		goto done;
      +	}
      +	err = reftable_stack_add(refs->stack, &write_delete_refs_table, &arg);
      +done:
     ++	assert(err != REFTABLE_API_ERROR);
      +	return err;
      +}
      +
     @@ refs/reftable-backend.c (new)
      +	}
      +	err = reftable_stack_add(refs->stack, &write_create_symref_table, &arg);
      +done:
     ++	assert(err != REFTABLE_API_ERROR);
      +	return err;
      +}
      +
     @@ refs/reftable-backend.c (new)
      +	}
      +
      +done:
     ++	assert(err != REFTABLE_API_ERROR);
      +	reftable_ref_record_clear(&ref);
      +	return err;
      +}
     @@ refs/reftable-backend.c (new)
      +
      +	err = reftable_stack_add(refs->stack, &write_rename_table, &arg);
      +done:
     ++	assert(err != REFTABLE_API_ERROR);
      +	return err;
      +}
      +
     @@ refs/reftable-backend.c (new)
      +	err = reftable_stack_add(refs->stack, &write_reflog_expiry_table, &arg);
      +
      +done:
     ++	assert(err != REFTABLE_API_ERROR);
      +	reftable_log_record_clear(&log);
      +	reftable_iterator_destroy(&it);
      +	clear_log_tombstones(&arg);
     @@ refs/reftable-backend.c (new)
      +		err = -1;
      +	}
      +done:
     ++	assert(err != REFTABLE_API_ERROR);
      +	reftable_ref_record_clear(&ref);
      +	return err;
      +}
     @@ t/t0031-reftable.sh (new)
      +	test_cmp expect actual
      +'
      +
     ++test_expect_success 'clone calls transaction_initial_commit' '
     ++	test_commit message1 file1 &&
     ++	git clone . cloned &&
     ++	(test  -f cloned/file1 || echo "Fixme.")
     ++'
     ++
      +test_expect_success 'basic operation of reftable storage: commit, show-ref' '
      +	initialize &&
      +	test_commit file &&
  7:  6b248d5fdb4 = 11:  d3613c2ff53 Add GIT_DEBUG_REFS debugging mechanism
  8:  54102355ce7 = 12:  9b98ed614ec vcxproj: adjust for the reftable changes
  9:  7764ebf0956 ! 13:  5e401e4f1ac Add reftable testing infrastructure
     @@ Commit message
           * t1404-update-ref-errors.sh - Manipulates .git/refs/ directly
           * t1405 - inspecs .git/ directly.
      
     -    t6030-bisect-porcelain.sh                - 62 of 72
     +    Worst offenders:
     +
     +    t1400-update-ref.sh                      - 82 of 185
          t2400-worktree-add.sh                    - 58 of 69
     -    t3200-branch.sh                          - 58 of 145
     -    t7406-submodule-update.sh                - 54 of 54
     -    t5601-clone.sh                           - 51 of 105
     -    t9903-bash-prompt.sh                     - 50 of 66
          t1404-update-ref-errors.sh               - 44 of 53
     -    t5510-fetch.sh                           - 40 of 171
     -    t7400-submodule-basic.sh                 - 38 of 111
          t3514-cherry-pick-revert-gpg.sh          - 36 of 36
     +    t5541-http-push-smart.sh                 - 29 of 38
     +    t6003-rev-list-topo-order.sh             - 29 of 35
     +    t3420-rebase-autostash.sh                - 28 of 42
     +    t6120-describe.sh                        - 21 of 82
     +    t3430-rebase-merges.sh                   - 18 of 24
     +    t2018-checkout-branch.sh                 - 15 of 22
          ..
      
          Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
     @@ t/t9903-bash-prompt.sh: test_description='test git-specific bash prompt function
       actual="$TRASH_DIRECTORY/actual"
      
       ## t/test-lib.sh ##
     -@@ t/test-lib.sh: FreeBSD)
     +@@ t/test-lib.sh: parisc* | hppa*)
       	;;
       esac
       

-- 
gitgitgadget

  parent reply	other threads:[~2020-05-28 19:48 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                           ` Han-Wen Nienhuys via GitGitGadget [this message]
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                                   ` [PATCH v19 00/20] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
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.v15.git.1590695209.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.