From: "Han-Wen Nienhuys via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Han-Wen Nienhuys <hanwenn@gmail.com>
Subject: [PATCH v18 00/19] Reftable support git-core
Date: Mon, 22 Jun 2020 21:55:01 +0000 [thread overview]
Message-ID: <pull.539.v18.git.1592862920.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.539.v17.git.1592335242.gitgitgadget@gmail.com>
This adds the reftable library, and hooks it up as a ref backend. Based on
hn/refs-cleanup.
Includes testing support, to test: make -C t/ GIT_TEST_REFTABLE=1
Summary 21561 tests pass 899 tests fail
Some issues:
* many tests inspect .git/{logs,heads}/ directly.
* worktrees broken.
v21
* reftable/ is now fully imported from upstream.
* reftable/ uses strbuf
* fix of the HEAD file.
* check for reload on every read
Han-Wen Nienhuys (17):
lib-t6000.sh: write tag using git-update-ref
checkout: add '\n' to reflog message
Write pseudorefs through ref backends.
Make refs_ref_exists public
Treat BISECT_HEAD as a pseudo ref
Treat CHERRY_PICK_HEAD as a pseudo ref
Treat REVERT_HEAD as a pseudo ref
Move REF_LOG_ONLY to refs-internal.h
Iterate over the "refs/" namespace in for_each_[raw]ref
Add .gitattributes for the reftable/ directory
Add reftable library
Add standalone build infrastructure for reftable
Reftable support for git-core
Hookup unittests for the reftable library.
Add GIT_DEBUG_REFS debugging mechanism
Add reftable testing infrastructure
Add "test-tool dump-reftable" command.
Johannes Schindelin (1):
vcxproj: adjust for the reftable changes
SZEDER Gábor (1):
git-prompt: prepare for reftable refs backend
.../technical/repository-version.txt | 7 +
Makefile | 47 +-
builtin/bisect--helper.c | 3 +-
builtin/checkout.c | 5 +-
builtin/clone.c | 3 +-
builtin/commit.c | 34 +-
builtin/init-db.c | 56 +-
builtin/merge.c | 2 +-
cache.h | 6 +-
config.mak.uname | 2 +-
contrib/buildsystems/Generators/Vcxproj.pm | 11 +-
contrib/completion/git-prompt.sh | 7 +-
git-bisect.sh | 4 +-
path.c | 2 -
path.h | 9 +-
refs.c | 157 +-
refs.h | 16 +
refs/debug.c | 411 +++++
refs/files-backend.c | 121 +-
refs/packed-backend.c | 21 +-
refs/refs-internal.h | 32 +
refs/reftable-backend.c | 1335 +++++++++++++++++
reftable/.gitattributes | 1 +
reftable/BUILD | 203 +++
reftable/LICENSE | 31 +
reftable/README.md | 33 +
reftable/VERSION | 1 +
reftable/WORKSPACE | 14 +
reftable/basics.c | 215 +++
reftable/basics.h | 53 +
reftable/block.c | 432 ++++++
reftable/block.h | 129 ++
reftable/block_test.c | 157 ++
reftable/compat.c | 98 ++
reftable/compat.h | 48 +
reftable/constants.h | 21 +
reftable/dump.c | 212 +++
reftable/file.c | 95 ++
reftable/iter.c | 242 +++
reftable/iter.h | 72 +
reftable/merged.c | 321 ++++
reftable/merged.h | 39 +
reftable/merged_test.c | 273 ++++
reftable/pq.c | 115 ++
reftable/pq.h | 34 +
reftable/reader.c | 744 +++++++++
reftable/reader.h | 65 +
reftable/record.c | 1126 ++++++++++++++
reftable/record.h | 143 ++
reftable/record_test.c | 410 +++++
reftable/refname.c | 209 +++
reftable/refname.h | 38 +
reftable/refname_test.c | 99 ++
reftable/reftable-tests.h | 22 +
reftable/reftable.c | 90 ++
reftable/reftable.h | 571 +++++++
reftable/reftable_test.c | 631 ++++++++
reftable/stack.c | 1209 +++++++++++++++
reftable/stack.h | 48 +
reftable/stack_test.c | 787 ++++++++++
reftable/strbuf.c | 206 +++
reftable/strbuf.h | 88 ++
reftable/strbuf_test.c | 39 +
reftable/system.h | 53 +
reftable/test_framework.c | 69 +
reftable/test_framework.h | 64 +
reftable/tree.c | 63 +
reftable/tree.h | 34 +
reftable/tree_test.c | 62 +
reftable/update.sh | 19 +
reftable/writer.c | 662 ++++++++
reftable/writer.h | 60 +
reftable/zlib-compat.c | 92 ++
reftable/zlib.BUILD | 36 +
repository.c | 2 +
repository.h | 3 +
sequencer.c | 56 +-
setup.c | 12 +-
t/helper/test-reftable.c | 20 +
t/helper/test-tool.c | 2 +
t/helper/test-tool.h | 2 +
t/lib-t6000.sh | 5 +-
t/t0031-reftable.sh | 160 ++
t/t0033-debug-refs.sh | 18 +
t/t1409-avoid-packing-refs.sh | 6 +
t/t1450-fsck.sh | 6 +
t/t3210-pack-refs.sh | 6 +
t/test-lib.sh | 5 +
wt-status.c | 6 +-
89 files changed, 12977 insertions(+), 201 deletions(-)
create mode 100644 refs/debug.c
create mode 100644 refs/reftable-backend.c
create mode 100644 reftable/.gitattributes
create mode 100644 reftable/BUILD
create mode 100644 reftable/LICENSE
create mode 100644 reftable/README.md
create mode 100644 reftable/VERSION
create mode 100644 reftable/WORKSPACE
create mode 100644 reftable/basics.c
create mode 100644 reftable/basics.h
create mode 100644 reftable/block.c
create mode 100644 reftable/block.h
create mode 100644 reftable/block_test.c
create mode 100644 reftable/compat.c
create mode 100644 reftable/compat.h
create mode 100644 reftable/constants.h
create mode 100644 reftable/dump.c
create mode 100644 reftable/file.c
create mode 100644 reftable/iter.c
create mode 100644 reftable/iter.h
create mode 100644 reftable/merged.c
create mode 100644 reftable/merged.h
create mode 100644 reftable/merged_test.c
create mode 100644 reftable/pq.c
create mode 100644 reftable/pq.h
create mode 100644 reftable/reader.c
create mode 100644 reftable/reader.h
create mode 100644 reftable/record.c
create mode 100644 reftable/record.h
create mode 100644 reftable/record_test.c
create mode 100644 reftable/refname.c
create mode 100644 reftable/refname.h
create mode 100644 reftable/refname_test.c
create mode 100644 reftable/reftable-tests.h
create mode 100644 reftable/reftable.c
create mode 100644 reftable/reftable.h
create mode 100644 reftable/reftable_test.c
create mode 100644 reftable/stack.c
create mode 100644 reftable/stack.h
create mode 100644 reftable/stack_test.c
create mode 100644 reftable/strbuf.c
create mode 100644 reftable/strbuf.h
create mode 100644 reftable/strbuf_test.c
create mode 100644 reftable/system.h
create mode 100644 reftable/test_framework.c
create mode 100644 reftable/test_framework.h
create mode 100644 reftable/tree.c
create mode 100644 reftable/tree.h
create mode 100644 reftable/tree_test.c
create mode 100755 reftable/update.sh
create mode 100644 reftable/writer.c
create mode 100644 reftable/writer.h
create mode 100644 reftable/zlib-compat.c
create mode 100644 reftable/zlib.BUILD
create mode 100644 t/helper/test-reftable.c
create mode 100755 t/t0031-reftable.sh
create mode 100755 t/t0033-debug-refs.sh
base-commit: 4d328a12d95bbea4e742463974ca03e49933bf7e
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-539%2Fhanwen%2Freftable-v18
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-539/hanwen/reftable-v18
Pull-Request: https://github.com/gitgitgadget/git/pull/539
Range-diff vs v17:
1: 8304c3d6379 = 1: b968b795af9 lib-t6000.sh: write tag using git-update-ref
2: 4012d801e3c = 2: 52102259773 checkout: add '\n' to reflog message
3: 95a6a1d968e = 3: 15c9dd66e17 Write pseudorefs through ref backends.
4: 1f8865f4b3e = 4: a5bce2e3fe6 Make refs_ref_exists public
5: 7f376a76d84 = 5: a29d898907a Treat BISECT_HEAD as a pseudo ref
6: 959c69b5ee4 = 6: 11a690d2b8e Treat CHERRY_PICK_HEAD as a pseudo ref
7: 3f18475d0d3 = 7: 4e52ec0dbc1 Treat REVERT_HEAD as a pseudo ref
8: 4981e5395c6 = 8: 37e350af159 Move REF_LOG_ONLY to refs-internal.h
9: f452c48ae44 = 9: 468f00eaf67 Iterate over the "refs/" namespace in for_each_[raw]ref
10: 1fa68d5d34f = 10: 21febeaa81f Add .gitattributes for the reftable/ directory
11: 86646c834c2 ! 11: 3c84f43cfa0 Add reftable library
@@ Metadata
## Commit message ##
Add reftable library
- Reftable is a format for storing the ref database. Its rationale and
- specification is in the preceding commit.
+ Reftable is a format for storing the ref database. The rationale and format
+ layout is detailed in commit 35e6c47404 ("reftable: file format documentation",
+ 2020-05-20).
- This imports the upstream library as one big commit. For understanding
- the code, it is suggested to read the code in the following order:
+ This commits imports a fully functioning library for reading and writing
+ reftables, along with unittests.
+
+ It is suggested to read the code in the following order:
* The specification under Documentation/technical/reftable.txt
@@ Commit message
* block.{c,h} - reading and writing blocks.
+ * reader.{c,h} - reading a complete reftable file.
+
* writer.{c,h} - writing a complete reftable file.
* merged.{c,h} and pq.{c,h} - reading a stack of reftables
@@ reftable/LICENSE (new)
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- ## reftable/README.md (new) ##
-@@
-+
-+The source code in this directory comes from https://github.com/google/reftable.
-+
-+The VERSION file keeps track of the current version of the reftable library.
-+
-+To update the library, do:
-+
-+ sh reftable/update.sh
-+
-+Bugfixes should be accompanied by a test and applied to upstream project at
-+https://github.com/google/reftable.
-
## reftable/VERSION (new) ##
@@
-+2c91c4b305dcbf6500c0806bb1a7fbcfc668510c C: include system.h in compat.h
++d7472cbd1afe6bf3da53e94971b1cc79ce183fa8 Remove outdated bits of the README file
## reftable/basics.c (new) ##
@@
@@ reftable/basics.c (new)
+
+#include "system.h"
+
-+void put_be24(byte *out, uint32_t i)
++void put_be24(uint8_t *out, uint32_t i)
+{
-+ out[0] = (byte)((i >> 16) & 0xff);
-+ out[1] = (byte)((i >> 8) & 0xff);
-+ out[2] = (byte)(i & 0xff);
++ out[0] = (uint8_t)((i >> 16) & 0xff);
++ out[1] = (uint8_t)((i >> 8) & 0xff);
++ out[2] = (uint8_t)(i & 0xff);
+}
+
-+uint32_t get_be24(byte *in)
++uint32_t get_be24(uint8_t *in)
+{
+ return (uint32_t)(in[0]) << 16 | (uint32_t)(in[1]) << 8 |
+ (uint32_t)(in[2]);
@@ reftable/basics.h (new)
+
+/* Bigendian en/decoding of integers */
+
-+void put_be24(byte *out, uint32_t i);
-+uint32_t get_be24(byte *in);
++void put_be24(uint8_t *out, uint32_t i);
++uint32_t get_be24(uint8_t *in);
+void put_be16(uint8_t *out, uint16_t i);
+
+/*
@@ reftable/block.c (new)
+}
+
+int block_writer_register_restart(struct block_writer *w, int n, bool restart,
-+ struct slice *key);
++ struct strbuf *key);
+
-+void block_writer_init(struct block_writer *bw, byte typ, byte *buf,
++void block_writer_init(struct block_writer *bw, uint8_t typ, uint8_t *buf,
+ uint32_t block_size, uint32_t header_off, int hash_size)
+{
+ bw->buf = buf;
@@ reftable/block.c (new)
+ bw->entries = 0;
+ bw->restart_len = 0;
+ bw->last_key.len = 0;
-+ bw->last_key.canary = SLICE_CANARY;
+}
+
-+byte block_writer_type(struct block_writer *bw)
++uint8_t block_writer_type(struct block_writer *bw)
+{
+ return bw->buf[bw->header_off];
+}
@@ reftable/block.c (new)
+ success */
+int block_writer_add(struct block_writer *w, struct reftable_record *rec)
+{
-+ struct slice empty = SLICE_INIT;
-+ struct slice last = w->entries % w->restart_interval == 0 ? empty :
-+ w->last_key;
-+ struct slice out = {
++ struct strbuf empty = STRBUF_INIT;
++ struct strbuf last =
++ w->entries % w->restart_interval == 0 ? empty : w->last_key;
++ struct string_view out = {
+ .buf = w->buf + w->next,
+ .len = w->block_size - w->next,
-+ .canary = SLICE_CANARY,
+ };
+
-+ struct slice start = out;
++ struct string_view start = out;
+
+ bool restart = false;
-+ struct slice key = SLICE_INIT;
++ struct strbuf key = STRBUF_INIT;
+ int n = 0;
+
+ reftable_record_key(rec, &key);
@@ reftable/block.c (new)
+ reftable_record_val_type(rec));
+ if (n < 0)
+ goto done;
-+ slice_consume(&out, n);
++ string_view_consume(&out, n);
+
+ n = reftable_record_encode(rec, out, w->hash_size);
+ if (n < 0)
+ goto done;
-+ slice_consume(&out, n);
++ string_view_consume(&out, n);
+
+ if (block_writer_register_restart(w, start.len - out.len, restart,
+ &key) < 0)
+ goto done;
+
-+ slice_release(&key);
++ strbuf_release(&key);
+ return 0;
+
+done:
-+ slice_release(&key);
++ strbuf_release(&key);
+ return -1;
+}
+
+int block_writer_register_restart(struct block_writer *w, int n, bool restart,
-+ struct slice *key)
++ struct strbuf *key)
+{
+ int rlen = w->restart_len;
+ if (rlen >= MAX_RESTARTS) {
@@ reftable/block.c (new)
+
+ w->next += n;
+
-+ slice_reset(&w->last_key);
-+ slice_addbuf(&w->last_key, key);
++ strbuf_reset(&w->last_key);
++ strbuf_addbuf(&w->last_key, key);
+ w->entries++;
+ return 0;
+}
@@ reftable/block.c (new)
+
+ if (block_writer_type(w) == BLOCK_TYPE_LOG) {
+ int block_header_skip = 4 + w->header_off;
-+ byte *compressed = NULL;
++ uint8_t *compressed = NULL;
+ int zresult = 0;
+ uLongf src_len = w->next - block_header_skip;
+ size_t dest_cap = src_len;
@@ reftable/block.c (new)
+ return w->next;
+}
+
-+byte block_reader_type(struct block_reader *r)
++uint8_t block_reader_type(struct block_reader *r)
+{
+ return r->block.data[r->header_off];
+}
@@ reftable/block.c (new)
+ int hash_size)
+{
+ uint32_t full_block_size = table_block_size;
-+ byte typ = block->data[header_off];
++ uint8_t typ = block->data[header_off];
+ uint32_t sz = get_be24(block->data + header_off + 1);
+
+ uint16_t restart_count = 0;
+ uint32_t restart_start = 0;
-+ byte *restart_bytes = NULL;
++ uint8_t *restart_bytes = NULL;
+
+ if (!reftable_is_block_type(typ))
+ return REFTABLE_FORMAT_ERROR;
@@ reftable/block.c (new)
+ uLongf src_len = block->len - block_header_skip;
+ /* Log blocks specify the *uncompressed* size in their header.
+ */
-+ byte *uncompressed = reftable_malloc(sz);
++ uint8_t *uncompressed = reftable_malloc(sz);
+
+ /* Copy over the block header verbatim. It's not compressed. */
+ memcpy(uncompressed, block->data, block_header_skip);
@@ reftable/block.c (new)
+void block_reader_start(struct block_reader *br, struct block_iter *it)
+{
+ it->br = br;
-+ slice_reset(&it->last_key);
++ strbuf_reset(&it->last_key);
+ it->next_off = br->header_off + 4;
+}
+
+struct restart_find_args {
+ int error;
-+ struct slice key;
++ struct strbuf key;
+ struct block_reader *r;
+};
+
@@ reftable/block.c (new)
+{
+ struct restart_find_args *a = (struct restart_find_args *)args;
+ uint32_t off = block_reader_restart_offset(a->r, idx);
-+ struct slice in = {
++ struct string_view in = {
+ .buf = a->r->block.data + off,
+ .len = a->r->block_len - off,
-+ .canary = SLICE_CANARY,
+ };
+
+ /* the restart key is verbatim in the block, so this could avoid the
+ alloc for decoding the key */
-+ struct slice rkey = SLICE_INIT;
-+ struct slice last_key = SLICE_INIT;
-+ byte unused_extra;
++ struct strbuf rkey = STRBUF_INIT;
++ struct strbuf last_key = STRBUF_INIT;
++ uint8_t unused_extra;
+ int n = reftable_decode_key(&rkey, &unused_extra, last_key, in);
+ int result;
+ if (n < 0) {
@@ reftable/block.c (new)
+ return -1;
+ }
+
-+ result = slice_cmp(&a->key, &rkey);
-+ slice_release(&rkey);
++ result = strbuf_cmp(&a->key, &rkey);
++ strbuf_release(&rkey);
+ return result;
+}
+
@@ reftable/block.c (new)
+{
+ dest->br = src->br;
+ dest->next_off = src->next_off;
-+ slice_reset(&dest->last_key);
-+ slice_addbuf(&dest->last_key, &src->last_key);
++ strbuf_reset(&dest->last_key);
++ strbuf_addbuf(&dest->last_key, &src->last_key);
+}
+
+int block_iter_next(struct block_iter *it, struct reftable_record *rec)
+{
-+ struct slice in = {
++ struct string_view in = {
+ .buf = it->br->block.data + it->next_off,
+ .len = it->br->block_len - it->next_off,
-+ .canary = SLICE_CANARY,
+ };
-+ struct slice start = in;
-+ struct slice key = SLICE_INIT;
-+ byte extra = 0;
++ struct string_view start = in;
++ struct strbuf key = STRBUF_INIT;
++ uint8_t extra = 0;
+ int n = 0;
+
+ if (it->next_off >= it->br->block_len)
@@ reftable/block.c (new)
+ if (n < 0)
+ return -1;
+
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+ n = reftable_record_decode(rec, key, extra, in, it->br->hash_size);
+ if (n < 0)
+ return -1;
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+
-+ slice_reset(&it->last_key);
-+ slice_addbuf(&it->last_key, &key);
++ strbuf_reset(&it->last_key);
++ strbuf_addbuf(&it->last_key, &key);
+ it->next_off += start.len - in.len;
-+ slice_release(&key);
++ strbuf_release(&key);
+ return 0;
+}
+
-+int block_reader_first_key(struct block_reader *br, struct slice *key)
++int block_reader_first_key(struct block_reader *br, struct strbuf *key)
+{
-+ struct slice empty = SLICE_INIT;
++ struct strbuf empty = STRBUF_INIT;
+ int off = br->header_off + 4;
-+ struct slice in = {
++ struct string_view in = {
+ .buf = br->block.data + off,
+ .len = br->block_len - off,
-+ .canary = SLICE_CANARY,
+ };
+
-+ byte extra = 0;
++ uint8_t extra = 0;
+ int n = reftable_decode_key(key, &extra, empty, in);
+ if (n < 0)
+ return n;
@@ reftable/block.c (new)
+ return 0;
+}
+
-+int block_iter_seek(struct block_iter *it, struct slice *want)
++int block_iter_seek(struct block_iter *it, struct strbuf *want)
+{
+ return block_reader_seek(it->br, it, want);
+}
+
+void block_iter_close(struct block_iter *it)
+{
-+ slice_release(&it->last_key);
++ strbuf_release(&it->last_key);
+}
+
+int block_reader_seek(struct block_reader *br, struct block_iter *it,
-+ struct slice *want)
++ struct strbuf *want)
+{
+ struct restart_find_args args = {
+ .key = *want,
+ .r = br,
+ };
+ struct reftable_record rec = reftable_new_record(block_reader_type(br));
-+ struct slice key = SLICE_INIT;
++ struct strbuf key = STRBUF_INIT;
+ int err = 0;
+ struct block_iter next = {
-+ .last_key = SLICE_INIT,
++ .last_key = STRBUF_INIT,
+ };
+
+ int i = binsearch(br->restart_count, &restart_key_less, &args);
@@ reftable/block.c (new)
+ goto done;
+
+ reftable_record_key(&rec, &key);
-+ if (err > 0 || slice_cmp(&key, want) >= 0) {
++ if (err > 0 || strbuf_cmp(&key, want) >= 0) {
+ err = 0;
+ goto done;
+ }
@@ reftable/block.c (new)
+ }
+
+done:
-+ slice_release(&key);
-+ slice_release(&next.last_key);
++ strbuf_release(&key);
++ strbuf_release(&next.last_key);
+ reftable_record_destroy(&rec);
+
+ return err;
@@ reftable/block.c (new)
+void block_writer_clear(struct block_writer *bw)
+{
+ FREE_AND_NULL(bw->restarts);
-+ slice_release(&bw->last_key);
++ strbuf_release(&bw->last_key);
+ /* the block is not owned. */
+}
@@ reftable/block.h (new)
+ allocation overhead.
+*/
+struct block_writer {
-+ byte *buf;
++ uint8_t *buf;
+ uint32_t block_size;
+
+ /* Offset ofof the global header. Nonzero in the first block only. */
@@ reftable/block.h (new)
+ int restart_interval;
+ int hash_size;
+
-+ /* Offset of next byte to write. */
++ /* Offset of next uint8_t to write. */
+ uint32_t next;
+ uint32_t *restarts;
+ uint32_t restart_len;
+ uint32_t restart_cap;
+
-+ struct slice last_key;
++ struct strbuf last_key;
+ int entries;
+};
+
+/*
+ initializes the blockwriter to write `typ` entries, using `buf` as temporary
+ storage. `buf` is not owned by the block_writer. */
-+void block_writer_init(struct block_writer *bw, byte typ, byte *buf,
++void block_writer_init(struct block_writer *bw, uint8_t typ, uint8_t *buf,
+ uint32_t block_size, uint32_t header_off, int hash_size);
+
+/*
+ returns the block type (eg. 'r' for ref records.
+*/
-+byte block_writer_type(struct block_writer *bw);
++uint8_t block_writer_type(struct block_writer *bw);
+
+/* appends the record, or -1 if it doesn't fit. */
+int block_writer_add(struct block_writer *w, struct reftable_record *rec);
@@ reftable/block.h (new)
+
+ /* size of the data, excluding restart data. */
+ uint32_t block_len;
-+ byte *restart_bytes;
++ uint8_t *restart_bytes;
+ uint16_t restart_count;
+
+ /* size of the data in the file. For log blocks, this is the compressed
@@ reftable/block.h (new)
+ struct block_reader *br;
+
+ /* key for last entry we read. */
-+ struct slice last_key;
++ struct strbuf last_key;
+};
+
+/* initializes a block reader. */
@@ reftable/block.h (new)
+
+/* Position `it` to the `want` key in the block */
+int block_reader_seek(struct block_reader *br, struct block_iter *it,
-+ struct slice *want);
++ struct strbuf *want);
+
+/* Returns the block type (eg. 'r' for refs) */
-+byte block_reader_type(struct block_reader *r);
++uint8_t block_reader_type(struct block_reader *r);
+
+/* Decodes the first key in the block */
-+int block_reader_first_key(struct block_reader *br, struct slice *key);
++int block_reader_first_key(struct block_reader *br, struct strbuf *key);
+
+void block_iter_copy_from(struct block_iter *dest, struct block_iter *src);
+
@@ reftable/block.h (new)
+int block_iter_next(struct block_iter *it, struct reftable_record *rec);
+
+/* Seek to `want` with in the block pointed to by `it` */
-+int block_iter_seek(struct block_iter *it, struct slice *want);
++int block_iter_seek(struct block_iter *it, struct strbuf *want);
+
+/* deallocate memory for `it`. The block reader and its block is left intact. */
+void block_iter_close(struct block_iter *it);
@@ reftable/block_test.c (new)
+ const int block_size = 1024;
+ struct reftable_block block = { 0 };
+ struct block_writer bw = {
-+ .last_key = SLICE_INIT,
++ .last_key = STRBUF_INIT,
+ };
+ struct reftable_ref_record ref = { 0 };
+ struct reftable_record rec = { 0 };
+ int i = 0;
+ int n;
+ struct block_reader br = { 0 };
-+ struct block_iter it = { .last_key = SLICE_INIT };
++ struct block_iter it = { .last_key = STRBUF_INIT };
+ int j = 0;
-+ struct slice want = SLICE_INIT;
++ struct strbuf want = STRBUF_INIT;
+
+ block.data = reftable_calloc(block_size);
+ block.len = block_size;
@@ reftable/block_test.c (new)
+
+ for (i = 0; i < N; i++) {
+ char name[100];
-+ byte hash[SHA1_SIZE];
++ uint8_t hash[SHA1_SIZE];
+ snprintf(name, sizeof(name), "branch%02d", i);
+ memset(hash, i, sizeof(hash));
+
@@ reftable/block_test.c (new)
+ block_iter_close(&it);
+
+ for (i = 0; i < N; i++) {
-+ struct block_iter it = { .last_key = SLICE_INIT };
-+ slice_reset(&want);
-+ slice_addstr(&want, names[i]);
++ struct block_iter it = { .last_key = STRBUF_INIT };
++ strbuf_reset(&want);
++ strbuf_addstr(&want, names[i]);
+
+ n = block_reader_seek(&br, &it, &want);
+ assert(n == 0);
@@ reftable/block_test.c (new)
+
+ reftable_record_clear(&rec);
+ reftable_block_done(&br.block);
-+ slice_release(&want);
++ strbuf_release(&want);
+ for (i = 0; i < N; i++) {
+ reftable_free(names[i]);
+ }
@@ reftable/compat.c (new)
+#include "system.h"
+#include "basics.h"
+
-+#ifndef REFTABLE_IN_GITCORE
++#ifdef REFTABLE_STANDALONE
+
+#include <dirent.h>
+
+void put_be32(void *p, uint32_t i)
+{
-+ byte *out = (byte *)p;
++ uint8_t *out = (uint8_t *)p;
+
+ out[0] = (uint8_t)((i >> 24) & 0xff);
+ out[1] = (uint8_t)((i >> 16) & 0xff);
@@ reftable/compat.c (new)
+
+void put_be64(void *p, uint64_t v)
+{
-+ byte *out = (byte *)p;
++ uint8_t *out = (uint8_t *)p;
+ int i = sizeof(uint64_t);
+ while (i--) {
+ out[i] = (uint8_t)(v & 0xff);
@@ reftable/compat.c (new)
+ }
+}
+
-+uint64_t get_be64(uint8_t *out)
++uint64_t get_be64(void *out)
+{
++ uint8_t *bytes = (uint8_t *)out;
+ uint64_t v = 0;
+ int i = 0;
+ for (i = 0; i < sizeof(uint64_t); i++) {
-+ v = (v << 8) | (uint8_t)(out[i] & 0xff);
++ v = (v << 8) | (uint8_t)(bytes[i] & 0xff);
+ }
+ return v;
+}
@@ reftable/compat.h (new)
+
+#include "system.h"
+
-+#ifndef REFTABLE_IN_GITCORE
++#ifdef REFTABLE_STANDALONE
+
+/* functions that git-core provides, for standalone compilation */
+#include <stdint.h>
+
-+uint64_t get_be64(uint8_t *in);
++uint64_t get_be64(void *in);
+void put_be64(void *out, uint64_t i);
+
+void put_be32(void *out, uint32_t i);
@@ reftable/file.c (new)
+ return 0;
+}
+
-+int reftable_fd_write(void *arg, byte *data, size_t sz)
++int reftable_fd_write(void *arg, const void *data, size_t sz)
+{
+ int *fdp = (int *)arg;
+ return write(*fdp, data, sz);
@@ reftable/iter.c (new)
+{
+ struct filtering_ref_iterator *fri =
+ (struct filtering_ref_iterator *)iter_arg;
-+ slice_release(&fri->oid);
++ strbuf_release(&fri->oid);
+ reftable_iterator_destroy(&fri->it);
+}
+
@@ reftable/iter.c (new)
+ struct indexed_table_ref_iter *it = (struct indexed_table_ref_iter *)p;
+ block_iter_close(&it->cur);
+ reftable_block_done(&it->block_reader.block);
-+ slice_release(&it->oid);
++ strbuf_release(&it->oid);
+}
+
+static int indexed_table_ref_iter_next_block(struct indexed_table_ref_iter *it)
@@ reftable/iter.c (new)
+}
+
+int new_indexed_table_ref_iter(struct indexed_table_ref_iter **dest,
-+ struct reftable_reader *r, byte *oid,
++ struct reftable_reader *r, uint8_t *oid,
+ int oid_len, uint64_t *offsets, int offset_len)
+{
+ struct indexed_table_ref_iter empty = INDEXED_TABLE_REF_ITER_INIT;
@@ reftable/iter.c (new)
+
+ *itr = empty;
+ itr->r = r;
-+ slice_add(&itr->oid, oid, oid_len);
++ strbuf_add(&itr->oid, oid, oid_len);
+
+ itr->offsets = offsets;
+ itr->offset_len = offset_len;
@@ reftable/iter.h (new)
+
+#include "block.h"
+#include "record.h"
-+#include "slice.h"
++#include "strbuf.h"
+
+struct reftable_iterator_vtable {
+ int (*next)(void *iter_arg, struct reftable_record *rec);
@@ reftable/iter.h (new)
+struct filtering_ref_iterator {
+ bool double_check;
+ struct reftable_table tab;
-+ struct slice oid;
++ struct strbuf oid;
+ struct reftable_iterator it;
+};
+#define FILTERING_REF_ITERATOR_INIT \
+ { \
-+ .oid = SLICE_INIT \
++ .oid = STRBUF_INIT \
+ }
+
+void iterator_from_filtering_ref_iterator(struct reftable_iterator *,
@@ reftable/iter.h (new)
+ */
+struct indexed_table_ref_iter {
+ struct reftable_reader *r;
-+ struct slice oid;
++ struct strbuf oid;
+
+ /* mutable */
+ uint64_t *offsets;
@@ reftable/iter.h (new)
+ bool finished;
+};
+
-+#define INDEXED_TABLE_REF_ITER_INIT \
-+ { \
-+ .cur = { .last_key = SLICE_INIT }, .oid = SLICE_INIT, \
++#define INDEXED_TABLE_REF_ITER_INIT \
++ { \
++ .cur = { .last_key = STRBUF_INIT }, .oid = STRBUF_INIT, \
+ }
+
+void iterator_from_indexed_table_ref_iter(struct reftable_iterator *it,
+ struct indexed_table_ref_iter *itr);
+int new_indexed_table_ref_iter(struct indexed_table_ref_iter **dest,
-+ struct reftable_reader *r, byte *oid,
++ struct reftable_reader *r, uint8_t *oid,
+ int oid_len, uint64_t *offsets, int offset_len);
+
+#endif
@@ reftable/merged.c (new)
+#include "iter.h"
+#include "pq.h"
+#include "reader.h"
++#include "record.h"
+
+static int merged_iter_init(struct merged_iter *mi)
+{
@@ reftable/merged.c (new)
+static int merged_iter_next_entry(struct merged_iter *mi,
+ struct reftable_record *rec)
+{
-+ struct slice entry_key = SLICE_INIT;
++ struct strbuf entry_key = STRBUF_INIT;
+ struct pq_entry entry = { 0 };
+ int err = 0;
+
@@ reftable/merged.c (new)
+ reftable_record_key(&entry.rec, &entry_key);
+ while (!merged_iter_pqueue_is_empty(mi->pq)) {
+ struct pq_entry top = merged_iter_pqueue_top(mi->pq);
-+ struct slice k = SLICE_INIT;
++ struct strbuf k = STRBUF_INIT;
+ int err = 0, cmp = 0;
+
+ reftable_record_key(&top.rec, &k);
+
-+ cmp = slice_cmp(&k, &entry_key);
-+ slice_release(&k);
++ cmp = strbuf_cmp(&k, &entry_key);
++ strbuf_release(&k);
+
+ if (cmp > 0) {
+ break;
@@ reftable/merged.c (new)
+
+ reftable_record_copy_from(rec, &entry.rec, hash_size(mi->hash_id));
+ reftable_record_destroy(&entry.rec);
-+ slice_release(&entry_key);
++ strbuf_release(&entry_key);
+ return 0;
+}
+
@@ reftable/merged.h (new)
+ struct reftable_iterator *stack;
+ uint32_t hash_id;
+ int stack_len;
-+ byte typ;
++ uint8_t typ;
+ bool suppress_deletions;
+ struct merged_iter_pqueue pq;
+};
@@ reftable/merged_test.c (new)
+ merged_iter_pqueue_clear(&pq);
+}
+
-+static void write_test_table(struct slice *buf,
++static void write_test_table(struct strbuf *buf,
+ struct reftable_ref_record refs[], int n)
+{
+ int min = 0xffffffff;
@@ reftable/merged_test.c (new)
+ }
+ }
+
-+ w = reftable_new_writer(&slice_add_void, buf, &opts);
++ w = reftable_new_writer(&strbuf_add_void, buf, &opts);
+ reftable_writer_set_limits(w, min, max);
+
+ for (i = 0; i < n; i++) {
@@ reftable/merged_test.c (new)
+static struct reftable_merged_table *
+merged_table_from_records(struct reftable_ref_record **refs,
+ struct reftable_block_source **source, int *sizes,
-+ struct slice *buf, int n)
++ struct strbuf *buf, int n)
+{
+ struct reftable_reader **rd = reftable_calloc(n * sizeof(*rd));
+ int i = 0;
@@ reftable/merged_test.c (new)
+ *source = reftable_calloc(n * sizeof(**source));
+ for (i = 0; i < n; i++) {
+ write_test_table(&buf[i], refs[i], sizes[i]);
-+ block_source_from_slice(&(*source)[i], &buf[i]);
++ block_source_from_strbuf(&(*source)[i], &buf[i]);
+
+ err = reftable_new_reader(&rd[i], &(*source)[i], "name");
+ assert_err(err);
@@ reftable/merged_test.c (new)
+
+static void test_merged_between(void)
+{
-+ byte hash1[SHA1_SIZE] = { 1, 2, 3, 0 };
++ uint8_t hash1[SHA1_SIZE] = { 1, 2, 3, 0 };
+
+ struct reftable_ref_record r1[] = { {
+ .ref_name = "b",
@@ reftable/merged_test.c (new)
+
+ struct reftable_ref_record *refs[] = { r1, r2 };
+ int sizes[] = { 1, 1 };
-+ struct slice bufs[2] = { SLICE_INIT, SLICE_INIT };
++ struct strbuf bufs[2] = { STRBUF_INIT, STRBUF_INIT };
+ struct reftable_block_source *bs = NULL;
+ struct reftable_merged_table *mt =
+ merged_table_from_records(refs, &bs, sizes, bufs, 2);
@@ reftable/merged_test.c (new)
+ reftable_merged_table_close(mt);
+ reftable_merged_table_free(mt);
+ for (i = 0; i < ARRAY_SIZE(bufs); i++) {
-+ slice_release(&bufs[i]);
++ strbuf_release(&bufs[i]);
+ }
+ reftable_free(bs);
+}
+
+static void test_merged(void)
+{
-+ byte hash1[SHA1_SIZE] = { 1 };
-+ byte hash2[SHA1_SIZE] = { 2 };
++ uint8_t hash1[SHA1_SIZE] = { 1 };
++ uint8_t hash2[SHA1_SIZE] = { 2 };
+ struct reftable_ref_record r1[] = { {
+ .ref_name = "a",
+ .update_index = 1,
@@ reftable/merged_test.c (new)
+
+ struct reftable_ref_record *refs[] = { r1, r2, r3 };
+ int sizes[3] = { 3, 1, 2 };
-+ struct slice bufs[3] = { SLICE_INIT, SLICE_INIT, SLICE_INIT };
++ struct strbuf bufs[3] = { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT };
+ struct reftable_block_source *bs = NULL;
+
+ struct reftable_merged_table *mt =
@@ reftable/merged_test.c (new)
+ reftable_free(out);
+
+ for (i = 0; i < 3; i++) {
-+ slice_release(&bufs[i]);
++ strbuf_release(&bufs[i]);
+ }
+ reftable_merged_table_close(mt);
+ reftable_merged_table_free(mt);
@@ reftable/pq.c (new)
+
+#include "pq.h"
+
++#include "reftable.h"
+#include "system.h"
++#include "basics.h"
+
+int pq_less(struct pq_entry a, struct pq_entry b)
+{
-+ struct slice ak = SLICE_INIT;
-+ struct slice bk = SLICE_INIT;
++ struct strbuf ak = STRBUF_INIT;
++ struct strbuf bk = STRBUF_INIT;
+ int cmp = 0;
+ reftable_record_key(&a.rec, &ak);
+ reftable_record_key(&b.rec, &bk);
+
-+ cmp = slice_cmp(&ak, &bk);
++ cmp = strbuf_cmp(&ak, &bk);
+
-+ slice_release(&ak);
-+ slice_release(&bk);
++ strbuf_release(&ak);
++ strbuf_release(&bk);
+
+ if (cmp == 0)
+ return a.index > b.index;
@@ reftable/reader.c (new)
+}
+
+static struct reftable_reader_offsets *
-+reader_offsets_for(struct reftable_reader *r, byte typ)
++reader_offsets_for(struct reftable_reader *r, uint8_t typ)
+{
+ switch (typ) {
+ case BLOCK_TYPE_REF:
@@ reftable/reader.c (new)
+ return r->name;
+}
+
-+static int parse_footer(struct reftable_reader *r, byte *footer, byte *header)
++static int parse_footer(struct reftable_reader *r, uint8_t *footer,
++ uint8_t *header)
+{
-+ byte *f = footer;
-+ byte first_block_typ;
++ uint8_t *f = footer;
++ uint8_t first_block_typ;
+ int err = 0;
+ uint32_t computed_crc;
+ uint32_t file_crc;
@@ reftable/reader.c (new)
+
+struct table_iter {
+ struct reftable_reader *r;
-+ byte typ;
++ uint8_t typ;
+ uint64_t block_off;
+ struct block_iter bi;
+ bool finished;
+};
-+#define TABLE_ITER_INIT \
-+ { \
-+ .bi = {.last_key = SLICE_INIT } \
++#define TABLE_ITER_INIT \
++ { \
++ .bi = {.last_key = STRBUF_INIT } \
+ }
+
+static void table_iter_copy_from(struct table_iter *dest,
@@ reftable/reader.c (new)
+ ti->bi.next_off = 0;
+}
+
-+static int32_t extract_block_size(byte *data, byte *typ, uint64_t off,
++static int32_t extract_block_size(uint8_t *data, uint8_t *typ, uint64_t off,
+ int version)
+{
+ int32_t result = 0;
@@ reftable/reader.c (new)
+}
+
+int reader_init_block_reader(struct reftable_reader *r, struct block_reader *br,
-+ uint64_t next_off, byte want_typ)
++ uint64_t next_off, uint8_t want_typ)
+{
+ int32_t guess_block_size = r->block_size ? r->block_size :
+ DEFAULT_BLOCK_SIZE;
+ struct reftable_block block = { 0 };
-+ byte block_typ = 0;
++ uint8_t block_typ = 0;
+ int err = 0;
+ uint32_t header_off = next_off ? 0 : header_size(r->version);
+ int32_t block_size = 0;
@@ reftable/reader.c (new)
+}
+
+static int reader_table_iter_at(struct reftable_reader *r,
-+ struct table_iter *ti, uint64_t off, byte typ)
++ struct table_iter *ti, uint64_t off,
++ uint8_t typ)
+{
+ struct block_reader br = { 0 };
+ struct block_reader *brp = NULL;
@@ reftable/reader.c (new)
+}
+
+static int reader_start(struct reftable_reader *r, struct table_iter *ti,
-+ byte typ, bool index)
++ uint8_t typ, bool index)
+{
+ struct reftable_reader_offsets *offs = reader_offsets_for(r, typ);
+ uint64_t off = offs->offset;
@@ reftable/reader.c (new)
+{
+ struct reftable_record rec =
+ reftable_new_record(reftable_record_type(want));
-+ struct slice want_key = SLICE_INIT;
-+ struct slice got_key = SLICE_INIT;
++ struct strbuf want_key = STRBUF_INIT;
++ struct strbuf got_key = STRBUF_INIT;
+ struct table_iter next = TABLE_ITER_INIT;
+ int err = -1;
+
@@ reftable/reader.c (new)
+ if (err < 0)
+ goto done;
+
-+ if (slice_cmp(&got_key, &want_key) > 0) {
++ if (strbuf_cmp(&got_key, &want_key) > 0) {
+ table_iter_block_done(&next);
+ break;
+ }
@@ reftable/reader.c (new)
+done:
+ block_iter_close(&next.bi);
+ reftable_record_destroy(&rec);
-+ slice_release(&want_key);
-+ slice_release(&got_key);
++ strbuf_release(&want_key);
++ strbuf_release(&got_key);
+ return err;
+}
+
@@ reftable/reader.c (new)
+ struct reftable_iterator *it,
+ struct reftable_record *rec)
+{
-+ struct reftable_index_record want_index = { .last_key = SLICE_INIT };
++ struct reftable_index_record want_index = { .last_key = STRBUF_INIT };
+ struct reftable_record want_index_rec = { 0 };
-+ struct reftable_index_record index_result = { .last_key = SLICE_INIT };
++ struct reftable_index_record index_result = { .last_key = STRBUF_INIT };
+ struct reftable_record index_result_rec = { 0 };
+ struct table_iter index_iter = TABLE_ITER_INIT;
+ struct table_iter next = TABLE_ITER_INIT;
@@ reftable/reader.c (new)
+int reader_seek(struct reftable_reader *r, struct reftable_iterator *it,
+ struct reftable_record *rec)
+{
-+ byte typ = reftable_record_type(rec);
++ uint8_t typ = reftable_record_type(rec);
+
+ struct reftable_reader_offsets *offs = reader_offsets_for(r, typ);
+ if (!offs->present) {
@@ reftable/reader.c (new)
+
+static int reftable_reader_refs_for_indexed(struct reftable_reader *r,
+ struct reftable_iterator *it,
-+ byte *oid)
++ uint8_t *oid)
+{
+ struct reftable_obj_record want = {
+ .hash_prefix = oid,
@@ reftable/reader.c (new)
+
+static int reftable_reader_refs_for_unindexed(struct reftable_reader *r,
+ struct reftable_iterator *it,
-+ byte *oid)
++ uint8_t *oid)
+{
+ struct table_iter ti_empty = TABLE_ITER_INIT;
+ struct table_iter *ti = reftable_calloc(sizeof(struct table_iter));
@@ reftable/reader.c (new)
+ filter = reftable_malloc(sizeof(struct filtering_ref_iterator));
+ *filter = empty;
+
-+ slice_add(&filter->oid, oid, oid_len);
++ strbuf_add(&filter->oid, oid, oid_len);
+ reftable_table_from_reader(&filter->tab, r);
+ filter->double_check = false;
+ iterator_from_table_iter(&filter->it, ti);
@@ reftable/reader.c (new)
+}
+
+int reftable_reader_refs_for(struct reftable_reader *r,
-+ struct reftable_iterator *it, byte *oid)
++ struct reftable_iterator *it, uint8_t *oid)
+{
+ if (r->obj_offsets.present)
+ return reftable_reader_refs_for_indexed(r, it, oid);
@@ reftable/reader.h (new)
+
+/* initialize a block reader to read from `r` */
+int reader_init_block_reader(struct reftable_reader *r, struct block_reader *br,
-+ uint64_t next_off, byte want_typ);
++ uint64_t next_off, uint8_t want_typ);
+
+#endif
@@ reftable/record.c (new)
+#include "record.h"
+
+#include "system.h"
-+
+#include "constants.h"
+#include "reftable.h"
++#include "basics.h"
+
-+int get_var_int(uint64_t *dest, struct slice *in)
++int get_var_int(uint64_t *dest, struct string_view *in)
+{
+ int ptr = 0;
+ uint64_t val;
@@ reftable/record.c (new)
+ return ptr + 1;
+}
+
-+int put_var_int(struct slice *dest, uint64_t val)
++int put_var_int(struct string_view *dest, uint64_t val)
+{
-+ byte buf[10] = { 0 };
++ uint8_t buf[10] = { 0 };
+ int i = 9;
+ int n = 0;
-+ buf[i] = (byte)(val & 0x7f);
++ buf[i] = (uint8_t)(val & 0x7f);
+ i--;
+ while (true) {
+ val >>= 7;
@@ reftable/record.c (new)
+ break;
+ }
+ val--;
-+ buf[i] = 0x80 | (byte)(val & 0x7f);
++ buf[i] = 0x80 | (uint8_t)(val & 0x7f);
+ i--;
+ }
+
@@ reftable/record.c (new)
+ return n;
+}
+
-+int reftable_is_block_type(byte typ)
++int reftable_is_block_type(uint8_t typ)
+{
+ switch (typ) {
+ case BLOCK_TYPE_REF:
@@ reftable/record.c (new)
+ return false;
+}
+
-+static int decode_string(struct slice *dest, struct slice in)
++static int decode_string(struct strbuf *dest, struct string_view in)
+{
+ int start_len = in.len;
+ uint64_t tsize = 0;
+ int n = get_var_int(&tsize, &in);
+ if (n <= 0)
+ return -1;
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+ if (in.len < tsize)
+ return -1;
+
-+ slice_reset(dest);
-+ slice_add(dest, in.buf, tsize);
-+ slice_consume(&in, tsize);
++ strbuf_reset(dest);
++ strbuf_add(dest, in.buf, tsize);
++ string_view_consume(&in, tsize);
+
+ return start_len - in.len;
+}
+
-+static int encode_string(char *str, struct slice s)
++static int encode_string(char *str, struct string_view s)
+{
-+ struct slice start = s;
++ struct string_view start = s;
+ int l = strlen(str);
+ int n = put_var_int(&s, l);
+ if (n < 0)
+ return -1;
-+ slice_consume(&s, n);
++ string_view_consume(&s, n);
+ if (s.len < l)
+ return -1;
+ memcpy(s.buf, str, l);
-+ slice_consume(&s, l);
++ string_view_consume(&s, l);
+
+ return start.len - s.len;
+}
+
-+int reftable_encode_key(bool *restart, struct slice dest, struct slice prev_key,
-+ struct slice key, byte extra)
++int reftable_encode_key(bool *restart, struct string_view dest,
++ struct strbuf prev_key, struct strbuf key,
++ uint8_t extra)
+{
-+ struct slice start = dest;
++ struct string_view start = dest;
+ int prefix_len = common_prefix_size(&prev_key, &key);
+ uint64_t suffix_len = key.len - prefix_len;
+ int n = put_var_int(&dest, (uint64_t)prefix_len);
+ if (n < 0)
+ return -1;
-+ slice_consume(&dest, n);
++ string_view_consume(&dest, n);
+
+ *restart = (prefix_len == 0);
+
+ n = put_var_int(&dest, suffix_len << 3 | (uint64_t)extra);
+ if (n < 0)
+ return -1;
-+ slice_consume(&dest, n);
++ string_view_consume(&dest, n);
+
+ if (dest.len < suffix_len)
+ return -1;
+ memcpy(dest.buf, key.buf + prefix_len, suffix_len);
-+ slice_consume(&dest, suffix_len);
++ string_view_consume(&dest, suffix_len);
+
+ return start.len - dest.len;
+}
+
-+int reftable_decode_key(struct slice *key, byte *extra, struct slice last_key,
-+ struct slice in)
++int reftable_decode_key(struct strbuf *key, uint8_t *extra,
++ struct strbuf last_key, struct string_view in)
+{
+ int start_len = in.len;
+ uint64_t prefix_len = 0;
@@ reftable/record.c (new)
+ int n = get_var_int(&prefix_len, &in);
+ if (n < 0)
+ return -1;
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+
+ if (prefix_len > last_key.len)
+ return -1;
@@ reftable/record.c (new)
+ n = get_var_int(&suffix_len, &in);
+ if (n <= 0)
+ return -1;
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+
-+ *extra = (byte)(suffix_len & 0x7);
++ *extra = (uint8_t)(suffix_len & 0x7);
+ suffix_len >>= 3;
+
+ if (in.len < suffix_len)
+ return -1;
+
-+ slice_reset(key);
-+ slice_add(key, last_key.buf, prefix_len);
-+ slice_add(key, in.buf, suffix_len);
-+ slice_consume(&in, suffix_len);
++ strbuf_reset(key);
++ strbuf_add(key, last_key.buf, prefix_len);
++ strbuf_add(key, in.buf, suffix_len);
++ string_view_consume(&in, suffix_len);
+
+ return start_len - in.len;
+}
+
-+static void reftable_ref_record_key(const void *r, struct slice *dest)
++static void reftable_ref_record_key(const void *r, struct strbuf *dest)
+{
+ const struct reftable_ref_record *rec =
+ (const struct reftable_ref_record *)r;
-+ slice_reset(dest);
-+ slice_addstr(dest, rec->ref_name);
++ strbuf_reset(dest);
++ strbuf_addstr(dest, rec->ref_name);
+}
+
+static void reftable_ref_record_copy_from(void *rec, const void *src_rec,
@@ reftable/record.c (new)
+ return 'a' + (c - 10);
+}
+
-+static void hex_format(char *dest, byte *src, int hash_size)
++static void hex_format(char *dest, uint8_t *src, int hash_size)
+{
+ assert(hash_size > 0);
+ if (src != NULL) {
@@ reftable/record.c (new)
+ memset(ref, 0, sizeof(struct reftable_ref_record));
+}
+
-+static byte reftable_ref_record_val_type(const void *rec)
++static uint8_t reftable_ref_record_val_type(const void *rec)
+{
+ const struct reftable_ref_record *r =
+ (const struct reftable_ref_record *)rec;
@@ reftable/record.c (new)
+ return 0;
+}
+
-+static int reftable_ref_record_encode(const void *rec, struct slice s,
++static int reftable_ref_record_encode(const void *rec, struct string_view s,
+ int hash_size)
+{
+ const struct reftable_ref_record *r =
+ (const struct reftable_ref_record *)rec;
-+ struct slice start = s;
++ struct string_view start = s;
+ int n = put_var_int(&s, r->update_index);
+ assert(hash_size > 0);
+ if (n < 0)
+ return -1;
-+ slice_consume(&s, n);
++ string_view_consume(&s, n);
+
+ if (r->value != NULL) {
+ if (s.len < hash_size) {
+ return -1;
+ }
+ memcpy(s.buf, r->value, hash_size);
-+ slice_consume(&s, hash_size);
++ string_view_consume(&s, hash_size);
+ }
+
+ if (r->target_value != NULL) {
@@ reftable/record.c (new)
+ return -1;
+ }
+ memcpy(s.buf, r->target_value, hash_size);
-+ slice_consume(&s, hash_size);
++ string_view_consume(&s, hash_size);
+ }
+
+ if (r->target != NULL) {
@@ reftable/record.c (new)
+ if (n < 0) {
+ return -1;
+ }
-+ slice_consume(&s, n);
++ string_view_consume(&s, n);
+ }
+
+ return start.len - s.len;
+}
+
-+static int reftable_ref_record_decode(void *rec, struct slice key,
-+ byte val_type, struct slice in,
++static int reftable_ref_record_decode(void *rec, struct strbuf key,
++ uint8_t val_type, struct string_view in,
+ int hash_size)
+{
+ struct reftable_ref_record *r = (struct reftable_ref_record *)rec;
-+ struct slice start = in;
++ struct string_view start = in;
+ bool seen_value = false;
+ bool seen_target_value = false;
+ bool seen_target = false;
@@ reftable/record.c (new)
+ return n;
+ assert(hash_size > 0);
+
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+
+ r->ref_name = reftable_realloc(r->ref_name, key.len + 1);
+ memcpy(r->ref_name, key.buf, key.len);
@@ reftable/record.c (new)
+ }
+ seen_value = true;
+ memcpy(r->value, in.buf, hash_size);
-+ slice_consume(&in, hash_size);
++ string_view_consume(&in, hash_size);
+ if (val_type == 1) {
+ break;
+ }
@@ reftable/record.c (new)
+ }
+ seen_target_value = true;
+ memcpy(r->target_value, in.buf, hash_size);
-+ slice_consume(&in, hash_size);
++ string_view_consume(&in, hash_size);
+ break;
+ case 3: {
-+ struct slice dest = SLICE_INIT;
++ struct strbuf dest = STRBUF_INIT;
+ int n = decode_string(&dest, in);
+ if (n < 0) {
+ return -1;
+ }
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+ seen_target = true;
+ if (r->target != NULL) {
+ reftable_free(r->target);
+ }
-+ r->target = (char *)slice_as_string(&dest);
++ r->target = dest.buf;
+ } break;
+
+ case 0:
@@ reftable/record.c (new)
+ .is_deletion = &reftable_ref_record_is_deletion_void,
+};
+
-+static void reftable_obj_record_key(const void *r, struct slice *dest)
++static void reftable_obj_record_key(const void *r, struct strbuf *dest)
+{
+ const struct reftable_obj_record *rec =
+ (const struct reftable_obj_record *)r;
-+ slice_reset(dest);
-+ slice_add(dest, rec->hash_prefix, rec->hash_prefix_len);
++ strbuf_reset(dest);
++ strbuf_add(dest, rec->hash_prefix, rec->hash_prefix_len);
+}
+
+static void reftable_obj_record_clear(void *rec)
@@ reftable/record.c (new)
+ memcpy(obj->offsets, src->offsets, olen);
+}
+
-+static byte reftable_obj_record_val_type(const void *rec)
++static uint8_t reftable_obj_record_val_type(const void *rec)
+{
+ struct reftable_obj_record *r = (struct reftable_obj_record *)rec;
+ if (r->offset_len > 0 && r->offset_len < 8)
@@ reftable/record.c (new)
+ return 0;
+}
+
-+static int reftable_obj_record_encode(const void *rec, struct slice s,
++static int reftable_obj_record_encode(const void *rec, struct string_view s,
+ int hash_size)
+{
+ struct reftable_obj_record *r = (struct reftable_obj_record *)rec;
-+ struct slice start = s;
++ struct string_view start = s;
+ int i = 0;
+ int n = 0;
+ uint64_t last = 0;
@@ reftable/record.c (new)
+ if (n < 0) {
+ return -1;
+ }
-+ slice_consume(&s, n);
++ string_view_consume(&s, n);
+ }
+ if (r->offset_len == 0)
+ return start.len - s.len;
+ n = put_var_int(&s, r->offsets[0]);
+ if (n < 0)
+ return -1;
-+ slice_consume(&s, n);
++ string_view_consume(&s, n);
+
+ last = r->offsets[0];
+ for (i = 1; i < r->offset_len; i++) {
@@ reftable/record.c (new)
+ if (n < 0) {
+ return -1;
+ }
-+ slice_consume(&s, n);
++ string_view_consume(&s, n);
+ last = r->offsets[i];
+ }
+ return start.len - s.len;
+}
+
-+static int reftable_obj_record_decode(void *rec, struct slice key,
-+ byte val_type, struct slice in,
++static int reftable_obj_record_decode(void *rec, struct strbuf key,
++ uint8_t val_type, struct string_view in,
+ int hash_size)
+{
-+ struct slice start = in;
++ struct string_view start = in;
+ struct reftable_obj_record *r = (struct reftable_obj_record *)rec;
+ uint64_t count = val_type;
+ int n = 0;
@@ reftable/record.c (new)
+ return n;
+ }
+
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+ }
+
+ r->offsets = NULL;
@@ reftable/record.c (new)
+ n = get_var_int(&r->offsets[0], &in);
+ if (n < 0)
+ return n;
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+
+ last = r->offsets[0];
+ j = 1;
@@ reftable/record.c (new)
+ if (n < 0) {
+ return n;
+ }
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+
+ last = r->offsets[j] = (delta + last);
+ j++;
@@ reftable/record.c (new)
+ printf("%s\n\n%s\n}\n", hex, log->message);
+}
+
-+static void reftable_log_record_key(const void *r, struct slice *dest)
++static void reftable_log_record_key(const void *r, struct strbuf *dest)
+{
+ const struct reftable_log_record *rec =
+ (const struct reftable_log_record *)r;
+ int len = strlen(rec->ref_name);
-+ byte i64[8];
++ uint8_t i64[8];
+ uint64_t ts = 0;
-+ slice_reset(dest);
-+ slice_add(dest, (byte *)rec->ref_name, len + 1);
++ strbuf_reset(dest);
++ strbuf_add(dest, (uint8_t *)rec->ref_name, len + 1);
+
+ ts = (~ts) - rec->update_index;
+ put_be64(&i64[0], ts);
-+ slice_add(dest, i64, sizeof(i64));
++ strbuf_add(dest, i64, sizeof(i64));
+}
+
+static void reftable_log_record_copy_from(void *rec, const void *src_rec,
@@ reftable/record.c (new)
+ memset(r, 0, sizeof(struct reftable_log_record));
+}
+
-+static byte reftable_log_record_val_type(const void *rec)
++static uint8_t reftable_log_record_val_type(const void *rec)
+{
+ const struct reftable_log_record *log =
+ (const struct reftable_log_record *)rec;
@@ reftable/record.c (new)
+ return reftable_log_record_is_deletion(log) ? 0 : 1;
+}
+
-+static byte zero[SHA256_SIZE] = { 0 };
++static uint8_t zero[SHA256_SIZE] = { 0 };
+
-+static int reftable_log_record_encode(const void *rec, struct slice s,
++static int reftable_log_record_encode(const void *rec, struct string_view s,
+ int hash_size)
+{
+ struct reftable_log_record *r = (struct reftable_log_record *)rec;
-+ struct slice start = s;
++ struct string_view start = s;
+ int n = 0;
-+ byte *oldh = r->old_hash;
-+ byte *newh = r->new_hash;
++ uint8_t *oldh = r->old_hash;
++ uint8_t *newh = r->new_hash;
+ if (reftable_log_record_is_deletion(r))
+ return 0;
+
@@ reftable/record.c (new)
+
+ memcpy(s.buf, oldh, hash_size);
+ memcpy(s.buf + hash_size, newh, hash_size);
-+ slice_consume(&s, 2 * hash_size);
++ string_view_consume(&s, 2 * hash_size);
+
+ n = encode_string(r->name ? r->name : "", s);
+ if (n < 0)
+ return -1;
-+ slice_consume(&s, n);
++ string_view_consume(&s, n);
+
+ n = encode_string(r->email ? r->email : "", s);
+ if (n < 0)
+ return -1;
-+ slice_consume(&s, n);
++ string_view_consume(&s, n);
+
+ n = put_var_int(&s, r->time);
+ if (n < 0)
+ return -1;
-+ slice_consume(&s, n);
++ string_view_consume(&s, n);
+
+ if (s.len < 2)
+ return -1;
+
+ put_be16(s.buf, r->tz_offset);
-+ slice_consume(&s, 2);
++ string_view_consume(&s, 2);
+
+ n = encode_string(r->message ? r->message : "", s);
+ if (n < 0)
+ return -1;
-+ slice_consume(&s, n);
++ string_view_consume(&s, n);
+
+ return start.len - s.len;
+}
+
-+static int reftable_log_record_decode(void *rec, struct slice key,
-+ byte val_type, struct slice in,
++static int reftable_log_record_decode(void *rec, struct strbuf key,
++ uint8_t val_type, struct string_view in,
+ int hash_size)
+{
-+ struct slice start = in;
++ struct string_view start = in;
+ struct reftable_log_record *r = (struct reftable_log_record *)rec;
+ uint64_t max = 0;
+ uint64_t ts = 0;
-+ struct slice dest = SLICE_INIT;
++ struct strbuf dest = STRBUF_INIT;
+ int n;
+
+ if (key.len <= 9 || key.buf[key.len - 9] != 0)
@@ reftable/record.c (new)
+ memcpy(r->old_hash, in.buf, hash_size);
+ memcpy(r->new_hash, in.buf + hash_size, hash_size);
+
-+ slice_consume(&in, 2 * hash_size);
++ string_view_consume(&in, 2 * hash_size);
+
+ n = decode_string(&dest, in);
+ if (n < 0)
+ goto done;
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+
+ r->name = reftable_realloc(r->name, dest.len + 1);
+ memcpy(r->name, dest.buf, dest.len);
+ r->name[dest.len] = 0;
+
-+ slice_reset(&dest);
++ strbuf_reset(&dest);
+ n = decode_string(&dest, in);
+ if (n < 0)
+ goto done;
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+
+ r->email = reftable_realloc(r->email, dest.len + 1);
+ memcpy(r->email, dest.buf, dest.len);
@@ reftable/record.c (new)
+ n = get_var_int(&ts, &in);
+ if (n < 0)
+ goto done;
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+ r->time = ts;
+ if (in.len < 2)
+ goto done;
+
+ r->tz_offset = get_be16(in.buf);
-+ slice_consume(&in, 2);
++ string_view_consume(&in, 2);
+
-+ slice_reset(&dest);
++ strbuf_reset(&dest);
+ n = decode_string(&dest, in);
+ if (n < 0)
+ goto done;
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+
+ r->message = reftable_realloc(r->message, dest.len + 1);
+ memcpy(r->message, dest.buf, dest.len);
+ r->message[dest.len] = 0;
+
-+ slice_release(&dest);
++ strbuf_release(&dest);
+ return start.len - in.len;
+
+done:
-+ slice_release(&dest);
++ strbuf_release(&dest);
+ return REFTABLE_FORMAT_ERROR;
+}
+
@@ reftable/record.c (new)
+ return 0 == strcmp(a, b);
+}
+
-+static bool zero_hash_eq(byte *a, byte *b, int sz)
++static bool zero_hash_eq(uint8_t *a, uint8_t *b, int sz)
+{
+ if (a == NULL)
+ a = zero;
@@ reftable/record.c (new)
+ .is_deletion = &reftable_log_record_is_deletion_void,
+};
+
-+struct reftable_record reftable_new_record(byte typ)
++struct reftable_record reftable_new_record(uint8_t typ)
+{
+ struct reftable_record rec = { NULL };
+ switch (typ) {
@@ reftable/record.c (new)
+ return rec;
+ }
+ case BLOCK_TYPE_INDEX: {
-+ struct reftable_index_record empty = { .last_key = SLICE_INIT };
++ struct reftable_index_record empty = { .last_key =
++ STRBUF_INIT };
+ struct reftable_index_record *r =
+ reftable_calloc(sizeof(struct reftable_index_record));
+ *r = empty;
@@ reftable/record.c (new)
+ reftable_free(reftable_record_yield(rec));
+}
+
-+static void reftable_index_record_key(const void *r, struct slice *dest)
++static void reftable_index_record_key(const void *r, struct strbuf *dest)
+{
+ struct reftable_index_record *rec = (struct reftable_index_record *)r;
-+ slice_reset(dest);
-+ slice_addbuf(dest, &rec->last_key);
++ strbuf_reset(dest);
++ strbuf_addbuf(dest, &rec->last_key);
+}
+
+static void reftable_index_record_copy_from(void *rec, const void *src_rec,
@@ reftable/record.c (new)
+ struct reftable_index_record *src =
+ (struct reftable_index_record *)src_rec;
+
-+ slice_reset(&dst->last_key);
-+ slice_addbuf(&dst->last_key, &src->last_key);
++ strbuf_reset(&dst->last_key);
++ strbuf_addbuf(&dst->last_key, &src->last_key);
+ dst->offset = src->offset;
+}
+
+static void reftable_index_record_clear(void *rec)
+{
+ struct reftable_index_record *idx = (struct reftable_index_record *)rec;
-+ slice_release(&idx->last_key);
++ strbuf_release(&idx->last_key);
+}
+
-+static byte reftable_index_record_val_type(const void *rec)
++static uint8_t reftable_index_record_val_type(const void *rec)
+{
+ return 0;
+}
+
-+static int reftable_index_record_encode(const void *rec, struct slice out,
++static int reftable_index_record_encode(const void *rec, struct string_view out,
+ int hash_size)
+{
+ const struct reftable_index_record *r =
+ (const struct reftable_index_record *)rec;
-+ struct slice start = out;
++ struct string_view start = out;
+
+ int n = put_var_int(&out, r->offset);
+ if (n < 0)
+ return n;
+
-+ slice_consume(&out, n);
++ string_view_consume(&out, n);
+
+ return start.len - out.len;
+}
+
-+static int reftable_index_record_decode(void *rec, struct slice key,
-+ byte val_type, struct slice in,
++static int reftable_index_record_decode(void *rec, struct strbuf key,
++ uint8_t val_type, struct string_view in,
+ int hash_size)
+{
-+ struct slice start = in;
++ struct string_view start = in;
+ struct reftable_index_record *r = (struct reftable_index_record *)rec;
+ int n = 0;
+
-+ slice_reset(&r->last_key);
-+ slice_addbuf(&r->last_key, &key);
++ strbuf_reset(&r->last_key);
++ strbuf_addbuf(&r->last_key, &key);
+
+ n = get_var_int(&r->offset, &in);
+ if (n < 0)
+ return n;
+
-+ slice_consume(&in, n);
++ string_view_consume(&in, n);
+ return start.len - in.len;
+}
+
@@ reftable/record.c (new)
+ .is_deletion = ¬_a_deletion,
+};
+
-+void reftable_record_key(struct reftable_record *rec, struct slice *dest)
++void reftable_record_key(struct reftable_record *rec, struct strbuf *dest)
+{
+ rec->ops->key(rec->data, dest);
+}
+
-+byte reftable_record_type(struct reftable_record *rec)
++uint8_t reftable_record_type(struct reftable_record *rec)
+{
+ return rec->ops->type;
+}
+
-+int reftable_record_encode(struct reftable_record *rec, struct slice dest,
++int reftable_record_encode(struct reftable_record *rec, struct string_view dest,
+ int hash_size)
+{
+ return rec->ops->encode(rec->data, dest, hash_size);
@@ reftable/record.c (new)
+ rec->ops->copy_from(rec->data, src->data, hash_size);
+}
+
-+byte reftable_record_val_type(struct reftable_record *rec)
++uint8_t reftable_record_val_type(struct reftable_record *rec)
+{
+ return rec->ops->val_type(rec->data);
+}
+
-+int reftable_record_decode(struct reftable_record *rec, struct slice key,
-+ byte extra, struct slice src, int hash_size)
++int reftable_record_decode(struct reftable_record *rec, struct strbuf key,
++ uint8_t extra, struct string_view src, int hash_size)
+{
+ return rec->ops->decode(rec->data, key, extra, src, hash_size);
+}
@@ reftable/record.c (new)
+ return (struct reftable_log_record *)rec->data;
+}
+
-+static bool hash_equal(byte *a, byte *b, int hash_size)
++static bool hash_equal(uint8_t *a, uint8_t *b, int hash_size)
+{
+ if (a != NULL && b != NULL)
+ return !memcmp(a, b, hash_size);
@@ reftable/record.c (new)
+ return SHA256_SIZE;
+ }
+ abort();
++}
++
++void string_view_consume(struct string_view *s, int n)
++{
++ s->buf += n;
++ s->len -= n;
+}
## reftable/record.h (new) ##
@@ reftable/record.h (new)
+#define RECORD_H
+
+#include "reftable.h"
-+#include "slice.h"
++#include "strbuf.h"
++#include "system.h"
++
++/*
++ A substring of existing string data. This structure takes no responsibility
++ for the lifetime of the data it points to.
++*/
++struct string_view {
++ uint8_t *buf;
++ int len;
++};
++
++/* Advance `s.buf` by `n`, and decrease length. */
++void string_view_consume(struct string_view *s, int n);
+
+/* utilities for de/encoding varints */
+
-+int get_var_int(uint64_t *dest, struct slice *in);
-+int put_var_int(struct slice *dest, uint64_t val);
++int get_var_int(uint64_t *dest, struct string_view *in);
++int put_var_int(struct string_view *dest, uint64_t val);
+
+/* Methods for records. */
+struct reftable_record_vtable {
-+ /* encode the key of to a byte slice. */
-+ void (*key)(const void *rec, struct slice *dest);
++ /* encode the key of to a uint8_t strbuf. */
++ void (*key)(const void *rec, struct strbuf *dest);
+
+ /* The record type of ('r' for ref). */
-+ byte type;
++ uint8_t type;
+
+ void (*copy_from)(void *dest, const void *src, int hash_size);
+
+ /* a value of [0..7], indicating record subvariants (eg. ref vs. symref
+ * vs ref deletion) */
-+ byte (*val_type)(const void *rec);
++ uint8_t (*val_type)(const void *rec);
+
+ /* encodes rec into dest, returning how much space was used. */
-+ int (*encode)(const void *rec, struct slice dest, int hash_size);
++ int (*encode)(const void *rec, struct string_view dest, int hash_size);
+
+ /* decode data from `src` into the record. */
-+ int (*decode)(void *rec, struct slice key, byte extra, struct slice src,
-+ int hash_size);
++ int (*decode)(void *rec, struct strbuf key, uint8_t extra,
++ struct string_view src, int hash_size);
+
+ /* deallocate and null the record. */
+ void (*clear)(void *rec);
@@ reftable/record.h (new)
+};
+
+/* returns true for recognized block types. Block start with the block type. */
-+int reftable_is_block_type(byte typ);
++int reftable_is_block_type(uint8_t typ);
+
+/* creates a malloced record of the given type. Dispose with record_destroy */
-+struct reftable_record reftable_new_record(byte typ);
++struct reftable_record reftable_new_record(uint8_t typ);
+
+extern struct reftable_record_vtable reftable_ref_record_vtable;
+
+/* Encode `key` into `dest`. Sets `restart` to indicate a restart. Returns
+ number of bytes written. */
-+int reftable_encode_key(bool *restart, struct slice dest, struct slice prev_key,
-+ struct slice key, byte extra);
++int reftable_encode_key(bool *restart, struct string_view dest,
++ struct strbuf prev_key, struct strbuf key,
++ uint8_t extra);
+
+/* Decode into `key` and `extra` from `in` */
-+int reftable_decode_key(struct slice *key, byte *extra, struct slice last_key,
-+ struct slice in);
++int reftable_decode_key(struct strbuf *key, uint8_t *extra,
++ struct strbuf last_key, struct string_view in);
+
+/* reftable_index_record are used internally to speed up lookups. */
+struct reftable_index_record {
+ uint64_t offset; /* Offset of block */
-+ struct slice last_key; /* Last key of the block. */
++ struct strbuf last_key; /* Last key of the block. */
+};
+
+/* reftable_obj_record stores an object ID => ref mapping. */
+struct reftable_obj_record {
-+ byte *hash_prefix; /* leading bytes of the object ID */
++ uint8_t *hash_prefix; /* leading bytes of the object ID */
+ int hash_prefix_len; /* number of leading bytes. Constant
+ * across a single table. */
+ uint64_t *offsets; /* a vector of file offsets. */
@@ reftable/record.h (new)
+
+/* see struct record_vtable */
+
-+void reftable_record_key(struct reftable_record *rec, struct slice *dest);
-+byte reftable_record_type(struct reftable_record *rec);
++void reftable_record_key(struct reftable_record *rec, struct strbuf *dest);
++uint8_t reftable_record_type(struct reftable_record *rec);
+void reftable_record_copy_from(struct reftable_record *rec,
+ struct reftable_record *src, int hash_size);
-+byte reftable_record_val_type(struct reftable_record *rec);
-+int reftable_record_encode(struct reftable_record *rec, struct slice dest,
++uint8_t reftable_record_val_type(struct reftable_record *rec);
++int reftable_record_encode(struct reftable_record *rec, struct string_view dest,
++ int hash_size);
++int reftable_record_decode(struct reftable_record *rec, struct strbuf key,
++ uint8_t extra, struct string_view src,
+ int hash_size);
-+int reftable_record_decode(struct reftable_record *rec, struct slice key,
-+ byte extra, struct slice src, int hash_size);
+bool reftable_record_is_deletion(struct reftable_record *rec);
+
+/* zeroes out the embedded record */
@@ reftable/record_test.c (new)
+ ((uint64_t)1 << 63) + ((uint64_t)1 << 63) - 1 };
+ int i = 0;
+ for (i = 0; i < ARRAY_SIZE(inputs); i++) {
-+ byte dest[10];
-+
-+ struct slice out = { .buf = dest, .len = 10, .cap = 10 };
++ uint8_t dest[10];
+
++ struct string_view out = {
++ .buf = dest,
++ .len = sizeof(dest),
++ };
+ uint64_t in = inputs[i];
+ int n = put_var_int(&out, in);
+ uint64_t got = 0;
@@ reftable/record_test.c (new)
+
+ int i = 0;
+ for (i = 0; i < ARRAY_SIZE(cases); i++) {
-+ struct slice a = SLICE_INIT;
-+ struct slice b = SLICE_INIT;
-+ slice_addstr(&a, cases[i].a);
-+ slice_addstr(&b, cases[i].b);
++ struct strbuf a = STRBUF_INIT;
++ struct strbuf b = STRBUF_INIT;
++ strbuf_addstr(&a, cases[i].a);
++ strbuf_addstr(&b, cases[i].b);
+ assert(common_prefix_size(&a, &b) == cases[i].want);
+
-+ slice_release(&a);
-+ slice_release(&b);
++ strbuf_release(&a);
++ strbuf_release(&b);
+ }
+}
+
-+static void set_hash(byte *h, int j)
++static void set_hash(uint8_t *h, int j)
+{
+ int i = 0;
+ for (i = 0; i < hash_size(SHA1_ID); i++) {
@@ reftable/record_test.c (new)
+ .target = xstrdup("old value"),
+ };
+ struct reftable_record rec_out = { 0 };
-+ struct slice key = SLICE_INIT;
++ struct strbuf key = STRBUF_INIT;
+ struct reftable_record rec = { 0 };
-+ struct slice dest = SLICE_INIT;
++ uint8_t buffer[1024] = { 0 };
++ struct string_view dest = {
++ .buf = buffer,
++ .len = sizeof(buffer),
++ };
++
+ int n, m;
+
+ switch (i) {
@@ reftable/record_test.c (new)
+ assert(reftable_record_val_type(&rec) == i);
+
+ reftable_record_key(&rec, &key);
-+ slice_grow(&dest, 1024);
-+ slice_setlen(&dest, 1024);
+ n = reftable_record_encode(&rec, dest, SHA1_SIZE);
+ assert(n > 0);
+
@@ reftable/record_test.c (new)
+ assert((out.target != NULL) == (in.target != NULL));
+ reftable_record_clear(&rec_out);
+
-+ slice_release(&key);
-+ slice_release(&dest);
++ strbuf_release(&key);
+ reftable_ref_record_clear(&in);
+ }
+}
@@ reftable/record_test.c (new)
+ set_test_hash(in[0].old_hash, 2);
+ for (int i = 0; i < ARRAY_SIZE(in); i++) {
+ struct reftable_record rec = { 0 };
-+ struct slice key = SLICE_INIT;
-+ struct slice dest = SLICE_INIT;
++ struct strbuf key = STRBUF_INIT;
++ uint8_t buffer[1024] = { 0 };
++ struct string_view dest = {
++ .buf = buffer,
++ .len = sizeof(buffer),
++ };
+ /* populate out, to check for leaks. */
+ struct reftable_log_record out = {
+ .ref_name = xstrdup("old name"),
@@ reftable/record_test.c (new)
+
+ reftable_record_key(&rec, &key);
+
-+ slice_grow(&dest, 1024);
-+ slice_setlen(&dest, 1024);
-+
+ n = reftable_record_encode(&rec, dest, SHA1_SIZE);
+ assert(n >= 0);
+ reftable_record_from_log(&rec_out, &out);
@@ reftable/record_test.c (new)
+
+ assert(reftable_log_record_equal(&in[i], &out, SHA1_SIZE));
+ reftable_log_record_clear(&in[i]);
-+ slice_release(&key);
-+ slice_release(&dest);
++ strbuf_release(&key);
+ reftable_record_clear(&rec_out);
+ }
+}
@@ reftable/record_test.c (new)
+static void test_u24_roundtrip(void)
+{
+ uint32_t in = 0x112233;
-+ byte dest[3];
++ uint8_t dest[3];
+ uint32_t out;
+ put_be24(dest, in);
+ out = get_be24(dest);
@@ reftable/record_test.c (new)
+
+static void test_key_roundtrip(void)
+{
-+ struct slice dest = SLICE_INIT;
-+ struct slice last_key = SLICE_INIT;
-+ struct slice key = SLICE_INIT;
-+ struct slice roundtrip = SLICE_INIT;
++ uint8_t buffer[1024] = { 0 };
++ struct string_view dest = {
++ .buf = buffer,
++ .len = sizeof(buffer),
++ };
++ struct strbuf last_key = STRBUF_INIT;
++ struct strbuf key = STRBUF_INIT;
++ struct strbuf roundtrip = STRBUF_INIT;
+ bool restart;
-+ byte extra;
++ uint8_t extra;
+ int n, m;
-+ byte rt_extra;
++ uint8_t rt_extra;
+
-+ slice_grow(&dest, 1024);
-+ slice_setlen(&dest, 1024);
-+ slice_addstr(&last_key, "refs/heads/master");
-+ slice_addstr(&key, "refs/tags/bla");
++ strbuf_addstr(&last_key, "refs/heads/master");
++ strbuf_addstr(&key, "refs/tags/bla");
+ extra = 6;
+ n = reftable_encode_key(&restart, dest, last_key, key, extra);
+ assert(!restart);
@@ reftable/record_test.c (new)
+
+ m = reftable_decode_key(&roundtrip, &rt_extra, last_key, dest);
+ assert(n == m);
-+ assert(0 == slice_cmp(&key, &roundtrip));
++ assert(0 == strbuf_cmp(&key, &roundtrip));
+ assert(rt_extra == extra);
+
-+ slice_release(&last_key);
-+ slice_release(&key);
-+ slice_release(&dest);
-+ slice_release(&roundtrip);
++ strbuf_release(&last_key);
++ strbuf_release(&key);
++ strbuf_release(&roundtrip);
+}
+
+static void test_reftable_obj_record_roundtrip(void)
+{
-+ byte testHash1[SHA1_SIZE] = { 1, 2, 3, 4, 0 };
++ uint8_t testHash1[SHA1_SIZE] = { 1, 2, 3, 4, 0 };
+ uint64_t till9[] = { 1, 2, 3, 4, 500, 600, 700, 800, 9000 };
+ struct reftable_obj_record recs[3] = { {
+ .hash_prefix = testHash1,
@@ reftable/record_test.c (new)
+ int i = 0;
+ for (i = 0; i < ARRAY_SIZE(recs); i++) {
+ struct reftable_obj_record in = recs[i];
-+ struct slice dest = SLICE_INIT;
++ uint8_t buffer[1024] = { 0 };
++ struct string_view dest = {
++ .buf = buffer,
++ .len = sizeof(buffer),
++ };
+ struct reftable_record rec = { 0 };
-+ struct slice key = SLICE_INIT;
++ struct strbuf key = STRBUF_INIT;
+ struct reftable_obj_record out = { 0 };
+ struct reftable_record rec_out = { 0 };
+ int n, m;
-+ byte extra;
++ uint8_t extra;
+
+ reftable_record_from_obj(&rec, &in);
+ test_copy(&rec);
+ reftable_record_key(&rec, &key);
-+ slice_grow(&dest, 1024);
-+ slice_setlen(&dest, 1024);
+ n = reftable_record_encode(&rec, dest, SHA1_SIZE);
+ assert(n > 0);
+ extra = reftable_record_val_type(&rec);
@@ reftable/record_test.c (new)
+ in.hash_prefix_len));
+ assert(0 == memcmp(in.offsets, out.offsets,
+ sizeof(uint64_t) * in.offset_len));
-+ slice_release(&key);
-+ slice_release(&dest);
++ strbuf_release(&key);
+ reftable_record_clear(&rec_out);
+ }
+}
@@ reftable/record_test.c (new)
+{
+ struct reftable_index_record in = {
+ .offset = 42,
-+ .last_key = SLICE_INIT,
++ .last_key = STRBUF_INIT,
++ };
++ uint8_t buffer[1024] = { 0 };
++ struct string_view dest = {
++ .buf = buffer,
++ .len = sizeof(buffer),
+ };
-+ struct slice dest = SLICE_INIT;
-+ struct slice key = SLICE_INIT;
++ struct strbuf key = STRBUF_INIT;
+ struct reftable_record rec = { 0 };
-+ struct reftable_index_record out = { .last_key = SLICE_INIT };
++ struct reftable_index_record out = { .last_key = STRBUF_INIT };
+ struct reftable_record out_rec = { NULL };
+ int n, m;
-+ byte extra;
++ uint8_t extra;
+
-+ slice_addstr(&in.last_key, "refs/heads/master");
++ strbuf_addstr(&in.last_key, "refs/heads/master");
+ reftable_record_from_index(&rec, &in);
+ reftable_record_key(&rec, &key);
+ test_copy(&rec);
+
-+ assert(0 == slice_cmp(&key, &in.last_key));
-+ slice_grow(&dest, 1024);
-+ slice_setlen(&dest, 1024);
++ assert(0 == strbuf_cmp(&key, &in.last_key));
+ n = reftable_record_encode(&rec, dest, SHA1_SIZE);
+ assert(n > 0);
+
@@ reftable/record_test.c (new)
+ assert(in.offset == out.offset);
+
+ reftable_record_clear(&out_rec);
-+ slice_release(&key);
-+ slice_release(&in.last_key);
-+ slice_release(&dest);
++ strbuf_release(&key);
++ strbuf_release(&in.last_key);
+}
+
+int record_test_main(int argc, const char *argv[])
@@ reftable/refname.c (new)
+#include "reftable.h"
+#include "basics.h"
+#include "refname.h"
-+#include "slice.h"
++#include "strbuf.h"
+
+struct find_arg {
+ char **names;
@@ reftable/refname.c (new)
+ return err;
+}
+
-+static void slice_trim_component(struct slice *sl)
++static void strbuf_trim_component(struct strbuf *sl)
+{
+ while (sl->len > 0) {
+ bool is_slash = (sl->buf[sl->len - 1] == '/');
-+ slice_setlen(sl, sl->len - 1);
++ strbuf_setlen(sl, sl->len - 1);
+ if (is_slash)
+ break;
+ }
@@ reftable/refname.c (new)
+
+int modification_validate(struct modification *mod)
+{
-+ struct slice slashed = SLICE_INIT;
++ struct strbuf slashed = STRBUF_INIT;
+ int err = 0;
+ int i = 0;
+ for (; i < mod->add_len; i++) {
+ err = validate_ref_name(mod->add[i]);
+ if (err)
+ goto done;
-+ slice_reset(&slashed);
-+ slice_addstr(&slashed, mod->add[i]);
-+ slice_addstr(&slashed, "/");
++ strbuf_reset(&slashed);
++ strbuf_addstr(&slashed, mod->add[i]);
++ strbuf_addstr(&slashed, "/");
+
-+ err = modification_has_ref_with_prefix(
-+ mod, slice_as_string(&slashed));
++ err = modification_has_ref_with_prefix(mod, slashed.buf);
+ if (err == 0) {
+ err = REFTABLE_NAME_CONFLICT;
+ goto done;
@@ reftable/refname.c (new)
+ if (err < 0)
+ goto done;
+
-+ slice_reset(&slashed);
-+ slice_addstr(&slashed, mod->add[i]);
++ strbuf_reset(&slashed);
++ strbuf_addstr(&slashed, mod->add[i]);
+ while (slashed.len) {
-+ slice_trim_component(&slashed);
-+ err = modification_has_ref(mod,
-+ slice_as_string(&slashed));
++ strbuf_trim_component(&slashed);
++ err = modification_has_ref(mod, slashed.buf);
+ if (err == 0) {
+ err = REFTABLE_NAME_CONFLICT;
+ goto done;
@@ reftable/refname.c (new)
+ }
+ err = 0;
+done:
-+ slice_release(&slashed);
++ strbuf_release(&slashed);
+ return err;
+}
@@ reftable/refname_test.c (new)
+static void test_conflict(void)
+{
+ struct reftable_write_options opts = { 0 };
-+ struct slice buf = SLICE_INIT;
++ struct strbuf buf = STRBUF_INIT;
+ struct reftable_writer *w =
-+ reftable_new_writer(&slice_add_void, &buf, &opts);
++ reftable_new_writer(&strbuf_add_void, &buf, &opts);
+ struct reftable_ref_record rec = {
+ .ref_name = "a/b",
+ .target = "destination", /* make sure it's not a symref. */
@@ reftable/refname_test.c (new)
+ assert_err(err);
+ reftable_writer_free(w);
+
-+ block_source_from_slice(&source, &buf);
++ block_source_from_strbuf(&source, &buf);
+ err = reftable_new_reader(&rd, &source, "filename");
+ assert_err(err);
+
@@ reftable/refname_test.c (new)
+ }
+
+ reftable_reader_free(rd);
-+ slice_release(&buf);
++ strbuf_release(&buf);
+}
+
+int refname_test_main(int argc, const char *argv[])
@@ reftable/reftable-tests.h (new)
+int record_test_main(int argc, const char **argv);
+int refname_test_main(int argc, const char **argv);
+int reftable_test_main(int argc, const char **argv);
-+int slice_test_main(int argc, const char **argv);
++int strbuf_test_main(int argc, const char **argv);
+int stack_test_main(int argc, const char **argv);
+int tree_test_main(int argc, const char **argv);
+int reftable_dump_main(int argc, char *const *argv);
@@ reftable/reftable.h (new)
+
+/* reftable_new_writer creates a new writer */
+struct reftable_writer *
-+reftable_new_writer(int (*writer_func)(void *, uint8_t *, size_t),
++reftable_new_writer(int (*writer_func)(void *, const void *, size_t),
+ void *writer_arg, struct reftable_write_options *opts);
+
+/* write to a file descriptor. fdp should be an int* pointing to the fd. */
-+int reftable_fd_write(void *fdp, uint8_t *data, size_t size);
++int reftable_fd_write(void *fdp, const void *data, size_t size);
+
+/* 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/reftable_test.c (new)
+
+static void test_buffer(void)
+{
-+ struct slice buf = SLICE_INIT;
++ struct strbuf buf = STRBUF_INIT;
+ struct reftable_block_source source = { NULL };
+ struct reftable_block out = { 0 };
+ int n;
-+ byte in[] = "hello";
-+ slice_add(&buf, in, sizeof(in));
-+ block_source_from_slice(&source, &buf);
++ uint8_t in[] = "hello";
++ strbuf_add(&buf, in, sizeof(in));
++ block_source_from_strbuf(&source, &buf);
+ assert(block_source_size(&source) == 6);
+ n = block_source_read_block(&source, &out, 0, sizeof(in));
+ assert(n == sizeof(in));
@@ reftable/reftable_test.c (new)
+
+ reftable_block_done(&out);
+ block_source_close(&source);
-+ slice_release(&buf);
++ strbuf_release(&buf);
+}
+
+static void test_default_write_opts(void)
+{
+ struct reftable_write_options opts = { 0 };
-+ struct slice buf = SLICE_INIT;
++ struct strbuf buf = STRBUF_INIT;
+ struct reftable_writer *w =
-+ reftable_new_writer(&slice_add_void, &buf, &opts);
++ reftable_new_writer(&strbuf_add_void, &buf, &opts);
+
+ struct reftable_ref_record rec = {
+ .ref_name = "master",
@@ reftable/reftable_test.c (new)
+ assert_err(err);
+ reftable_writer_free(w);
+
-+ block_source_from_slice(&source, &buf);
++ block_source_from_strbuf(&source, &buf);
+
+ err = reftable_new_reader(&rd, &source, "filename");
+ assert_err(err);
@@ reftable/reftable_test.c (new)
+
+ reftable_merged_table_close(merged);
+ reftable_merged_table_free(merged);
-+ slice_release(&buf);
++ strbuf_release(&buf);
+}
+
-+static void write_table(char ***names, struct slice *buf, int N, int block_size,
-+ uint32_t hash_id)
++static void write_table(char ***names, struct strbuf *buf, int N,
++ int block_size, uint32_t hash_id)
+{
+ struct reftable_write_options opts = {
+ .block_size = block_size,
+ .hash_id = hash_id,
+ };
+ struct reftable_writer *w =
-+ reftable_new_writer(&slice_add_void, buf, &opts);
++ reftable_new_writer(&strbuf_add_void, buf, &opts);
+ struct reftable_ref_record ref = { 0 };
+ int i = 0, n;
+ struct reftable_log_record log = { 0 };
@@ reftable/reftable_test.c (new)
+ *names = reftable_calloc(sizeof(char *) * (N + 1));
+ reftable_writer_set_limits(w, update_index, update_index);
+ for (i = 0; i < N; i++) {
-+ byte hash[SHA256_SIZE] = { 0 };
++ uint8_t hash[SHA256_SIZE] = { 0 };
+ char name[100];
+ int n;
+
@@ reftable/reftable_test.c (new)
+ }
+
+ for (i = 0; i < N; i++) {
-+ byte hash[SHA256_SIZE] = { 0 };
++ uint8_t hash[SHA256_SIZE] = { 0 };
+ char name[100];
+ int n;
+
@@ reftable/reftable_test.c (new)
+
+static void test_log_buffer_size(void)
+{
-+ struct slice buf = SLICE_INIT;
++ struct strbuf buf = STRBUF_INIT;
+ struct reftable_write_options opts = {
+ .block_size = 4096,
+ };
@@ reftable/reftable_test.c (new)
+ .message = "commit: 9\n",
+ };
+ struct reftable_writer *w =
-+ reftable_new_writer(&slice_add_void, &buf, &opts);
++ reftable_new_writer(&strbuf_add_void, &buf, &opts);
+
+ /* This tests buffer extension for log compression. Must use a random
+ hash, to ensure that the compressed part is larger than the original.
+ */
-+ byte hash1[SHA1_SIZE], hash2[SHA1_SIZE];
++ uint8_t hash1[SHA1_SIZE], hash2[SHA1_SIZE];
+ for (int i = 0; i < SHA1_SIZE; i++) {
-+ hash1[i] = (byte)(rand() % 256);
-+ hash2[i] = (byte)(rand() % 256);
++ hash1[i] = (uint8_t)(rand() % 256);
++ hash2[i] = (uint8_t)(rand() % 256);
+ }
+ log.old_hash = hash1;
+ log.new_hash = hash2;
@@ reftable/reftable_test.c (new)
+ err = reftable_writer_close(w);
+ assert_err(err);
+ reftable_writer_free(w);
-+ slice_release(&buf);
++ strbuf_release(&buf);
+}
+
+static void test_log_write_read(void)
@@ reftable/reftable_test.c (new)
+ struct reftable_iterator it = { 0 };
+ struct reftable_reader rd = { 0 };
+ struct reftable_block_source source = { 0 };
-+ struct slice buf = SLICE_INIT;
++ struct strbuf buf = STRBUF_INIT;
+ struct reftable_writer *w =
-+ reftable_new_writer(&slice_add_void, &buf, &opts);
++ reftable_new_writer(&strbuf_add_void, &buf, &opts);
+ const struct reftable_stats *stats = NULL;
+ reftable_writer_set_limits(w, 0, N);
+ for (i = 0; i < N; i++) {
@@ reftable/reftable_test.c (new)
+ assert_err(err);
+ }
+ for (i = 0; i < N; i++) {
-+ byte hash1[SHA1_SIZE], hash2[SHA1_SIZE];
++ uint8_t hash1[SHA1_SIZE], hash2[SHA1_SIZE];
+ struct reftable_log_record log = { 0 };
+ set_test_hash(hash1, i);
+ set_test_hash(hash2, i + 1);
@@ reftable/reftable_test.c (new)
+ reftable_writer_free(w);
+ w = NULL;
+
-+ block_source_from_slice(&source, &buf);
++ block_source_from_strbuf(&source, &buf);
+
+ err = init_reader(&rd, &source, "file.log");
+ assert_err(err);
@@ reftable/reftable_test.c (new)
+ reftable_iterator_destroy(&it);
+
+ /* cleanup. */
-+ slice_release(&buf);
++ strbuf_release(&buf);
+ free_names(names);
+ reader_close(&rd);
+}
@@ reftable/reftable_test.c (new)
+static void test_table_read_write_sequential(void)
+{
+ char **names;
-+ struct slice buf = SLICE_INIT;
++ struct strbuf buf = STRBUF_INIT;
+ int N = 50;
+ struct reftable_iterator it = { 0 };
+ struct reftable_block_source source = { 0 };
@@ reftable/reftable_test.c (new)
+
+ write_table(&names, &buf, N, 256, SHA1_ID);
+
-+ block_source_from_slice(&source, &buf);
++ block_source_from_strbuf(&source, &buf);
+
+ err = init_reader(&rd, &source, "file.ref");
+ assert_err(err);
@@ reftable/reftable_test.c (new)
+ }
+ assert(j == N);
+ reftable_iterator_destroy(&it);
-+ slice_release(&buf);
++ strbuf_release(&buf);
+ free_names(names);
+
+ reader_close(&rd);
@@ reftable/reftable_test.c (new)
+static void test_table_write_small_table(void)
+{
+ char **names;
-+ struct slice buf = SLICE_INIT;
++ struct strbuf buf = STRBUF_INIT;
+ int N = 1;
+ write_table(&names, &buf, N, 4096, SHA1_ID);
+ assert(buf.len < 200);
-+ slice_release(&buf);
++ strbuf_release(&buf);
+ free_names(names);
+}
+
+static void test_table_read_api(void)
+{
+ char **names;
-+ struct slice buf = SLICE_INIT;
++ struct strbuf buf = STRBUF_INIT;
+ int N = 50;
+ struct reftable_reader rd = { 0 };
+ struct reftable_block_source source = { 0 };
@@ reftable/reftable_test.c (new)
+
+ write_table(&names, &buf, N, 256, SHA1_ID);
+
-+ block_source_from_slice(&source, &buf);
++ block_source_from_strbuf(&source, &buf);
+
+ err = init_reader(&rd, &source, "file.ref");
+ assert_err(err);
@@ reftable/reftable_test.c (new)
+ err = reftable_iterator_next_log(&it, &log);
+ assert(err == REFTABLE_API_ERROR);
+
-+ slice_release(&buf);
++ strbuf_release(&buf);
+ for (i = 0; i < N; i++) {
+ reftable_free(names[i]);
+ }
+ reftable_iterator_destroy(&it);
+ reftable_free(names);
+ reader_close(&rd);
-+ slice_release(&buf);
++ strbuf_release(&buf);
+}
+
+static void test_table_read_write_seek(bool index, int hash_id)
+{
+ char **names;
-+ struct slice buf = SLICE_INIT;
++ struct strbuf buf = STRBUF_INIT;
+ int N = 50;
+ struct reftable_reader rd = { 0 };
+ struct reftable_block_source source = { 0 };
@@ reftable/reftable_test.c (new)
+ int i = 0;
+
+ struct reftable_iterator it = { 0 };
-+ struct slice pastLast = SLICE_INIT;
++ struct strbuf pastLast = STRBUF_INIT;
+ struct reftable_ref_record ref = { 0 };
+
+ write_table(&names, &buf, N, 256, hash_id);
+
-+ block_source_from_slice(&source, &buf);
++ block_source_from_strbuf(&source, &buf);
+
+ err = init_reader(&rd, &source, "file.ref");
+ assert_err(err);
@@ reftable/reftable_test.c (new)
+ reftable_iterator_destroy(&it);
+ }
+
-+ slice_addstr(&pastLast, names[N - 1]);
-+ slice_addstr(&pastLast, "/");
++ strbuf_addstr(&pastLast, names[N - 1]);
++ strbuf_addstr(&pastLast, "/");
+
-+ err = reftable_reader_seek_ref(&rd, &it, slice_as_string(&pastLast));
++ err = reftable_reader_seek_ref(&rd, &it, pastLast.buf);
+ if (err == 0) {
+ struct reftable_ref_record ref = { 0 };
+ int err = reftable_iterator_next_ref(&it, &ref);
@@ reftable/reftable_test.c (new)
+ assert(err > 0);
+ }
+
-+ slice_release(&pastLast);
++ strbuf_release(&pastLast);
+ reftable_iterator_destroy(&it);
+
-+ slice_release(&buf);
++ strbuf_release(&buf);
+ for (i = 0; i < N; i++) {
+ reftable_free(names[i]);
+ }
@@ reftable/reftable_test.c (new)
+ int N = 50;
+ char **want_names = reftable_calloc(sizeof(char *) * (N + 1));
+ int want_names_len = 0;
-+ byte want_hash[SHA1_SIZE];
++ uint8_t want_hash[SHA1_SIZE];
+
+ struct reftable_write_options opts = {
+ .block_size = 256,
@@ reftable/reftable_test.c (new)
+ struct reftable_reader rd;
+ struct reftable_block_source source = { 0 };
+
-+ struct slice buf = SLICE_INIT;
++ struct strbuf buf = STRBUF_INIT;
+ struct reftable_writer *w =
-+ reftable_new_writer(&slice_add_void, &buf, &opts);
++ reftable_new_writer(&strbuf_add_void, &buf, &opts);
+
+ struct reftable_iterator it = { 0 };
+ int j;
@@ reftable/reftable_test.c (new)
+ set_test_hash(want_hash, 4);
+
+ for (i = 0; i < N; i++) {
-+ byte hash[SHA1_SIZE];
++ uint8_t hash[SHA1_SIZE];
+ char fill[51] = { 0 };
+ char name[100];
-+ byte hash1[SHA1_SIZE];
-+ byte hash2[SHA1_SIZE];
++ uint8_t hash1[SHA1_SIZE];
++ uint8_t hash2[SHA1_SIZE];
+ struct reftable_ref_record ref = { 0 };
+
+ memset(hash, i, sizeof(hash));
@@ reftable/reftable_test.c (new)
+ reftable_writer_free(w);
+ w = NULL;
+
-+ block_source_from_slice(&source, &buf);
++ block_source_from_strbuf(&source, &buf);
+
+ err = init_reader(&rd, &source, "file.ref");
+ assert_err(err);
@@ reftable/reftable_test.c (new)
+ }
+ assert(j == want_names_len);
+
-+ slice_release(&buf);
++ strbuf_release(&buf);
+ free_names(want_names);
+ reftable_iterator_destroy(&it);
+ reader_close(&rd);
@@ reftable/reftable_test.c (new)
+static void test_table_empty(void)
+{
+ struct reftable_write_options opts = { 0 };
-+ struct slice buf = SLICE_INIT;
++ struct strbuf buf = STRBUF_INIT;
+ struct reftable_writer *w =
-+ reftable_new_writer(&slice_add_void, &buf, &opts);
++ reftable_new_writer(&strbuf_add_void, &buf, &opts);
+ struct reftable_block_source source = { 0 };
+ struct reftable_reader *rd = NULL;
+ struct reftable_ref_record rec = { 0 };
@@ reftable/reftable_test.c (new)
+
+ assert(buf.len == header_size(1) + footer_size(1));
+
-+ block_source_from_slice(&source, &buf);
++ block_source_from_strbuf(&source, &buf);
+
+ err = reftable_new_reader(&rd, &source, "filename");
+ assert_err(err);
@@ reftable/reftable_test.c (new)
+
+ reftable_iterator_destroy(&it);
+ reftable_reader_free(rd);
-+ slice_release(&buf);
++ strbuf_release(&buf);
+}
+
+int reftable_test_main(int argc, const char *argv[])
@@ reftable/reftable_test.c (new)
+ return test_main(argc, argv);
+}
- ## reftable/slice.c (new) ##
+ ## reftable/stack.c (new) ##
@@
+/*
+Copyright 2020 Google LLC
@@ reftable/slice.c (new)
+https://developers.google.com/open-source/licenses/bsd
+*/
+
-+#include "slice.h"
++#include "stack.h"
+
+#include "system.h"
-+
++#include "merged.h"
++#include "reader.h"
++#include "refname.h"
+#include "reftable.h"
++#include "writer.h"
+
-+struct slice reftable_empty_slice = SLICE_INIT;
-+
-+void slice_init(struct slice *s)
-+{
-+ struct slice empty = SLICE_INIT;
-+ *s = empty;
-+}
-+
-+void slice_grow(struct slice *s, size_t extra)
++int reftable_new_stack(struct reftable_stack **dest, const char *dir,
++ struct reftable_write_options config)
+{
-+ size_t newcap = s->len + extra + 1;
-+ if (newcap > s->cap) {
-+ s->buf = reftable_realloc(s->buf, newcap);
-+ s->cap = newcap;
-+ }
-+}
++ struct reftable_stack *p =
++ reftable_calloc(sizeof(struct reftable_stack));
++ struct strbuf list_file_name = STRBUF_INIT;
++ int err = 0;
+
-+static void slice_resize(struct slice *s, int l)
-+{
-+ int zl = l + 1; /* one byte for 0 termination. */
-+ assert(s->canary == SLICE_CANARY);
-+ if (s->cap < zl) {
-+ int c = s->cap * 2;
-+ if (c < zl) {
-+ c = zl;
-+ }
-+ s->cap = c;
-+ s->buf = reftable_realloc(s->buf, s->cap);
++ if (config.hash_id == 0) {
++ config.hash_id = SHA1_ID;
+ }
-+ s->len = l;
-+ s->buf[l] = 0;
-+}
-+
-+void slice_setlen(struct slice *s, size_t l)
-+{
-+ assert(s->cap >= l + 1);
-+ s->len = l;
-+ s->buf[l] = 0;
-+}
+
-+void slice_reset(struct slice *s)
-+{
-+ slice_resize(s, 0);
-+}
++ *dest = NULL;
+
-+void slice_addstr(struct slice *d, const char *s)
-+{
-+ int l1 = d->len;
-+ int l2 = strlen(s);
-+ assert(d->canary == SLICE_CANARY);
++ strbuf_reset(&list_file_name);
++ strbuf_addstr(&list_file_name, dir);
++ strbuf_addstr(&list_file_name, "/tables.list");
+
-+ slice_resize(d, l2 + l1);
-+ memcpy(d->buf + l1, s, l2);
-+}
++ p->list_file = strbuf_detach(&list_file_name, NULL);
++ p->reftable_dir = xstrdup(dir);
++ p->config = config;
+
-+void slice_addbuf(struct slice *s, struct slice *a)
-+{
-+ int end = s->len;
-+ assert(s->canary == SLICE_CANARY);
-+ slice_resize(s, s->len + a->len);
-+ memcpy(s->buf + end, a->buf, a->len);
++ err = reftable_stack_reload_maybe_reuse(p, true);
++ if (err < 0) {
++ reftable_stack_destroy(p);
++ } else {
++ *dest = p;
++ }
++ return err;
+}
+
-+void slice_consume(struct slice *s, int n)
++static int fd_read_lines(int fd, char ***namesp)
+{
-+ assert(s->canary == SLICE_CANARY);
-+ s->buf += n;
-+ s->len -= n;
-+}
++ off_t size = lseek(fd, 0, SEEK_END);
++ char *buf = NULL;
++ int err = 0;
++ if (size < 0) {
++ err = REFTABLE_IO_ERROR;
++ goto done;
++ }
++ err = lseek(fd, 0, SEEK_SET);
++ if (err < 0) {
++ err = REFTABLE_IO_ERROR;
++ goto done;
++ }
+
-+char *slice_detach(struct slice *s)
-+{
-+ char *p = NULL;
-+ slice_as_string(s);
-+ p = (char *)s->buf;
-+ s->buf = NULL;
-+ s->cap = 0;
-+ s->len = 0;
-+ return p;
-+}
++ buf = reftable_malloc(size + 1);
++ if (read(fd, buf, size) != size) {
++ err = REFTABLE_IO_ERROR;
++ goto done;
++ }
++ buf[size] = 0;
+
-+void slice_release(struct slice *s)
-+{
-+ byte *ptr = s->buf;
-+ assert(s->canary == SLICE_CANARY);
-+ s->buf = NULL;
-+ s->cap = 0;
-+ s->len = 0;
-+ reftable_free(ptr);
-+}
++ parse_names(buf, size, namesp);
+
-+/* return the underlying data as char*. len is left unchanged, but
-+ a \0 is added at the end. */
-+const char *slice_as_string(struct slice *s)
-+{
-+ return (const char *)s->buf;
++done:
++ reftable_free(buf);
++ return err;
+}
+
-+int slice_cmp(const struct slice *a, const struct slice *b)
++int read_lines(const char *filename, char ***namesp)
+{
-+ int min = a->len < b->len ? a->len : b->len;
-+ int res = memcmp(a->buf, b->buf, min);
-+ assert(a->canary == SLICE_CANARY);
-+ assert(b->canary == SLICE_CANARY);
-+ if (res != 0)
-+ return res;
-+ if (a->len < b->len)
-+ return -1;
-+ else if (a->len > b->len)
-+ return 1;
-+ else
-+ return 0;
-+}
++ int fd = open(filename, O_RDONLY, 0644);
++ int err = 0;
++ if (fd < 0) {
++ if (errno == ENOENT) {
++ *namesp = reftable_calloc(sizeof(char *));
++ return 0;
++ }
+
-+int slice_add(struct slice *b, const byte *data, size_t sz)
-+{
-+ assert(b->canary == SLICE_CANARY);
-+ slice_grow(b, sz);
-+ memcpy(b->buf + b->len, data, sz);
-+ b->len += sz;
-+ b->buf[b->len] = 0;
-+ return sz;
++ return REFTABLE_IO_ERROR;
++ }
++ err = fd_read_lines(fd, namesp);
++ close(fd);
++ return err;
+}
+
-+int slice_add_void(void *b, byte *data, size_t sz)
++struct reftable_merged_table *
++reftable_stack_merged_table(struct reftable_stack *st)
+{
-+ return slice_add((struct slice *)b, data, sz);
++ return st->merged;
+}
+
-+static uint64_t slice_size(void *b)
++/* Close and free the stack */
++void reftable_stack_destroy(struct reftable_stack *st)
+{
-+ return ((struct slice *)b)->len;
++ if (st->merged != NULL) {
++ reftable_merged_table_close(st->merged);
++ reftable_merged_table_free(st->merged);
++ st->merged = NULL;
++ }
++ FREE_AND_NULL(st->list_file);
++ FREE_AND_NULL(st->reftable_dir);
++ reftable_free(st);
+}
+
-+static void slice_return_block(void *b, struct reftable_block *dest)
++static struct reftable_reader **stack_copy_readers(struct reftable_stack *st,
++ int cur_len)
+{
-+ memset(dest->data, 0xff, dest->len);
-+ reftable_free(dest->data);
++ struct reftable_reader **cur =
++ reftable_calloc(sizeof(struct reftable_reader *) * cur_len);
++ int i = 0;
++ for (i = 0; i < cur_len; i++) {
++ cur[i] = st->merged->stack[i];
++ }
++ return cur;
+}
+
-+static void slice_close(void *b)
++static int reftable_stack_reload_once(struct reftable_stack *st, char **names,
++ bool reuse_open)
+{
-+}
++ int cur_len = st->merged == NULL ? 0 : st->merged->stack_len;
++ struct reftable_reader **cur = stack_copy_readers(st, cur_len);
++ int err = 0;
++ int names_len = names_length(names);
++ struct reftable_reader **new_tables =
++ reftable_malloc(sizeof(struct reftable_reader *) * names_len);
++ int new_tables_len = 0;
++ struct reftable_merged_table *new_merged = NULL;
++ int i;
+
-+static int slice_read_block(void *v, struct reftable_block *dest, uint64_t off,
-+ uint32_t size)
-+{
-+ struct slice *b = (struct slice *)v;
-+ assert(off + size <= b->len);
-+ dest->data = reftable_calloc(size);
-+ memcpy(dest->data, b->buf + off, size);
-+ dest->len = size;
-+ return size;
-+}
++ while (*names) {
++ struct reftable_reader *rd = NULL;
++ char *name = *names++;
+
-+struct reftable_block_source_vtable slice_vtable = {
-+ .size = &slice_size,
-+ .read_block = &slice_read_block,
-+ .return_block = &slice_return_block,
-+ .close = &slice_close,
-+};
++ /* this is linear; we assume compaction keeps the number of
++ tables under control so this is not quadratic. */
++ int j = 0;
++ for (j = 0; reuse_open && j < cur_len; j++) {
++ if (cur[j] != NULL && 0 == strcmp(cur[j]->name, name)) {
++ rd = cur[j];
++ cur[j] = NULL;
++ break;
++ }
++ }
+
-+void block_source_from_slice(struct reftable_block_source *bs,
-+ struct slice *buf)
-+{
-+ assert(bs->ops == NULL);
-+ bs->ops = &slice_vtable;
-+ bs->arg = buf;
-+}
++ if (rd == NULL) {
++ struct reftable_block_source src = { 0 };
++ struct strbuf table_path = STRBUF_INIT;
++ strbuf_addstr(&table_path, st->reftable_dir);
++ strbuf_addstr(&table_path, "/");
++ strbuf_addstr(&table_path, name);
+
-+static void malloc_return_block(void *b, struct reftable_block *dest)
-+{
-+ memset(dest->data, 0xff, dest->len);
-+ reftable_free(dest->data);
-+}
++ err = reftable_block_source_from_file(&src,
++ table_path.buf);
++ strbuf_release(&table_path);
+
-+struct reftable_block_source_vtable malloc_vtable = {
-+ .return_block = &malloc_return_block,
-+};
++ if (err < 0)
++ goto done;
+
-+struct reftable_block_source malloc_block_source_instance = {
-+ .ops = &malloc_vtable,
-+};
++ err = reftable_new_reader(&rd, &src, name);
++ if (err < 0)
++ goto done;
++ }
+
-+struct reftable_block_source malloc_block_source(void)
-+{
-+ return malloc_block_source_instance;
-+}
-+
-+int common_prefix_size(struct slice *a, struct slice *b)
-+{
-+ int p = 0;
-+ assert(a->canary == SLICE_CANARY);
-+ assert(b->canary == SLICE_CANARY);
-+ while (p < a->len && p < b->len) {
-+ if (a->buf[p] != b->buf[p]) {
-+ break;
-+ }
-+ p++;
-+ }
-+
-+ return p;
-+}
-
- ## reftable/slice.h (new) ##
-@@
-+/*
-+Copyright 2020 Google LLC
-+
-+Use of this source code is governed by a BSD-style
-+license that can be found in the LICENSE file or at
-+https://developers.google.com/open-source/licenses/bsd
-+*/
-+
-+#ifndef SLICE_H
-+#define SLICE_H
-+
-+#include "basics.h"
-+#include "reftable.h"
-+
-+/*
-+ Provides a bounds-checked, growable byte ranges. To use, initialize as "slice
-+ x = SLICE_INIT;"
-+ */
-+struct slice {
-+ int len;
-+ int cap;
-+ byte *buf;
-+
-+ /* Used to enforce initialization with SLICE_INIT */
-+ byte canary;
-+};
-+#define SLICE_CANARY 0x42
-+#define SLICE_INIT \
-+ { \
-+ 0, 0, NULL, SLICE_CANARY \
-+ }
-+extern struct slice reftable_empty_slice;
-+
-+void slice_addstr(struct slice *dest, const char *src);
-+
-+/* Deallocate and clear slice */
-+void slice_release(struct slice *slice);
-+
-+/* Set slice to 0 length, but retain buffer. */
-+void slice_reset(struct slice *slice);
-+
-+/* Initializes a slice. Accepts a slice with random garbage. */
-+void slice_init(struct slice *slice);
-+
-+/* Ensure that `buf` is \0 terminated. */
-+const char *slice_as_string(struct slice *src);
-+
-+/* Return `buf`, clearing out `s` */
-+char *slice_detach(struct slice *s);
-+
-+/* Set length of the slace to `l`, but don't reallocated. */
-+void slice_setlen(struct slice *s, size_t l);
-+
-+/* Ensure `l` bytes beyond current length are available */
-+void slice_grow(struct slice *s, size_t l);
-+
-+/* Signed comparison */
-+int slice_cmp(const struct slice *a, const struct slice *b);
-+
-+/* Append `data` to the `dest` slice. */
-+int slice_add(struct slice *dest, const byte *data, size_t sz);
-+
-+/* Append `add` to `dest. */
-+void slice_addbuf(struct slice *dest, struct slice *add);
-+
-+/* Like slice_add, but suitable for passing to reftable_new_writer
-+ */
-+int slice_add_void(void *b, byte *data, size_t sz);
-+
-+/* Find the longest shared prefix size of `a` and `b` */
-+int common_prefix_size(struct slice *a, struct slice *b);
-+
-+struct reftable_block_source;
-+
-+/* Create an in-memory block source for reading reftables */
-+void block_source_from_slice(struct reftable_block_source *bs,
-+ struct slice *buf);
-+
-+struct reftable_block_source malloc_block_source(void);
-+
-+/* Advance `buf` by `n`, and decrease length. A copy of the slice
-+ should be kept for deallocating the slice. */
-+void slice_consume(struct slice *s, int n);
-+
-+#endif
-
- ## reftable/slice_test.c (new) ##
-@@
-+/*
-+Copyright 2020 Google LLC
-+
-+Use of this source code is governed by a BSD-style
-+license that can be found in the LICENSE file or at
-+https://developers.google.com/open-source/licenses/bsd
-+*/
-+
-+#include "slice.h"
-+
-+#include "system.h"
-+
-+#include "basics.h"
-+#include "record.h"
-+#include "reftable.h"
-+#include "test_framework.h"
-+#include "reftable-tests.h"
-+
-+static void test_slice(void)
-+{
-+ struct slice s = SLICE_INIT;
-+ struct slice t = SLICE_INIT;
-+
-+ slice_addstr(&s, "abc");
-+ assert(0 == strcmp("abc", slice_as_string(&s)));
-+
-+ slice_addstr(&t, "pqr");
-+ slice_addbuf(&s, &t);
-+ assert(0 == strcmp("abcpqr", slice_as_string(&s)));
-+
-+ slice_release(&s);
-+ slice_release(&t);
-+}
-+
-+int slice_test_main(int argc, const char *argv[])
-+{
-+ add_test_case("test_slice", &test_slice);
-+ return test_main(argc, argv);
-+}
-
- ## reftable/stack.c (new) ##
-@@
-+/*
-+Copyright 2020 Google LLC
-+
-+Use of this source code is governed by a BSD-style
-+license that can be found in the LICENSE file or at
-+https://developers.google.com/open-source/licenses/bsd
-+*/
-+
-+#include "stack.h"
-+
-+#include "system.h"
-+#include "merged.h"
-+#include "reader.h"
-+#include "refname.h"
-+#include "reftable.h"
-+#include "writer.h"
-+
-+int reftable_new_stack(struct reftable_stack **dest, const char *dir,
-+ struct reftable_write_options config)
-+{
-+ struct reftable_stack *p =
-+ reftable_calloc(sizeof(struct reftable_stack));
-+ struct slice list_file_name = SLICE_INIT;
-+ int err = 0;
-+
-+ if (config.hash_id == 0) {
-+ config.hash_id = SHA1_ID;
-+ }
-+
-+ *dest = NULL;
-+
-+ slice_reset(&list_file_name);
-+ slice_addstr(&list_file_name, dir);
-+ slice_addstr(&list_file_name, "/tables.list");
-+
-+ p->list_file = slice_detach(&list_file_name);
-+ p->reftable_dir = xstrdup(dir);
-+ p->config = config;
-+
-+ err = reftable_stack_reload_maybe_reuse(p, true);
-+ if (err < 0) {
-+ reftable_stack_destroy(p);
-+ } else {
-+ *dest = p;
-+ }
-+ return err;
-+}
-+
-+static int fd_read_lines(int fd, char ***namesp)
-+{
-+ off_t size = lseek(fd, 0, SEEK_END);
-+ char *buf = NULL;
-+ int err = 0;
-+ if (size < 0) {
-+ err = REFTABLE_IO_ERROR;
-+ goto done;
-+ }
-+ err = lseek(fd, 0, SEEK_SET);
-+ if (err < 0) {
-+ err = REFTABLE_IO_ERROR;
-+ goto done;
-+ }
-+
-+ buf = reftable_malloc(size + 1);
-+ if (read(fd, buf, size) != size) {
-+ err = REFTABLE_IO_ERROR;
-+ goto done;
-+ }
-+ buf[size] = 0;
-+
-+ parse_names(buf, size, namesp);
-+
-+done:
-+ reftable_free(buf);
-+ return err;
-+}
-+
-+int read_lines(const char *filename, char ***namesp)
-+{
-+ int fd = open(filename, O_RDONLY, 0644);
-+ int err = 0;
-+ if (fd < 0) {
-+ if (errno == ENOENT) {
-+ *namesp = reftable_calloc(sizeof(char *));
-+ return 0;
-+ }
-+
-+ return REFTABLE_IO_ERROR;
-+ }
-+ err = fd_read_lines(fd, namesp);
-+ close(fd);
-+ return err;
-+}
-+
-+struct reftable_merged_table *
-+reftable_stack_merged_table(struct reftable_stack *st)
-+{
-+ return st->merged;
-+}
-+
-+/* Close and free the stack */
-+void reftable_stack_destroy(struct reftable_stack *st)
-+{
-+ if (st->merged != NULL) {
-+ reftable_merged_table_close(st->merged);
-+ reftable_merged_table_free(st->merged);
-+ st->merged = NULL;
-+ }
-+ FREE_AND_NULL(st->list_file);
-+ FREE_AND_NULL(st->reftable_dir);
-+ reftable_free(st);
-+}
-+
-+static struct reftable_reader **stack_copy_readers(struct reftable_stack *st,
-+ int cur_len)
-+{
-+ struct reftable_reader **cur =
-+ reftable_calloc(sizeof(struct reftable_reader *) * cur_len);
-+ int i = 0;
-+ for (i = 0; i < cur_len; i++) {
-+ cur[i] = st->merged->stack[i];
-+ }
-+ return cur;
-+}
-+
-+static int reftable_stack_reload_once(struct reftable_stack *st, char **names,
-+ bool reuse_open)
-+{
-+ int cur_len = st->merged == NULL ? 0 : st->merged->stack_len;
-+ struct reftable_reader **cur = stack_copy_readers(st, cur_len);
-+ int err = 0;
-+ int names_len = names_length(names);
-+ struct reftable_reader **new_tables =
-+ reftable_malloc(sizeof(struct reftable_reader *) * names_len);
-+ int new_tables_len = 0;
-+ struct reftable_merged_table *new_merged = NULL;
-+ int i;
-+
-+ while (*names) {
-+ struct reftable_reader *rd = NULL;
-+ char *name = *names++;
-+
-+ /* this is linear; we assume compaction keeps the number of
-+ tables under control so this is not quadratic. */
-+ int j = 0;
-+ for (j = 0; reuse_open && j < cur_len; j++) {
-+ if (cur[j] != NULL && 0 == strcmp(cur[j]->name, name)) {
-+ rd = cur[j];
-+ cur[j] = NULL;
-+ break;
-+ }
-+ }
-+
-+ if (rd == NULL) {
-+ struct reftable_block_source src = { 0 };
-+ struct slice table_path = SLICE_INIT;
-+ slice_addstr(&table_path, st->reftable_dir);
-+ slice_addstr(&table_path, "/");
-+ slice_addstr(&table_path, name);
-+
-+ err = reftable_block_source_from_file(
-+ &src, slice_as_string(&table_path));
-+ slice_release(&table_path);
-+
-+ if (err < 0)
-+ goto done;
-+
-+ err = reftable_new_reader(&rd, &src, name);
-+ if (err < 0)
-+ goto done;
-+ }
-+
-+ new_tables[new_tables_len++] = rd;
-+ }
++ new_tables[new_tables_len++] = rd;
++ }
+
+ /* success! */
+ err = reftable_new_merged_table(&new_merged, new_tables, new_tables_len,
@@ reftable/stack.c (new)
+ return 0;
+}
+
-+static void format_name(struct slice *dest, uint64_t min, uint64_t max)
++static void format_name(struct strbuf *dest, uint64_t min, uint64_t max)
+{
+ char buf[100];
+ snprintf(buf, sizeof(buf), "0x%012" PRIx64 "-0x%012" PRIx64, min, max);
-+ slice_reset(dest);
-+ slice_addstr(dest, buf);
++ strbuf_reset(dest);
++ strbuf_addstr(dest, buf);
+}
+
+struct reftable_addition {
+ int lock_file_fd;
-+ struct slice lock_file_name;
++ struct strbuf lock_file_name;
+ struct reftable_stack *stack;
+ char **names;
+ char **new_tables;
@@ reftable/stack.c (new)
+ uint64_t next_update_index;
+};
+
-+#define REFTABLE_ADDITION_INIT \
-+ { \
-+ .lock_file_name = SLICE_INIT \
++#define REFTABLE_ADDITION_INIT \
++ { \
++ .lock_file_name = STRBUF_INIT \
+ }
+
+static int reftable_stack_init_addition(struct reftable_addition *add,
@@ reftable/stack.c (new)
+ int err = 0;
+ add->stack = st;
+
-+ slice_reset(&add->lock_file_name);
-+ slice_addstr(&add->lock_file_name, st->list_file);
-+ slice_addstr(&add->lock_file_name, ".lock");
++ strbuf_reset(&add->lock_file_name);
++ strbuf_addstr(&add->lock_file_name, st->list_file);
++ strbuf_addstr(&add->lock_file_name, ".lock");
+
-+ add->lock_file_fd = open(slice_as_string(&add->lock_file_name),
++ add->lock_file_fd = open(add->lock_file_name.buf,
+ O_EXCL | O_CREAT | O_WRONLY, 0644);
+ if (add->lock_file_fd < 0) {
+ if (errno == EEXIST) {
@@ reftable/stack.c (new)
+void reftable_addition_close(struct reftable_addition *add)
+{
+ int i = 0;
-+ struct slice nm = SLICE_INIT;
++ struct strbuf nm = STRBUF_INIT;
+ for (i = 0; i < add->new_tables_len; i++) {
-+ slice_reset(&nm);
-+ slice_addstr(&nm, add->stack->list_file);
-+ slice_addstr(&nm, "/");
-+ slice_addstr(&nm, add->new_tables[i]);
-+ unlink(slice_as_string(&nm));
++ strbuf_reset(&nm);
++ strbuf_addstr(&nm, add->stack->list_file);
++ strbuf_addstr(&nm, "/");
++ strbuf_addstr(&nm, add->new_tables[i]);
++ unlink(nm.buf);
+ reftable_free(add->new_tables[i]);
+ add->new_tables[i] = NULL;
+ }
@@ reftable/stack.c (new)
+ add->lock_file_fd = 0;
+ }
+ if (add->lock_file_name.len > 0) {
-+ unlink(slice_as_string(&add->lock_file_name));
-+ slice_release(&add->lock_file_name);
++ unlink(add->lock_file_name.buf);
++ strbuf_release(&add->lock_file_name);
+ }
+
+ free_names(add->names);
+ add->names = NULL;
-+ slice_release(&nm);
++ strbuf_release(&nm);
+}
+
+void reftable_addition_destroy(struct reftable_addition *add)
@@ reftable/stack.c (new)
+
+int reftable_addition_commit(struct reftable_addition *add)
+{
-+ struct slice table_list = SLICE_INIT;
++ struct strbuf table_list = STRBUF_INIT;
+ int i = 0;
+ int err = 0;
+ if (add->new_tables_len == 0)
+ goto done;
+
+ for (i = 0; i < add->stack->merged->stack_len; i++) {
-+ slice_addstr(&table_list, add->stack->merged->stack[i]->name);
-+ slice_addstr(&table_list, "\n");
++ strbuf_addstr(&table_list, add->stack->merged->stack[i]->name);
++ strbuf_addstr(&table_list, "\n");
+ }
+ for (i = 0; i < add->new_tables_len; i++) {
-+ slice_addstr(&table_list, add->new_tables[i]);
-+ slice_addstr(&table_list, "\n");
++ strbuf_addstr(&table_list, add->new_tables[i]);
++ strbuf_addstr(&table_list, "\n");
+ }
+
+ err = write(add->lock_file_fd, table_list.buf, table_list.len);
-+ slice_release(&table_list);
++ strbuf_release(&table_list);
+ if (err < 0) {
+ err = REFTABLE_IO_ERROR;
+ goto done;
@@ reftable/stack.c (new)
+ goto done;
+ }
+
-+ err = rename(slice_as_string(&add->lock_file_name),
-+ add->stack->list_file);
++ err = rename(add->lock_file_name.buf, add->stack->list_file);
+ if (err < 0) {
+ err = REFTABLE_IO_ERROR;
+ goto done;
@@ reftable/stack.c (new)
+ void *arg),
+ void *arg)
+{
-+ struct slice temp_tab_file_name = SLICE_INIT;
-+ struct slice tab_file_name = SLICE_INIT;
-+ struct slice next_name = SLICE_INIT;
++ struct strbuf temp_tab_file_name = STRBUF_INIT;
++ struct strbuf tab_file_name = STRBUF_INIT;
++ struct strbuf next_name = STRBUF_INIT;
+ struct reftable_writer *wr = NULL;
+ int err = 0;
+ int tab_fd = 0;
+
-+ slice_reset(&next_name);
++ strbuf_reset(&next_name);
+ format_name(&next_name, add->next_update_index, add->next_update_index);
+
-+ slice_addstr(&temp_tab_file_name, add->stack->reftable_dir);
-+ slice_addstr(&temp_tab_file_name, "/");
-+ slice_addbuf(&temp_tab_file_name, &next_name);
-+ slice_addstr(&temp_tab_file_name, ".temp.XXXXXX");
++ strbuf_addstr(&temp_tab_file_name, add->stack->reftable_dir);
++ strbuf_addstr(&temp_tab_file_name, "/");
++ strbuf_addbuf(&temp_tab_file_name, &next_name);
++ strbuf_addstr(&temp_tab_file_name, ".temp.XXXXXX");
+
-+ tab_fd = mkstemp((char *)slice_as_string(&temp_tab_file_name));
++ tab_fd = mkstemp(temp_tab_file_name.buf);
+ if (tab_fd < 0) {
+ err = REFTABLE_IO_ERROR;
+ goto done;
@@ reftable/stack.c (new)
+ goto done;
+ }
+
-+ err = stack_check_addition(add->stack,
-+ slice_as_string(&temp_tab_file_name));
++ err = stack_check_addition(add->stack, temp_tab_file_name.buf);
+ if (err < 0)
+ goto done;
+
@@ reftable/stack.c (new)
+ }
+
+ format_name(&next_name, wr->min_update_index, wr->max_update_index);
-+ slice_addstr(&next_name, ".ref");
++ strbuf_addstr(&next_name, ".ref");
+
-+ slice_addstr(&tab_file_name, add->stack->reftable_dir);
-+ slice_addstr(&tab_file_name, "/");
-+ slice_addbuf(&tab_file_name, &next_name);
++ strbuf_addstr(&tab_file_name, add->stack->reftable_dir);
++ strbuf_addstr(&tab_file_name, "/");
++ strbuf_addbuf(&tab_file_name, &next_name);
+
+ /* TODO: should check destination out of paranoia */
-+ err = rename(slice_as_string(&temp_tab_file_name),
-+ slice_as_string(&tab_file_name));
++ err = rename(temp_tab_file_name.buf, tab_file_name.buf);
+ if (err < 0) {
+ err = REFTABLE_IO_ERROR;
+ goto done;
@@ reftable/stack.c (new)
+ add->new_tables = reftable_realloc(add->new_tables,
+ sizeof(*add->new_tables) *
+ (add->new_tables_len + 1));
-+ add->new_tables[add->new_tables_len] = slice_detach(&next_name);
++ add->new_tables[add->new_tables_len] = strbuf_detach(&next_name, NULL);
+ add->new_tables_len++;
+done:
+ if (tab_fd > 0) {
@@ reftable/stack.c (new)
+ tab_fd = 0;
+ }
+ if (temp_tab_file_name.len > 0) {
-+ unlink(slice_as_string(&temp_tab_file_name));
++ unlink(temp_tab_file_name.buf);
+ }
+
-+ slice_release(&temp_tab_file_name);
-+ slice_release(&tab_file_name);
-+ slice_release(&next_name);
++ strbuf_release(&temp_tab_file_name);
++ strbuf_release(&tab_file_name);
++ strbuf_release(&next_name);
+ reftable_writer_free(wr);
+ return err;
+}
@@ reftable/stack.c (new)
+}
+
+static int stack_compact_locked(struct reftable_stack *st, int first, int last,
-+ struct slice *temp_tab,
++ struct strbuf *temp_tab,
+ struct reftable_log_expiry_config *config)
+{
-+ struct slice next_name = SLICE_INIT;
++ struct strbuf next_name = STRBUF_INIT;
+ int tab_fd = -1;
+ struct reftable_writer *wr = NULL;
+ int err = 0;
@@ reftable/stack.c (new)
+ reftable_reader_min_update_index(st->merged->stack[first]),
+ reftable_reader_max_update_index(st->merged->stack[first]));
+
-+ slice_reset(temp_tab);
-+ slice_addstr(temp_tab, st->reftable_dir);
-+ slice_addstr(temp_tab, "/");
-+ slice_addbuf(temp_tab, &next_name);
-+ slice_addstr(temp_tab, ".temp.XXXXXX");
++ strbuf_reset(temp_tab);
++ strbuf_addstr(temp_tab, st->reftable_dir);
++ strbuf_addstr(temp_tab, "/");
++ strbuf_addbuf(temp_tab, &next_name);
++ strbuf_addstr(temp_tab, ".temp.XXXXXX");
+
-+ tab_fd = mkstemp((char *)slice_as_string(temp_tab));
++ tab_fd = mkstemp(temp_tab->buf);
+ wr = reftable_new_writer(reftable_fd_write, &tab_fd, &st->config);
+
+ err = stack_write_compact(st, wr, first, last, config);
@@ reftable/stack.c (new)
+ tab_fd = 0;
+ }
+ if (err != 0 && temp_tab->len > 0) {
-+ unlink(slice_as_string(temp_tab));
-+ slice_release(temp_tab);
++ unlink(temp_tab->buf);
++ strbuf_release(temp_tab);
+ }
-+ slice_release(&next_name);
++ strbuf_release(&next_name);
+ return err;
+}
+
@@ reftable/stack.c (new)
+static int stack_compact_range(struct reftable_stack *st, int first, int last,
+ struct reftable_log_expiry_config *expiry)
+{
-+ struct slice temp_tab_file_name = SLICE_INIT;
-+ struct slice new_table_name = SLICE_INIT;
-+ struct slice lock_file_name = SLICE_INIT;
-+ struct slice ref_list_contents = SLICE_INIT;
-+ struct slice new_table_path = SLICE_INIT;
++ struct strbuf temp_tab_file_name = STRBUF_INIT;
++ struct strbuf new_table_name = STRBUF_INIT;
++ struct strbuf lock_file_name = STRBUF_INIT;
++ struct strbuf ref_list_contents = STRBUF_INIT;
++ struct strbuf new_table_path = STRBUF_INIT;
+ int err = 0;
+ bool have_lock = false;
+ int lock_file_fd = 0;
@@ reftable/stack.c (new)
+
+ st->stats.attempts++;
+
-+ slice_reset(&lock_file_name);
-+ slice_addstr(&lock_file_name, st->list_file);
-+ slice_addstr(&lock_file_name, ".lock");
++ strbuf_reset(&lock_file_name);
++ strbuf_addstr(&lock_file_name, st->list_file);
++ strbuf_addstr(&lock_file_name, ".lock");
+
-+ lock_file_fd = open(slice_as_string(&lock_file_name),
-+ O_EXCL | O_CREAT | O_WRONLY, 0644);
++ lock_file_fd =
++ open(lock_file_name.buf, O_EXCL | O_CREAT | O_WRONLY, 0644);
+ if (lock_file_fd < 0) {
+ if (errno == EEXIST) {
+ err = 1;
@@ reftable/stack.c (new)
+ goto done;
+
+ for (i = first, j = 0; i <= last; i++) {
-+ struct slice subtab_file_name = SLICE_INIT;
-+ struct slice subtab_lock = SLICE_INIT;
++ struct strbuf subtab_file_name = STRBUF_INIT;
++ struct strbuf subtab_lock = STRBUF_INIT;
+ int sublock_file_fd = -1;
+
-+ slice_addstr(&subtab_file_name, st->reftable_dir);
-+ slice_addstr(&subtab_file_name, "/");
-+ slice_addstr(&subtab_file_name,
-+ reader_name(st->merged->stack[i]));
++ strbuf_addstr(&subtab_file_name, st->reftable_dir);
++ strbuf_addstr(&subtab_file_name, "/");
++ strbuf_addstr(&subtab_file_name,
++ reader_name(st->merged->stack[i]));
+
-+ slice_reset(&subtab_lock);
-+ slice_addbuf(&subtab_lock, &subtab_file_name);
-+ slice_addstr(&subtab_lock, ".lock");
++ strbuf_reset(&subtab_lock);
++ strbuf_addbuf(&subtab_lock, &subtab_file_name);
++ strbuf_addstr(&subtab_lock, ".lock");
+
-+ sublock_file_fd = open(slice_as_string(&subtab_lock),
++ sublock_file_fd = open(subtab_lock.buf,
+ O_EXCL | O_CREAT | O_WRONLY, 0644);
+ if (sublock_file_fd > 0) {
+ close(sublock_file_fd);
@@ reftable/stack.c (new)
+ }
+ }
+
-+ subtable_locks[j] = (char *)slice_as_string(&subtab_lock);
-+ delete_on_success[j] =
-+ (char *)slice_as_string(&subtab_file_name);
++ subtable_locks[j] = subtab_lock.buf;
++ delete_on_success[j] = subtab_file_name.buf;
+ j++;
+
+ if (err != 0)
+ goto done;
+ }
+
-+ err = unlink(slice_as_string(&lock_file_name));
++ err = unlink(lock_file_name.buf);
+ if (err < 0)
+ goto done;
+ have_lock = false;
@@ reftable/stack.c (new)
+ if (err < 0)
+ goto done;
+
-+ lock_file_fd = open(slice_as_string(&lock_file_name),
-+ O_EXCL | O_CREAT | O_WRONLY, 0644);
++ lock_file_fd =
++ open(lock_file_name.buf, O_EXCL | O_CREAT | O_WRONLY, 0644);
+ if (lock_file_fd < 0) {
+ if (errno == EEXIST) {
+ err = 1;
@@ reftable/stack.c (new)
+
+ format_name(&new_table_name, st->merged->stack[first]->min_update_index,
+ st->merged->stack[last]->max_update_index);
-+ slice_addstr(&new_table_name, ".ref");
++ strbuf_addstr(&new_table_name, ".ref");
+
-+ slice_reset(&new_table_path);
-+ slice_addstr(&new_table_path, st->reftable_dir);
-+ slice_addstr(&new_table_path, "/");
-+ slice_addbuf(&new_table_path, &new_table_name);
++ strbuf_reset(&new_table_path);
++ strbuf_addstr(&new_table_path, st->reftable_dir);
++ strbuf_addstr(&new_table_path, "/");
++ strbuf_addbuf(&new_table_path, &new_table_name);
+
+ if (!is_empty_table) {
-+ err = rename(slice_as_string(&temp_tab_file_name),
-+ slice_as_string(&new_table_path));
++ err = rename(temp_tab_file_name.buf, new_table_path.buf);
+ if (err < 0) {
+ err = REFTABLE_IO_ERROR;
+ goto done;
@@ reftable/stack.c (new)
+ }
+
+ for (i = 0; i < first; i++) {
-+ slice_addstr(&ref_list_contents, st->merged->stack[i]->name);
-+ slice_addstr(&ref_list_contents, "\n");
++ strbuf_addstr(&ref_list_contents, st->merged->stack[i]->name);
++ strbuf_addstr(&ref_list_contents, "\n");
+ }
+ if (!is_empty_table) {
-+ slice_addbuf(&ref_list_contents, &new_table_name);
-+ slice_addstr(&ref_list_contents, "\n");
++ strbuf_addbuf(&ref_list_contents, &new_table_name);
++ strbuf_addstr(&ref_list_contents, "\n");
+ }
+ for (i = last + 1; i < st->merged->stack_len; i++) {
-+ slice_addstr(&ref_list_contents, st->merged->stack[i]->name);
-+ slice_addstr(&ref_list_contents, "\n");
++ strbuf_addstr(&ref_list_contents, st->merged->stack[i]->name);
++ strbuf_addstr(&ref_list_contents, "\n");
+ }
+
+ 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));
++ unlink(new_table_path.buf);
+ goto done;
+ }
+ err = close(lock_file_fd);
+ lock_file_fd = 0;
+ if (err < 0) {
+ err = REFTABLE_IO_ERROR;
-+ unlink(slice_as_string(&new_table_path));
++ unlink(new_table_path.buf);
+ goto done;
+ }
+
-+ err = rename(slice_as_string(&lock_file_name), st->list_file);
++ err = rename(lock_file_name.buf, st->list_file);
+ if (err < 0) {
+ err = REFTABLE_IO_ERROR;
-+ unlink(slice_as_string(&new_table_path));
++ unlink(new_table_path.buf);
+ goto done;
+ }
+ have_lock = false;
@@ reftable/stack.c (new)
+
+ listp = delete_on_success;
+ while (*listp) {
-+ if (strcmp(*listp, slice_as_string(&new_table_path))) {
++ if (strcmp(*listp, new_table_path.buf)) {
+ unlink(*listp);
+ }
+ listp++;
@@ reftable/stack.c (new)
+ lock_file_fd = 0;
+ }
+ if (have_lock) {
-+ unlink(slice_as_string(&lock_file_name));
++ unlink(lock_file_name.buf);
+ }
-+ slice_release(&new_table_name);
-+ slice_release(&new_table_path);
-+ slice_release(&ref_list_contents);
-+ slice_release(&temp_tab_file_name);
-+ slice_release(&lock_file_name);
++ strbuf_release(&new_table_name);
++ strbuf_release(&new_table_path);
++ strbuf_release(&ref_list_contents);
++ strbuf_release(&temp_tab_file_name);
++ strbuf_release(&lock_file_name);
+ return err;
+}
+
@@ reftable/stack_test.c (new)
+ struct reftable_stack *st = NULL;
+ char dir[256] = "/tmp/stack_test.XXXXXX";
+
-+ byte h1[SHA1_SIZE] = { 0x01 }, h2[SHA1_SIZE] = { 0x02 };
++ uint8_t h1[SHA1_SIZE] = { 0x01 }, h2[SHA1_SIZE] = { 0x02 };
+
+ struct reftable_log_record input = {
+ .ref_name = "branch",
@@ reftable/stack_test.c (new)
+ add_test_case("test_names_equal", &test_names_equal);
+ add_test_case("test_reftable_stack_add", &test_reftable_stack_add);
+ return test_main(argc, argv);
++}
+
+ ## reftable/strbuf.c (new) ##
+@@
++/*
++Copyright 2020 Google LLC
++
++Use of this source code is governed by a BSD-style
++license that can be found in the LICENSE file or at
++https://developers.google.com/open-source/licenses/bsd
++*/
++
++#include "strbuf.h"
++
++#include "system.h"
++#include "reftable.h"
++#include "basics.h"
++
++#ifdef REFTABLE_STANDALONE
++
++void strbuf_init(struct strbuf *s, size_t alloc)
++{
++ struct strbuf empty = STRBUF_INIT;
++ *s = empty;
++}
++
++void strbuf_grow(struct strbuf *s, size_t extra)
++{
++ size_t newcap = s->len + extra + 1;
++ if (newcap > s->cap) {
++ s->buf = reftable_realloc(s->buf, newcap);
++ s->cap = newcap;
++ }
++}
++
++static void strbuf_resize(struct strbuf *s, int l)
++{
++ int zl = l + 1; /* one uint8_t for 0 termination. */
++ assert(s->canary == STRBUF_CANARY);
++ if (s->cap < zl) {
++ int c = s->cap * 2;
++ if (c < zl) {
++ c = zl;
++ }
++ s->cap = c;
++ s->buf = reftable_realloc(s->buf, s->cap);
++ }
++ s->len = l;
++ s->buf[l] = 0;
++}
++
++void strbuf_setlen(struct strbuf *s, size_t l)
++{
++ assert(s->cap >= l + 1);
++ s->len = l;
++ s->buf[l] = 0;
++}
++
++void strbuf_reset(struct strbuf *s)
++{
++ strbuf_resize(s, 0);
++}
++
++void strbuf_addstr(struct strbuf *d, const char *s)
++{
++ int l1 = d->len;
++ int l2 = strlen(s);
++ assert(d->canary == STRBUF_CANARY);
++
++ strbuf_resize(d, l2 + l1);
++ memcpy(d->buf + l1, s, l2);
++}
++
++void strbuf_addbuf(struct strbuf *s, struct strbuf *a)
++{
++ int end = s->len;
++ assert(s->canary == STRBUF_CANARY);
++ strbuf_resize(s, s->len + a->len);
++ memcpy(s->buf + end, a->buf, a->len);
++}
++
++char *strbuf_detach(struct strbuf *s, size_t *sz)
++{
++ char *p = NULL;
++ p = (char *)s->buf;
++ if (sz)
++ *sz = s->len;
++ s->buf = NULL;
++ s->cap = 0;
++ s->len = 0;
++ return p;
++}
++
++void strbuf_release(struct strbuf *s)
++{
++ assert(s->canary == STRBUF_CANARY);
++ s->cap = 0;
++ s->len = 0;
++ reftable_free(s->buf);
++ s->buf = NULL;
++}
++
++int strbuf_cmp(const struct strbuf *a, const struct strbuf *b)
++{
++ int min = a->len < b->len ? a->len : b->len;
++ int res = memcmp(a->buf, b->buf, min);
++ assert(a->canary == STRBUF_CANARY);
++ assert(b->canary == STRBUF_CANARY);
++ if (res != 0)
++ return res;
++ if (a->len < b->len)
++ return -1;
++ else if (a->len > b->len)
++ return 1;
++ else
++ return 0;
++}
++
++int strbuf_add(struct strbuf *b, const void *data, size_t sz)
++{
++ assert(b->canary == STRBUF_CANARY);
++ strbuf_grow(b, sz);
++ memcpy(b->buf + b->len, data, sz);
++ b->len += sz;
++ b->buf[b->len] = 0;
++ return sz;
++}
++
++#endif
++
++static uint64_t strbuf_size(void *b)
++{
++ return ((struct strbuf *)b)->len;
++}
++
++int strbuf_add_void(void *b, const void *data, size_t sz)
++{
++ strbuf_add((struct strbuf *)b, data, sz);
++ return sz;
++}
++
++static void strbuf_return_block(void *b, struct reftable_block *dest)
++{
++ memset(dest->data, 0xff, dest->len);
++ reftable_free(dest->data);
++}
++
++static void strbuf_close(void *b)
++{
++}
++
++static int strbuf_read_block(void *v, struct reftable_block *dest, uint64_t off,
++ uint32_t size)
++{
++ struct strbuf *b = (struct strbuf *)v;
++ assert(off + size <= b->len);
++ dest->data = reftable_calloc(size);
++ memcpy(dest->data, b->buf + off, size);
++ dest->len = size;
++ return size;
++}
++
++struct reftable_block_source_vtable strbuf_vtable = {
++ .size = &strbuf_size,
++ .read_block = &strbuf_read_block,
++ .return_block = &strbuf_return_block,
++ .close = &strbuf_close,
++};
++
++void block_source_from_strbuf(struct reftable_block_source *bs,
++ struct strbuf *buf)
++{
++ assert(bs->ops == NULL);
++ bs->ops = &strbuf_vtable;
++ bs->arg = buf;
++}
++
++static void malloc_return_block(void *b, struct reftable_block *dest)
++{
++ memset(dest->data, 0xff, dest->len);
++ reftable_free(dest->data);
++}
++
++struct reftable_block_source_vtable malloc_vtable = {
++ .return_block = &malloc_return_block,
++};
++
++struct reftable_block_source malloc_block_source_instance = {
++ .ops = &malloc_vtable,
++};
++
++struct reftable_block_source malloc_block_source(void)
++{
++ return malloc_block_source_instance;
++}
++
++int common_prefix_size(struct strbuf *a, struct strbuf *b)
++{
++ int p = 0;
++ while (p < a->len && p < b->len) {
++ if (a->buf[p] != b->buf[p]) {
++ break;
++ }
++ p++;
++ }
++
++ return p;
++}
++
++struct strbuf reftable_empty_strbuf = STRBUF_INIT;
+
+ ## reftable/strbuf.h (new) ##
+@@
++/*
++Copyright 2020 Google LLC
++
++Use of this source code is governed by a BSD-style
++license that can be found in the LICENSE file or at
++https://developers.google.com/open-source/licenses/bsd
++*/
++
++#ifndef SLICE_H
++#define SLICE_H
++
++#ifdef REFTABLE_STANDALONE
++
++#include "basics.h"
++#include "reftable.h"
++
++/*
++ Provides a bounds-checked, growable byte ranges. To use, initialize as "strbuf
++ x = STRBUF_INIT;"
++ */
++struct strbuf {
++ int len;
++ int cap;
++ char *buf;
++
++ /* Used to enforce initialization with STRBUF_INIT */
++ uint8_t canary;
++};
++#define STRBUF_CANARY 0x42
++#define STRBUF_INIT \
++ { \
++ 0, 0, NULL, STRBUF_CANARY \
++ }
++
++void strbuf_addstr(struct strbuf *dest, const char *src);
++
++/* Deallocate and clear strbuf */
++void strbuf_release(struct strbuf *strbuf);
++
++/* Set strbuf to 0 length, but retain buffer. */
++void strbuf_reset(struct strbuf *strbuf);
++
++/* Initializes a strbuf. Accepts a strbuf with random garbage. */
++void strbuf_init(struct strbuf *strbuf, size_t alloc);
++
++/* Return `buf`, clearing out `s`. Optionally return len (not cap) in `sz`. */
++char *strbuf_detach(struct strbuf *s, size_t *sz);
++
++/* Set length of the slace to `l`, but don't reallocated. */
++void strbuf_setlen(struct strbuf *s, size_t l);
++
++/* Ensure `l` bytes beyond current length are available */
++void strbuf_grow(struct strbuf *s, size_t l);
++
++/* Signed comparison */
++int strbuf_cmp(const struct strbuf *a, const struct strbuf *b);
++
++/* Append `data` to the `dest` strbuf. */
++int strbuf_add(struct strbuf *dest, const void *data, size_t sz);
++
++/* Append `add` to `dest. */
++void strbuf_addbuf(struct strbuf *dest, struct strbuf *add);
++
++#else
++
++#include "../git-compat-util.h"
++#include "../strbuf.h"
++
++#endif
++
++extern struct strbuf reftable_empty_strbuf;
++
++/* Like strbuf_add, but suitable for passing to reftable_new_writer
++ */
++int strbuf_add_void(void *b, const void *data, size_t sz);
++
++/* Find the longest shared prefix size of `a` and `b` */
++int common_prefix_size(struct strbuf *a, struct strbuf *b);
++
++struct reftable_block_source;
++
++/* Create an in-memory block source for reading reftables */
++void block_source_from_strbuf(struct reftable_block_source *bs,
++ struct strbuf *buf);
++
++struct reftable_block_source malloc_block_source(void);
++
++#endif
+
+ ## reftable/strbuf_test.c (new) ##
+@@
++/*
++Copyright 2020 Google LLC
++
++Use of this source code is governed by a BSD-style
++license that can be found in the LICENSE file or at
++https://developers.google.com/open-source/licenses/bsd
++*/
++
++#include "strbuf.h"
++
++#include "system.h"
++
++#include "basics.h"
++#include "record.h"
++#include "reftable.h"
++#include "test_framework.h"
++#include "reftable-tests.h"
++
++static void test_strbuf(void)
++{
++ struct strbuf s = STRBUF_INIT;
++ struct strbuf t = STRBUF_INIT;
++
++ strbuf_addstr(&s, "abc");
++ assert(0 == strcmp("abc", s.buf));
++
++ strbuf_addstr(&t, "pqr");
++ strbuf_addbuf(&s, &t);
++ assert(0 == strcmp("abcpqr", s.buf));
++
++ strbuf_release(&s);
++ strbuf_release(&t);
++}
++
++int strbuf_test_main(int argc, const char *argv[])
++{
++ add_test_case("test_strbuf", &test_strbuf);
++ return test_main(argc, argv);
+}
## reftable/system.h (new) ##
@@ reftable/system.h (new)
+#ifndef SYSTEM_H
+#define SYSTEM_H
+
-+#if 1 /* REFTABLE_IN_GITCORE */
-+#define REFTABLE_IN_GITCORE
++#ifndef REFTABLE_STANDALONE
+
+#include "git-compat-util.h"
+#include "cache.h"
@@ reftable/system.h (new)
+
+#include "compat.h"
+
-+#endif /* REFTABLE_IN_GITCORE */
++#endif /* REFTABLE_STANDALONE */
+
+void reftable_clear_dir(const char *dirname);
+
@@ reftable/system.h (new)
+#define SHA1_SIZE 20
+#define SHA256_SIZE 32
+
-+typedef uint8_t byte;
+typedef int bool;
+
+/* This is uncompress2, which is only available in zlib as of 2017.
@@ reftable/test_framework.c (new)
+ return 0;
+}
+
-+void set_test_hash(byte *p, int i)
++void set_test_hash(uint8_t *p, int i)
+{
-+ memset(p, (byte)i, hash_size(SHA1_ID));
++ memset(p, (uint8_t)i, hash_size(SHA1_ID));
+}
## reftable/test_framework.h (new) ##
@@ reftable/test_framework.h (new)
+struct test_case *add_test_case(const char *name, void (*testfunc)(void));
+int test_main(int argc, const char *argv[]);
+
-+void set_test_hash(byte *p, int i);
++void set_test_hash(uint8_t *p, int i);
+
+#endif
@@ reftable/writer.c (new)
+#include "tree.h"
+
+static struct reftable_block_stats *
-+writer_reftable_block_stats(struct reftable_writer *w, byte typ)
++writer_reftable_block_stats(struct reftable_writer *w, uint8_t typ)
+{
+ switch (typ) {
+ case 'r':
@@ reftable/writer.c (new)
+
+/* write data, queuing the padding for the next write. Returns negative for
+ * error. */
-+static int padded_write(struct reftable_writer *w, byte *data, size_t len,
++static int padded_write(struct reftable_writer *w, uint8_t *data, size_t len,
+ int padding)
+{
+ int n = 0;
+ if (w->pending_padding > 0) {
-+ byte *zeroed = reftable_calloc(w->pending_padding);
++ uint8_t *zeroed = reftable_calloc(w->pending_padding);
+ int n = w->write(w->write_arg, zeroed, w->pending_padding);
+ if (n < 0)
+ return n;
@@ reftable/writer.c (new)
+ return (w->opts.hash_id == 0 || w->opts.hash_id == SHA1_ID) ? 1 : 2;
+}
+
-+static int writer_write_header(struct reftable_writer *w, byte *dest)
++static int writer_write_header(struct reftable_writer *w, uint8_t *dest)
+{
+ memcpy((char *)dest, "REFT", 4);
+
@@ reftable/writer.c (new)
+ return header_size(writer_version(w));
+}
+
-+static void writer_reinit_block_writer(struct reftable_writer *w, byte typ)
++static void writer_reinit_block_writer(struct reftable_writer *w, uint8_t typ)
+{
+ int block_start = 0;
+ if (w->next == 0) {
+ block_start = header_size(writer_version(w));
+ }
+
-+ slice_release(&w->last_key);
++ strbuf_release(&w->last_key);
+ block_writer_init(&w->block_writer_data, typ, w->block,
+ w->opts.block_size, block_start,
+ hash_size(w->opts.hash_id));
@@ reftable/writer.c (new)
+}
+
+struct reftable_writer *
-+reftable_new_writer(int (*writer_func)(void *, byte *, size_t),
++reftable_new_writer(int (*writer_func)(void *, const void *, size_t),
+ void *writer_arg, struct reftable_write_options *opts)
+{
+ struct reftable_writer *wp =
+ reftable_calloc(sizeof(struct reftable_writer));
-+ slice_init(&wp->block_writer_data.last_key);
++ strbuf_init(&wp->block_writer_data.last_key, 0);
+ options_set_defaults(opts);
+ if (opts->block_size >= (1 << 24)) {
+ /* TODO - error return? */
+ abort();
+ }
-+ wp->last_key = reftable_empty_slice;
++ wp->last_key = reftable_empty_strbuf;
+ wp->block = reftable_calloc(opts->block_size);
+ wp->write = writer_func;
+ wp->write_arg = writer_arg;
@@ reftable/writer.c (new)
+}
+
+struct obj_index_tree_node {
-+ struct slice hash;
++ struct strbuf hash;
+ uint64_t *offsets;
+ int offset_len;
+ int offset_cap;
+};
-+#define OBJ_INDEX_TREE_NODE_INIT \
-+ { \
-+ .hash = SLICE_INIT \
++#define OBJ_INDEX_TREE_NODE_INIT \
++ { \
++ .hash = STRBUF_INIT \
+ }
+
+static int obj_index_tree_node_compare(const void *a, const void *b)
+{
-+ return slice_cmp(&((const struct obj_index_tree_node *)a)->hash,
-+ &((const struct obj_index_tree_node *)b)->hash);
++ return strbuf_cmp(&((const struct obj_index_tree_node *)a)->hash,
++ &((const struct obj_index_tree_node *)b)->hash);
+}
+
-+static void writer_index_hash(struct reftable_writer *w, struct slice *hash)
++static void writer_index_hash(struct reftable_writer *w, struct strbuf *hash)
+{
+ uint64_t off = w->next;
+
@@ reftable/writer.c (new)
+ key = reftable_malloc(sizeof(struct obj_index_tree_node));
+ *key = empty;
+
-+ slice_reset(&key->hash);
-+ slice_addbuf(&key->hash, hash);
++ strbuf_reset(&key->hash);
++ strbuf_addbuf(&key->hash, hash);
+ tree_search((void *)key, &w->obj_index_tree,
+ &obj_index_tree_node_compare, 1);
+ } else {
@@ reftable/writer.c (new)
+ struct reftable_record *rec)
+{
+ int result = -1;
-+ struct slice key = SLICE_INIT;
++ struct strbuf key = STRBUF_INIT;
+ int err = 0;
+ reftable_record_key(rec, &key);
-+ if (slice_cmp(&w->last_key, &key) >= 0)
++ if (strbuf_cmp(&w->last_key, &key) >= 0)
+ goto done;
+
-+ slice_reset(&w->last_key);
-+ slice_addbuf(&w->last_key, &key);
++ strbuf_reset(&w->last_key);
++ strbuf_addbuf(&w->last_key, &key);
+ if (w->block_writer == NULL) {
+ writer_reinit_block_writer(w, reftable_record_type(rec));
+ }
@@ reftable/writer.c (new)
+
+ result = 0;
+done:
-+ slice_release(&key);
++ strbuf_release(&key);
+ return result;
+}
+
@@ reftable/writer.c (new)
+ return err;
+
+ if (!w->opts.skip_index_objects && ref->value != NULL) {
-+ struct slice h = SLICE_INIT;
-+ slice_add(&h, ref->value, hash_size(w->opts.hash_id));
++ struct strbuf h = STRBUF_INIT;
++ strbuf_add(&h, (char *)ref->value, hash_size(w->opts.hash_id));
+ writer_index_hash(w, &h);
-+ slice_release(&h);
++ strbuf_release(&h);
+ }
+
+ if (!w->opts.skip_index_objects && ref->target_value != NULL) {
-+ struct slice h = SLICE_INIT;
-+ slice_add(&h, ref->target_value, hash_size(w->opts.hash_id));
++ struct strbuf h = STRBUF_INIT;
++ strbuf_add(&h, ref->target_value, hash_size(w->opts.hash_id));
+ writer_index_hash(w, &h);
+ }
+ return 0;
@@ reftable/writer.c (new)
+{
+ struct reftable_record rec = { 0 };
+ char *input_log_message = log->message;
-+ struct slice cleaned_message = SLICE_INIT;
++ struct strbuf cleaned_message = STRBUF_INIT;
+ int err;
+ if (log->ref_name == NULL)
+ return REFTABLE_API_ERROR;
@@ reftable/writer.c (new)
+ }
+
+ if (!w->opts.exact_log_message && log->message != NULL) {
-+ slice_addstr(&cleaned_message, log->message);
++ strbuf_addstr(&cleaned_message, log->message);
+ while (cleaned_message.len &&
+ cleaned_message.buf[cleaned_message.len - 1] == '\n')
-+ slice_setlen(&cleaned_message, cleaned_message.len - 1);
-+ if (strchr(slice_as_string(&cleaned_message), '\n')) {
++ strbuf_setlen(&cleaned_message,
++ cleaned_message.len - 1);
++ if (strchr(cleaned_message.buf, '\n')) {
+ // multiple lines not allowed.
+ err = REFTABLE_API_ERROR;
+ goto done;
+ }
-+ slice_addstr(&cleaned_message, "\n");
-+ log->message = (char *)slice_as_string(&cleaned_message);
++ strbuf_addstr(&cleaned_message, "\n");
++ log->message = cleaned_message.buf;
+ }
+
+ w->next -= w->pending_padding;
@@ reftable/writer.c (new)
+
+done:
+ log->message = input_log_message;
-+ slice_release(&cleaned_message);
++ strbuf_release(&cleaned_message);
+ return err;
+}
+
@@ reftable/writer.c (new)
+
+static int writer_finish_section(struct reftable_writer *w)
+{
-+ byte typ = block_writer_type(w->block_writer);
++ uint8_t typ = block_writer_type(w->block_writer);
+ uint64_t index_start = 0;
+ int max_level = 0;
+ int threshold = w->opts.unpadded ? 1 : 3;
@@ reftable/writer.c (new)
+ }
+ }
+ for (i = 0; i < idx_len; i++) {
-+ slice_release(&idx[i].last_key);
++ strbuf_release(&idx[i].last_key);
+ }
+ reftable_free(idx);
+ }
@@ reftable/writer.c (new)
+}
+
+struct common_prefix_arg {
-+ struct slice *last;
++ struct strbuf *last;
+ int max;
+};
+
@@ reftable/writer.c (new)
+ struct write_record_arg *arg = (struct write_record_arg *)void_arg;
+ struct obj_index_tree_node *entry = (struct obj_index_tree_node *)key;
+ struct reftable_obj_record obj_rec = {
-+ .hash_prefix = entry->hash.buf,
++ .hash_prefix = (uint8_t *)entry->hash.buf,
+ .hash_prefix_len = arg->w->stats.object_id_len,
+ .offsets = entry->offsets,
+ .offset_len = entry->offset_len,
@@ reftable/writer.c (new)
+ struct obj_index_tree_node *entry = (struct obj_index_tree_node *)key;
+
+ FREE_AND_NULL(entry->offsets);
-+ slice_release(&entry->hash);
++ strbuf_release(&entry->hash);
+ reftable_free(entry);
+}
+
@@ reftable/writer.c (new)
+
+int writer_finish_public_section(struct reftable_writer *w)
+{
-+ byte typ = 0;
++ uint8_t typ = 0;
+ int err = 0;
+
+ if (w->block_writer == NULL)
@@ reftable/writer.c (new)
+
+int reftable_writer_close(struct reftable_writer *w)
+{
-+ byte footer[72];
-+ byte *p = footer;
++ uint8_t footer[72];
++ uint8_t *p = footer;
+ int err = writer_finish_public_section(w);
+ int empty_table = w->next == 0;
+ if (err != 0)
@@ reftable/writer.c (new)
+ w->pending_padding = 0;
+ if (empty_table) {
+ /* Empty tables need a header anyway. */
-+ byte header[28];
++ uint8_t header[28];
+ int n = writer_write_header(w, header);
+ err = padded_write(w, header, n, 0);
+ if (err < 0)
@@ reftable/writer.c (new)
+ /* free up memory. */
+ block_writer_clear(&w->block_writer_data);
+ writer_clear_index(w);
-+ slice_release(&w->last_key);
++ strbuf_release(&w->last_key);
+ return err;
+}
+
@@ reftable/writer.c (new)
+{
+ int i = 0;
+ for (i = 0; i < w->index_len; i++) {
-+ slice_release(&w->index[i].last_key);
++ strbuf_release(&w->index[i].last_key);
+ }
+
+ FREE_AND_NULL(w->index);
@@ reftable/writer.c (new)
+
+static int writer_flush_nonempty_block(struct reftable_writer *w)
+{
-+ byte typ = block_writer_type(w->block_writer);
++ uint8_t typ = block_writer_type(w->block_writer);
+ struct reftable_block_stats *bstats =
+ writer_reftable_block_stats(w, typ);
+ uint64_t block_typ_off = (bstats->blocks == 0) ? w->next : 0;
+ int raw_bytes = block_writer_finish(w->block_writer);
+ int padding = 0;
+ int err = 0;
-+ struct reftable_index_record ir = { .last_key = SLICE_INIT };
++ struct reftable_index_record ir = { .last_key = STRBUF_INIT };
+ if (raw_bytes < 0)
+ return raw_bytes;
+
@@ reftable/writer.c (new)
+ }
+
+ ir.offset = w->next;
-+ slice_reset(&ir.last_key);
-+ slice_addbuf(&ir.last_key, &w->block_writer->last_key);
++ strbuf_reset(&ir.last_key);
++ strbuf_addbuf(&ir.last_key, &w->block_writer->last_key);
+ w->index[w->index_len] = ir;
+
+ w->index_len++;
@@ reftable/writer.h (new)
+#include "basics.h"
+#include "block.h"
+#include "reftable.h"
-+#include "slice.h"
++#include "strbuf.h"
+#include "tree.h"
+
+struct reftable_writer {
-+ int (*write)(void *, byte *, size_t);
++ int (*write)(void *, const void *, size_t);
+ void *write_arg;
+ int pending_padding;
-+ struct slice last_key;
++ struct strbuf last_key;
+
+ /* offset of next block to write. */
+ uint64_t next;
@@ reftable/writer.h (new)
+ struct reftable_write_options opts;
+
+ /* memory buffer for writing */
-+ byte *block;
++ uint8_t *block;
+
+ /* writer for the current section. NULL or points to
+ * block_writer_data */
-: ----------- > 12: c92b8d12ec6 Add standalone build infrastructure for reftable
12: e1b01927454 ! 13: 479fe884e98 Reftable support for git-core
@@ Commit message
It can be activated by passing --ref-storage=reftable to "git init".
- TODO:
-
- * Fix worktree commands
-
- * Spots marked XXX
-
Example use: see t/t0031-reftable.sh
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
@@ Makefile: VCSSVN_OBJS += vcs-svn/sliding_window.o
+REFTABLE_OBJS += reftable/record.o
+REFTABLE_OBJS += reftable/refname.o
+REFTABLE_OBJS += reftable/reftable.o
-+REFTABLE_OBJS += reftable/slice.o
++REFTABLE_OBJS += reftable/strbuf.o
+REFTABLE_OBJS += reftable/stack.o
+REFTABLE_OBJS += reftable/tree.o
+REFTABLE_OBJS += reftable/writer.o
@@ 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, INIT_DB_QUIET);
++ default_ref_storage(), INIT_DB_QUIET);
if (real_git_dir)
git_dir = real_git_dir;
@@ cache.h: int path_inside_repo(const char *prefix, const char *path);
void sanitize_stdfds(void);
int daemonize(void);
@@ cache.h: struct repository_format {
- int is_bare;
int hash_algo;
+ int has_extensions;
char *work_tree;
+ char *ref_storage;
struct string_list unknown_extensions;
@@ refs.c: struct ref_store *get_main_ref_store(struct repository *r)
+ r->refs_private = ref_store_init(r->gitdir,
+ r->ref_storage_format ?
+ r->ref_storage_format :
-+ DEFAULT_REF_STORAGE,
++ default_ref_storage(),
+ REF_STORE_ALL_CAPS);
return r->refs_private;
}
@@ refs.c: struct ref_store *get_submodule_ref_store(const char *submodule)
/* assume that add_submodule_odb() has been called */
- refs = ref_store_init(submodule_sb.buf,
-+ refs = ref_store_init(submodule_sb.buf, DEFAULT_REF_STORAGE, /* XXX */
++ refs = ref_store_init(submodule_sb.buf, default_ref_storage(),
REF_STORE_READ | REF_STORE_ODB);
register_ref_store_map(&submodule_ref_stores, "submodule",
refs, submodule);
@@ refs.c: struct ref_store *get_submodule_ref_store(const char *submodule)
struct ref_store *get_worktree_ref_store(const struct worktree *wt)
{
-+ const char *format = DEFAULT_REF_STORAGE; /* XXX */
++ const char *format = default_ref_storage();
struct ref_store *refs;
const char *id;
@@ refs/reftable-backend.c (new)
+ safe_create_dir(refs->reftable_dir, 1);
+
+ strbuf_addf(&sb, "%s/HEAD", refs->repo_dir);
-+ write_file(sb.buf, "ref: refs/.invalid");
++ write_file(sb.buf, "ref: refs/heads/.invalid");
+ strbuf_reset(&sb);
+
+ strbuf_addf(&sb, "%s/refs", refs->repo_dir);
@@ refs/reftable-backend.c (new)
+ return refs->err;
+ }
+
++ /* This is usually not needed, but Git doesn't signal to ref backend if
++ a subprocess updated the ref DB. So we always check.
++ */
++ err = reftable_stack_reload(refs->stack);
++ if (err) {
++ goto done;
++ }
++
+ err = reftable_stack_read_ref(refs->stack, refname, &ref);
+ if (err > 0) {
+ errno = ENOENT;
@@ refs/reftable-backend.c (new)
+ reftable_reflog_expire,
+};
+ ## reftable/update.sh ##
+@@ reftable/update.sh: cp reftable-repo/LICENSE reftable/
+ git --git-dir reftable-repo/.git show --no-patch --format=oneline HEAD \
+ > 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
+-
+ git add reftable/*.[ch] reftable/LICENSE reftable/VERSION
+
## repository.c ##
@@ repository.c: int repo_init(struct repository *repo,
if (worktree)
@@ 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 &&
+ git pack-refs &&
+ ls -1 .git/reftable >table-files &&
@@ t/t0031-reftable.sh (new)
+ git branch source &&
+ git checkout HEAD^ &&
+ test_commit message3 file3 &&
-+ git rebase source &&
++ git rebase source &&
+ test -f file2
+'
+
13: 0359fe416fa ! 14: eafd8eeefcc Hookup unittests for the reftable library.
@@ Makefile: REFTABLE_OBJS += reftable/tree.o
+REFTABLE_TEST_OBJS += reftable/record_test.o
+REFTABLE_TEST_OBJS += reftable/refname_test.o
+REFTABLE_TEST_OBJS += reftable/reftable_test.o
-+REFTABLE_TEST_OBJS += reftable/slice_test.o
++REFTABLE_TEST_OBJS += reftable/strbuf_test.o
+REFTABLE_TEST_OBJS += reftable/stack_test.o
+REFTABLE_TEST_OBJS += reftable/tree_test.o
+REFTABLE_TEST_OBJS += reftable/test_framework.o
@@ t/helper/test-reftable.c (new)
+ record_test_main(argc, argv);
+ refname_test_main(argc, argv);
+ reftable_test_main(argc, argv);
-+ slice_test_main(argc, argv);
++ strbuf_test_main(argc, argv);
+ stack_test_main(argc, argv);
+ tree_test_main(argc, argv);
+ return 0;
14: 88640ea13f9 ! 15: 46af142f33b Add GIT_DEBUG_REFS debugging mechanism
@@ Makefile: LIB_OBJS += rebase.o
## refs.c ##
@@ refs.c: struct ref_store *get_main_ref_store(struct repository *r)
r->ref_storage_format :
- DEFAULT_REF_STORAGE,
+ default_ref_storage(),
REF_STORE_ALL_CAPS);
+ if (getenv("GIT_DEBUG_REFS")) {
+ r->refs_private = debug_wrap(r->refs_private);
@@ refs/debug.c (new)
+{
+ struct debug_ref_store *drefs = (struct debug_ref_store *)refs;
+ int res = drefs->refs->be->init_db(drefs->refs, err);
++ fprintf(stderr, "init_db: %d\n", res);
+ return res;
+}
+
@@ refs/debug.c (new)
+ transaction->ref_store = drefs->refs;
+ res = drefs->refs->be->transaction_prepare(drefs->refs, transaction,
+ err);
++ fprintf(stderr, "transaction_prepare: %d\n", res);
+ return res;
+}
+
@@ refs/debug.c (new)
+ type &= 0xf; /* see refs.h REF_* */
+ flags &= REF_HAVE_NEW | REF_HAVE_OLD | REF_NO_DEREF |
+ REF_FORCE_CREATE_REFLOG | REF_LOG_ONLY;
-+ printf("%d: %s %s -> %s (F=0x%x, T=0x%x) \"%s\"\n", i, refname, o, n,
-+ flags, type, msg);
++ fprintf(stderr, "%d: %s %s -> %s (F=0x%x, T=0x%x) \"%s\"\n", i, refname,
++ o, n, flags, type, msg);
+}
+
+static void print_transaction(struct ref_transaction *transaction)
+{
-+ printf("transaction {\n");
++ fprintf(stderr, "transaction {\n");
+ for (int i = 0; i < transaction->nr; i++) {
+ struct ref_update *u = transaction->updates[i];
+ print_update(i, u->refname, &u->old_oid, &u->new_oid, u->flags,
+ u->type, u->msg);
+ }
-+ printf("}\n");
++ fprintf(stderr, "}\n");
+}
+
+static int debug_transaction_finish(struct ref_store *refs,
@@ refs/debug.c (new)
+ res = drefs->refs->be->transaction_finish(drefs->refs, transaction,
+ err);
+ print_transaction(transaction);
-+ printf("finish: %d\n", res);
++ fprintf(stderr, "finish: %d\n", res);
+ return res;
+}
+
@@ refs/debug.c (new)
+{
+ struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
+ int res = drefs->refs->be->pack_refs(drefs->refs, flags);
++ fprintf(stderr, "pack_refs: %d\n", res);
+ return res;
+}
+
@@ refs/debug.c (new)
+ struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
+ int res = drefs->refs->be->create_symref(drefs->refs, ref_name, target,
+ logmsg);
-+ printf("create_symref: %s -> %s \"%s\": %d\n", ref_name, target, logmsg,
-+ res);
++ fprintf(stderr, "create_symref: %s -> %s \"%s\": %d\n", ref_name,
++ target, logmsg, res);
+ return res;
+}
+
@@ refs/debug.c (new)
+ struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
+ int res = drefs->refs->be->rename_ref(drefs->refs, oldref, newref,
+ logmsg);
-+ printf("rename_ref: %s -> %s \"%s\": %d\n", oldref, newref, logmsg,
-+ res);
++ fprintf(stderr, "rename_ref: %s -> %s \"%s\": %d\n", oldref, newref,
++ logmsg, res);
+ return res;
+}
+
@@ refs/debug.c (new)
+ struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
+ int res =
+ drefs->refs->be->copy_ref(drefs->refs, oldref, newref, logmsg);
-+ printf("copy_ref: %s -> %s \"%s\": %d\n", oldref, newref, logmsg, res);
++ fprintf(stderr, "copy_ref: %s -> %s \"%s\": %d\n", oldref, newref,
++ logmsg, res);
+ return res;
+}
+
@@ refs/debug.c (new)
+ oid_to_hex_r(o, oid);
+ if (old_oid)
+ oid_to_hex_r(n, old_oid);
-+ printf("write_pseudoref: %s, %s => %s, err %s: %d\n", pseudoref, o, n,
-+ err->buf, res);
++ fprintf(stderr, "write_pseudoref: %s, %s => %s, err %s: %d\n",
++ pseudoref, o, n, err->buf, res);
+ return res;
+}
+
@@ refs/debug.c (new)
+ char hex[100] = "null";
+ if (old_oid)
+ oid_to_hex_r(hex, old_oid);
-+ printf("delete_pseudoref: %s (%s): %d\n", pseudoref, hex, res);
++ fprintf(stderr, "delete_pseudoref: %s (%s): %d\n", pseudoref, hex, res);
+ return res;
+}
+
++struct debug_ref_iterator {
++ struct ref_iterator base;
++ struct ref_iterator *iter;
++};
++
++static int debug_ref_iterator_advance(struct ref_iterator *ref_iterator)
++{
++ struct debug_ref_iterator *diter =
++ (struct debug_ref_iterator *)ref_iterator;
++ int res = diter->iter->vtable->advance(diter->iter);
++ fprintf(stderr, "iterator_advance: %s: %d\n", diter->iter->refname,
++ res);
++ diter->base.ordered = diter->iter->ordered;
++ diter->base.refname = diter->iter->refname;
++ diter->base.oid = diter->iter->oid;
++ diter->base.flags = diter->iter->flags;
++ return res;
++}
++static int debug_ref_iterator_peel(struct ref_iterator *ref_iterator,
++ struct object_id *peeled)
++{
++ struct debug_ref_iterator *diter =
++ (struct debug_ref_iterator *)ref_iterator;
++ int res = diter->iter->vtable->peel(diter->iter, peeled);
++ fprintf(stderr, "iterator_peel: %s: %d\n", diter->iter->refname, res);
++ return res;
++}
++
++static int debug_ref_iterator_abort(struct ref_iterator *ref_iterator)
++{
++ struct debug_ref_iterator *diter =
++ (struct debug_ref_iterator *)ref_iterator;
++ int res = diter->iter->vtable->abort(diter->iter);
++ fprintf(stderr, "iterator_abort: %d\n", res);
++ return res;
++}
++
++static struct ref_iterator_vtable debug_ref_iterator_vtable = {
++ debug_ref_iterator_advance, debug_ref_iterator_peel,
++ debug_ref_iterator_abort
++};
++
+static struct ref_iterator *
+debug_ref_iterator_begin(struct ref_store *ref_store, const char *prefix,
+ unsigned int flags)
@@ refs/debug.c (new)
+ struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
+ struct ref_iterator *res =
+ drefs->refs->be->iterator_begin(drefs->refs, prefix, flags);
-+ return res;
++ struct debug_ref_iterator *diter = xcalloc(1, sizeof(*diter));
++ base_ref_iterator_init(&diter->base, &debug_ref_iterator_vtable, 1);
++ diter->iter = res;
++ fprintf(stderr, "ref_iterator_begin: %s (0x%x)\n", prefix, flags);
++ return &diter->base;
+}
+
+static int debug_read_raw_ref(struct ref_store *ref_store, const char *refname,
@@ refs/debug.c (new)
+ type);
+
+ if (res == 0) {
-+ printf("read_raw_ref: %s: %s (=> %s) type %x: %d\n", refname,
-+ oid_to_hex(oid), referent->buf, *type, res);
++ fprintf(stderr, "read_raw_ref: %s: %s (=> %s) type %x: %d\n",
++ refname, oid_to_hex(oid), referent->buf, *type, res);
+ } else {
-+ printf("read_raw_ref: %s err %d\n", refname, res);
++ fprintf(stderr, "read_raw_ref: %s err %d\n", refname, res);
+ }
+ return res;
+}
@@ refs/debug.c (new)
+ struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
+ struct ref_iterator *res =
+ drefs->refs->be->reflog_iterator_begin(drefs->refs);
-+ printf("for_each_reflog_iterator_begin\n");
++ fprintf(stderr, "for_each_reflog_iterator_begin\n");
+ return res;
+}
+
@@ refs/debug.c (new)
+
+ ret = dbg->fn(old_oid, new_oid, committer, timestamp, tz, msg,
+ dbg->cb_data);
-+ printf("reflog_ent %s (ret %d): %s -> %s, %s %ld \"%s\"\n",
-+ dbg->refname, ret, o, n, committer, (long int)timestamp, msg);
++ fprintf(stderr, "reflog_ent %s (ret %d): %s -> %s, %s %ld \"%s\"\n",
++ dbg->refname, ret, o, n, committer, (long int)timestamp, msg);
+ return ret;
+}
+
@@ refs/debug.c (new)
+
+ int res = drefs->refs->be->for_each_reflog_ent(
+ drefs->refs, refname, &debug_print_reflog_ent, &dbg);
-+ printf("for_each_reflog: %s: %d\n", refname, res);
++ fprintf(stderr, "for_each_reflog: %s: %d\n", refname, res);
+ return res;
+}
+
@@ refs/debug.c (new)
+ };
+ int res = drefs->refs->be->for_each_reflog_ent_reverse(
+ drefs->refs, refname, &debug_print_reflog_ent, &dbg);
-+ printf("for_each_reflog_reverse: %s: %d\n", refname, res);
++ fprintf(stderr, "for_each_reflog_reverse: %s: %d\n", refname, res);
+ return res;
+}
+
@@ refs/debug.c (new)
+{
+ struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
+ int res = drefs->refs->be->reflog_exists(drefs->refs, refname);
-+ printf("reflog_exists: %s: %d\n", refname, res);
++ fprintf(stderr, "reflog_exists: %s: %d\n", refname, res);
+ return res;
+}
+
@@ refs/debug.c (new)
+ struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
+ int res = drefs->refs->be->create_reflog(drefs->refs, refname,
+ force_create, err);
++ fprintf(stderr, "create_reflog: %s: %d\n", refname, res);
+ return res;
+}
+
@@ refs/debug.c (new)
+{
+ struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
+ int res = drefs->refs->be->delete_reflog(drefs->refs, refname);
++ fprintf(stderr, "delete_reflog: %s: %d\n", refname, res);
+ return res;
+}
+
@@ refs/debug.c (new)
+ flags, prepare_fn,
+ should_prune_fn, cleanup_fn,
+ policy_cb_data);
++ fprintf(stderr, "reflog_expire: %s: %d\n", refname, res);
+ return res;
+}
+
15: 1c0cc646084 = 16: 5211c643104 vcxproj: adjust for the reftable changes
-: ----------- > 17: 9724854088c git-prompt: prepare for reftable refs backend
16: 4f24b5f73de ! 18: ece1fa1f625 Add reftable testing infrastructure
@@ Commit message
* Skip some tests that are incompatible:
* t3210-pack-refs.sh - does not apply
- * t9903-bash-prompt - The bash mode reads .git/HEAD directly
* t1450-fsck.sh - manipulates .git/ directly to create invalid state
Major test failures:
@@ Commit message
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
- ## builtin/clone.c ##
-@@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
- }
-
- init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN,
-- DEFAULT_REF_STORAGE, INIT_DB_QUIET);
-+ default_ref_storage(), INIT_DB_QUIET);
-
- if (real_git_dir)
- git_dir = real_git_dir;
-
- ## refs.c ##
-@@ refs.c: struct ref_store *get_main_ref_store(struct repository *r)
- r->refs_private = ref_store_init(r->gitdir,
- r->ref_storage_format ?
- r->ref_storage_format :
-- DEFAULT_REF_STORAGE,
-+ default_ref_storage(),
- REF_STORE_ALL_CAPS);
- if (getenv("GIT_DEBUG_REFS")) {
- r->refs_private = debug_wrap(r->refs_private);
-@@ refs.c: struct ref_store *get_submodule_ref_store(const char *submodule)
- goto done;
-
- /* assume that add_submodule_odb() has been called */
-- refs = ref_store_init(submodule_sb.buf, DEFAULT_REF_STORAGE, /* XXX */
-+ refs = ref_store_init(submodule_sb.buf, default_ref_storage(),
- REF_STORE_READ | REF_STORE_ODB);
- register_ref_store_map(&submodule_ref_stores, "submodule",
- refs, submodule);
-@@ refs.c: struct ref_store *get_submodule_ref_store(const char *submodule)
-
- struct ref_store *get_worktree_ref_store(const struct worktree *wt)
- {
-- const char *format = DEFAULT_REF_STORAGE; /* XXX */
-+ const char *format = default_ref_storage();
- struct ref_store *refs;
- const char *id;
-
-
## t/t1409-avoid-packing-refs.sh ##
@@ t/t1409-avoid-packing-refs.sh: test_description='avoid rewriting packed-refs unnecessarily'
@@ t/t3210-pack-refs.sh: semantic is still the same.
git config core.logallrefupdates true
'
- ## t/t9903-bash-prompt.sh ##
-@@ t/t9903-bash-prompt.sh: test_description='test git-specific bash prompt functions'
-
- . ./lib-bash.sh
-
-+if test_have_prereq REFTABLE
-+then
-+ skip_all='skipping tests; incompatible with reftable'
-+ test_done
-+fi
-+
- . "$GIT_BUILD_DIR/contrib/completion/git-prompt.sh"
-
- actual="$TRASH_DIRECTORY/actual"
-
## t/test-lib.sh ##
@@ t/test-lib.sh: parisc* | hppa*)
;;
17: ad5658ffc51 = 19: 991abf9e1b2 Add "test-tool dump-reftable" command.
--
gitgitgadget
next prev parent reply other threads:[~2020-06-22 21:55 UTC|newest]
Thread overview: 409+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-23 19:41 [PATCH 0/5] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-01-23 19:41 ` [PATCH 1/5] setup.c: enable repo detection for reftable Han-Wen Nienhuys via GitGitGadget
2020-01-23 19:41 ` [PATCH 2/5] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-01-23 19:41 ` [PATCH 3/5] Document how ref iterators and symrefs interact Han-Wen Nienhuys via GitGitGadget
2020-01-23 19:41 ` [PATCH 4/5] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-01-23 19:41 ` [PATCH 5/5] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-01-23 21:44 ` [PATCH 0/5] Reftable support git-core Junio C Hamano
2020-01-27 13:52 ` Han-Wen Nienhuys
2020-01-27 13:57 ` Han-Wen Nienhuys
2020-01-23 22:45 ` Stephan Beyer
2020-01-27 13:57 ` Han-Wen Nienhuys
2020-01-27 14:22 ` [PATCH v2 " Han-Wen Nienhuys via GitGitGadget
2020-01-27 14:22 ` [PATCH v2 1/5] setup.c: enable repo detection for reftable Han-Wen Nienhuys via GitGitGadget
2020-01-27 14:22 ` [PATCH v2 2/5] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-01-27 22:28 ` Junio C Hamano
2020-01-28 15:58 ` Han-Wen Nienhuys
2020-01-30 4:19 ` Junio C Hamano
2020-01-27 14:22 ` [PATCH v2 3/5] Document how ref iterators and symrefs interact Han-Wen Nienhuys via GitGitGadget
2020-01-27 22:53 ` Junio C Hamano
2020-01-28 16:07 ` Han-Wen Nienhuys
2020-01-28 19:35 ` Junio C Hamano
2020-01-27 14:22 ` [PATCH v2 4/5] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-01-27 14:22 ` [PATCH v2 5/5] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-01-28 7:31 ` Jeff King
2020-01-28 15:36 ` Martin Fick
2020-01-29 8:12 ` Jeff King
2020-01-29 16:49 ` Martin Fick
2020-01-29 18:40 ` Han-Wen Nienhuys
2020-01-29 19:47 ` Martin Fick
2020-01-29 19:50 ` Han-Wen Nienhuys
2020-01-30 7:21 ` Jeff King
2020-02-03 16:39 ` Han-Wen Nienhuys
2020-02-03 17:05 ` Jeff King
2020-02-03 17:09 ` Han-Wen Nienhuys
2020-02-04 18:54 ` Han-Wen Nienhuys
2020-02-04 20:06 ` Jeff King
2020-02-04 20:26 ` Han-Wen Nienhuys
2020-01-29 18:34 ` Junio C Hamano
2020-01-28 15:56 ` Han-Wen Nienhuys
2020-01-29 10:47 ` Jeff King
2020-01-29 18:43 ` Junio C Hamano
2020-01-29 18:53 ` Han-Wen Nienhuys
2020-01-30 7:26 ` Jeff King
2020-02-04 19:06 ` Han-Wen Nienhuys
2020-02-04 19:54 ` Jeff King
2020-02-04 20:22 ` Han-Wen Nienhuys
2020-02-04 22:13 ` Jeff King
2020-02-04 20:27 ` [PATCH v3 0/6] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-02-04 20:27 ` [PATCH v3 1/6] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-02-04 20:27 ` [PATCH v3 2/6] setup.c: enable repo detection for reftable Han-Wen Nienhuys via GitGitGadget
2020-02-04 20:31 ` Han-Wen Nienhuys
2020-02-04 20:27 ` [PATCH v3 3/6] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-02-04 21:29 ` Junio C Hamano
2020-02-05 11:34 ` Han-Wen Nienhuys
2020-02-05 11:42 ` SZEDER Gábor
2020-02-05 12:24 ` Jeff King
2020-02-04 20:27 ` [PATCH v3 4/6] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-02-04 20:27 ` [PATCH v3 5/6] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-02-04 20:27 ` [PATCH v3 6/6] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-02-06 22:55 ` [PATCH v4 0/5] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-02-06 22:55 ` [PATCH v4 1/5] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-02-06 22:55 ` [PATCH v4 2/5] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-02-06 22:55 ` [PATCH v4 3/5] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-02-06 22:55 ` [PATCH v4 4/5] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-02-06 23:07 ` Junio C Hamano
2020-02-07 0:16 ` brian m. carlson
2020-02-10 13:16 ` Han-Wen Nienhuys
2020-02-11 0:05 ` brian m. carlson
2020-02-11 14:20 ` Han-Wen Nienhuys
2020-02-11 16:31 ` Junio C Hamano
2020-02-11 16:40 ` Han-Wen Nienhuys
2020-02-11 23:40 ` brian m. carlson
2020-02-18 9:25 ` Han-Wen Nienhuys
2020-02-11 16:46 ` Han-Wen Nienhuys
2020-02-20 17:20 ` Jonathan Nieder
2020-02-06 22:55 ` [PATCH v4 5/5] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-02-06 23:49 ` brian m. carlson
2020-02-10 13:18 ` Han-Wen Nienhuys
2020-02-06 23:31 ` [PATCH v4 0/5] Reftable support git-core brian m. carlson
2020-02-10 14:14 ` [PATCH v5 " Han-Wen Nienhuys via GitGitGadget
2020-02-10 14:14 ` [PATCH v5 1/5] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-02-10 14:14 ` [PATCH v5 2/5] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-02-10 14:14 ` [PATCH v5 3/5] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-02-10 14:14 ` [PATCH v5 4/5] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-02-10 14:14 ` [PATCH v5 5/5] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-02-18 8:43 ` [PATCH v6 0/5] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-02-18 8:43 ` [PATCH v6 1/5] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-02-18 8:43 ` [PATCH v6 2/5] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-02-18 8:43 ` [PATCH v6 3/5] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-02-18 8:43 ` [PATCH v6 4/5] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-02-18 21:11 ` Junio C Hamano
2020-02-19 6:55 ` Jeff King
2020-02-19 17:00 ` Han-Wen Nienhuys
2020-02-18 8:43 ` [PATCH v6 5/5] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-02-18 21:05 ` [PATCH v6 0/5] Reftable support git-core Junio C Hamano
2020-02-19 16:59 ` Han-Wen Nienhuys
2020-02-19 17:02 ` Junio C Hamano
2020-02-19 17:21 ` Han-Wen Nienhuys
2020-02-19 18:10 ` Junio C Hamano
2020-02-19 19:14 ` Han-Wen Nienhuys
2020-02-19 20:09 ` Junio C Hamano
2020-02-20 11:19 ` Jeff King
2020-02-21 6:40 ` Jonathan Nieder
2020-02-26 17:16 ` Han-Wen Nienhuys
2020-02-26 20:04 ` Junio C Hamano
2020-02-27 0:01 ` brian m. carlson
[not found] ` <CAFQ2z_NQn9O3kFmHk8Cr31FY66ToU4bUdE=asHUfN++zBG+SPw@mail.gmail.com>
2020-02-26 17:41 ` Jonathan Nieder
2020-02-26 17:54 ` Han-Wen Nienhuys
2020-02-26 8:49 ` [PATCH v7 0/6] " Han-Wen Nienhuys via GitGitGadget
2020-02-26 8:49 ` [PATCH v7 1/6] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-02-26 8:49 ` [PATCH v7 2/6] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-02-26 8:49 ` [PATCH v7 3/6] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-02-26 8:49 ` [PATCH v7 4/6] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-02-26 8:49 ` [PATCH v7 5/6] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-02-26 8:49 ` [PATCH v7 6/6] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-02-26 18:12 ` Junio C Hamano
2020-02-26 18:59 ` Han-Wen Nienhuys
2020-02-26 19:59 ` Junio C Hamano
2020-02-27 16:03 ` Han-Wen Nienhuys
2020-02-27 16:23 ` Junio C Hamano
2020-02-27 17:56 ` Han-Wen Nienhuys
2020-02-26 21:31 ` Junio C Hamano
2020-02-27 16:01 ` Han-Wen Nienhuys
2020-02-27 16:26 ` Junio C Hamano
2020-02-26 17:35 ` [PATCH v7 0/6] Reftable support git-core Junio C Hamano
2020-03-24 6:06 ` Jonathan Nieder
2020-04-01 11:28 ` [PATCH v8 0/9] " Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28 ` [PATCH v8 1/9] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28 ` [PATCH v8 2/9] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28 ` [PATCH v8 3/9] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28 ` [PATCH v8 4/9] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28 ` [PATCH v8 5/9] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-04-01 11:28 ` [PATCH v8 6/9] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28 ` [PATCH v8 7/9] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28 ` [PATCH v8 8/9] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-04-01 11:28 ` [PATCH v8 9/9] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-04-15 23:29 ` [PATCH v8 0/9] Reftable support git-core Junio C Hamano
2020-04-18 3:22 ` Danh Doan
2020-04-20 21:14 ` [PATCH v9 00/10] " Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14 ` [PATCH v9 01/10] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14 ` [PATCH v9 02/10] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14 ` [PATCH v9 03/10] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14 ` [PATCH v9 04/10] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14 ` [PATCH v9 05/10] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14 ` [PATCH v9 06/10] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-04-20 21:14 ` [PATCH v9 07/10] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14 ` [PATCH v9 08/10] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-04-20 21:14 ` [PATCH v9 09/10] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-04-20 22:06 ` Junio C Hamano
2020-04-21 19:04 ` Han-Wen Nienhuys
2020-04-22 17:35 ` Johannes Schindelin
2020-04-20 21:14 ` [PATCH v9 10/10] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-04-21 20:13 ` [PATCH v9 00/10] Reftable support git-core Junio C Hamano
2020-04-23 21:27 ` Han-Wen Nienhuys
2020-04-23 21:43 ` Junio C Hamano
2020-04-23 21:52 ` Junio C Hamano
2020-04-25 13:58 ` Johannes Schindelin
2020-04-27 20:13 ` [PATCH v10 00/12] " Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13 ` [PATCH v10 01/12] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13 ` [PATCH v10 02/12] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-04-30 21:17 ` Emily Shaffer
2020-05-04 18:03 ` Han-Wen Nienhuys
2020-05-05 18:26 ` Pseudo ref handling (was Re: [PATCH v10 02/12] Iterate over the "refs/" namespace in for_each_[raw]ref) Han-Wen Nienhuys
2020-04-27 20:13 ` [PATCH v10 03/12] create .git/refs in files-backend.c Han-Wen Nienhuys via GitGitGadget
2020-04-30 21:24 ` Emily Shaffer
2020-04-30 21:49 ` Junio C Hamano
2020-05-04 18:10 ` Han-Wen Nienhuys
2020-04-27 20:13 ` [PATCH v10 04/12] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13 ` [PATCH v10 05/12] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13 ` [PATCH v10 06/12] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-04-27 20:13 ` [PATCH v10 07/12] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13 ` [PATCH v10 08/12] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13 ` [PATCH v10 09/12] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-04-28 14:55 ` Danh Doan
2020-04-28 15:29 ` Junio C Hamano
2020-04-28 15:31 ` Junio C Hamano
2020-04-28 20:21 ` Han-Wen Nienhuys
2020-04-28 20:23 ` Han-Wen Nienhuys
2020-04-27 20:13 ` [PATCH v10 10/12] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13 ` [PATCH v10 11/12] Add some reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-04-27 20:13 ` [PATCH v10 12/12] t: use update-ref and show-ref to reading/writing refs Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03 ` [PATCH v11 00/12] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03 ` [PATCH v11 01/12] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03 ` [PATCH v11 02/12] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03 ` [PATCH v11 03/12] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03 ` [PATCH v11 04/12] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03 ` [PATCH v11 05/12] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-05-04 19:03 ` [PATCH v11 06/12] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03 ` [PATCH v11 07/12] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03 ` [PATCH v11 08/12] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03 ` [PATCH v11 09/12] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03 ` [PATCH v11 10/12] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-04 19:03 ` [PATCH v11 11/12] Add some reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-04 19:03 ` [PATCH v11 12/12] t: use update-ref and show-ref to reading/writing refs Han-Wen Nienhuys via GitGitGadget
2020-05-06 4:29 ` [PATCH v11 00/12] Reftable support git-core Junio C Hamano
2020-05-07 9:59 ` [PATCH v12 " Han-Wen Nienhuys via GitGitGadget
2020-05-07 9:59 ` [PATCH v12 01/12] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-05-08 18:54 ` Junio C Hamano
2020-05-07 9:59 ` [PATCH v12 02/12] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-08 18:54 ` Junio C Hamano
2020-05-11 11:41 ` Han-Wen Nienhuys
2020-05-07 9:59 ` [PATCH v12 03/12] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-05-08 18:58 ` Junio C Hamano
2020-05-11 11:42 ` Han-Wen Nienhuys
2020-05-11 14:49 ` Junio C Hamano
2020-05-11 15:11 ` Han-Wen Nienhuys
2020-05-07 9:59 ` [PATCH v12 04/12] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-07 9:59 ` [PATCH v12 05/12] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-05-07 9:59 ` [PATCH v12 06/12] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-05-08 19:59 ` Junio C Hamano
2020-05-07 9:59 ` [PATCH v12 07/12] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-05-07 9:59 ` [PATCH v12 08/12] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-07 9:59 ` [PATCH v12 09/12] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-07 9:59 ` [PATCH v12 10/12] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-07 9:59 ` [PATCH v12 11/12] t: use update-ref and show-ref to reading/writing refs Han-Wen Nienhuys via GitGitGadget
2020-05-07 9:59 ` [PATCH v12 12/12] Add some reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46 ` [PATCH v13 00/13] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46 ` [PATCH v13 01/13] refs.h: clarify reflog iteration order Han-Wen Nienhuys via GitGitGadget
2020-05-18 23:31 ` Junio C Hamano
2020-05-11 19:46 ` [PATCH v13 02/13] t: use update-ref and show-ref to reading/writing refs Han-Wen Nienhuys via GitGitGadget
2020-05-18 23:34 ` Junio C Hamano
2020-05-11 19:46 ` [PATCH v13 03/13] refs: document how ref_iterator_advance_fn should handle symrefs Han-Wen Nienhuys via GitGitGadget
2020-05-18 23:43 ` Junio C Hamano
2020-05-11 19:46 ` [PATCH v13 04/13] reftable: file format documentation Jonathan Nieder via GitGitGadget
2020-05-19 22:00 ` Junio C Hamano
2020-05-20 16:06 ` Han-Wen Nienhuys
2020-05-20 17:20 ` Han-Wen Nienhuys
2020-05-20 17:25 ` Han-Wen Nienhuys
2020-05-20 17:33 ` Junio C Hamano
2020-05-20 18:52 ` Jonathan Nieder
2020-05-11 19:46 ` [PATCH v13 05/13] reftable: clarify how empty tables should be written Han-Wen Nienhuys via GitGitGadget
2020-05-19 22:01 ` Junio C Hamano
2020-05-11 19:46 ` [PATCH v13 06/13] reftable: define version 2 of the spec to accomodate SHA256 Han-Wen Nienhuys via GitGitGadget
2020-05-19 22:32 ` Junio C Hamano
2020-05-20 12:38 ` Han-Wen Nienhuys
2020-05-20 14:40 ` Junio C Hamano
2020-05-11 19:46 ` [PATCH v13 07/13] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-05-12 10:22 ` Phillip Wood
2020-05-12 16:48 ` Han-Wen Nienhuys
2020-05-13 10:06 ` Phillip Wood
2020-05-13 18:10 ` Phillip Wood
2020-05-11 19:46 ` [PATCH v13 08/13] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46 ` [PATCH v13 09/13] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46 ` [PATCH v13 10/13] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-11 19:46 ` [PATCH v13 11/13] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-13 19:55 ` Junio C Hamano
2020-05-11 19:46 ` [PATCH v13 12/13] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-11 19:46 ` [PATCH v13 13/13] Add some reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-13 19:57 ` Junio C Hamano
2020-05-19 13:54 ` Han-Wen Nienhuys
2020-05-19 15:21 ` Junio C Hamano
2020-05-12 0:41 ` [PATCH v13 00/13] Reftable support git-core Junio C Hamano
2020-05-12 7:49 ` Han-Wen Nienhuys
2020-05-13 21:21 ` Junio C Hamano
2020-05-18 20:31 ` [PATCH v14 0/9] " Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31 ` [PATCH v14 1/9] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31 ` [PATCH v14 2/9] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31 ` [PATCH v14 3/9] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31 ` [PATCH v14 4/9] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31 ` [PATCH v14 5/9] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31 ` [PATCH v14 6/9] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31 ` [PATCH v14 7/9] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-05-18 20:31 ` [PATCH v14 8/9] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-18 20:31 ` [PATCH v14 9/9] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46 ` [PATCH v15 00/13] Reftable support git-core Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46 ` [PATCH v15 01/13] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46 ` [PATCH v15 02/13] Make refs_ref_exists public Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46 ` [PATCH v15 03/13] Treat BISECT_HEAD as a pseudo ref Han-Wen Nienhuys via GitGitGadget
2020-05-28 20:52 ` Junio C Hamano
2020-05-28 19:46 ` [PATCH v15 04/13] Treat CHERRY_PICK_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46 ` [PATCH v15 05/13] Treat REVERT_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46 ` [PATCH v15 06/13] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46 ` [PATCH v15 07/13] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46 ` [PATCH v15 08/13] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46 ` [PATCH v15 09/13] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46 ` [PATCH v15 10/13] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46 ` [PATCH v15 11/13] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-05-28 19:46 ` [PATCH v15 12/13] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-05-28 19:46 ` [PATCH v15 13/13] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-05-28 20:15 ` [PATCH v15 00/13] Reftable support git-core Junio C Hamano
2020-05-28 21:21 ` Junio C Hamano
2020-06-05 18:03 ` [PATCH v16 00/14] " Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03 ` [PATCH v16 01/14] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-06-09 10:16 ` Phillip Wood
2020-06-05 18:03 ` [PATCH v16 02/14] Make refs_ref_exists public Han-Wen Nienhuys via GitGitGadget
2020-06-09 10:36 ` Phillip Wood
2020-06-10 18:05 ` Han-Wen Nienhuys
2020-06-11 14:59 ` Phillip Wood
2020-06-12 9:51 ` Phillip Wood
2020-06-15 11:32 ` Han-Wen Nienhuys
2020-06-05 18:03 ` [PATCH v16 03/14] Treat BISECT_HEAD as a pseudo ref Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03 ` [PATCH v16 04/14] Treat CHERRY_PICK_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03 ` [PATCH v16 05/14] Treat REVERT_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03 ` [PATCH v16 06/14] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03 ` [PATCH v16 07/14] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03 ` [PATCH v16 08/14] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03 ` [PATCH v16 09/14] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03 ` [PATCH v16 10/14] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03 ` [PATCH v16 11/14] Hookup unittests for the reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-08 19:39 ` Junio C Hamano
2020-06-09 17:22 ` [PATCH] Fixup! Add t/helper/test-reftable.c hanwen
2020-06-09 20:45 ` Junio C Hamano
2020-06-05 18:03 ` [PATCH v16 12/14] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-06-05 18:03 ` [PATCH v16 13/14] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-06-05 18:03 ` [PATCH v16 14/14] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-06-09 23:14 ` [PATCH v16 00/14] Reftable support git-core Junio C Hamano
2020-06-10 6:56 ` Han-Wen Nienhuys
2020-06-10 17:09 ` Junio C Hamano
2020-06-10 17:38 ` Junio C Hamano
2020-06-10 18:59 ` Johannes Schindelin
2020-06-10 19:04 ` Han-Wen Nienhuys
2020-06-10 19:20 ` Johannes Schindelin
2020-06-10 16:57 ` Han-Wen Nienhuys
2020-06-16 19:20 ` [PATCH v17 00/17] " Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 01/17] lib-t6000.sh: write tag using git-update-ref Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 02/17] checkout: add '\n' to reflog message Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 03/17] Write pseudorefs through ref backends Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 04/17] Make refs_ref_exists public Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 05/17] Treat BISECT_HEAD as a pseudo ref Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 06/17] Treat CHERRY_PICK_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 07/17] Treat REVERT_HEAD " Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 08/17] Move REF_LOG_ONLY to refs-internal.h Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 09/17] Iterate over the "refs/" namespace in for_each_[raw]ref Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 10/17] Add .gitattributes for the reftable/ directory Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 11/17] Add reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 12/17] Reftable support for git-core Han-Wen Nienhuys via GitGitGadget
2020-06-19 14:24 ` SZEDER Gábor
2020-06-16 19:20 ` [PATCH v17 13/17] Hookup unittests for the reftable library Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 14/17] Add GIT_DEBUG_REFS debugging mechanism Han-Wen Nienhuys via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 15/17] vcxproj: adjust for the reftable changes Johannes Schindelin via GitGitGadget
2020-06-16 19:20 ` [PATCH v17 16/17] Add reftable testing infrastructure Han-Wen Nienhuys via GitGitGadget
2020-06-19 16:03 ` SZEDER Gábor
2020-06-16 19:20 ` [PATCH v17 17/17] Add "test-tool dump-reftable" command Han-Wen Nienhuys via GitGitGadget
2020-06-22 21:55 ` Han-Wen Nienhuys via GitGitGadget [this message]
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
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.539.v18.git.1592862920.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.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).