git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 5/5] Reftable support for git-core

From
Han-Wen Nienhuys via GitGitGadget <gitgitgadget@gmail.com>
Date
Jan 27, 2020, 14:22 UTC
Message-ID
<721201269df47dc2e406e4091ab6b18a4a59b65f.1580134944.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.539.v2.git.1580134944.gitgitgadget@gmail.com>
From: Han-Wen Nienhuys <hanwen@google.com>
For background, see the previous commit introducing the library.
TODO:
 * Resolve the design problem with reflog expiry.
 * Resolve spots marked with XXX
Example use:
  $ ~/vc/git/git init
  warning: templates not found in /usr/local/google/home/hanwen/share/git-core/templates
  Initialized empty Git repository in /tmp/qz/.git/
  $ echo q > a
  $ ~/vc/git/git add a
  $ ~/vc/git/git commit -mx
  fatal: not a git repository (or any of the parent directories): .git
  [master (root-commit) 373d969] x
   1 file changed, 1 insertion(+)
   create mode 100644 a
  $ ~/vc/git/git show-ref
  373d96972fca9b63595740bba3898a762778ba20 HEAD
  373d96972fca9b63595740bba3898a762778ba20 refs/heads/master
  $ ls -l .git/reftable/
  total 12
  -rw------- 1 hanwen primarygroup  126 Jan 23 20:08 000000000001-000000000001.ref
  -rw------- 1 hanwen primarygroup 4277 Jan 23 20:08 000000000002-000000000002.ref
  $ go run ~/vc/reftable/cmd/dump.go  -table /tmp/qz/.git/reftable/000000000002-000000000002.ref
  ** DEBUG **
  name /tmp/qz/.git/reftable/000000000002-000000000002.ref, sz 4209: 'r' reftable.readerOffsets{Present:true, Offset:0x0, IndexOffset:0x0}, 'o' reftable.readerOffsets{Present:false, Offset:0x0, IndexOffset:0x0} 'g' reftable.readerOffsets{Present:true, Offset:0x1000, IndexOffset:0x0}
  ** REFS **
  reftable.RefRecord{RefName:"refs/heads/master", UpdateIndex:0x2, Value:[]uint8{0x37, 0x3d, 0x96, 0x97, 0x2f, 0xca, 0x9b, 0x63, 0x59, 0x57, 0x40, 0xbb, 0xa3, 0x89, 0x8a, 0x76, 0x27, 0x78, 0xba, 0x20}, TargetValue:[]uint8(nil), Target:""}
  ** LOGS **
  reftable.LogRecord{RefName:"HEAD", UpdateIndex:0x2, New:[]uint8{0x37, 0x3d, 0x96, 0x97, 0x2f, 0xca, 0x9b, 0x63, 0x59, 0x57, 0x40, 0xbb, 0xa3, 0x89, 0x8a, 0x76, 0x27, 0x78, 0xba, 0x20}, Old:[]uint8{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, Name:"Han-Wen Nienhuys", Email:"hanwen@google.com", Time:0x5e29ef27, TZOffset:100, Message:"commit (initial): x\n"}
Change-Id: I225ee6317b7911edf9aa95f43299f6c7c4511914
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
---
 Makefile                |  23 +-
 refs.c                  |  18 +-
 refs.h                  |   2 +
 refs/refs-internal.h    |   1 +
 refs/reftable-backend.c | 812 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 852 insertions(+), 4 deletions(-)
 create mode 100644 refs/reftable-backend.c
diff --git a/Makefile b/Makefile
index 09f98b777c..4f0bcbfbcb 100644
--- a/Makefile
+++ b/Makefile
@@ -813,6 +813,7 @@ TEST_SHELL_PATH = $(SHELL_PATH)
 LIB_FILE = libgit.a
 XDIFF_LIB = xdiff/lib.a
 VCSSVN_LIB = vcs-svn/lib.a
+REFTABLE_LIB = reftable/libreftable.a
 
 GENERATED_H += command-list.h
 
@@ -958,6 +959,7 @@ LIB_OBJS += rebase-interactive.o
 LIB_OBJS += reflog-walk.o
 LIB_OBJS += refs.o
 LIB_OBJS += refs/files-backend.o
+LIB_OBJS += refs/reftable-backend.o
 LIB_OBJS += refs/iterator.o
 LIB_OBJS += refs/packed-backend.o
 LIB_OBJS += refs/ref-cache.o
@@ -1162,7 +1164,7 @@ THIRD_PARTY_SOURCES += compat/regex/%
 THIRD_PARTY_SOURCES += sha1collisiondetection/%
 THIRD_PARTY_SOURCES += sha1dc/%
 
-GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB)
+GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB)
 EXTLIBS =
 
 GIT_USER_AGENT = git/$(GIT_VERSION)
@@ -2343,11 +2345,27 @@ VCSSVN_OBJS += vcs-svn/fast_export.o
 VCSSVN_OBJS += vcs-svn/svndiff.o
 VCSSVN_OBJS += vcs-svn/svndump.o
 
+REFTABLE_OBJS += reftable/basics.o
+REFTABLE_OBJS += reftable/block.o
+REFTABLE_OBJS += reftable/bytes.o
+REFTABLE_OBJS += reftable/file.o
+REFTABLE_OBJS += reftable/iter.o
+REFTABLE_OBJS += reftable/merged.o
+REFTABLE_OBJS += reftable/pq.o
+REFTABLE_OBJS += reftable/reader.o
+REFTABLE_OBJS += reftable/record.o
+REFTABLE_OBJS += reftable/slice.o
+REFTABLE_OBJS += reftable/stack.o
+REFTABLE_OBJS += reftable/tree.o
+REFTABLE_OBJS += reftable/writer.o
+
+
 TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
 OBJECTS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \
 	$(XDIFF_OBJS) \
 	$(VCSSVN_OBJS) \
 	$(FUZZ_OBJS) \
+	$(REFTABLE_OBJS) \
 	common-main.o \
 	git.o
 ifndef NO_CURL
@@ -2484,6 +2502,9 @@ $(XDIFF_LIB): $(XDIFF_OBJS)
 $(VCSSVN_LIB): $(VCSSVN_OBJS)
 	$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^
 
+$(REFTABLE_LIB): $(REFTABLE_OBJS)
+	$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^
+
 export DEFAULT_EDITOR DEFAULT_PAGER
 
 Documentation/GIT-EXCLUDED-PROGRAMS: FORCE
diff --git a/refs.c b/refs.c
index 1ab0bb54d3..26d9637e55 100644
--- a/refs.c
+++ b/refs.c
@@ -20,7 +20,7 @@
 /*
  * List of all available backends
  */
-static struct ref_storage_be *refs_backends = &refs_be_files;
+static struct ref_storage_be *refs_backends = &refs_be_reftable;
 
 static struct ref_storage_be *find_ref_storage_backend(const char *name)
 {
@@ -1839,10 +1839,22 @@ static struct ref_store *lookup_ref_store_map(struct hashmap *map,
 static struct ref_store *ref_store_init(const char *gitdir,
 					unsigned int flags)
 {
-	const char *be_name = "files";
-	struct ref_storage_be *be = find_ref_storage_backend(be_name);
+	struct strbuf refs_path = STRBUF_INIT;
+
+        /* XXX this should probably come from a git config setting and not
+           default to reftable. */
+	const char *be_name = "reftable";
+	struct ref_storage_be *be;
 	struct ref_store *refs;
 
+	strbuf_addstr(&refs_path, gitdir);
+	strbuf_addstr(&refs_path, "/refs");
+
+	if (!is_directory(refs_path.buf)) {
+		be_name = "reftable";
+	}
+	strbuf_release(&refs_path);
+	be = find_ref_storage_backend(be_name);
 	if (!be)
 		BUG("reference backend %s is unknown", be_name);
 
diff --git a/refs.h b/refs.h
index 545029c6d8..99656d2065 100644
--- a/refs.h
+++ b/refs.h
@@ -456,6 +456,8 @@ int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
 				     const char *refname,
 				     each_reflog_ent_fn fn,
 				     void *cb_data);
+
+/* XXX which ordering are these? Newest or oldest first? */
 int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data);
 int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data);
 
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index fc18b12340..2744aa57f2 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -659,6 +659,7 @@ struct ref_storage_be {
 };
 
 extern struct ref_storage_be refs_be_files;
+extern struct ref_storage_be refs_be_reftable;
 extern struct ref_storage_be refs_be_packed;
 
 /*
diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
new file mode 100644
index 0000000000..c89884af0c
--- /dev/null
+++ b/refs/reftable-backend.c
@@ -0,0 +1,812 @@
+#include "../cache.h"
+#include "../config.h"
+#include "../refs.h"
+#include "refs-internal.h"
+#include "../iterator.h"
+#include "../lockfile.h"
+#include "../chdir-notify.h"
+
+#include "../reftable/reftable.h"
+
+extern struct ref_storage_be refs_be_reftable;
+
+struct reftable_ref_store {
+	struct ref_store base;
+	unsigned int store_flags;
+
+	int err;
+	char *reftable_dir;
+	char *table_list_file;
+	struct stack *stack;
+};
+
+static void clear_log_record(struct log_record *log)
+{
+	log->old_hash = NULL;
+	log->new_hash = NULL;
+	log->message = NULL;
+	log->ref_name = NULL;
+	log_record_clear(log);
+}
+
+static void fill_log_record(struct log_record *log)
+{
+	const char *info = git_committer_info(0);
+	struct ident_split split = {};
+	int result = split_ident_line(&split, info, strlen(info));
+	int sign = 1;
+	assert(0 == result);
+
+	log_record_clear(log);
+	log->name =
+		xstrndup(split.name_begin, split.name_end - split.name_begin);
+	log->email =
+		xstrndup(split.mail_begin, split.mail_end - split.mail_begin);
+	log->time = atol(split.date_begin);
+	if (*split.tz_begin == '-') {
+		sign = -1;
+		split.tz_begin++;
+	}
+	if (*split.tz_begin == '+') {
+		sign = 1;
+		split.tz_begin++;
+	}
+
+	log->tz_offset = sign * atoi(split.tz_begin);
+}
+
+static struct ref_store *reftable_ref_store_create(const char *path,
+						   unsigned int store_flags)
+{
+	struct reftable_ref_store *refs = xcalloc(1, sizeof(*refs));
+	struct ref_store *ref_store = (struct ref_store *)refs;
+	struct write_options cfg = {
+		.block_size = 4096,
+	};
+	struct strbuf sb = STRBUF_INIT;
+
+	base_ref_store_init(ref_store, &refs_be_reftable);
+	refs->store_flags = store_flags;
+
+	strbuf_addf(&sb, "%s/refs", path);
+	refs->table_list_file = xstrdup(sb.buf);
+	strbuf_reset(&sb);
+	strbuf_addf(&sb, "%s/reftable", path);
+	refs->reftable_dir = xstrdup(sb.buf);
+	strbuf_release(&sb);
+
+	refs->err = new_stack(&refs->stack, refs->reftable_dir,
+			      refs->table_list_file, cfg);
+
+	return ref_store;
+}
+
+static int reftable_init_db(struct ref_store *ref_store, struct strbuf *err)
+{
+	struct reftable_ref_store *refs =
+		(struct reftable_ref_store *)ref_store;
+	FILE *f = fopen(refs->table_list_file, "a");
+	if (f == NULL) {
+		return -1;
+	}
+	fclose(f);
+
+	safe_create_dir(refs->reftable_dir, 1);
+	return 0;
+}
+
+struct reftable_iterator {
+	struct ref_iterator base;
+	struct iterator iter;
+	struct ref_record ref;
+	struct object_id oid;
+	struct ref_store *ref_store;
+	char *prefix;
+};
+
+static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
+{
+	while (1) {
+		struct reftable_iterator *ri =
+			(struct reftable_iterator *)ref_iterator;
+		int err = iterator_next_ref(ri->iter, &ri->ref);
+		if (err > 0) {
+			return ITER_DONE;
+		}
+		if (err < 0) {
+			return ITER_ERROR;
+		}
+
+		ri->base.refname = ri->ref.ref_name;
+		if (ri->prefix != NULL &&
+		    strncmp(ri->prefix, ri->ref.ref_name, strlen(ri->prefix))) {
+			return ITER_DONE;
+		}
+
+		ri->base.flags = 0;
+		if (ri->ref.value != NULL) {
+			memcpy(ri->oid.hash, ri->ref.value, GIT_SHA1_RAWSZ);
+		} else if (ri->ref.target != NULL) {
+			int out_flags = 0;
+			const char *resolved = refs_resolve_ref_unsafe(
+				ri->ref_store, ri->ref.ref_name,
+				RESOLVE_REF_READING, &ri->oid, &out_flags);
+			ri->base.flags = out_flags;
+			if (resolved == NULL &&
+			    !(ri->base.flags & DO_FOR_EACH_INCLUDE_BROKEN) &&
+			    (ri->base.flags & REF_ISBROKEN)) {
+				continue;
+			}
+		}
+		ri->base.oid = &ri->oid;
+		return ITER_OK;
+	}
+}
+
+static int reftable_ref_iterator_peel(struct ref_iterator *ref_iterator,
+				      struct object_id *peeled)
+{
+	struct reftable_iterator *ri = (struct reftable_iterator *)ref_iterator;
+	if (ri->ref.target_value != NULL) {
+		memcpy(peeled->hash, ri->ref.target_value, GIT_SHA1_RAWSZ);
+		return 0;
+	}
+
+	return -1;
+}
+
+static int reftable_ref_iterator_abort(struct ref_iterator *ref_iterator)
+{
+	struct reftable_iterator *ri = (struct reftable_iterator *)ref_iterator;
+	ref_record_clear(&ri->ref);
+	iterator_destroy(&ri->iter);
+	return 0;
+}
+
+static struct ref_iterator_vtable reftable_ref_iterator_vtable = {
+	reftable_ref_iterator_advance, reftable_ref_iterator_peel,
+	reftable_ref_iterator_abort
+};
+
+static struct ref_iterator *
+reftable_ref_iterator_begin(struct ref_store *ref_store, const char *prefix,
+			    unsigned int flags)
+{
+	struct reftable_ref_store *refs =
+		(struct reftable_ref_store *)ref_store;
+	struct reftable_iterator *ri = xcalloc(1, sizeof(*ri));
+	struct merged_table *mt = NULL;
+	int err = 0;
+	if (refs->err) {
+		/* how to propagate errors? */
+		return NULL;
+	}
+
+	mt = stack_merged_table(refs->stack);
+
+	/* XXX something with flags? */
+	err = merged_table_seek_ref(mt, &ri->iter, prefix);
+	/* XXX what to do with err? */
+	assert(err == 0);
+	base_ref_iterator_init(&ri->base, &reftable_ref_iterator_vtable, 1);
+	ri->base.oid = &ri->oid;
+	ri->ref_store = ref_store;
+	return &ri->base;
+}
+
+static int reftable_transaction_prepare(struct ref_store *ref_store,
+					struct ref_transaction *transaction,
+					struct strbuf *err)
+{
+	return 0;
+}
+
+static int reftable_transaction_abort(struct ref_store *ref_store,
+				      struct ref_transaction *transaction,
+				      struct strbuf *err)
+{
+	struct reftable_ref_store *refs =
+		(struct reftable_ref_store *)ref_store;
+	(void)refs;
+	return 0;
+}
+
+static int ref_update_cmp(const void *a, const void *b)
+{
+	return strcmp(((struct ref_update *)a)->refname,
+		      ((struct ref_update *)b)->refname);
+}
+
+static int reftable_check_old_oid(struct ref_store *refs, const char *refname,
+				  struct object_id *want_oid)
+{
+	struct object_id out_oid = {};
+	int out_flags = 0;
+	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;
+	}
+
+	if (resolved != NULL && !oideq(&out_oid, want_oid)) {
+		return LOCK_ERROR;
+	}
+
+	return 0;
+}
+
+static int write_transaction_table(struct writer *writer, void *arg)
+{
+	struct ref_transaction *transaction = (struct ref_transaction *)arg;
+	struct reftable_ref_store *refs =
+		(struct reftable_ref_store *)transaction->ref_store;
+	uint64_t ts = stack_next_update_index(refs->stack);
+	int err = 0;
+	/* XXX - are we allowed to mutate the input data? */
+	qsort(transaction->updates, transaction->nr,
+	      sizeof(struct ref_update *), ref_update_cmp);
+	writer_set_limits(writer, ts, ts);
+
+	for (int i = 0; i < transaction->nr; i++) {
+		struct ref_update *u = transaction->updates[i];
+		if (u->flags & REF_HAVE_OLD) {
+			err = reftable_check_old_oid(transaction->ref_store,
+						     u->refname, &u->old_oid);
+			if (err < 0) {
+				goto exit;
+			}
+		}
+	}
+
+	for (int i = 0; i < transaction->nr; i++) {
+		struct ref_update *u = transaction->updates[i];
+		if (u->flags & REF_HAVE_NEW) {
+			struct object_id out_oid = {};
+			int out_flags = 0;
+			/* XXX who owns the memory here? */
+			const char *resolved = refs_resolve_ref_unsafe(
+				transaction->ref_store, u->refname, 0, &out_oid,
+				&out_flags);
+			struct ref_record ref = {};
+			ref.ref_name =
+				(char *)(resolved ? resolved : u->refname);
+			ref.value = u->new_oid.hash;
+			ref.update_index = ts;
+			err = writer_add_ref(writer, &ref);
+			if (err < 0) {
+				goto exit;
+			}
+		}
+	}
+
+	for (int i = 0; i < transaction->nr; i++) {
+		struct ref_update *u = transaction->updates[i];
+		struct log_record log = {};
+		fill_log_record(&log);
+
+		log.ref_name = (char *)u->refname;
+		log.old_hash = u->old_oid.hash;
+		log.new_hash = u->new_oid.hash;
+		log.update_index = ts;
+		log.message = u->msg;
+
+		err = writer_add_log(writer, &log);
+		clear_log_record(&log);
+		if (err < 0) {
+			return err;
+		}
+	}
+exit:
+	return err;
+}
+
+static int reftable_transaction_commit(struct ref_store *ref_store,
+				       struct ref_transaction *transaction,
+				       struct strbuf *errmsg)
+{
+	struct reftable_ref_store *refs =
+		(struct reftable_ref_store *)ref_store;
+	int err = stack_add(refs->stack, &write_transaction_table, transaction);
+	if (err < 0) {
+		strbuf_addf(errmsg, "reftable: transaction failure %s",
+			    error_str(err));
+		return -1;
+	}
+
+	return 0;
+}
+
+static int reftable_transaction_finish(struct ref_store *ref_store,
+				       struct ref_transaction *transaction,
+				       struct strbuf *err)
+{
+	return reftable_transaction_commit(ref_store, transaction, err);
+}
+
+struct write_delete_refs_arg {
+	struct stack *stack;
+	struct string_list *refnames;
+	const char *logmsg;
+	unsigned int flags;
+};
+
+static int write_delete_refs_table(struct writer *writer, void *argv)
+{
+	struct write_delete_refs_arg *arg =
+		(struct write_delete_refs_arg *)argv;
+	uint64_t ts = stack_next_update_index(arg->stack);
+	int err = 0;
+
+	writer_set_limits(writer, ts, ts);
+	for (int i = 0; i < arg->refnames->nr; i++) {
+		struct ref_record ref = {
+			.ref_name = (char *)arg->refnames->items[i].string,
+			.update_index = ts,
+		};
+		err = writer_add_ref(writer, &ref);
+		if (err < 0) {
+			return err;
+		}
+	}
+
+	for (int i = 0; i < arg->refnames->nr; i++) {
+		struct log_record log = {};
+		fill_log_record(&log);
+		log.message = xstrdup(arg->logmsg);
+		log.new_hash = NULL;
+
+		/* XXX should lookup old oid. */
+		log.old_hash = NULL;
+		log.update_index = ts;
+		log.ref_name = (char *)arg->refnames->items[i].string;
+
+		err = writer_add_log(writer, &log);
+		clear_log_record(&log);
+		if (err < 0) {
+			return err;
+		}
+	}
+	return 0;
+}
+
+static int reftable_delete_refs(struct ref_store *ref_store, const char *msg,
+				struct string_list *refnames,
+				unsigned int flags)
+{
+	struct reftable_ref_store *refs =
+		(struct reftable_ref_store *)ref_store;
+	struct write_delete_refs_arg arg = {
+		.stack = refs->stack,
+		.refnames = refnames,
+		.logmsg = msg,
+		.flags = flags,
+	};
+	return stack_add(refs->stack, &write_delete_refs_table, &arg);
+}
+
+static int reftable_pack_refs(struct ref_store *ref_store, unsigned int flags)
+{
+	struct reftable_ref_store *refs =
+		(struct reftable_ref_store *)ref_store;
+	/* XXX reflog expiry. */
+	return stack_compact_all(refs->stack, NULL);
+}
+
+struct write_create_symref_arg {
+	struct stack *stack;
+	const char *refname;
+	const char *target;
+	const char *logmsg;
+};
+
+static int write_create_symref_table(struct writer *writer, void *arg)
+{
+	struct write_create_symref_arg *create =
+		(struct write_create_symref_arg *)arg;
+	uint64_t ts = stack_next_update_index(create->stack);
+	int err = 0;
+
+	struct ref_record ref = {
+		.ref_name = (char *)create->refname,
+		.target = (char *)create->target,
+		.update_index = ts,
+	};
+	writer_set_limits(writer, ts, ts);
+	err = writer_add_ref(writer, &ref);
+	if (err < 0) {
+		return err;
+	}
+
+	/* XXX reflog? */
+
+	return 0;
+}
+
+static int reftable_create_symref(struct ref_store *ref_store,
+				  const char *refname, const char *target,
+				  const char *logmsg)
+{
+	struct reftable_ref_store *refs =
+		(struct reftable_ref_store *)ref_store;
+	struct write_create_symref_arg arg = { .stack = refs->stack,
+					       .refname = refname,
+					       .target = target,
+					       .logmsg = logmsg };
+	return stack_add(refs->stack, &write_create_symref_table, &arg);
+}
+
+struct write_rename_arg {
+	struct stack *stack;
+	const char *oldname;
+	const char *newname;
+	const char *logmsg;
+};
+
+static int write_rename_table(struct writer *writer, void *argv)
+{
+	struct write_rename_arg *arg = (struct write_rename_arg *)argv;
+	uint64_t ts = stack_next_update_index(arg->stack);
+	struct ref_record ref = {};
+	int err = stack_read_ref(arg->stack, arg->oldname, &ref);
+	if (err) {
+		goto exit;
+	}
+
+	/* XXX should check that dest doesn't exist? */
+	free(ref.ref_name);
+	ref.ref_name = strdup(arg->newname);
+	writer_set_limits(writer, ts, ts);
+	ref.update_index = ts;
+
+	{
+		struct ref_record todo[2] = {};
+		todo[0].ref_name = (char *)arg->oldname;
+		todo[0].update_index = ts;
+		todo[1] = ref;
+		todo[1].update_index = ts;
+
+		err = writer_add_refs(writer, todo, 2);
+		if (err < 0) {
+			goto exit;
+		}
+	}
+
+	if (ref.value != NULL) {
+		struct log_record todo[2] = {};
+		fill_log_record(&todo[0]);
+		fill_log_record(&todo[1]);
+
+		todo[0].ref_name = (char *)arg->oldname;
+		todo[0].update_index = ts;
+		todo[0].message = (char *)arg->logmsg;
+		todo[0].old_hash = ref.value;
+		todo[0].new_hash = NULL;
+
+		todo[1].ref_name = (char *)arg->newname;
+		todo[1].update_index = ts;
+		todo[1].old_hash = NULL;
+		todo[1].new_hash = ref.value;
+		todo[1].message = (char *)arg->logmsg;
+
+		err = writer_add_logs(writer, todo, 2);
+
+		clear_log_record(&todo[0]);
+		clear_log_record(&todo[1]);
+
+		if (err < 0) {
+			goto exit;
+		}
+
+	} else {
+		/* XXX symrefs? */
+	}
+
+exit:
+	ref_record_clear(&ref);
+	return err;
+}
+
+static int reftable_rename_ref(struct ref_store *ref_store,
+			       const char *oldrefname, const char *newrefname,
+			       const char *logmsg)
+{
+	struct reftable_ref_store *refs =
+		(struct reftable_ref_store *)ref_store;
+	struct write_rename_arg arg = {
+		.stack = refs->stack,
+		.oldname = oldrefname,
+		.newname = newrefname,
+		.logmsg = logmsg,
+	};
+	return stack_add(refs->stack, &write_rename_table, &arg);
+}
+
+static int reftable_copy_ref(struct ref_store *ref_store,
+			     const char *oldrefname, const char *newrefname,
+			     const char *logmsg)
+{
+	BUG("reftable reference store does not support copying references");
+}
+
+struct reftable_reflog_ref_iterator {
+	struct ref_iterator base;
+	struct iterator iter;
+	struct log_record log;
+	struct object_id oid;
+	char *last_name;
+};
+
+static int
+reftable_reflog_ref_iterator_advance(struct ref_iterator *ref_iterator)
+{
+	struct reftable_reflog_ref_iterator *ri =
+		(struct reftable_reflog_ref_iterator *)ref_iterator;
+
+	while (1) {
+		int err = iterator_next_log(ri->iter, &ri->log);
+		if (err > 0) {
+			return ITER_DONE;
+		}
+		if (err < 0) {
+			return ITER_ERROR;
+		}
+
+		ri->base.refname = ri->log.ref_name;
+		if (ri->last_name != NULL &&
+		    !strcmp(ri->log.ref_name, ri->last_name)) {
+			continue;
+		}
+
+		free(ri->last_name);
+		ri->last_name = xstrdup(ri->log.ref_name);
+		/* XXX const? */
+		memcpy(&ri->oid.hash, ri->log.new_hash, GIT_SHA1_RAWSZ);
+		return ITER_OK;
+	}
+}
+
+static int reftable_reflog_ref_iterator_peel(struct ref_iterator *ref_iterator,
+					     struct object_id *peeled)
+{
+	BUG("not supported.");
+	return -1;
+}
+
+static int reftable_reflog_ref_iterator_abort(struct ref_iterator *ref_iterator)
+{
+	struct reftable_reflog_ref_iterator *ri =
+		(struct reftable_reflog_ref_iterator *)ref_iterator;
+	log_record_clear(&ri->log);
+	iterator_destroy(&ri->iter);
+	return 0;
+}
+
+static struct ref_iterator_vtable reftable_reflog_ref_iterator_vtable = {
+	reftable_reflog_ref_iterator_advance, reftable_reflog_ref_iterator_peel,
+	reftable_reflog_ref_iterator_abort
+};
+
+static struct ref_iterator *
+reftable_reflog_iterator_begin(struct ref_store *ref_store)
+{
+	struct reftable_reflog_ref_iterator *ri = xcalloc(sizeof(*ri), 1);
+	struct reftable_ref_store *refs =
+		(struct reftable_ref_store *)ref_store;
+
+	struct merged_table *mt = stack_merged_table(refs->stack);
+	int err = merged_table_seek_log(mt, &ri->iter, "");
+	if (err < 0) {
+		free(ri);
+		return NULL;
+	}
+
+	base_ref_iterator_init(&ri->base, &reftable_reflog_ref_iterator_vtable,
+			       1);
+	ri->base.oid = &ri->oid;
+
+	return empty_ref_iterator_begin();
+}
+
+static int
+reftable_for_each_reflog_ent_newest_first(struct ref_store *ref_store,
+					  const char *refname,
+					  each_reflog_ent_fn fn, void *cb_data)
+{
+	struct iterator it = {};
+	struct reftable_ref_store *refs =
+		(struct reftable_ref_store *)ref_store;
+	struct merged_table *mt = stack_merged_table(refs->stack);
+	int err = merged_table_seek_log(mt, &it, refname);
+	struct log_record log = {};
+
+	while (err == 0) {
+		err = iterator_next_log(it, &log);
+		if (err != 0) {
+			break;
+		}
+
+		if (strcmp(log.ref_name, refname)) {
+			break;
+		}
+
+		{
+			struct object_id old_oid = {};
+			struct object_id new_oid = {};
+
+			memcpy(&old_oid.hash, log.old_hash, GIT_SHA1_RAWSZ);
+			memcpy(&new_oid.hash, log.new_hash, GIT_SHA1_RAWSZ);
+
+			/* XXX committer = email? name? */
+			if (fn(&old_oid, &new_oid, log.name, log.time,
+			       log.tz_offset, log.message, cb_data)) {
+				err = -1;
+				break;
+			}
+		}
+	}
+
+	log_record_clear(&log);
+	iterator_destroy(&it);
+	if (err > 0) {
+		err = 0;
+	}
+	return err;
+}
+
+static int
+reftable_for_each_reflog_ent_oldest_first(struct ref_store *ref_store,
+					  const char *refname,
+					  each_reflog_ent_fn fn, void *cb_data)
+{
+	struct iterator it = {};
+	struct reftable_ref_store *refs =
+		(struct reftable_ref_store *)ref_store;
+	struct merged_table *mt = stack_merged_table(refs->stack);
+	int err = merged_table_seek_log(mt, &it, refname);
+
+	struct log_record *logs = NULL;
+	int cap = 0;
+	int len = 0;
+
+	printf("oldest first\n");
+	while (err == 0) {
+		struct log_record log = {};
+		err = iterator_next_log(it, &log);
+		if (err != 0) {
+			break;
+		}
+
+		if (strcmp(log.ref_name, refname)) {
+			break;
+		}
+
+		if (len == cap) {
+			cap = 2 * cap + 1;
+			logs = realloc(logs, cap * sizeof(*logs));
+		}
+
+		logs[len++] = log;
+	}
+
+	for (int i = len; i--;) {
+		struct log_record *log = &logs[i];
+		struct object_id old_oid = {};
+		struct object_id new_oid = {};
+
+		memcpy(&old_oid.hash, log->old_hash, GIT_SHA1_RAWSZ);
+		memcpy(&new_oid.hash, log->new_hash, GIT_SHA1_RAWSZ);
+
+		/* XXX committer = email? name? */
+		if (!fn(&old_oid, &new_oid, log->name, log->time,
+			log->tz_offset, log->message, cb_data)) {
+			err = -1;
+			break;
+		}
+	}
+
+	for (int i = 0; i < len; i++) {
+		log_record_clear(&logs[i]);
+	}
+	free(logs);
+
+	iterator_destroy(&it);
+	if (err > 0) {
+		err = 0;
+	}
+	return err;
+}
+
+static int reftable_reflog_exists(struct ref_store *ref_store,
+				  const char *refname)
+{
+	/* always exists. */
+	return 1;
+}
+
+static int reftable_create_reflog(struct ref_store *ref_store,
+				  const char *refname, int force_create,
+				  struct strbuf *err)
+{
+	return 0;
+}
+
+static int reftable_delete_reflog(struct ref_store *ref_store,
+				  const char *refname)
+{
+	return 0;
+}
+
+static int reftable_reflog_expire(struct ref_store *ref_store,
+				  const char *refname,
+				  const struct object_id *oid,
+				  unsigned int flags,
+				  reflog_expiry_prepare_fn prepare_fn,
+				  reflog_expiry_should_prune_fn should_prune_fn,
+				  reflog_expiry_cleanup_fn cleanup_fn,
+				  void *policy_cb_data)
+{
+	/*
+	  XXX
+
+	  This doesn't fit with the reftable API. If we are expiring for space
+	  reasons, the expiry should be combined with a compaction, and there
+	  should be a policy that can be called for all refnames, not for a
+	  single ref name.
+
+	  If this is for cleaning up individual entries, we'll have to write
+	  extra data to create tombstones.
+	 */
+	return 0;
+}
+
+static int reftable_read_raw_ref(struct ref_store *ref_store,
+				 const char *refname, struct object_id *oid,
+				 struct strbuf *referent, unsigned int *type)
+{
+	struct reftable_ref_store *refs =
+		(struct reftable_ref_store *)ref_store;
+	struct ref_record ref = {};
+	int err = stack_read_ref(refs->stack, refname, &ref);
+	if (err) {
+		goto exit;
+	}
+	if (ref.target != NULL) {
+		strbuf_reset(referent);
+		strbuf_addstr(referent, ref.target);
+		*type |= REF_ISSYMREF;
+	} else {
+		memcpy(oid->hash, ref.value, GIT_SHA1_RAWSZ);
+	}
+
+exit:
+	ref_record_clear(&ref);
+	return err;
+}
+
+struct ref_storage_be refs_be_reftable = {
+	&refs_be_files,
+	"reftable",
+	reftable_ref_store_create,
+	reftable_init_db,
+	reftable_transaction_prepare,
+	reftable_transaction_finish,
+	reftable_transaction_abort,
+	reftable_transaction_commit,
+
+	reftable_pack_refs,
+	reftable_create_symref,
+	reftable_delete_refs,
+	reftable_rename_ref,
+	reftable_copy_ref,
+
+	reftable_ref_iterator_begin,
+	reftable_read_raw_ref,
+
+	reftable_reflog_iterator_begin,
+	reftable_for_each_reflog_ent_newest_first,
+	reftable_for_each_reflog_ent_oldest_first,
+	reftable_reflog_exists,
+	reftable_create_reflog,
+	reftable_delete_reflog,
+	reftable_reflog_expire
+};
-- 
gitgitgadget
Previous: Junio C HamanoNext: Jeff King
Message 22 of 409 in “Reftable support git-core”
  1. 0/5 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Jan 23, 2020
  2. 1/5 setup.c: enable repo detection for reftableHan-Wen Nienhuys via GitGitGadget, Jan 23, 2020
  3. 3/5 Document how ref iterators and symrefs interactHan-Wen Nienhuys via GitGitGadget, Jan 23, 2020
  4. 2/5 create .git/refs in files-backend.cHan-Wen Nienhuys via GitGitGadget, Jan 23, 2020
  5. 5/5 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Jan 23, 2020
  6. 4/5 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Jan 23, 2020
  7. Junio C HamanoJan 23, 2020
  8. Han-Wen NienhuysJan 27, 2020
  9. Han-Wen NienhuysJan 27, 2020
  10. Stephan BeyerJan 23, 2020
  11. Han-Wen NienhuysJan 27, 2020
  12. 0/5 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Jan 27, 2020
  13. 1/5 setup.c: enable repo detection for reftableHan-Wen Nienhuys via GitGitGadget, Jan 27, 2020
  14. 2/5 create .git/refs in files-backend.cHan-Wen Nienhuys via GitGitGadget, Jan 27, 2020
  15. Junio C HamanoJan 27, 2020
  16. Han-Wen NienhuysJan 28, 2020
  17. Junio C HamanoJan 30, 2020
  18. 3/5 Document how ref iterators and symrefs interactHan-Wen Nienhuys via GitGitGadget, Jan 27, 2020
  19. Junio C HamanoJan 27, 2020
  20. Han-Wen NienhuysJan 28, 2020
  21. Junio C HamanoJan 28, 2020
  22. 5/5 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Jan 27, 2020
  23. Jeff KingJan 28, 2020
  24. Martin FickJan 28, 2020
  25. Jeff KingJan 29, 2020
  26. Martin FickJan 29, 2020
  27. Han-Wen NienhuysJan 29, 2020
  28. Martin FickJan 29, 2020
  29. Han-Wen NienhuysJan 29, 2020
  30. Jeff KingJan 30, 2020
  31. Han-Wen NienhuysFeb 3, 2020
  32. Jeff KingFeb 3, 2020
  33. Han-Wen NienhuysFeb 3, 2020
  34. Han-Wen NienhuysFeb 4, 2020
  35. Jeff KingFeb 4, 2020
  36. Han-Wen NienhuysFeb 4, 2020
  37. Junio C HamanoJan 29, 2020
  38. Han-Wen NienhuysJan 28, 2020
  39. Jeff KingJan 29, 2020
  40. Junio C HamanoJan 29, 2020
  41. Han-Wen NienhuysJan 29, 2020
  42. Jeff KingJan 30, 2020
  43. Han-Wen NienhuysFeb 4, 2020
  44. Jeff KingFeb 4, 2020
  45. Han-Wen NienhuysFeb 4, 2020
  46. Jeff KingFeb 4, 2020
  47. 4/5 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Jan 27, 2020
  48. 0/6 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Feb 4, 2020
  49. 2/6 setup.c: enable repo detection for reftableHan-Wen Nienhuys via GitGitGadget, Feb 4, 2020
  50. Han-Wen NienhuysFeb 4, 2020
  51. 1/6 refs.h: clarify reflog iteration orderHan-Wen Nienhuys via GitGitGadget, Feb 4, 2020
  52. 3/6 create .git/refs in files-backend.cHan-Wen Nienhuys via GitGitGadget, Feb 4, 2020
  53. Junio C HamanoFeb 4, 2020
  54. Han-Wen NienhuysFeb 5, 2020
  55. SZEDER GáborFeb 5, 2020
  56. Jeff KingFeb 5, 2020
  57. 4/6 refs: document how ref_iterator_advance_fn should handle symrefsHan-Wen Nienhuys via GitGitGadget, Feb 4, 2020
  58. 6/6 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Feb 4, 2020
  59. 5/6 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Feb 4, 2020
  60. 0/5 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Feb 6, 2020
  61. 2/5 create .git/refs in files-backend.cHan-Wen Nienhuys via GitGitGadget, Feb 6, 2020
  62. 1/5 refs.h: clarify reflog iteration orderHan-Wen Nienhuys via GitGitGadget, Feb 6, 2020
  63. 3/5 refs: document how ref_iterator_advance_fn should handle symrefsHan-Wen Nienhuys via GitGitGadget, Feb 6, 2020
  64. 5/5 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Feb 6, 2020
  65. brian m. carlsonFeb 6, 2020
  66. Han-Wen NienhuysFeb 10, 2020
  67. 4/5 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Feb 6, 2020
  68. Junio C HamanoFeb 6, 2020
  69. brian m. carlsonFeb 7, 2020
  70. Han-Wen NienhuysFeb 10, 2020
  71. brian m. carlsonFeb 11, 2020
  72. Han-Wen NienhuysFeb 11, 2020
  73. Junio C HamanoFeb 11, 2020
  74. Han-Wen NienhuysFeb 11, 2020
  75. brian m. carlsonFeb 11, 2020
  76. Han-Wen NienhuysFeb 18, 2020
  77. Han-Wen NienhuysFeb 11, 2020
  78. Jonathan NiederFeb 20, 2020
  79. brian m. carlsonFeb 6, 2020
  80. 0/5 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Feb 10, 2020
  81. 1/5 refs.h: clarify reflog iteration orderHan-Wen Nienhuys via GitGitGadget, Feb 10, 2020
  82. 2/5 create .git/refs in files-backend.cHan-Wen Nienhuys via GitGitGadget, Feb 10, 2020
  83. 3/5 refs: document how ref_iterator_advance_fn should handle symrefsHan-Wen Nienhuys via GitGitGadget, Feb 10, 2020
  84. 5/5 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Feb 10, 2020
  85. 4/5 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Feb 10, 2020
  86. 0/5 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Feb 18, 2020
  87. 2/5 create .git/refs in files-backend.cHan-Wen Nienhuys via GitGitGadget, Feb 18, 2020
  88. 1/5 refs.h: clarify reflog iteration orderHan-Wen Nienhuys via GitGitGadget, Feb 18, 2020
  89. 3/5 refs: document how ref_iterator_advance_fn should handle symrefsHan-Wen Nienhuys via GitGitGadget, Feb 18, 2020
  90. 5/5 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Feb 18, 2020
  91. 4/5 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Feb 18, 2020
  92. Junio C HamanoFeb 18, 2020
  93. Jeff KingFeb 19, 2020
  94. Han-Wen NienhuysFeb 19, 2020
  95. Junio C HamanoFeb 18, 2020
  96. Han-Wen NienhuysFeb 19, 2020
  97. Junio C HamanoFeb 19, 2020
  98. Han-Wen NienhuysFeb 19, 2020
  99. Junio C HamanoFeb 19, 2020
  100. Han-Wen NienhuysFeb 19, 2020
  101. Junio C HamanoFeb 19, 2020
  102. Jeff KingFeb 20, 2020
  103. Jonathan NiederFeb 21, 2020
  104. Han-Wen NienhuysFeb 26, 2020
  105. Junio C HamanoFeb 26, 2020
  106. brian m. carlsonFeb 27, 2020
  107. 0/6 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Feb 26, 2020
  108. 3/6 refs: document how ref_iterator_advance_fn should handle symrefsHan-Wen Nienhuys via GitGitGadget, Feb 26, 2020
  109. 1/6 refs.h: clarify reflog iteration orderHan-Wen Nienhuys via GitGitGadget, Feb 26, 2020
  110. 2/6 create .git/refs in files-backend.cHan-Wen Nienhuys via GitGitGadget, Feb 26, 2020
  111. 4/6 reftable: file format documentationJonathan Nieder via GitGitGadget, Feb 26, 2020
  112. 6/6 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Feb 26, 2020
  113. Junio C HamanoFeb 26, 2020
  114. Han-Wen NienhuysFeb 26, 2020
  115. Junio C HamanoFeb 26, 2020
  116. Han-Wen NienhuysFeb 27, 2020
  117. Junio C HamanoFeb 27, 2020
  118. Han-Wen NienhuysFeb 27, 2020
  119. Junio C HamanoFeb 26, 2020
  120. Han-Wen NienhuysFeb 27, 2020
  121. Junio C HamanoFeb 27, 2020
  122. 5/6 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Feb 26, 2020
  123. Junio C HamanoFeb 26, 2020
  124. Jonathan NiederMar 24, 2020
  125. 0/9 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Apr 1, 2020
  126. 1/9 refs.h: clarify reflog iteration orderHan-Wen Nienhuys via GitGitGadget, Apr 1, 2020
  127. 4/9 Add .gitattributes for the reftable/ directoryHan-Wen Nienhuys via GitGitGadget, Apr 1, 2020
  128. 3/9 refs: document how ref_iterator_advance_fn should handle symrefsHan-Wen Nienhuys via GitGitGadget, Apr 1, 2020
  129. 2/9 create .git/refs in files-backend.cHan-Wen Nienhuys via GitGitGadget, Apr 1, 2020
  130. 6/9 reftable: define version 2 of the spec to accomodate SHA256Han-Wen Nienhuys via GitGitGadget, Apr 1, 2020
  131. 7/9 reftable: clarify how empty tables should be writtenHan-Wen Nienhuys via GitGitGadget, Apr 1, 2020
  132. 9/9 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Apr 1, 2020
  133. 5/9 reftable: file format documentationJonathan Nieder via GitGitGadget, Apr 1, 2020
  134. 8/9 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Apr 1, 2020
  135. Junio C HamanoApr 15, 2020
  136. Danh DoanApr 18, 2020
  137. 00/10 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Apr 20, 2020
  138. 02/10 Iterate over the "refs/" namespace in for_each_[raw]refHan-Wen Nienhuys via GitGitGadget, Apr 20, 2020
  139. 03/10 create .git/refs in files-backend.cHan-Wen Nienhuys via GitGitGadget, Apr 20, 2020
  140. 01/10 refs.h: clarify reflog iteration orderHan-Wen Nienhuys via GitGitGadget, Apr 20, 2020
  141. 05/10 Add .gitattributes for the reftable/ directoryHan-Wen Nienhuys via GitGitGadget, Apr 20, 2020
  142. 04/10 refs: document how ref_iterator_advance_fn should handle symrefsHan-Wen Nienhuys via GitGitGadget, Apr 20, 2020
  143. 07/10 reftable: define version 2 of the spec to accomodate SHA256Han-Wen Nienhuys via GitGitGadget, Apr 20, 2020
  144. 06/10 reftable: file format documentationJonathan Nieder via GitGitGadget, Apr 20, 2020
  145. 08/10 reftable: clarify how empty tables should be writtenHan-Wen Nienhuys via GitGitGadget, Apr 20, 2020
  146. 10/10 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Apr 20, 2020
  147. 09/10 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Apr 20, 2020
  148. Junio C HamanoApr 20, 2020
  149. Han-Wen NienhuysApr 21, 2020
  150. Johannes SchindelinApr 22, 2020
  151. Junio C HamanoApr 21, 2020
  152. Han-Wen NienhuysApr 23, 2020
  153. Junio C HamanoApr 23, 2020
  154. Junio C HamanoApr 23, 2020
  155. Johannes SchindelinApr 25, 2020
  156. 00/12 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Apr 27, 2020
  157. 08/12 reftable: clarify how empty tables should be writtenHan-Wen Nienhuys via GitGitGadget, Apr 27, 2020
  158. 07/12 reftable: define version 2 of the spec to accomodate SHA256Han-Wen Nienhuys via GitGitGadget, Apr 27, 2020
  159. 10/12 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Apr 27, 2020
  160. 02/12 Iterate over the "refs/" namespace in for_each_[raw]refHan-Wen Nienhuys via GitGitGadget, Apr 27, 2020
  161. Emily ShafferApr 30, 2020
  162. Han-Wen NienhuysMay 4, 2020
  163. Pseudo ref handling (was Re: [PATCH v10 02/12] Iterate over the "refs/" namespace in for_each_[raw]ref)Han-Wen Nienhuys, May 5, 2020
  164. 05/12 Add .gitattributes for the reftable/ directoryHan-Wen Nienhuys via GitGitGadget, Apr 27, 2020
  165. 12/12 t: use update-ref and show-ref to reading/writing refsHan-Wen Nienhuys via GitGitGadget, Apr 27, 2020
  166. 11/12 Add some reftable testing infrastructureHan-Wen Nienhuys via GitGitGadget, Apr 27, 2020
  167. 03/12 create .git/refs in files-backend.cHan-Wen Nienhuys via GitGitGadget, Apr 27, 2020
  168. Emily ShafferApr 30, 2020
  169. Junio C HamanoApr 30, 2020
  170. Han-Wen NienhuysMay 4, 2020
  171. 01/12 refs.h: clarify reflog iteration orderHan-Wen Nienhuys via GitGitGadget, Apr 27, 2020
  172. 06/12 reftable: file format documentationJonathan Nieder via GitGitGadget, Apr 27, 2020
  173. 04/12 refs: document how ref_iterator_advance_fn should handle symrefsHan-Wen Nienhuys via GitGitGadget, Apr 27, 2020
  174. 09/12 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Apr 27, 2020
  175. Danh DoanApr 28, 2020
  176. Junio C HamanoApr 28, 2020
  177. Junio C HamanoApr 28, 2020
  178. Han-Wen NienhuysApr 28, 2020
  179. Han-Wen NienhuysApr 28, 2020
  180. 00/12 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, May 4, 2020
  181. 01/12 refs.h: clarify reflog iteration orderHan-Wen Nienhuys via GitGitGadget, May 4, 2020
  182. 02/12 Iterate over the "refs/" namespace in for_each_[raw]refHan-Wen Nienhuys via GitGitGadget, May 4, 2020
  183. 04/12 Add .gitattributes for the reftable/ directoryHan-Wen Nienhuys via GitGitGadget, May 4, 2020
  184. 06/12 reftable: define version 2 of the spec to accomodate SHA256Han-Wen Nienhuys via GitGitGadget, May 4, 2020
  185. 03/12 refs: document how ref_iterator_advance_fn should handle symrefsHan-Wen Nienhuys via GitGitGadget, May 4, 2020
  186. 07/12 reftable: clarify how empty tables should be writtenHan-Wen Nienhuys via GitGitGadget, May 4, 2020
  187. 10/12 vcxproj: adjust for the reftable changesJohannes Schindelin via GitGitGadget, May 4, 2020
  188. 05/12 reftable: file format documentationJonathan Nieder via GitGitGadget, May 4, 2020
  189. 11/12 Add some reftable testing infrastructureHan-Wen Nienhuys via GitGitGadget, May 4, 2020
  190. 09/12 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, May 4, 2020
  191. 12/12 t: use update-ref and show-ref to reading/writing refsHan-Wen Nienhuys via GitGitGadget, May 4, 2020
  192. 08/12 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, May 4, 2020
  193. Junio C HamanoMay 6, 2020
  194. 00/12 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, May 7, 2020
  195. 01/12 refs.h: clarify reflog iteration orderHan-Wen Nienhuys via GitGitGadget, May 7, 2020
  196. Junio C HamanoMay 8, 2020
  197. 02/12 Iterate over the "refs/" namespace in for_each_[raw]refHan-Wen Nienhuys via GitGitGadget, May 7, 2020
  198. Junio C HamanoMay 8, 2020
  199. Han-Wen NienhuysMay 11, 2020
  200. 03/12 refs: document how ref_iterator_advance_fn should handle symrefsHan-Wen Nienhuys via GitGitGadget, May 7, 2020
  201. Junio C HamanoMay 8, 2020
  202. Han-Wen NienhuysMay 11, 2020
  203. Junio C HamanoMay 11, 2020
  204. Han-Wen NienhuysMay 11, 2020
  205. 06/12 reftable: define version 2 of the spec to accomodate SHA256Han-Wen Nienhuys via GitGitGadget, May 7, 2020
  206. Junio C HamanoMay 8, 2020
  207. 07/12 reftable: clarify how empty tables should be writtenHan-Wen Nienhuys via GitGitGadget, May 7, 2020
  208. 05/12 reftable: file format documentationJonathan Nieder via GitGitGadget, May 7, 2020
  209. 04/12 Add .gitattributes for the reftable/ directoryHan-Wen Nienhuys via GitGitGadget, May 7, 2020
  210. 10/12 vcxproj: adjust for the reftable changesJohannes Schindelin via GitGitGadget, May 7, 2020
  211. 09/12 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, May 7, 2020
  212. 08/12 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, May 7, 2020
  213. 11/12 t: use update-ref and show-ref to reading/writing refsHan-Wen Nienhuys via GitGitGadget, May 7, 2020
  214. 12/12 Add some reftable testing infrastructureHan-Wen Nienhuys via GitGitGadget, May 7, 2020
  215. 00/13 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, May 11, 2020
  216. 01/13 refs.h: clarify reflog iteration orderHan-Wen Nienhuys via GitGitGadget, May 11, 2020
  217. Junio C HamanoMay 18, 2020
  218. 03/13 refs: document how ref_iterator_advance_fn should handle symrefsHan-Wen Nienhuys via GitGitGadget, May 11, 2020
  219. Junio C HamanoMay 18, 2020
  220. 02/13 t: use update-ref and show-ref to reading/writing refsHan-Wen Nienhuys via GitGitGadget, May 11, 2020
  221. Junio C HamanoMay 18, 2020
  222. 05/13 reftable: clarify how empty tables should be writtenHan-Wen Nienhuys via GitGitGadget, May 11, 2020
  223. Junio C HamanoMay 19, 2020
  224. 06/13 reftable: define version 2 of the spec to accomodate SHA256Han-Wen Nienhuys via GitGitGadget, May 11, 2020
  225. Junio C HamanoMay 19, 2020
  226. Han-Wen NienhuysMay 20, 2020
  227. Junio C HamanoMay 20, 2020
  228. 07/13 Write pseudorefs through ref backends.Han-Wen Nienhuys via GitGitGadget, May 11, 2020
  229. Phillip WoodMay 12, 2020
  230. Han-Wen NienhuysMay 12, 2020
  231. Phillip WoodMay 13, 2020
  232. Phillip WoodMay 13, 2020
  233. 04/13 reftable: file format documentationJonathan Nieder via GitGitGadget, May 11, 2020
  234. Junio C HamanoMay 19, 2020
  235. Han-Wen NienhuysMay 20, 2020
  236. Han-Wen NienhuysMay 20, 2020
  237. Han-Wen NienhuysMay 20, 2020
  238. Junio C HamanoMay 20, 2020
  239. Jonathan NiederMay 20, 2020
  240. 08/13 Iterate over the "refs/" namespace in for_each_[raw]refHan-Wen Nienhuys via GitGitGadget, May 11, 2020
  241. 09/13 Add .gitattributes for the reftable/ directoryHan-Wen Nienhuys via GitGitGadget, May 11, 2020
  242. 10/13 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, May 11, 2020
  243. 12/13 vcxproj: adjust for the reftable changesJohannes Schindelin via GitGitGadget, May 11, 2020
  244. 11/13 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, May 11, 2020
  245. Junio C HamanoMay 13, 2020
  246. 13/13 Add some reftable testing infrastructureHan-Wen Nienhuys via GitGitGadget, May 11, 2020
  247. Junio C HamanoMay 13, 2020
  248. Han-Wen NienhuysMay 19, 2020
  249. Junio C HamanoMay 19, 2020
  250. Junio C HamanoMay 12, 2020
  251. Han-Wen NienhuysMay 12, 2020
  252. Junio C HamanoMay 13, 2020
  253. 0/9 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, May 18, 2020
  254. 2/9 Move REF_LOG_ONLY to refs-internal.hHan-Wen Nienhuys via GitGitGadget, May 18, 2020
  255. 1/9 Write pseudorefs through ref backends.Han-Wen Nienhuys via GitGitGadget, May 18, 2020
  256. 3/9 Iterate over the "refs/" namespace in for_each_[raw]refHan-Wen Nienhuys via GitGitGadget, May 18, 2020
  257. 4/9 Add .gitattributes for the reftable/ directoryHan-Wen Nienhuys via GitGitGadget, May 18, 2020
  258. 7/9 Add GIT_DEBUG_REFS debugging mechanismHan-Wen Nienhuys via GitGitGadget, May 18, 2020
  259. 8/9 vcxproj: adjust for the reftable changesJohannes Schindelin via GitGitGadget, May 18, 2020
  260. 9/9 Add reftable testing infrastructureHan-Wen Nienhuys via GitGitGadget, May 18, 2020
  261. 6/9 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, May 18, 2020
  262. 5/9 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, May 18, 2020
  263. 00/13 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, May 28, 2020
  264. 13/13 Add reftable testing infrastructureHan-Wen Nienhuys via GitGitGadget, May 28, 2020
  265. 10/13 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, May 28, 2020
  266. 09/13 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, May 28, 2020
  267. 11/13 Add GIT_DEBUG_REFS debugging mechanismHan-Wen Nienhuys via GitGitGadget, May 28, 2020
  268. 08/13 Add .gitattributes for the reftable/ directoryHan-Wen Nienhuys via GitGitGadget, May 28, 2020
  269. 12/13 vcxproj: adjust for the reftable changesJohannes Schindelin via GitGitGadget, May 28, 2020
  270. 07/13 Iterate over the "refs/" namespace in for_each_[raw]refHan-Wen Nienhuys via GitGitGadget, May 28, 2020
  271. 06/13 Move REF_LOG_ONLY to refs-internal.hHan-Wen Nienhuys via GitGitGadget, May 28, 2020
  272. 05/13 Treat REVERT_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, May 28, 2020
  273. 02/13 Make refs_ref_exists publicHan-Wen Nienhuys via GitGitGadget, May 28, 2020
  274. 04/13 Treat CHERRY_PICK_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, May 28, 2020
  275. 03/13 Treat BISECT_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, May 28, 2020
  276. Junio C HamanoMay 28, 2020
  277. 01/13 Write pseudorefs through ref backends.Han-Wen Nienhuys via GitGitGadget, May 28, 2020
  278. Junio C HamanoMay 28, 2020
  279. Junio C HamanoMay 28, 2020
  280. 00/14 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  281. 02/14 Make refs_ref_exists publicHan-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  282. Phillip WoodJun 9, 2020
  283. Han-Wen NienhuysJun 10, 2020
  284. Phillip WoodJun 11, 2020
  285. Phillip WoodJun 12, 2020
  286. Han-Wen NienhuysJun 15, 2020
  287. 01/14 Write pseudorefs through ref backends.Han-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  288. Phillip WoodJun 9, 2020
  289. 03/14 Treat BISECT_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  290. 05/14 Treat REVERT_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  291. 04/14 Treat CHERRY_PICK_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  292. 06/14 Move REF_LOG_ONLY to refs-internal.hHan-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  293. 07/14 Iterate over the "refs/" namespace in for_each_[raw]refHan-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  294. 08/14 Add .gitattributes for the reftable/ directoryHan-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  295. 11/14 Hookup unittests for the reftable library.Han-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  296. Junio C HamanoJun 8, 2020
  297. Fixup! Add t/helper/test-reftable.chanwen@google.com, Jun 9, 2020
  298. Junio C HamanoJun 9, 2020
  299. 10/14 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  300. 13/14 vcxproj: adjust for the reftable changesJohannes Schindelin via GitGitGadget, Jun 5, 2020
  301. 09/14 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  302. 14/14 Add reftable testing infrastructureHan-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  303. 12/14 Add GIT_DEBUG_REFS debugging mechanismHan-Wen Nienhuys via GitGitGadget, Jun 5, 2020
  304. Junio C HamanoJun 9, 2020
  305. Han-Wen NienhuysJun 10, 2020
  306. Junio C HamanoJun 10, 2020
  307. Junio C HamanoJun 10, 2020
  308. Johannes SchindelinJun 10, 2020
  309. Han-Wen NienhuysJun 10, 2020
  310. Johannes SchindelinJun 10, 2020
  311. Han-Wen NienhuysJun 10, 2020
  312. 00/17 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  313. 01/17 lib-t6000.sh: write tag using git-update-refHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  314. 02/17 checkout: add '\n' to reflog messageHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  315. 04/17 Make refs_ref_exists publicHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  316. 03/17 Write pseudorefs through ref backends.Han-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  317. 05/17 Treat BISECT_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  318. 07/17 Treat REVERT_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  319. 12/17 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  320. SZEDER GáborJun 19, 2020
  321. 14/17 Add GIT_DEBUG_REFS debugging mechanismHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  322. 15/17 vcxproj: adjust for the reftable changesJohannes Schindelin via GitGitGadget, Jun 16, 2020
  323. 17/17 Add "test-tool dump-reftable" command.Han-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  324. 13/17 Hookup unittests for the reftable library.Han-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  325. 11/17 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  326. 16/17 Add reftable testing infrastructureHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  327. SZEDER GáborJun 19, 2020
  328. 10/17 Add .gitattributes for the reftable/ directoryHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  329. 09/17 Iterate over the "refs/" namespace in for_each_[raw]refHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  330. 06/17 Treat CHERRY_PICK_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  331. 08/17 Move REF_LOG_ONLY to refs-internal.hHan-Wen Nienhuys via GitGitGadget, Jun 16, 2020
  332. 00/19 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  333. 02/19 checkout: add '\n' to reflog messageHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  334. 04/19 Make refs_ref_exists publicHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  335. 05/19 Treat BISECT_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  336. 06/19 Treat CHERRY_PICK_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  337. 07/19 Treat REVERT_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  338. 08/19 Move REF_LOG_ONLY to refs-internal.hHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  339. 03/19 Write pseudorefs through ref backends.Han-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  340. 01/19 lib-t6000.sh: write tag using git-update-refHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  341. 12/19 Add standalone build infrastructure for reftableHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  342. 18/19 Add reftable testing infrastructureHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  343. 11/19 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  344. 09/19 Iterate over the "refs/" namespace in for_each_[raw]refHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  345. 19/19 Add "test-tool dump-reftable" command.Han-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  346. 17/19 git-prompt: prepare for reftable refs backendSZEDER Gábor via GitGitGadget, Jun 22, 2020
  347. 10/19 Add .gitattributes for the reftable/ directoryHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  348. 15/19 Add GIT_DEBUG_REFS debugging mechanismHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  349. 13/19 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  350. 14/19 Hookup unittests for the reftable library.Han-Wen Nienhuys via GitGitGadget, Jun 22, 2020
  351. 16/19 vcxproj: adjust for the reftable changesJohannes Schindelin via GitGitGadget, Jun 22, 2020
  352. 00/20 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  353. 05/20 Make refs_ref_exists publicHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  354. 09/20 Move REF_LOG_ONLY to refs-internal.hHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  355. 11/20 Add .gitattributes for the reftable/ directoryHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  356. 03/20 checkout: add '\n' to reflog messageHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  357. Junio C HamanoJun 29, 2020
  358. Han-Wen NienhuysJun 30, 2020
  359. Junio C HamanoJun 30, 2020
  360. Han-Wen NienhuysJul 1, 2020
  361. Re* [PATCH v19 03/20] checkout: add '\n' to reflog messageJunio C Hamano, Jul 1, 2020
  362. Han-Wen NienhuysJul 6, 2020
  363. Junio C HamanoJul 6, 2020
  364. 17/20 vcxproj: adjust for the reftable changesJohannes Schindelin via GitGitGadget, Jun 29, 2020
  365. 08/20 Treat REVERT_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  366. 10/20 Iterate over the "refs/" namespace in for_each_[raw]refHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  367. 20/20 Add "test-tool dump-reftable" command.Han-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  368. 19/20 Add reftable testing infrastructureHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  369. 16/20 Add GIT_DEBUG_REFS debugging mechanismHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  370. 18/20 git-prompt: prepare for reftable refs backendSZEDER Gábor via GitGitGadget, Jun 29, 2020
  371. 14/20 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  372. 12/20 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  373. 15/20 Hookup unittests for the reftable library.Han-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  374. 13/20 Add standalone build infrastructure for reftableHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  375. 07/20 Treat CHERRY_PICK_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  376. 06/20 Treat BISECT_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  377. 04/20 Write pseudorefs through ref backends.Han-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  378. 01/20 lib-t6000.sh: write tag using git-update-refHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  379. 02/20 t3432: use git-reflog to inspect the reflog for HEADHan-Wen Nienhuys via GitGitGadget, Jun 29, 2020
  380. Denton LiuJun 30, 2020
  381. Junio C HamanoJun 29, 2020
  382. Han-Wen NienhuysJun 30, 2020
  383. Junio C HamanoJul 1, 2020
  384. Han-Wen NienhuysJul 1, 2020
  385. Junio C HamanoJul 1, 2020
  386. 00/21 Reftable support git-coreHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  387. 01/21 refs: add \t to reflog in the files backendHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  388. 03/21 t1400: use git rev-parse for testing PSEUDOREF existenceHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  389. 04/21 Modify pseudo refs through ref backend storageHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  390. 05/21 Make HEAD a PSEUDOREF rather than PER_WORKTREE.Han-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  391. 06/21 Make refs_ref_exists publicHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  392. 07/21 Treat CHERRY_PICK_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  393. 08/21 Treat REVERT_HEAD as a pseudo refHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  394. 10/21 Iteration over entire ref namespace is iterating over "refs/"Han-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  395. 02/21 Split off reading loose ref data in separate functionHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  396. 09/21 Move REF_LOG_ONLY to refs-internal.hHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  397. 13/21 Add standalone build infrastructure for reftableHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  398. 11/21 Add .gitattributes for the reftable/ directoryHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  399. 15/21 Read FETCH_HEAD as loose refHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  400. 16/21 Hookup unittests for the reftable library.Han-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  401. 18/21 vcxproj: adjust for the reftable changesJohannes Schindelin via GitGitGadget, Jul 31, 2020
  402. 14/21 Reftable support for git-coreHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  403. 19/21 git-prompt: prepare for reftable refs backendSZEDER Gábor via GitGitGadget, Jul 31, 2020
  404. 21/21 Add "test-tool dump-reftable" command.Han-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  405. 20/21 Add reftable testing infrastructureHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  406. 17/21 Add GIT_DEBUG_REFS debugging mechanismHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  407. 12/21 Add reftable libraryHan-Wen Nienhuys via GitGitGadget, Jul 31, 2020
  408. Jonathan NiederFeb 26, 2020
  409. Han-Wen NienhuysFeb 26, 2020

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.