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 v10 00/12] Reftable support git-core
Date: Mon, 27 Apr 2020 20:13:26 +0000	[thread overview]
Message-ID: <pull.539.v10.git.1588018418.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.539.v9.git.1587417295.gitgitgadget@gmail.com>

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

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

Summary 18816 tests pass 2994 tests fail

Some issues:

 * worktree support looks broken
 * no detection for file/dir conflicts. You can have branch {a, a/b}
   simultaneously.
 * submodules (eg. t1013)
 * many tests inspect .git/logs/ directly.

v13

 * Avoid exposing tombstones from reftable_stack to git 
 * Write peeled tags
 * Fix GC issue: use git-refpack in test
 * Fix unborn branches: must propagate errno from read_raw_ref.
 * add GIT_TEST_REFTABLE environment to control default.
 * add REFTABLE test prerequisite.
 * fix & test update-ref -d.
 * print error message for failed update-ref transactions.

Han-Wen Nienhuys (11):
  refs.h: clarify reflog iteration order
  Iterate over the "refs/" namespace in for_each_[raw]ref
  create .git/refs in files-backend.c
  refs: document how ref_iterator_advance_fn should handle symrefs
  Add .gitattributes for the reftable/ directory
  reftable: define version 2 of the spec to accomodate SHA256
  reftable: clarify how empty tables should be written
  Add reftable library
  Reftable support for git-core
  Add some reftable testing infrastructure
  t: use update-ref and show-ref to reading/writing refs

Jonathan Nieder (1):
  reftable: file format documentation

 Documentation/Makefile                        |    1 +
 Documentation/technical/reftable.txt          | 1080 ++++++++++++++++
 .../technical/repository-version.txt          |    7 +
 Makefile                                      |   26 +-
 builtin/clone.c                               |    3 +-
 builtin/init-db.c                             |   63 +-
 cache.h                                       |    6 +-
 refs.c                                        |   33 +-
 refs.h                                        |    8 +-
 refs/files-backend.c                          |    6 +
 refs/refs-internal.h                          |    6 +
 refs/reftable-backend.c                       | 1045 +++++++++++++++
 reftable/.gitattributes                       |    1 +
 reftable/LICENSE                              |   31 +
 reftable/README.md                            |   11 +
 reftable/VERSION                              |    5 +
 reftable/basics.c                             |  209 +++
 reftable/basics.h                             |   53 +
 reftable/block.c                              |  425 ++++++
 reftable/block.h                              |  124 ++
 reftable/blocksource.h                        |   22 +
 reftable/bytes.c                              |    0
 reftable/config.h                             |    1 +
 reftable/constants.h                          |   21 +
 reftable/dump.c                               |   97 ++
 reftable/file.c                               |   98 ++
 reftable/iter.c                               |  234 ++++
 reftable/iter.h                               |   60 +
 reftable/merged.c                             |  327 +++++
 reftable/merged.h                             |   36 +
 reftable/pq.c                                 |  115 ++
 reftable/pq.h                                 |   34 +
 reftable/reader.c                             |  754 +++++++++++
 reftable/reader.h                             |   68 +
 reftable/record.c                             | 1126 ++++++++++++++++
 reftable/record.h                             |  121 ++
 reftable/reftable.h                           |  527 ++++++++
 reftable/slice.c                              |  224 ++++
 reftable/slice.h                              |   76 ++
 reftable/stack.c                              | 1151 +++++++++++++++++
 reftable/stack.h                              |   44 +
 reftable/system.h                             |   53 +
 reftable/tree.c                               |   67 +
 reftable/tree.h                               |   34 +
 reftable/update.sh                            |   23 +
 reftable/writer.c                             |  661 ++++++++++
 reftable/writer.h                             |   60 +
 reftable/zlib-compat.c                        |   92 ++
 repository.c                                  |    2 +
 repository.h                                  |    3 +
 setup.c                                       |   12 +-
 t/t0002-gitfile.sh                            |    2 +-
 t/t0031-reftable.sh                           |   99 ++
 t/t1400-update-ref.sh                         |   32 +-
 t/t1506-rev-parse-diagnosis.sh                |    2 +-
 t/t3210-pack-refs.sh                          |    6 +
 t/t6050-replace.sh                            |    2 +-
 t/t9020-remote-svn.sh                         |    4 +-
 t/test-lib.sh                                 |    5 +
 59 files changed, 9378 insertions(+), 60 deletions(-)
 create mode 100644 Documentation/technical/reftable.txt
 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/blocksource.h
 create mode 100644 reftable/bytes.c
 create mode 100644 reftable/config.h
 create mode 100644 reftable/constants.h
 create mode 100644 reftable/dump.c
 create mode 100644 reftable/file.c
 create mode 100644 reftable/iter.c
 create mode 100644 reftable/iter.h
 create mode 100644 reftable/merged.c
 create mode 100644 reftable/merged.h
 create mode 100644 reftable/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/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


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

Range-diff vs v9:

  1:  b600d0bc6dd =  1:  d3d8ed2032c refs.h: clarify reflog iteration order
  2:  89b68145e8f =  2:  45fd65f72e0 Iterate over the "refs/" namespace in for_each_[raw]ref
  3:  91f1efe24ec =  3:  bc89bcd9c8c create .git/refs in files-backend.c
  4:  56f65a2a0d7 =  4:  fd67cdff0cd refs: document how ref_iterator_advance_fn should handle symrefs
  5:  b432c1cc2ae =  5:  5373828f854 Add .gitattributes for the reftable/ directory
  6:  b1d94be691a =  6:  8eeed29ebbf reftable: file format documentation
  7:  3e418d27f67 =  7:  5ebc272e23d reftable: define version 2 of the spec to accomodate SHA256
  8:  6f62be4067b =  8:  95aae041613 reftable: clarify how empty tables should be written
  9:  a30001ad1e8 !  9:  59209a5ad39 Add reftable library
     @@ Commit message
      
          * reftable.h - the public API
      
     +    * record.{c,h} - reading and writing records
     +
          * block.{c,h} - reading and writing blocks.
      
          * writer.{c,h} - writing a complete reftable file.
     @@ reftable/README.md (new)
      
       ## reftable/VERSION (new) ##
      @@
     -+commit b68690acad769d59e80cbb4f79c442ece133e6bd
     ++commit a6d6b31bea256044621d789df64a8159647f21bc
      +Author: Han-Wen Nienhuys <hanwen@google.com>
     -+Date:   Mon Apr 20 21:33:11 2020 +0200
     ++Date:   Mon Apr 27 20:46:21 2020 +0200
      +
     -+    C: fix search/replace error in dump.c
     ++    C: prefix error codes with REFTABLE_
      
       ## reftable/basics.c (new) ##
      @@
     @@ reftable/basics.c (new)
      +const char *reftable_error_str(int err)
      +{
      +	switch (err) {
     -+	case IO_ERROR:
     ++	case REFTABLE_IO_ERROR:
      +		return "I/O error";
     -+	case FORMAT_ERROR:
     -+		return "FORMAT_ERROR";
     -+	case NOT_EXIST_ERROR:
     -+		return "NOT_EXIST_ERROR";
     -+	case LOCK_ERROR:
     -+		return "LOCK_ERROR";
     -+	case API_ERROR:
     -+		return "API_ERROR";
     -+	case ZLIB_ERROR:
     -+		return "ZLIB_ERROR";
     ++	case REFTABLE_FORMAT_ERROR:
     ++		return "corrupt reftable file";
     ++	case REFTABLE_NOT_EXIST_ERROR:
     ++		return "file does not exist";
     ++	case REFTABLE_LOCK_ERROR:
     ++		return "data is outdated";
     ++	case REFTABLE_API_ERROR:
     ++		return "misuse of the reftable API";
     ++	case REFTABLE_ZLIB_ERROR:
     ++		return "zlib failure";
      +	case -1:
      +		return "general error";
      +	default:
     @@ reftable/basics.c (new)
      +	}
      +}
      +
     ++int reftable_error_to_errno(int err) {
     ++	switch (err) {
     ++	case REFTABLE_IO_ERROR:
     ++		return EIO;
     ++	case REFTABLE_FORMAT_ERROR:
     ++		return EFAULT;
     ++	case REFTABLE_NOT_EXIST_ERROR:
     ++		return ENOENT;
     ++	case REFTABLE_LOCK_ERROR:
     ++		return EBUSY;
     ++	case REFTABLE_API_ERROR:
     ++		return EINVAL;
     ++	case REFTABLE_ZLIB_ERROR:
     ++		return EDOM;
     ++	default:
     ++		return ERANGE;
     ++	}
     ++}
     ++
     ++
      +void *(*reftable_malloc_ptr)(size_t sz) = &malloc;
      +void *(*reftable_realloc_ptr)(void *, size_t) = &realloc;
      +void (*reftable_free_ptr)(void *) = &free;
     @@ reftable/block.c (new)
      +
      +			if (Z_OK != zresult) {
      +				slice_clear(&compressed);
     -+				return ZLIB_ERROR;
     ++				return REFTABLE_ZLIB_ERROR;
      +			}
      +
      +			memcpy(w->buf + block_header_skip, compressed.buf,
     @@ reftable/block.c (new)
      +	uint32_t sz = get_be24(block->data + header_off + 1);
      +
      +	if (!is_block_type(typ)) {
     -+		return FORMAT_ERROR;
     ++		return REFTABLE_FORMAT_ERROR;
      +	}
      +
      +	if (typ == BLOCK_TYPE_LOG) {
     @@ reftable/block.c (new)
      +				    &dst_len, block->data + block_header_skip,
      +				    &src_len)) {
      +			slice_clear(&uncompressed);
     -+			return ZLIB_ERROR;
     ++			return REFTABLE_ZLIB_ERROR;
      +		}
      +
      +		block_source_return_block(block->source, block);
     @@ reftable/file.c (new)
      +	int fd = open(name, O_RDONLY);
      +	if (fd < 0) {
      +		if (errno == ENOENT) {
     -+			return NOT_EXIST_ERROR;
     ++			return REFTABLE_NOT_EXIST_ERROR;
      +		}
      +		return -1;
      +	}
     @@ reftable/iter.c (new)
      +		}
      +		if (err > 0) {
      +			/* indexed block does not exist. */
     -+			return FORMAT_ERROR;
     ++			return REFTABLE_FORMAT_ERROR;
      +		}
      +	}
      +	block_reader_start(&it->block_reader, &it->cur);
     @@ reftable/merged.c (new)
      +	return 0;
      +}
      +
     -+static int merged_iter_next(struct merged_iter *mi, struct record rec)
     ++static int merged_iter_next_entry(struct merged_iter *mi, struct record rec)
      +{
      +	struct slice entry_key = { 0 };
     -+	struct pq_entry entry = merged_iter_pqueue_remove(&mi->pq);
     -+	int err = merged_iter_advance_subiter(mi, entry.index);
     ++	struct pq_entry entry = { 0 };
     ++	int err = 0;
     ++
     ++	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) {
      +		return err;
      +	}
      +
     -+
     -+        /*
     -+          One can also use reftable as datacenter-local storage, where the ref
     -+          database is maintained in globally consistent database (eg.
     -+          CockroachDB or Spanner). In this scenario, replication delays together
     -+          with compaction may cause newer tables to contain older entries. In
     -+          such a deployment, the loop below must be changed to collect all
     -+          entries for the same key, and return new the newest one.
     -+        */
     ++	/*
     ++	  One can also use reftable as datacenter-local storage, where the ref
     ++	  database is maintained in globally consistent database (eg.
     ++	  CockroachDB or Spanner). In this scenario, replication delays together
     ++	  with compaction may cause newer tables to contain older entries. In
     ++	  such a deployment, the loop below must be changed to collect all
     ++	  entries for the same key, and return new the newest one.
     ++	*/
      +	record_key(entry.rec, &entry_key);
      +	while (!merged_iter_pqueue_is_empty(mi->pq)) {
      +		struct pq_entry top = merged_iter_pqueue_top(mi->pq);
     @@ reftable/merged.c (new)
      +	return 0;
      +}
      +
     ++static int merged_iter_next(struct merged_iter *mi, struct record rec)
     ++{
     ++	while (true) {
     ++		int err = merged_iter_next_entry(mi, rec);
     ++		if (err == 0 && mi->suppress_deletions &&
     ++		    record_is_deletion(rec)) {
     ++			continue;
     ++		}
     ++
     ++		return err;
     ++	}
     ++}
     ++
      +static int merged_iter_next_void(void *p, struct record rec)
      +{
      +	struct merged_iter *mi = (struct merged_iter *)p;
     @@ reftable/merged.c (new)
      +	for (i = 0; i < n; i++) {
      +		struct reftable_reader *r = stack[i];
      +		if (r->hash_id != hash_id) {
     -+			return FORMAT_ERROR;
     ++			return REFTABLE_FORMAT_ERROR;
      +		}
      +		if (i > 0 && last_max >= reftable_reader_min_update_index(r)) {
     -+			return FORMAT_ERROR;
     ++			return REFTABLE_FORMAT_ERROR;
      +		}
      +		if (i == 0) {
      +			first_min = reftable_reader_min_update_index(r);
     @@ reftable/merged.c (new)
      +		.stack = iters,
      +		.typ = record_type(rec),
      +		.hash_id = mt->hash_id,
     ++		.suppress_deletions = mt->suppress_deletions,
      +	};
      +	int n = 0;
      +	int err = 0;
     @@ reftable/merged.h (new)
      +	struct reftable_reader **stack;
      +	int stack_len;
      +	uint32_t hash_id;
     ++	bool suppress_deletions;
      +
      +	uint64_t min;
      +	uint64_t max;
     @@ reftable/merged.h (new)
      +	uint32_t hash_id;
      +	int stack_len;
      +	byte typ;
     ++	bool suppress_deletions;
      +	struct merged_iter_pqueue pq;
      +};
      +
     @@ reftable/reader.c (new)
      +	byte *f = footer;
      +	int err = 0;
      +	if (memcmp(f, "REFT", 4)) {
     -+		err = FORMAT_ERROR;
     ++		err = REFTABLE_FORMAT_ERROR;
      +		goto exit;
      +	}
      +	f += 4;
      +
      +	if (memcmp(footer, header, header_size(r->version))) {
     -+		err = FORMAT_ERROR;
     ++		err = REFTABLE_FORMAT_ERROR;
      +		goto exit;
      +	}
      +
     @@ reftable/reader.c (new)
      +		case SHA256_ID:
      +			break;
      +		default:
     -+			err = FORMAT_ERROR;
     ++			err = REFTABLE_FORMAT_ERROR;
      +			goto exit;
      +		}
      +		f += 4;
     @@ reftable/reader.c (new)
      +		uint32_t file_crc = get_be32(f);
      +		f += 4;
      +		if (computed_crc != file_crc) {
     -+			err = FORMAT_ERROR;
     ++			err = REFTABLE_FORMAT_ERROR;
      +			goto exit;
      +		}
      +	}
     @@ reftable/reader.c (new)
      +	/* Need +1 to read type of first block. */
      +	err = block_source_read_block(source, &header, 0, header_size(2) + 1);
      +	if (err != header_size(2) + 1) {
     -+		err = IO_ERROR;
     ++		err = REFTABLE_IO_ERROR;
      +		goto exit;
      +	}
      +
      +	if (memcmp(header.data, "REFT", 4)) {
     -+		err = FORMAT_ERROR;
     ++		err = REFTABLE_FORMAT_ERROR;
      +		goto exit;
      +	}
      +	r->version = header.data[4];
      +	if (r->version != 1 && r->version != 2) {
     -+		err = FORMAT_ERROR;
     ++		err = REFTABLE_FORMAT_ERROR;
      +		goto exit;
      +	}
      +
     @@ reftable/reader.c (new)
      +	err = block_source_read_block(source, &footer, r->size,
      +				      footer_size(r->version));
      +	if (err != footer_size(r->version)) {
     -+		err = IO_ERROR;
     ++		err = REFTABLE_IO_ERROR;
      +		goto exit;
      +	}
      +
     @@ reftable/reader.c (new)
      +static int table_iter_next(struct table_iter *ti, struct record rec)
      +{
      +	if (record_type(rec) != ti->typ) {
     -+		return API_ERROR;
     ++		return REFTABLE_API_ERROR;
      +	}
      +
      +	while (true) {
     @@ reftable/reader.c (new)
      +		}
      +
      +		if (next.typ != BLOCK_TYPE_INDEX) {
     -+			err = FORMAT_ERROR;
     ++			err = REFTABLE_FORMAT_ERROR;
      +			break;
      +		}
      +
     @@ reftable/record.c (new)
      +	return start_len - in.len;
      +}
      +
     -+static byte reftable_ref_record_type(void)
     -+{
     -+	return BLOCK_TYPE_REF;
     -+}
     -+
      +static void reftable_ref_record_key(const void *r, struct slice *dest)
      +{
      +	const struct reftable_ref_record *rec =
     @@ reftable/record.c (new)
      +	}
      +}
      +
     -+void reftable_ref_record_print(struct reftable_ref_record *ref, int hash_size)
     ++void reftable_ref_record_print(struct reftable_ref_record *ref,
     ++			       uint32_t hash_id)
      +{
      +	char hex[SHA256_SIZE + 1] = { 0 };
     -+
      +	printf("ref{%s(%" PRIu64 ") ", ref->ref_name, ref->update_index);
      +	if (ref->value != NULL) {
     -+		hex_format(hex, ref->value, hash_size);
     ++		hex_format(hex, ref->value, hash_size(hash_id));
      +		printf("%s", hex);
      +	}
      +	if (ref->target_value != NULL) {
     -+		hex_format(hex, ref->target_value, hash_size);
     ++		hex_format(hex, ref->target_value, hash_size(hash_id));
      +		printf(" (T %s)", hex);
      +	}
      +	if (ref->target != NULL) {
     @@ reftable/record.c (new)
      +	return start.len - in.len;
      +}
      +
     ++static bool reftable_ref_record_is_deletion_void(const void *p)
     ++{
     ++	return reftable_ref_record_is_deletion(
     ++		(const struct reftable_ref_record *)p);
     ++}
     ++
      +struct record_vtable reftable_ref_record_vtable = {
      +	.key = &reftable_ref_record_key,
     -+	.type = &reftable_ref_record_type,
     ++	.type = BLOCK_TYPE_REF,
      +	.copy_from = &reftable_ref_record_copy_from,
      +	.val_type = &reftable_ref_record_val_type,
      +	.encode = &reftable_ref_record_encode,
      +	.decode = &reftable_ref_record_decode,
      +	.clear = &reftable_ref_record_clear_void,
     ++	.is_deletion = &reftable_ref_record_is_deletion_void,
      +};
      +
     -+static byte obj_record_type(void)
     -+{
     -+	return BLOCK_TYPE_OBJ;
     -+}
     -+
      +static void obj_record_key(const void *r, struct slice *dest)
      +{
      +	const struct obj_record *rec = (const struct obj_record *)r;
     @@ reftable/record.c (new)
      +	return start.len - in.len;
      +}
      +
     ++static bool not_a_deletion(const void *p)
     ++{
     ++	return false;
     ++}
     ++
      +struct record_vtable obj_record_vtable = {
      +	.key = &obj_record_key,
     -+	.type = &obj_record_type,
     ++	.type = BLOCK_TYPE_OBJ,
      +	.copy_from = &obj_record_copy_from,
      +	.val_type = &obj_record_val_type,
      +	.encode = &obj_record_encode,
      +	.decode = &obj_record_decode,
      +	.clear = &obj_record_clear,
     ++	.is_deletion = not_a_deletion,
      +};
      +
     -+void reftable_log_record_print(struct reftable_log_record *log, int hash_size)
     ++void reftable_log_record_print(struct reftable_log_record *log,
     ++			       uint32_t hash_id)
      +{
      +	char hex[SHA256_SIZE + 1] = { 0 };
      +
      +	printf("log{%s(%" PRIu64 ") %s <%s> %" PRIu64 " %04d\n", log->ref_name,
      +	       log->update_index, log->name, log->email, log->time,
      +	       log->tz_offset);
     -+	hex_format(hex, log->old_hash, hash_size);
     ++	hex_format(hex, log->old_hash, hash_size(hash_id));
      +	printf("%s => ", hex);
     -+	hex_format(hex, log->new_hash, hash_size);
     ++	hex_format(hex, log->new_hash, hash_size(hash_id));
      +	printf("%s\n\n%s\n}\n", hex, log->message);
      +}
      +
     -+static byte reftable_log_record_type(void)
     -+{
     -+	return BLOCK_TYPE_LOG;
     -+}
     -+
      +static void reftable_log_record_key(const void *r, struct slice *dest)
      +{
      +	const struct reftable_log_record *rec =
     @@ reftable/record.c (new)
      +	int n;
      +
      +	if (key.len <= 9 || key.buf[key.len - 9] != 0) {
     -+		return FORMAT_ERROR;
     ++		return REFTABLE_FORMAT_ERROR;
      +	}
      +
      +	r->ref_name = reftable_realloc(r->ref_name, key.len - 8);
     @@ reftable/record.c (new)
      +	}
      +
      +	if (in.len < 2 * hash_size) {
     -+		return FORMAT_ERROR;
     ++		return REFTABLE_FORMAT_ERROR;
      +	}
      +
      +	r->old_hash = reftable_realloc(r->old_hash, hash_size);
     @@ reftable/record.c (new)
      +
      +error:
      +	slice_clear(&dest);
     -+	return FORMAT_ERROR;
     ++	return REFTABLE_FORMAT_ERROR;
      +}
      +
      +static bool null_streq(char *a, char *b)
     @@ reftable/record.c (new)
      +	       a->update_index == b->update_index;
      +}
      +
     ++static bool reftable_log_record_is_deletion_void(const void *p)
     ++{
     ++	return reftable_log_record_is_deletion(
     ++		(const struct reftable_log_record *)p);
     ++}
     ++
      +struct record_vtable reftable_log_record_vtable = {
      +	.key = &reftable_log_record_key,
     -+	.type = &reftable_log_record_type,
     ++	.type = BLOCK_TYPE_LOG,
      +	.copy_from = &reftable_log_record_copy_from,
      +	.val_type = &reftable_log_record_val_type,
      +	.encode = &reftable_log_record_encode,
      +	.decode = &reftable_log_record_decode,
      +	.clear = &reftable_log_record_clear_void,
     ++	.is_deletion = &reftable_log_record_is_deletion_void,
      +};
      +
      +struct record new_record(byte typ)
     @@ reftable/record.c (new)
      +	reftable_free(record_yield(rec));
      +}
      +
     -+static byte index_record_type(void)
     -+{
     -+	return BLOCK_TYPE_INDEX;
     -+}
     -+
      +static void index_record_key(const void *r, struct slice *dest)
      +{
      +	struct index_record *rec = (struct index_record *)r;
     @@ reftable/record.c (new)
      +
      +struct record_vtable index_record_vtable = {
      +	.key = &index_record_key,
     -+	.type = &index_record_type,
     ++	.type = BLOCK_TYPE_INDEX,
      +	.copy_from = &index_record_copy_from,
      +	.val_type = &index_record_val_type,
      +	.encode = &index_record_encode,
      +	.decode = &index_record_decode,
      +	.clear = &index_record_clear,
     ++	.is_deletion = &not_a_deletion,
      +};
      +
      +void record_key(struct record rec, struct slice *dest)
     @@ reftable/record.c (new)
      +
      +byte record_type(struct record rec)
      +{
     -+	return rec.ops->type();
     ++	return rec.ops->type;
      +}
      +
      +int record_encode(struct record rec, struct slice dest, int hash_size)
     @@ reftable/record.c (new)
      +
      +void record_copy_from(struct record rec, struct record src, int hash_size)
      +{
     -+	assert(src.ops->type() == rec.ops->type());
     ++	assert(src.ops->type == rec.ops->type);
      +
      +	rec.ops->copy_from(rec.data, src.data, hash_size);
      +}
     @@ reftable/record.c (new)
      +	return rec.ops->clear(rec.data);
      +}
      +
     ++bool record_is_deletion(struct record rec)
     ++{
     ++	return rec.ops->is_deletion(rec.data);
     ++}
     ++
      +void record_from_ref(struct record *rec, struct reftable_ref_record *ref_rec)
      +{
      +	rec->data = ref_rec;
     @@ reftable/record.h (new)
      +	void (*key)(const void *rec, struct slice *dest);
      +
      +	/* The record type of ('r' for ref). */
     -+	byte (*type)(void);
     ++	byte type;
      +
      +	void (*copy_from)(void *dest, const void *src, int hash_size);
      +
     @@ reftable/record.h (new)
      +
      +	/* deallocate and null the record. */
      +	void (*clear)(void *rec);
     ++
     ++	/* is this a tombstone? */
     ++	bool (*is_deletion)(const void *rec);
      +};
      +
      +/* record is a generic wrapper for different types of records. */
     @@ reftable/record.h (new)
      +int record_encode(struct record rec, struct slice dest, int hash_size);
      +int record_decode(struct record rec, struct slice key, byte extra,
      +		  struct slice src, int hash_size);
     ++bool record_is_deletion(struct record rec);
      +
      +/* zeroes out the embedded record */
      +void record_clear(struct record rec);
     @@ reftable/reftable.h (new)
      +int reftable_ref_record_is_deletion(const struct reftable_ref_record *ref);
      +
      +/* prints a reftable_ref_record onto stdout */
     -+void reftable_ref_record_print(struct reftable_ref_record *ref, int hash_size);
     ++void reftable_ref_record_print(struct reftable_ref_record *ref,
     ++			       uint32_t hash_id);
      +
      +/* frees and nulls all pointer values. */
      +void reftable_ref_record_clear(struct reftable_ref_record *ref);
     @@ reftable/reftable.h (new)
      +			      struct reftable_log_record *b, int hash_size);
      +
      +/* dumps a reftable_log_record on stdout, for debugging/testing. */
     -+void reftable_log_record_print(struct reftable_log_record *log, int hash_size);
     ++void reftable_log_record_print(struct reftable_log_record *log,
     ++			       uint32_t hash_id);
      +
      +/****************************************************************
      + Error handling
     @@ reftable/reftable.h (new)
      +/* different types of errors */
      +enum reftable_error {
      +	/* Unexpected file system behavior */
     -+	IO_ERROR = -2,
     ++	REFTABLE_IO_ERROR = -2,
      +
      +	/* Format inconsistency on reading data
      +	 */
     -+	FORMAT_ERROR = -3,
     ++	REFTABLE_FORMAT_ERROR = -3,
      +
      +	/* File does not exist. Returned from block_source_from_file(),  because
      +	   it needs special handling in stack.
      +	*/
     -+	NOT_EXIST_ERROR = -4,
     ++	REFTABLE_NOT_EXIST_ERROR = -4,
      +
      +	/* Trying to write out-of-date data. */
     -+	LOCK_ERROR = -5,
     ++	REFTABLE_LOCK_ERROR = -5,
      +
      +	/* Misuse of the API:
      +	   - on writing a record with NULL ref_name.
     @@ reftable/reftable.h (new)
      +	   - on writing a ref or log record before the stack's next_update_index
      +	   - on reading a reftable_ref_record from log iterator, or vice versa.
      +	*/
     -+	API_ERROR = -6,
     ++	REFTABLE_API_ERROR = -6,
      +
      +	/* Decompression error */
     -+	ZLIB_ERROR = -7,
     ++	REFTABLE_ZLIB_ERROR = -7,
      +
      +	/* Wrote a table without blocks. */
     -+	EMPTY_TABLE_ERROR = -8,
     ++	REFTABLE_EMPTY_TABLE_ERROR = -8,
      +};
      +
      +/* convert the numeric error code to a string. The string should not be
      + * deallocated. */
      +const char *reftable_error_str(int err);
      +
     ++/*
     ++ * Convert the numeric error code to an equivalent errno code.
     ++ */
     ++int reftable_error_to_errno(int err);
     ++
      +/****************************************************************
      + Writing
      +
     @@ reftable/reftable.h (new)
      +
      +/* Set the range of update indices for the records we will add.  When
      +   writing a table into a stack, the min should be at least
     -+   reftable_stack_next_update_index(), or API_ERROR is returned.
     ++   reftable_stack_next_update_index(), or REFTABLE_API_ERROR is returned.
      +
      +   For transactional updates, typically min==max. When converting an existing
      +   ref database into a single reftable, this would be a range of update-index
     @@ reftable/reftable.h (new)
      +
      +/* adds a reftable_ref_record. Must be called in ascending
      +   order. The update_index must be within the limits set by
     -+   reftable_writer_set_limits(), or API_ERROR is returned.
     ++   reftable_writer_set_limits(), or REFTABLE_API_ERROR is returned.
      +
      +   It is an error to write a ref record after a log record.
      + */
     @@ reftable/reftable.h (new)
      +			      struct reftable_reader **stack, int n,
      +			      uint32_t hash_id);
      +
     -+/* returns the hash id used in this merged table. */
     -+uint32_t reftable_merged_table_hash_id(struct reftable_merged_table *mt);
     -+
      +/* returns an iterator positioned just before 'name' */
      +int reftable_merged_table_seek_ref(struct reftable_merged_table *mt,
      +				   struct reftable_iterator *it,
     @@ reftable/stack.c (new)
      +		reftable_calloc(sizeof(struct reftable_stack));
      +	struct slice list_file_name = {};
      +	int err = 0;
     ++
     ++	if (config.hash_id == 0) {
     ++		config.hash_id = SHA1_ID;
     ++	}
     ++
      +	*dest = NULL;
      +
      +	slice_set_string(&list_file_name, dir);
     -+	slice_append_string(&list_file_name, "/reftables.list");
     ++	slice_append_string(&list_file_name, "/tables.list");
      +
      +	p->list_file = slice_to_string(list_file_name);
      +	slice_clear(&list_file_name);
     @@ reftable/stack.c (new)
      +	return err;
      +}
      +
     -+static int fread_lines(FILE *f, char ***namesp)
     ++static int fd_read_lines(int fd, char ***namesp)
      +{
     -+	long size = 0;
     -+	int err = fseek(f, 0, SEEK_END);
     ++	off_t size = lseek(fd, 0, SEEK_END);
      +	char *buf = NULL;
     -+	if (err < 0) {
     -+		err = IO_ERROR;
     -+		goto exit;
     -+	}
     -+	size = ftell(f);
     ++	int err = 0;
      +	if (size < 0) {
     -+		err = IO_ERROR;
     ++		err = REFTABLE_IO_ERROR;
      +		goto exit;
      +	}
     -+	err = fseek(f, 0, SEEK_SET);
     ++	err = lseek(fd, 0, SEEK_SET);
      +	if (err < 0) {
     -+		err = IO_ERROR;
     ++		err = REFTABLE_IO_ERROR;
      +		goto exit;
      +	}
      +
      +	buf = reftable_malloc(size + 1);
     -+	if (fread(buf, 1, size, f) != size) {
     -+		err = IO_ERROR;
     ++	if (read(fd, buf, size) != size) {
     ++		err = REFTABLE_IO_ERROR;
      +		goto exit;
      +	}
      +	buf[size] = 0;
      +
      +	parse_names(buf, size, namesp);
     ++
      +exit:
      +	reftable_free(buf);
      +	return err;
     @@ reftable/stack.c (new)
      +
      +int read_lines(const char *filename, char ***namesp)
      +{
     -+	FILE *f = fopen(filename, "r");
     ++	int fd = open(filename, O_RDONLY, 0644);
      +	int err = 0;
     -+	if (f == NULL) {
     ++	if (fd < 0) {
      +		if (errno == ENOENT) {
      +			*namesp = reftable_calloc(sizeof(char *));
      +			return 0;
      +		}
      +
     -+		return IO_ERROR;
     ++		return REFTABLE_IO_ERROR;
      +	}
     -+	err = fread_lines(f, namesp);
     -+	fclose(f);
     ++	err = fd_read_lines(fd, namesp);
     ++	close(fd);
      +	return err;
      +}
      +
     @@ reftable/stack.c (new)
      +		merged_table_clear(st->merged);
      +		reftable_merged_table_free(st->merged);
      +	}
     ++	new_merged->suppress_deletions = true;
      +	st->merged = new_merged;
      +
      +	{
     @@ reftable/stack.c (new)
      +		char **names_after = NULL;
      +		struct timeval now = { 0 };
      +		int err = gettimeofday(&now, NULL);
     ++		int err2 = 0;
      +		if (err < 0) {
      +			return err;
      +		}
     @@ reftable/stack.c (new)
      +			free_names(names);
      +			break;
      +		}
     -+		if (err != NOT_EXIST_ERROR) {
     ++		if (err != REFTABLE_NOT_EXIST_ERROR) {
      +			free_names(names);
      +			return err;
      +		}
      +
     -+		err = read_lines(st->list_file, &names_after);
     -+		if (err < 0) {
     ++		/* err == REFTABLE_NOT_EXIST_ERROR can be caused by a concurrent
     ++		   writer. Check if there was one by checking if the name list
     ++		   changed.
     ++		*/
     ++		err2 = read_lines(st->list_file, &names_after);
     ++		if (err2 < 0) {
      +			free_names(names);
     -+			return err;
     ++			return err2;
      +		}
      +
      +		if (names_equal(names_after, names)) {
      +			free_names(names);
      +			free_names(names_after);
     -+			return -1;
     ++			return err;
      +		}
      +		free_names(names);
      +		free_names(names_after);
     @@ reftable/stack.c (new)
      +{
      +	int err = stack_try_add(st, write, arg);
      +	if (err < 0) {
     -+		if (err == LOCK_ERROR) {
     -+			err = reftable_stack_reload(st);
     ++		if (err == REFTABLE_LOCK_ERROR) {
     ++			// Ignore error return, we want to propagate
     ++			// REFTABLE_LOCK_ERROR.
     ++			reftable_stack_reload(st);
      +		}
      +		return err;
      +	}
      +
     -+	return reftable_stack_auto_compact(st);
     ++	if (!st->disable_auto_compact) {
     ++		return reftable_stack_auto_compact(st);
     ++	}
     ++
     ++	return 0;
      +}
      +
      +static void format_name(struct slice *dest, uint64_t min, uint64_t max)
      +{
      +	char buf[100];
     -+	snprintf(buf, sizeof(buf), "%012" PRIx64 "-%012" PRIx64, min, max);
     ++	snprintf(buf, sizeof(buf), "0x%012" PRIx64 "-0x%012" PRIx64, min, max);
      +	slice_set_string(dest, buf);
      +}
      +
     @@ reftable/stack.c (new)
      +				 O_EXCL | O_CREAT | O_WRONLY, 0644);
      +	if (add->lock_file_fd < 0) {
      +		if (errno == EEXIST) {
     -+			err = LOCK_ERROR;
     ++			err = REFTABLE_LOCK_ERROR;
      +		} else {
     -+			err = IO_ERROR;
     ++			err = REFTABLE_IO_ERROR;
      +		}
      +		goto exit;
      +	}
     @@ reftable/stack.c (new)
      +	}
      +
      +	if (err > 1) {
     -+		err = LOCK_ERROR;
     ++		err = REFTABLE_LOCK_ERROR;
      +		goto exit;
      +	}
      +
     @@ reftable/stack.c (new)
      +	err = write(add->lock_file_fd, table_list.buf, table_list.len);
      +	slice_clear(&table_list);
      +	if (err < 0) {
     -+		err = IO_ERROR;
     ++		err = REFTABLE_IO_ERROR;
      +		goto exit;
      +	}
      +
      +	err = close(add->lock_file_fd);
      +	add->lock_file_fd = 0;
      +	if (err < 0) {
     -+		err = IO_ERROR;
     ++		err = REFTABLE_IO_ERROR;
      +		goto exit;
      +	}
      +
      +	err = rename(slice_as_string(&add->lock_file_name),
      +		     add->stack->list_file);
      +	if (err < 0) {
     -+		err = IO_ERROR;
     ++		err = REFTABLE_IO_ERROR;
      +		goto exit;
      +	}
      +
     @@ reftable/stack.c (new)
      +
      +	tab_fd = mkstemp((char *)slice_as_string(&temp_tab_file_name));
      +	if (tab_fd < 0) {
     -+		err = IO_ERROR;
     ++		err = REFTABLE_IO_ERROR;
      +		goto exit;
      +	}
      +
     @@ reftable/stack.c (new)
      +	}
      +
      +	err = reftable_writer_close(wr);
     -+	if (err == EMPTY_TABLE_ERROR) {
     ++	if (err == REFTABLE_EMPTY_TABLE_ERROR) {
      +		err = 0;
      +		goto exit;
      +	}
     @@ reftable/stack.c (new)
      +	err = close(tab_fd);
      +	tab_fd = 0;
      +	if (err < 0) {
     -+		err = IO_ERROR;
     ++		err = REFTABLE_IO_ERROR;
      +		goto exit;
      +	}
      +
      +	if (wr->min_update_index < next_update_index) {
     -+		err = API_ERROR;
     ++		err = REFTABLE_API_ERROR;
      +		goto exit;
      +	}
      +
     @@ reftable/stack.c (new)
      +	err = rename(slice_as_string(&temp_tab_file_name),
      +		     slice_as_string(&tab_file_name));
      +	if (err < 0) {
     -+		err = IO_ERROR;
     ++		err = REFTABLE_IO_ERROR;
      +		goto exit;
      +	}
      +
     @@ reftable/stack.c (new)
      +		if (errno == EEXIST) {
      +			err = 1;
      +		} else {
     -+			err = IO_ERROR;
     ++			err = REFTABLE_IO_ERROR;
      +		}
      +		goto exit;
      +	}
     @@ reftable/stack.c (new)
      +			} else if (sublock_file_fd < 0) {
      +				if (errno == EEXIST) {
      +					err = 1;
     ++				} else {
     ++					err = REFTABLE_IO_ERROR;
      +				}
     -+				err = IO_ERROR;
      +			}
      +		}
      +
     @@ reftable/stack.c (new)
      +				   expiry);
      +	/* Compaction + tombstones can create an empty table out of non-empty
      +	 * tables. */
     -+	is_empty_table = (err == EMPTY_TABLE_ERROR);
     ++	is_empty_table = (err == REFTABLE_EMPTY_TABLE_ERROR);
      +	if (is_empty_table) {
      +		err = 0;
      +	}
     @@ reftable/stack.c (new)
      +		if (errno == EEXIST) {
      +			err = 1;
      +		} else {
     -+			err = IO_ERROR;
     ++			err = REFTABLE_IO_ERROR;
      +		}
      +		goto exit;
      +	}
     @@ reftable/stack.c (new)
      +		err = rename(slice_as_string(&temp_tab_file_name),
      +			     slice_as_string(&new_table_path));
      +		if (err < 0) {
     ++			err = REFTABLE_IO_ERROR;
      +			goto exit;
      +		}
      +	}
     @@ reftable/stack.c (new)
      +
      +	err = write(lock_file_fd, ref_list_contents.buf, ref_list_contents.len);
      +	if (err < 0) {
     ++		err = REFTABLE_IO_ERROR;
      +		unlink(slice_as_string(&new_table_path));
      +		goto exit;
      +	}
      +	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;
      +	}
      +
      +	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;
      +	}
     @@ reftable/stack.c (new)
      +{
      +	uint64_t *sizes =
      +		reftable_calloc(sizeof(uint64_t) * st->merged->stack_len);
     ++	int version = (st->config.hash_id == SHA1_ID) ? 1 : 2;
     ++	int overhead = footer_size(version) + header_size(version) - 1;
      +	int i = 0;
      +	for (i = 0; i < st->merged->stack_len; i++) {
     -+		/* overhead is 24 + 68 = 92. */
     -+		sizes[i] = st->merged->stack[i]->size - 91;
     ++		sizes[i] = st->merged->stack[i]->size - overhead;
      +	}
      +	return sizes;
      +}
     @@ reftable/stack.h (new)
      +#define STACK_H
      +
      +#include "reftable.h"
     ++#include "system.h"
      +
      +struct reftable_stack {
      +	char *list_file;
      +	char *reftable_dir;
     ++	bool disable_auto_compact;
      +
      +	struct reftable_write_options config;
      +
     @@ reftable/update.sh (new)
      @@
      +#!/bin/sh
      +
     -+set -eux
     ++set -eu
      +
     -+((cd reftable-repo && git fetch origin && git checkout origin/master ) ||
     -+git clone https://github.com/google/reftable reftable-repo) && \
     -+cp reftable-repo/c/*.[ch] reftable/ && \
     -+cp reftable-repo/c/include/*.[ch] reftable/ && \
     -+cp reftable-repo/LICENSE reftable/ &&
     ++# Override this to import from somewhere else, say "../reftable".
     ++SRC=${SRC:-origin} BRANCH=${BRANCH:-origin/master}
     ++
     ++((git --git-dir reftable-repo/.git fetch ${SRC} && cd reftable-repo && git checkout ${BRANCH} ) ||
     ++   git clone https://github.com/google/reftable reftable-repo)
     ++
     ++cp reftable-repo/c/*.[ch] reftable/
     ++cp reftable-repo/c/include/*.[ch] reftable/
     ++cp reftable-repo/LICENSE reftable/
      +git --git-dir reftable-repo/.git show --no-patch origin/master \
     -+> reftable/VERSION && \
     -+sed -i~ 's|if REFTABLE_IN_GITCORE|if 1 /* REFTABLE_IN_GITCORE */|' reftable/system.h
     ++  > reftable/VERSION
     ++
     ++mv reftable/system.h reftable/system.h~
     ++sed 's|if REFTABLE_IN_GITCORE|if 1 /* REFTABLE_IN_GITCORE */|'  < reftable/system.h~ > reftable/system.h
     ++
     ++# Remove unittests and compatibility hacks we don't need here.  
      +rm reftable/*_test.c reftable/test_framework.* reftable/compat.*
     -+git add reftable/*.[ch]
     ++
     ++git add reftable/*.[ch] reftable/LICENSE reftable/VERSION 
      
       ## reftable/writer.c (new) ##
      @@
     @@ reftable/writer.c (new)
      +	int err = 0;
      +
      +	if (ref->ref_name == NULL) {
     -+		return API_ERROR;
     ++		return REFTABLE_API_ERROR;
      +	}
      +	if (ref->update_index < w->min_update_index ||
      +	    ref->update_index > w->max_update_index) {
     -+		return API_ERROR;
     ++		return REFTABLE_API_ERROR;
      +	}
      +
      +	record_from_ref(&rec, &copy);
     @@ reftable/writer.c (new)
      +			    struct reftable_log_record *log)
      +{
      +	if (log->ref_name == NULL) {
     -+		return API_ERROR;
     ++		return REFTABLE_API_ERROR;
      +	}
      +
      +	if (w->block_writer != NULL &&
     @@ reftable/writer.c (new)
      +	}
      +
      +	if (empty_table) {
     -+		err = EMPTY_TABLE_ERROR;
     ++		err = REFTABLE_EMPTY_TABLE_ERROR;
      +		goto exit;
      +	}
      +
 10:  ad72edbcfd4 ! 10:  be2371cd6e4 Reftable support for git-core
     @@ Commit message
          TODO:
      
           * Resolve spots marked with XXX
     -     * Test strategy?
     +
     +     * Detect and prevent directory/file conflicts in naming.
     +
     +     * Support worktrees (t0002-gitfile "linked repo" testcase)
      
          Example use: see t/t0031-reftable.sh
      
     @@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
       	}
       
      -	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, INIT_DB_QUIET);
     -+	init_db(git_dir, real_git_dir, option_template,
     -+                GIT_HASH_UNKNOWN,
     -+		DEFAULT_REF_STORAGE, /* XXX */
     -+		INIT_DB_QUIET);
     ++	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN,
     ++		DEFAULT_REF_STORAGE, INIT_DB_QUIET);
       
       	if (real_git_dir)
       		git_dir = real_git_dir;
     @@ builtin/init-db.c: static int needs_work_tree_config(const char *git_dir, const
       }
       
      -void initialize_repository_version(int hash_algo)
     -+void initialize_repository_version(int hash_algo, const char *ref_storage_format)
     ++void initialize_repository_version(int hash_algo,
     ++				   const char *ref_storage_format)
       {
       	char repo_version_string[10];
       	int repo_version = GIT_REPO_VERSION;
     @@ builtin/init-db.c: void initialize_repository_version(int hash_algo)
       #endif
       
      -	if (hash_algo != GIT_HASH_SHA1)
     -+	if (hash_algo != GIT_HASH_SHA1 || !strcmp(ref_storage_format, "reftable"))
     ++	if (hash_algo != GIT_HASH_SHA1 ||
     ++	    !strcmp(ref_storage_format, "reftable"))
       		repo_version = GIT_REPO_VERSION_READ;
       
       	/* This forces creation of new config file */
     @@ builtin/init-db.c: static int create_default_files(const char *template_path,
      +	path = git_path_buf(&buf, "HEAD");
      +	reinit = (!access(path, R_OK) ||
      +		  readlink(path, junk, sizeof(junk) - 1) != -1);
     ++
     ++        /*
     ++         * refs/heads is a file when using reftable. We can't reinitialize with
     ++         * a reftable because it will overwrite HEAD
     ++         */
     ++	if (reinit && (!strcmp(fmt->ref_storage, "reftable")) ==
     ++			      is_directory(git_path_buf(&buf, "refs/heads"))) {
     ++		die("cannot switch ref storage format.");
     ++	}
      +
       	/*
       	 * We need to create a "refs" dir in any case so that older
       	 * versions of git can tell that this is a repository.
     + 	 */
     +-
     + 	if (refs_init_db(&err))
     + 		die("failed to set up refs db: %s", err.buf);
     + 
      @@ builtin/init-db.c: static int create_default_files(const char *template_path,
       	 * Create the default symlink from ".git/HEAD" to the "master"
       	 * branch, if it does not exist yet.
     @@ builtin/init-db.c: static int create_default_files(const char *template_path,
       	if (!reinit) {
       		if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
       			exit(1);
     -+	} else {
     -+		/*
     -+		 * XXX should check whether our ref backend matches the
     -+		 * original one; if not, either die() or convert
     -+		 */
     - 	}
     - 
     +-	}
     +-
      -	initialize_repository_version(fmt->hash_algo);
     -+	initialize_repository_version(fmt->hash_algo, fmt->ref_storage);
     ++	} 
       
     ++	initialize_repository_version(fmt->hash_algo, fmt->ref_storage);
     ++        
       	/* Check filemode trustability */
       	path = git_path_buf(&buf, "config");
     + 	filemode = TEST_FILEMODE;
      @@ builtin/init-db.c: static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash
       }
       
       int init_db(const char *git_dir, const char *real_git_dir,
      -	    const char *template_dir, int hash, unsigned int flags)
      +	    const char *template_dir, int hash, const char *ref_storage_format,
     -+            unsigned int flags)
     ++	    unsigned int flags)
       {
       	int reinit;
       	int exist_ok = flags & INIT_DB_EXIST_OK;
     @@ builtin/init-db.c: int init_db(const char *git_dir, const char *real_git_dir,
       	 * is an attempt to reinitialize new repository with an old tool.
       	 */
       	check_repository_format(&repo_fmt);
     -+        repo_fmt.ref_storage = xstrdup(ref_storage_format);
     ++	repo_fmt.ref_storage = xstrdup(ref_storage_format);
       
       	validate_hash_algorithm(&repo_fmt, hash);
       
     @@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *pref
       
       	flags |= INIT_DB_EXIST_OK;
      -	return init_db(git_dir, real_git_dir, template_dir, hash_algo, flags);
     -+	return init_db(git_dir, real_git_dir, template_dir, hash_algo, ref_storage_format, flags);
     ++	return init_db(git_dir, real_git_dir, template_dir, hash_algo,
     ++		       ref_storage_format, flags);
       }
      
       ## cache.h ##
     @@ cache.h: int path_inside_repo(const char *prefix, const char *path);
       
       int init_db(const char *git_dir, const char *real_git_dir,
       	    const char *template_dir, int hash_algo,
     -+            const char *ref_storage_format,
     - 	    unsigned int flags);
     +-	    unsigned int flags);
      -void initialize_repository_version(int hash_algo);
     -+void initialize_repository_version(int hash_algo, const char *ref_storage_format);
     ++	    const char *ref_storage_format, unsigned int flags);
     ++void initialize_repository_version(int hash_algo,
     ++				   const char *ref_storage_format);
       
       void sanitize_stdfds(void);
       int daemonize(void);
     @@ cache.h: struct repository_format {
      
       ## refs.c ##
      @@
     + #include "argv-array.h"
     + #include "repository.h"
     + 
     ++const char *default_ref_storage(void)
     ++{
     ++	const char *test = getenv("GIT_TEST_REFTABLE");
     ++	return test ? "reftable" : "files";
     ++}
     ++
       /*
        * List of all available backends
        */
     @@ refs.c: struct ref_store *get_main_ref_store(struct repository *r)
       	if (!r->gitdir)
       		BUG("attempting to get main_ref_store outside of repository");
       
     --	r->refs = ref_store_init(r->gitdir, REF_STORE_ALL_CAPS);
     -+	r->refs = ref_store_init(r->gitdir,
     -+				 r->ref_storage_format ? r->ref_storage_format :
     -+							 DEFAULT_REF_STORAGE,
     -+				 REF_STORE_ALL_CAPS);
     - 	return r->refs;
     +-	r->refs_private = ref_store_init(r->gitdir, REF_STORE_ALL_CAPS);
     ++	r->refs_private = ref_store_init(
     ++                r->gitdir,
     ++                r->ref_storage_format ? r->ref_storage_format : DEFAULT_REF_STORAGE,
     ++                REF_STORE_ALL_CAPS);
     + 	return r->refs_private;
       }
       
      @@ refs.c: struct ref_store *get_submodule_ref_store(const char *submodule)
     @@ refs.h: struct string_list;
       struct string_list_item;
       struct worktree;
       
     -+#define DEFAULT_REF_STORAGE "files"
     ++/* Returns the ref storage backend to use by default. */
     ++const char *default_ref_storage(void);
      +
       /*
        * Resolve a reference, recursively following symbolic refererences.
     @@ refs/reftable-backend.c (new)
      +	unsigned int store_flags;
      +
      +	int err;
     ++        char *repo_dir;
      +	char *reftable_dir;
      +	struct reftable_stack *stack;
      +};
     @@ refs/reftable-backend.c (new)
      +
      +	base_ref_store_init(ref_store, &refs_be_reftable);
      +	refs->store_flags = store_flags;
     -+
     ++        refs->repo_dir = xstrdup(path);
      +	strbuf_addf(&sb, "%s/reftable", path);
      +	refs->reftable_dir = xstrdup(sb.buf);
      +	strbuf_reset(&sb);
      +
     -+	strbuf_addf(&sb, "%s/refs", path);
     -+	safe_create_dir(sb.buf, 1);
     -+	strbuf_reset(&sb);
     -+
     -+	strbuf_addf(&sb, "%s/HEAD", path);
     -+	write_file(sb.buf, "ref: refs/.invalid");
     -+	strbuf_reset(&sb);
     -+
     -+	strbuf_addf(&sb, "%s/refs/heads", path);
     -+	write_file(sb.buf, "this repository uses the reftable format");
     -+
      +	refs->err = reftable_new_stack(&refs->stack, refs->reftable_dir, cfg);
      +	strbuf_release(&sb);
      +	return ref_store;
     @@ refs/reftable-backend.c (new)
      +{
      +	struct git_reftable_ref_store *refs =
      +		(struct git_reftable_ref_store *)ref_store;
     ++	struct strbuf sb = STRBUF_INIT;
     ++
      +	safe_create_dir(refs->reftable_dir, 1);
     -+	return 0;
     ++
     ++	strbuf_addf(&sb, "%s/HEAD", refs->repo_dir);
     ++	write_file(sb.buf, "ref: refs/.invalid");
     ++	strbuf_reset(&sb);
     ++
     ++	strbuf_addf(&sb, "%s/refs", refs->repo_dir);
     ++	safe_create_dir(sb.buf, 1);
     ++	strbuf_reset(&sb);
     ++
     ++	strbuf_addf(&sb, "%s/refs/heads", refs->repo_dir);
     ++	write_file(sb.buf, "this repository uses the reftable format");
     ++
     ++        return 0;
      +}
      +
      +struct git_reftable_iterator {
     @@ refs/reftable-backend.c (new)
      +	}
      +
      +	base_ref_iterator_init(&ri->base, &reftable_ref_iterator_vtable, 1);
     -+        ri->prefix = prefix;
     ++	ri->prefix = prefix;
      +	ri->base.oid = &ri->oid;
      +	ri->flags = flags;
      +	ri->ref_store = ref_store;
     @@ refs/reftable-backend.c (new)
      +	const char *resolved = refs_resolve_ref_unsafe(
      +		refs, refname, RESOLVE_REF_READING, &out_oid, &out_flags);
      +	if (is_null_oid(want_oid) != (resolved == NULL)) {
     -+		return LOCK_ERROR;
     ++		return REFTABLE_LOCK_ERROR;
      +	}
      +
      +	if (resolved != NULL && !oideq(&out_oid, want_oid)) {
     -+		return LOCK_ERROR;
     ++		return REFTABLE_LOCK_ERROR;
      +	}
      +
      +	return 0;
     @@ refs/reftable-backend.c (new)
      +		(struct git_reftable_ref_store *)transaction->ref_store;
      +	uint64_t ts = reftable_stack_next_update_index(refs->stack);
      +	int err = 0;
     ++	int i = 0;
      +	struct reftable_log_record *logs =
      +		calloc(transaction->nr, sizeof(*logs));
      +	struct ref_update **sorted =
     @@ refs/reftable-backend.c (new)
      +	QSORT(sorted, transaction->nr, ref_update_cmp);
      +	reftable_writer_set_limits(writer, ts, ts);
      +
     -+	for (int i = 0; i < transaction->nr; i++) {
     ++	for (i = 0; i < transaction->nr; i++) {
      +		struct ref_update *u = sorted[i];
      +		if (u->flags & REF_HAVE_OLD) {
      +			err = reftable_check_old_oid(transaction->ref_store,
     @@ refs/reftable-backend.c (new)
      +		}
      +	}
      +
     -+	for (int i = 0; i < transaction->nr; i++) {
     ++	for (i = 0; i < transaction->nr; i++) {
      +		struct ref_update *u = sorted[i];
      +		struct reftable_log_record *log = &logs[i];
      +		fill_reftable_log_record(log);
     @@ refs/reftable-backend.c (new)
      +				transaction->ref_store, u->refname, 0, &out_oid,
      +				&out_flags);
      +			struct reftable_ref_record ref = { NULL };
     ++			struct object_id peeled;
     ++			int peel_error = peel_object(&u->new_oid, &peeled);
     ++
      +			ref.ref_name =
      +				(char *)(resolved ? resolved : u->refname);
      +			log->ref_name = ref.ref_name;
     -+			ref.value = u->new_oid.hash;
     ++
     ++			if (!is_null_oid(&u->new_oid)) {
     ++				ref.value = u->new_oid.hash;
     ++			}
      +			ref.update_index = ts;
     ++			if (!peel_error) {
     ++				ref.target_value = peeled.hash;
     ++			}
     ++
      +			err = reftable_writer_add_ref(writer, &ref);
      +			if (err < 0) {
      +				goto exit;
     @@ refs/reftable-backend.c (new)
      +		}
      +	}
      +
     -+	for (int i = 0; i < transaction->nr; i++) {
     ++	for (i = 0; i < transaction->nr; i++) {
      +		err = reftable_writer_add_log(writer, &logs[i]);
      +		clear_reftable_log_record(&logs[i]);
      +		if (err < 0) {
     @@ refs/reftable-backend.c (new)
      +	err = reftable_stack_add(refs->stack, &write_transaction_table,
      +				 transaction);
      +	if (err < 0) {
     -+		strbuf_addf(errmsg, "reftable: transaction failure %s",
     ++		strbuf_addf(errmsg, "reftable: transaction failure: %s",
      +			    reftable_error_str(err));
      +		return -1;
      +	}
     @@ refs/reftable-backend.c (new)
      +		(struct write_delete_refs_arg *)argv;
      +	uint64_t ts = reftable_stack_next_update_index(arg->stack);
      +	int err = 0;
     ++	int i = 0;
      +
      +	reftable_writer_set_limits(writer, ts, ts);
     -+	for (int i = 0; i < arg->refnames->nr; i++) {
     ++	for (i = 0; i < arg->refnames->nr; i++) {
      +		struct reftable_ref_record ref = {
      +			.ref_name = (char *)arg->refnames->items[i].string,
      +			.update_index = ts,
     @@ refs/reftable-backend.c (new)
      +		}
      +	}
      +
     -+	for (int i = 0; i < arg->refnames->nr; i++) {
     ++	for (i = 0; i < arg->refnames->nr; i++) {
      +		struct reftable_log_record log = { NULL };
      +		struct reftable_ref_record current = { NULL };
      +		fill_reftable_log_record(&log);
     @@ refs/reftable-backend.c (new)
      +			return ITER_ERROR;
      +		}
      +
     -+                if (reftable_log_record_is_deletion(&ri->log)) {
     -+                        /* XXX - Why does the reftable_stack filter these? */
     -+                        continue;
     -+                }
      +		ri->base.refname = ri->log.ref_name;
      +		if (ri->last_name != NULL &&
      +		    !strcmp(ri->log.ref_name, ri->last_name)) {
     -+                        /* we want the refnames that we have reflogs for, so we
     -+                         * skip if we've already produced this name. This could
     -+                         * be faster by seeking directly to
     -+                         * reflog@update_index==0.
     -+                         */
     ++			/* we want the refnames that we have reflogs for, so we
     ++			 * skip if we've already produced this name. This could
     ++			 * be faster by seeking directly to
     ++			 * reflog@update_index==0.
     ++			 */
      +			continue;
      +		}
      +
     @@ refs/reftable-backend.c (new)
      +	int cap = 0;
      +	int len = 0;
      +	int err = 0;
     ++	int i = 0;
      +
      +	if (refs->err < 0) {
      +		return refs->err;
     @@ refs/reftable-backend.c (new)
      +		logs[len++] = log;
      +	}
      +
     -+	for (int i = len; i--;) {
     ++	for (i = len; i--;) {
      +		struct reftable_log_record *log = &logs[i];
      +		struct object_id old_oid;
      +		struct object_id new_oid;
     @@ refs/reftable-backend.c (new)
      +		}
      +	}
      +
     -+	for (int i = 0; i < len; i++) {
     ++	for (i = 0; i < len; i++) {
      +		reftable_log_record_clear(&logs[i]);
      +	}
      +	free(logs);
     @@ refs/reftable-backend.c (new)
      +	}
      +
      +	err = reftable_stack_read_ref(refs->stack, refname, &ref);
     -+	if (err) {
     ++        if (err > 0) {
     ++                errno = ENOENT;
     ++                err = -1;
     ++                goto exit;
     ++        }
     ++	if (err < 0) {
     ++                errno = reftable_error_to_errno(err);
     ++                err = -1;
      +		goto exit;
      +	}
      +	if (ref.target != NULL) {
     @@ refs/reftable-backend.c (new)
      +		strbuf_reset(referent);
      +		strbuf_addstr(referent, ref.target);
      +		*type |= REF_ISSYMREF;
     -+	} else {
     ++	} else if (ref.value != NULL) {
      +		hashcpy(oid->hash, ref.value);
     -+	}
     ++	} else {
     ++                *type |= REF_ISBROKEN;
     ++                errno = EINVAL;
     ++                err = -1;
     ++        }
      +exit:
      +	reftable_ref_record_clear(&ref);
      +	return err;
     @@ refs/reftable-backend.c (new)
      +	reftable_reflog_expire
      +};
      
     + ## reftable/update.sh ##
     +@@ reftable/update.sh: SRC=${SRC:-origin} BRANCH=${BRANCH:-origin/master}
     + cp reftable-repo/c/*.[ch] reftable/
     + cp reftable-repo/c/include/*.[ch] reftable/
     + cp reftable-repo/LICENSE reftable/
     +-git --git-dir reftable-repo/.git show --no-patch origin/master \
     ++git --git-dir reftable-repo/.git show --no-patch ${BRANCH} \
     +   > reftable/VERSION
     + 
     + mv reftable/system.h reftable/system.h~
     +
       ## repository.c ##
      @@ repository.c: int repo_init(struct repository *repo,
       	if (worktree)
     @@ repository.c: int repo_init(struct repository *repo,
      
       ## repository.h ##
      @@ repository.h: struct repository {
     - 	/* The store in which the refs are held. */
     - 	struct ref_store *refs;
     + 	 */
     + 	struct ref_store *refs_private;
       
      +	/* The format to use for the ref database. */
      +	char *ref_storage_format;
     @@ t/t0031-reftable.sh (new)
      +
      +. ./test-lib.sh
      +
     -+# XXX - fix GC
     -+test_expect_success 'basic operation of reftable storage' '
     ++INVALID_SHA1=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
     ++
     ++initialize ()  {
      +	rm -rf .git &&
      +	git init --ref-storage=reftable &&
     -+	mv .git/hooks .git/hooks-disabled &&
     ++	mv .git/hooks .git/hooks-disabled
     ++}
     ++
     ++test_expect_success 'delete ref' '
     ++	initialize &&
     ++	test_commit file &&
     ++	SHA=$(git show-ref -s --verify HEAD) &&
     ++	test_write_lines "$SHA refs/heads/master" "$SHA refs/tags/file" >expect &&
     ++	git show-ref > actual &&
     ++	! git update-ref -d refs/tags/file $INVALID_SHA1 &&
     ++	test_cmp expect actual &&
     ++	git update-ref -d refs/tags/file $SHA  &&
     ++	test_write_lines "$SHA refs/heads/master" >expect &&
     ++	git show-ref > actual &&
     ++	test_cmp expect actual
     ++'
     ++
     ++test_expect_success 'basic operation of reftable storage: commit, reflog, repack' '
     ++	initialize &&
      +	test_commit file &&
      +	test_write_lines refs/heads/master refs/tags/file >expect &&
      +	git show-ref &&
     @@ t/t0031-reftable.sh (new)
      +	for count in $(test_seq 1 10)
      +	do
      +		test_commit "number $count" file.t $count number-$count ||
     -+ 		return 1
     ++	        return 1
      +	done &&
     -+(true || (test_pause &&
     -+	git gc &&
     ++	git pack-refs &&
      +	ls -1 .git/reftable >table-files &&
      +	test_line_count = 2 table-files &&
     -+ 	git reflog refs/heads/master >output &&
     ++	git reflog refs/heads/master >output &&
      +	test_line_count = 11 output &&
     -+	grep "commit (initial): first post" output &&
     -+	grep "commit: number 10" output ))
     ++	grep "commit (initial): file" output &&
     ++	grep "commit: number 10" output &&
     ++	git gc &&
     ++	git reflog refs/heads/master >output &&
     ++	test_line_count = 0 output 
     ++'
     ++
     ++# This matches show-ref's output
     ++print_ref() {
     ++	echo "$(git rev-parse "$1") $1"
     ++}
     ++
     ++test_expect_success 'peeled tags are stored' '
     ++	initialize &&
     ++	test_commit file &&
     ++	git tag -m "annotated tag" test_tag HEAD &&
     ++	{
     ++		print_ref "refs/heads/master" &&
     ++		print_ref "refs/tags/file" &&
     ++		print_ref "refs/tags/test_tag" &&
     ++		print_ref "refs/tags/test_tag^{}" 
     ++	} >expect &&
     ++	git show-ref -d >actual &&
     ++	test_cmp expect actual
     ++'
     ++
     ++test_expect_success 'show-ref works on fresh repo' '
     ++	initialize &&
     ++	rm -rf .git &&
     ++	git init --ref-storage=reftable &&
     ++	>expect &&
     ++	! git show-ref > actual &&
     ++	test_cmp expect actual
     ++'
     ++
     ++test_expect_success 'checkout unborn branch' '
     ++	initialize &&
     ++	git checkout -b master
     ++'
     ++
     ++test_expect_success 'do not clobber existing repo' '
     ++	rm -rf .git &&
     ++	git init --ref-storage=files &&
     ++	cat .git/HEAD > expect &&
     ++	test_commit file &&
     ++	(git init --ref-storage=reftable || true) &&
     ++	cat .git/HEAD > actual &&
     ++	test_cmp expect actual
      +'
      +
      +test_done
  -:  ----------- > 11:  8af67b85e49 Add some reftable testing infrastructure
  -:  ----------- > 12:  b02b83a92ad t: use update-ref and show-ref to reading/writing refs

-- 
gitgitgadget

  parent reply	other threads:[~2020-04-27 20:20 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                 ` Han-Wen Nienhuys via GitGitGadget [this message]
2020-04-27 20:13                   ` [PATCH v10 01/12] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 02/12] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-04-30 21:17                     ` Emily Shaffer
2020-05-04 18:03                       ` Han-Wen Nienhuys
2020-05-05 18:26                         ` Pseudo ref handling (was Re: [PATCH v10 02/12] Iterate over the "refs/" namespace in for_each_[raw]ref) Han-Wen Nienhuys
2020-04-27 20:13                   ` [PATCH v10 03/12] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-04-30 21:24                     ` Emily Shaffer
2020-04-30 21:49                       ` Junio C Hamano
2020-05-04 18:10                       ` Han-Wen Nienhuys
2020-04-27 20:13                   ` [PATCH v10 04/12] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 05/12] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 06/12] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 07/12] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 08/12] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 09/12] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-04-28 14:55                     ` Danh Doan
2020-04-28 15:29                       ` Junio C Hamano
2020-04-28 15:31                         ` Junio C Hamano
2020-04-28 20:21                       ` Han-Wen Nienhuys
2020-04-28 20:23                         ` Han-Wen Nienhuys
2020-04-27 20:13                   ` [PATCH v10 10/12] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 11/12] Add some reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13                   ` [PATCH v10 12/12] t: use update-ref and show-ref to reading/writing refs Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                   ` [PATCH v11 00/12] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 01/12] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 02/12] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 03/12] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 04/12] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 05/12] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 06/12] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 07/12] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 08/12] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 09/12] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 10/12] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 11/12] Add some reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03                     ` [PATCH v11 12/12] t: use update-ref and show-ref to reading/writing refs Han-Wen Nienhuys via GitGitGadget
2020-05-06  4:29                     ` [PATCH v11 00/12] Reftable support git-core Junio C Hamano
2020-05-07  9:59                     ` [PATCH v12 " Han-Wen Nienhuys via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 01/12] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-05-08 18:54                         ` Junio C Hamano
2020-05-07  9:59                       ` [PATCH v12 02/12] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-08 18:54                         ` Junio C Hamano
2020-05-11 11:41                           ` Han-Wen Nienhuys
2020-05-07  9:59                       ` [PATCH v12 03/12] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-05-08 18:58                         ` Junio C Hamano
2020-05-11 11:42                           ` Han-Wen Nienhuys
2020-05-11 14:49                             ` Junio C Hamano
2020-05-11 15:11                               ` Han-Wen Nienhuys
2020-05-07  9:59                       ` [PATCH v12 04/12] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 05/12] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 06/12] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-05-08 19:59                         ` Junio C Hamano
2020-05-07  9:59                       ` [PATCH v12 07/12] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 08/12] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 09/12] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 10/12] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 11/12] t: use update-ref and show-ref to reading/writing refs Han-Wen Nienhuys via GitGitGadget
2020-05-07  9:59                       ` [PATCH v12 12/12] Add some reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46                       ` [PATCH v13 00/13] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46                         ` [PATCH v13 01/13] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-05-18 23:31                           ` Junio C Hamano
2020-05-11 19:46                         ` [PATCH v13 02/13] t: use update-ref and show-ref to reading/writing refs Han-Wen Nienhuys via GitGitGadget
2020-05-18 23:34                           ` Junio C Hamano
2020-05-11 19:46                         ` [PATCH v13 03/13] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-05-18 23:43                           ` Junio C Hamano
2020-05-11 19:46                         ` [PATCH v13 04/13] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-05-19 22:00                           ` Junio C Hamano
2020-05-20 16:06                             ` Han-Wen Nienhuys
2020-05-20 17:20                               ` Han-Wen Nienhuys
2020-05-20 17:25                                 ` Han-Wen Nienhuys
2020-05-20 17:33                                   ` Junio C Hamano
2020-05-20 18:52                             ` Jonathan Nieder
2020-05-11 19:46                         ` [PATCH v13 05/13] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-05-19 22:01                           ` Junio C Hamano
2020-05-11 19:46                         ` [PATCH v13 06/13] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-05-19 22:32                           ` Junio C Hamano
2020-05-20 12:38                             ` Han-Wen Nienhuys
2020-05-20 14:40                               ` Junio C Hamano
2020-05-11 19:46                         ` [PATCH v13 07/13] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-05-12 10:22                           ` Phillip Wood
2020-05-12 16:48                             ` Han-Wen Nienhuys
2020-05-13 10:06                               ` Phillip Wood
2020-05-13 18:10                                 ` Phillip Wood
2020-05-11 19:46                         ` [PATCH v13 08/13] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46                         ` [PATCH v13 09/13] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46                         ` [PATCH v13 10/13] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46                         ` [PATCH v13 11/13] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-13 19:55                           ` Junio C Hamano
2020-05-11 19:46                         ` [PATCH v13 12/13] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-11 19:46                         ` [PATCH v13 13/13] Add some reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-13 19:57                           ` Junio C Hamano
2020-05-19 13:54                             ` Han-Wen Nienhuys
2020-05-19 15:21                               ` Junio C Hamano
2020-05-12  0:41                         ` [PATCH v13 00/13] Reftable support git-core Junio C Hamano
2020-05-12  7:49                           ` Han-Wen Nienhuys
2020-05-13 21:21                             ` Junio C Hamano
2020-05-18 20:31                         ` [PATCH v14 0/9] " Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 1/9] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 2/9] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 3/9] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 4/9] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 5/9] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 6/9] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 7/9] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 8/9] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-18 20:31                           ` [PATCH v14 9/9] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                           ` [PATCH v15 00/13] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 01/13] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 02/13] Make refs_ref_exists public Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 03/13] Treat BISECT_HEAD as a pseudo ref Han-Wen Nienhuys via GitGitGadget
2020-05-28 20:52                               ` Junio C Hamano
2020-05-28 19:46                             ` [PATCH v15 04/13] Treat CHERRY_PICK_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 05/13] Treat REVERT_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 06/13] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 07/13] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 08/13] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 09/13] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 10/13] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 11/13] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 12/13] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-28 19:46                             ` [PATCH v15 13/13] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-28 20:15                             ` [PATCH v15 00/13] Reftable support git-core Junio C Hamano
2020-05-28 21:21                             ` Junio C Hamano
2020-06-05 18:03                             ` [PATCH v16 00/14] " Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 01/14] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-06-09 10:16                                 ` Phillip Wood
2020-06-05 18:03                               ` [PATCH v16 02/14] Make refs_ref_exists public Han-Wen Nienhuys via GitGitGadget
2020-06-09 10:36                                 ` Phillip Wood
2020-06-10 18:05                                   ` Han-Wen Nienhuys
2020-06-11 14:59                                     ` Phillip Wood
2020-06-12  9:51                                       ` Phillip Wood
2020-06-15 11:32                                         ` Han-Wen Nienhuys
2020-06-05 18:03                               ` [PATCH v16 03/14] Treat BISECT_HEAD as a pseudo ref Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 04/14] Treat CHERRY_PICK_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 05/14] Treat REVERT_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 06/14] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 07/14] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 08/14] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 09/14] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 10/14] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 11/14] Hookup unittests for the reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-08 19:39                                 ` Junio C Hamano
2020-06-09 17:22                                   ` [PATCH] Fixup! Add t/helper/test-reftable.c hanwen
2020-06-09 20:45                                     ` Junio C Hamano
2020-06-05 18:03                               ` [PATCH v16 12/14] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 13/14] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-06-05 18:03                               ` [PATCH v16 14/14] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-06-09 23:14                               ` [PATCH v16 00/14] Reftable support git-core Junio C Hamano
2020-06-10  6:56                                 ` Han-Wen Nienhuys
2020-06-10 17:09                                   ` Junio C Hamano
2020-06-10 17:38                                     ` Junio C Hamano
2020-06-10 18:59                                     ` Johannes Schindelin
2020-06-10 19:04                                       ` Han-Wen Nienhuys
2020-06-10 19:20                                         ` Johannes Schindelin
2020-06-10 16:57                                 ` Han-Wen Nienhuys
2020-06-16 19:20                               ` [PATCH v17 00/17] " Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 01/17] lib-t6000.sh: write tag using git-update-ref Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 02/17] checkout: add '\n' to reflog message Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 03/17] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 04/17] Make refs_ref_exists public Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 05/17] Treat BISECT_HEAD as a pseudo ref Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 06/17] Treat CHERRY_PICK_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 07/17] Treat REVERT_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 08/17] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 09/17] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 10/17] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 11/17] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 12/17] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-06-19 14:24                                   ` SZEDER Gábor
2020-06-16 19:20                                 ` [PATCH v17 13/17] Hookup unittests for the reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 14/17] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 15/17] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-06-16 19:20                                 ` [PATCH v17 16/17] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-06-19 16:03                                   ` SZEDER Gábor
2020-06-16 19:20                                 ` [PATCH v17 17/17] Add "test-tool dump-reftable" command Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                 ` [PATCH v18 00/19] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 01/19] lib-t6000.sh: write tag using git-update-ref Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 02/19] checkout: add '\n' to reflog message Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 03/19] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 04/19] Make refs_ref_exists public Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 05/19] Treat BISECT_HEAD as a pseudo ref Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 06/19] Treat CHERRY_PICK_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 07/19] Treat REVERT_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 08/19] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 09/19] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 10/19] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 11/19] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 12/19] Add standalone build infrastructure for reftable Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 13/19] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 14/19] Hookup unittests for the reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 15/19] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 16/19] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 17/19] git-prompt: prepare for reftable refs backend SZEDER Gábor via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 18/19] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55                                   ` [PATCH v18 19/19] Add "test-tool dump-reftable" command Han-Wen Nienhuys via GitGitGadget
2020-06-29 18:56                                   ` [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.v10.git.1588018418.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.