Support reftable ref backend for Git
Subsystems (2)
PATCH 1/26 hash.h: provide constants for the hash IDs
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This will simplify referencing them from code that is not deeply integrated with Git, in particular, the reftable library.
--- hash.h | 6 ++++++ object-file.c | 7 ++----- 2 files changed, 8 insertions(+), 5 deletions(-)
hash.h +6 -0
@@ -95,12 +95,18 @@ static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *s/* Number of algorithms supported (including unknown). */ #define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1) +/* "sha1", big-endian */ +#define GIT_SHA1_FORMAT_ID 0x73686131 +/* The length in bytes and in hex digits of an object name (SHA-1 value). */ #define GIT_SHA1_RAWSZ 20#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)/* The block size of SHA-1. */ #define GIT_SHA1_BLKSZ 64 +/* "s256", big-endian */ +#define GIT_SHA256_FORMAT_ID 0x73323536 +/* The length in bytes and in hex digits of an object name (SHA-256 value). */ #define GIT_SHA256_RAWSZ 32#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
object-file.c +2 -5
@@ -164,7 +164,6 @@ static void git_hash_unknown_final_oid(struct object_id *oid, git_hash_ctx *ctx)BUG ("trying to finalize unknown hash" ); } -const struct git_hash_algo hash_algos[GIT_HASH_NALGOS ] = { {NULL ,
@@ -183,8 +182,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { }, {"sha1" , -/* "sha1", big-endian */ -0x73686131 , +GIT_SHA1_FORMAT_ID ,GIT_SHA1_RAWSZ ,GIT_SHA1_HEXSZ , GIT_SHA1_BLKSZ,
@@ -199,8 +197,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { }, {"sha256" , -/* "s256", big-endian */ -0x73323536 , +GIT_SHA256_FORMAT_ID ,GIT_SHA256_RAWSZ ,GIT_SHA256_HEXSZ , GIT_SHA256_BLKSZ,
Signature · 1 line
gitgitgadget
cover Support reftable ref backend for Git
This continues the work in https://github.com/git/git/pull/847, which the gitgitgadget erroneously closed.
Changes relative to last series (version 19 Apr 2021, tip: b8729fe)
* drop EINVAL for broken refs.
* fix 2 UBSAN warnings. Thanks to Andrzej Hunt for reporting.
* make tests pass against master (use oidread)
* handle worktree/xx/refname refs.
* handle main-worktree/ref
* fix double free in branch renaming
* handle relative paths (used in git upload-pack invocation) for ref backend creation.
* test and fix test-tool dump-reftable command
For the 'seen' branch, the following should be applied:
refs/reftable-backend.c +6 -7
@@ -108,7 +108,7 @@ static const char *bare_ref_name(const char *ref)static int git_reftable_read_raw_ref (struct ref_store *ref_store,const char *refname,struct object_id *oid,struct strbuf *referent, -unsigned int *type); +unsigned int *type,int *failure_errno);static void clear_reftable_log_record (struct reftable_log_record *log) {
@@ -425,13 +424,14 @@ static int fixup_symrefs(struct ref_store *ref_store,for (i =0 ; i < transaction->nr; i++) {struct ref_update *update = transaction->updates[i];struct object_id old_oid; +int failure_errno; err =git_reftable_read_raw_ref (ref_store, update->refname, &old_oid, &referent,/* mutate input, like files-backend.c */ - &update->type); -if (err <0 && errno ==ENOENT && + &update->type, &failure_errno); +if (err <0 && failure_errno ==ENOENT &&is_null_oid (&update->old_oid)) { err =0 ; }
@@ -1602,7 +1603,7 @@ static int reftable_error_to_errno(int err)static int git_reftable_read_raw_ref (struct ref_store *ref_store,const char *refname,struct object_id *oid,struct strbuf *referent, -unsigned int *type) +unsigned int *type,int *failure_errno) {struct git_reftable_ref_store *refs = (struct git_reftable_ref_store *)ref_store;
@@ -1626,13 +1627,11 @@ static int git_reftable_read_raw_ref(struct ref_store *ref_store, err =reftable_stack_read_ref (stack, refname, &ref);if (err >0 ) { - errno =ENOENT ; + *failure_errno =ENOENT ; err =-1 ; goto done; }if (err <0 ) { - errno =reftable_error_to_errno (err); - err =-1 ; goto done; }
Han-Wen Nienhuys (25):
hash.h: provide constants for the hash IDs
init-db: set the_repository->hash_algo early on
reftable: RFC: add LICENSE
reftable: add error related functionality
reftable: utility functions
reftable: add blocksource, an abstraction for random access reads
reftable: (de)serialization for the polymorphic record type. Provide zlib's uncompress2 from compat/zlib-compat.c
reftable: reading/writing blocks
reftable: a generic binary tree implementation
reftable: write reftable files
reftable: generic interface to tables
reftable: read reftable files
reftable: reftable file level tests
reftable: add a heap-based priority queue for reftable records
reftable: add merged table view
reftable: implement refname validation
reftable: implement stack, a mutable database of reftable files.
reftable: add dump utility
refs: RFC: Reftable support for git-core
Add "test-tool dump-reftable" command.
t1301: document what needs to be done for reftable t1401,t2011: parameterize HEAD.lock for REFFILES
t1404: annotate test cases with REFFILES
t7004: avoid direct filesystem access
SZEDER Gábor (1):
git-prompt: prepare for reftable refs backend
Documentation/config/extensions.txt | 9 + .../technical/repository-version.txt | 7 + Makefile | 54 +- builtin/clone.c | 5 +- builtin/init-db.c | 60 +- builtin/stash.c | 8 +- builtin/worktree.c | 27 +- cache.h | 8 +- ci/lib.sh | 1 + compat/.gitattributes | 1 + compat/zlib-uncompress2.c | 92 + config.mak.uname | 2 +- configure.ac | 13 + contrib/buildsystems/CMakeLists.txt | 14 +- contrib/buildsystems/Generators/Vcxproj.pm | 11 +- contrib/completion/git-prompt.sh | 7 +- hash.h | 6 + object-file.c | 7 +- refs.c | 26 +- refs.h | 3 + refs/refs-internal.h | 1 + refs/reftable-backend.c | 1683 +++++++++++++++++ reftable/LICENSE | 31 + reftable/basics.c | 128 ++ reftable/basics.h | 60 + reftable/basics_test.c | 98 + reftable/block.c | 446 +++++ reftable/block.h | 127 ++ reftable/block_test.c | 121 ++ reftable/blocksource.c | 148 ++ reftable/blocksource.h | 22 + reftable/constants.h | 21 + reftable/dump.c | 105 + reftable/error.c | 41 + reftable/generic.c | 169 ++ reftable/generic.h | 32 + reftable/iter.c | 194 ++ reftable/iter.h | 69 + reftable/merged.c | 362 ++++ reftable/merged.h | 35 + reftable/merged_test.c | 292 +++ reftable/pq.c | 115 ++ reftable/pq.h | 32 + reftable/pq_test.c | 72 + reftable/publicbasics.c | 58 + reftable/reader.c | 801 ++++++++ reftable/reader.h | 66 + reftable/readwrite_test.c | 650 +++++++ reftable/record.c | 1200 ++++++++++++ reftable/record.h | 139 ++ reftable/record_test.c | 407 ++++ reftable/refname.c | 209 ++ reftable/refname.h | 29 + reftable/refname_test.c | 102 + reftable/reftable-blocksource.h | 49 + reftable/reftable-error.h | 62 + reftable/reftable-generic.h | 47 + reftable/reftable-iterator.h | 39 + reftable/reftable-malloc.h | 18 + reftable/reftable-merged.h | 72 + reftable/reftable-reader.h | 101 + reftable/reftable-record.h | 114 ++ reftable/reftable-stack.h | 128 ++ reftable/reftable-tests.h | 23 + reftable/reftable-writer.h | 148 ++ reftable/reftable.c | 115 ++ reftable/stack.c | 1396 ++++++++++++++ reftable/stack.h | 41 + reftable/stack_test.c | 947 ++++++++++ reftable/system.h | 24 + reftable/test_framework.c | 23 + reftable/test_framework.h | 53 + reftable/tree.c | 63 + reftable/tree.h | 34 + reftable/tree_test.c | 61 + reftable/writer.c | 690 +++++++ reftable/writer.h | 50 + repository.c | 2 + repository.h | 3 + setup.c | 6 + t/helper/test-reftable.c | 21 + t/helper/test-tool.c | 4 +- t/helper/test-tool.h | 2 + t/t0031-reftable.sh | 297 +++ t/t0032-reftable-unittest.sh | 15 + t/t1301-shared-repo.sh | 8 +- t/t1401-symbolic-ref.sh | 11 +- t/t1404-update-ref-errors.sh | 56 +- t/t1409-avoid-packing-refs.sh | 6 + t/t1450-fsck.sh | 6 + t/t2011-checkout-invalid-head.sh | 11 +- t/t3210-pack-refs.sh | 6 + t/t7004-tag.sh | 7 +- t/test-lib.sh | 7 +- 94 files changed, 13129 insertions(+), 63 deletions(-) create mode 100644 compat/.gitattributes create mode 100644 compat/zlib-uncompress2.c create mode 100644 refs/reftable-backend.c create mode 100644 reftable/LICENSE create mode 100644 reftable/basics.c create mode 100644 reftable/basics.h create mode 100644 reftable/basics_test.c create mode 100644 reftable/block.c create mode 100644 reftable/block.h create mode 100644 reftable/block_test.c create mode 100644 reftable/blocksource.c create mode 100644 reftable/blocksource.h create mode 100644 reftable/constants.h create mode 100644 reftable/dump.c create mode 100644 reftable/error.c create mode 100644 reftable/generic.c create mode 100644 reftable/generic.h 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/pq_test.c create mode 100644 reftable/publicbasics.c create mode 100644 reftable/reader.c create mode 100644 reftable/reader.h create mode 100644 reftable/readwrite_test.c 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-blocksource.h create mode 100644 reftable/reftable-error.h create mode 100644 reftable/reftable-generic.h create mode 100644 reftable/reftable-iterator.h create mode 100644 reftable/reftable-malloc.h create mode 100644 reftable/reftable-merged.h create mode 100644 reftable/reftable-reader.h create mode 100644 reftable/reftable-record.h create mode 100644 reftable/reftable-stack.h create mode 100644 reftable/reftable-tests.h create mode 100644 reftable/reftable-writer.h create mode 100644 reftable/reftable.c create mode 100644 reftable/stack.c create mode 100644 reftable/stack.h create mode 100644 reftable/stack_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 100644 reftable/writer.c create mode 100644 reftable/writer.h create mode 100644 t/helper/test-reftable.c create mode 100755 t/t0031-reftable.sh create mode 100755 t/t0032-reftable-unittest.sh
base-commit: daab8a564f8bbac55f70f8bf86c070e001a9b006
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1054%2Fhanwen%2Flibreftable-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1054/hanwen/libreftable-v1
Pull-Request: https://github.com/git/git/pull/1054
Signature · 1 line
gitgitgadget
PATCH 2/26 init-db: set the_repository->hash_algo early on
From: Han-Wen Nienhuys <[email protected]>
The reftable backend needs to know the hash algorithm for writing the initialization hash table.
The initial reftable contains a symref HEAD => "main" (or "master"), which is agnostic to the size of hash value, but this is an exceptional circumstance, and the reftable library does not cater to this exception. It insists that all tables in the stack have a consistent format ID for the hash algorithm.
Call set_repo_hash_algo directly after calling validate_hash_algorithm() (which reads $GIT_DEFAULT_HASH).
--- builtin/init-db.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
builtin/init-db.c +21 -0
@@ -425,6 +425,27 @@ int init_db(const char *git_dir, const char *real_git_dir,validate_hash_algorithm (&repo_fmt, hash); +/* +* At this point, the_repository we have in-core does not look +* anything like one that we would see initialized in an already +* working repository after calling setup_git_directory(). +* +* Calling repository.c::initialize_the_repository() may have +* prepared the .index .objects and .parsed_objects members, but +* other members like .gitdir, .commondir, etc. have not been +* initialized. +* +* Many API functions assume they are working with the_repository +* that has sensibly been initialized, but because we haven't +* really read from an existing repository, we need to hand-craft +* the necessary members of the structure to get out of this +* chicken-and-egg situation. +* +* For now, we update the hash algorithm member to what the +* validate_hash_algorithm() call decided for us. +*/ +repo_set_hash_algo (the_repository, repo_fmt.hash_algo); + reinit =create_default_files (template_dir, original_git_dir, initial_branch, &repo_fmt, flags &INIT_DB_QUIET );
Signature · 1 line
gitgitgadget
PATCH 3/26 reftable: RFC: add LICENSE
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The objective of this code is to be usable as a C library, so it can be reused in libgit2.
This is currently using a BSD license as it is the liberal license I could find, but this could be changed to whatever fits the stated goal above.
This code is currently imported from github.com/hanwen/reftable. Once this code lands in git.git, the C code will be removed from github.com/hanwen/reftable, and the git.git code will be the source of truth.
--- reftable/LICENSE | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 reftable/LICENSE
reftable/LICENSE new file +31 -0
@@ -0,0 +1,31 @@ +BSD License + +Copyright (c) 2020, Google LLC +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +* Neither the name of Google LLC nor the names of its contributors may +be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Signature · 1 line
gitgitgadget
PATCH 4/26 reftable: add error related functionality
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable/ directory is structured as a library, so it cannot crash on misuse. Instead, it returns an error codes.
In addition, the error code can be used to signal conditions from lower levels of the library to be handled by higher levels of the library. For example, a transaction might legitimately write an empty reftable file, but in that case, we'd want to shortcut the transaction overhead.
--- reftable/error.c | 41 ++++++++++++++++++++++++++ reftable/reftable-error.h | 62 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 reftable/error.c create mode 100644 reftable/reftable-error.h
reftable/error.c new file +41 -0
@@ -0,0 +1,41 @@ +/* +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 "reftable-error.h" + +#include <stdio.h> + +const char *reftable_error_str (int err) +{ +static char buf[250 ]; +switch (err) { +case REFTABLE_IO_ERROR : +return "I/O error" ; +case REFTABLE_FORMAT_ERROR : +return "corrupt reftable file" ; +case REFTABLE_NOT_EXIST_ERROR : +return "file does not exist" ; +case REFTABLE_LOCK_ERROR : +return "data is outdated" ; +case REFTABLE_API_ERROR : +return "misuse of the reftable API" ; +case REFTABLE_ZLIB_ERROR : +return "zlib failure" ; +case REFTABLE_NAME_CONFLICT : +return "file/directory conflict" ; +case REFTABLE_EMPTY_TABLE_ERROR : +return "wrote empty table" ; +case REFTABLE_REFNAME_ERROR : +return "invalid refname" ; +case -1 : +return "general error" ; +default : +snprintf (buf,sizeof (buf),"unknown error code %d" , err); +return buf; + } +}
reftable/reftable-error.h new file +62 -0
62 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH 5/26 reftable: utility functions
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This commit provides basic utility classes for the reftable library.
--- Makefile | 25 +++++- contrib/buildsystems/CMakeLists.txt | 14 ++- reftable/basics.c | 128 ++++++++++++++++++++++++++++ reftable/basics.h | 60 +++++++++++++ reftable/basics_test.c | 98 +++++++++++++++++++++ reftable/publicbasics.c | 58 +++++++++++++ reftable/reftable-malloc.h | 18 ++++ reftable/reftable-tests.h | 22 +++++ reftable/system.h | 24 ++++++ reftable/test_framework.c | 23 +++++ reftable/test_framework.h | 53 ++++++++++++ t/helper/test-reftable.c | 9 ++ t/helper/test-tool.c | 3 +- t/helper/test-tool.h | 1 + t/t0032-reftable-unittest.sh | 15 ++++ 15 files changed, 545 insertions(+), 6 deletions(-) create mode 100644 reftable/basics.c create mode 100644 reftable/basics.h create mode 100644 reftable/basics_test.c create mode 100644 reftable/publicbasics.c create mode 100644 reftable/reftable-malloc.h create mode 100644 reftable/reftable-tests.h create mode 100644 reftable/system.h create mode 100644 reftable/test_framework.c create mode 100644 reftable/test_framework.h create mode 100644 t/helper/test-reftable.c create mode 100755 t/t0032-reftable-unittest.sh
Makefile +22 -3
@@ -741,6 +741,7 @@ TEST_BUILTINS_OBJS += test-read-cache.o TEST_BUILTINS_OBJS += test-read-graph.o TEST_BUILTINS_OBJS += test-read-midx.o TEST_BUILTINS_OBJS += test-ref-store.o +TEST_BUILTINS_OBJS += test-reftable.o TEST_BUILTINS_OBJS += test-regex.o TEST_BUILTINS_OBJS += test-repository.o TEST_BUILTINS_OBJS += test-revision-walking.o
@@ -819,6 +820,8 @@ TEST_SHELL_PATH = $(SHELL_PATH) LIB_FILE = libgit.a XDIFF_LIB = xdiff/lib.a +REFTABLE_LIB = reftable/libreftable.a +REFTABLE_TEST_LIB = reftable/libreftable_test.a GENERATED_H += command-list.h GENERATED_H += config-list.h
@@ -1191,7 +1194,7 @@ THIRD_PARTY_SOURCES += compat/regex/% THIRD_PARTY_SOURCES += sha1collisiondetection/% THIRD_PARTY_SOURCES += sha1dc/% -GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) +GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) EXTLIBS = GIT_USER_AGENT = git/$(GIT_VERSION)
@@ -2438,7 +2441,15 @@ XDIFF_OBJS += xdiff/xutils.o .PHONY: xdiff-objs xdiff-objs: $(XDIFF_OBJS) +REFTABLE_OBJS += reftable/basics.o +REFTABLE_OBJS += reftable/error.o +REFTABLE_OBJS += reftable/publicbasics.o + +REFTABLE_TEST_OBJS += reftable/test_framework.o +REFTABLE_TEST_OBJS += reftable/basics_test.o + TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS)) + .PHONY: test-objs test-objs: $(TEST_OBJS)
@@ -2454,6 +2465,8 @@ OBJECTS += $(PROGRAM_OBJS) OBJECTS += $(TEST_OBJS) OBJECTS += $(XDIFF_OBJS) OBJECTS += $(FUZZ_OBJS) +OBJECTS += $(REFTABLE_OBJS) $(REFTABLE_TEST_OBJS) + ifndef NO_CURL OBJECTS += http.o http-walker.o remote-curl.o endif
@@ -2604,6 +2617,12 @@ $(LIB_FILE): $(LIB_OBJS) $(XDIFF_LIB): $(XDIFF_OBJS) $(QUIET_AR)$(AR) $(ARFLAGS) $@ $^ +$(REFTABLE_LIB): $(REFTABLE_OBJS) + $(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^ + +$(REFTABLE_TEST_LIB): $(REFTABLE_TEST_OBJS) + $(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^ + export DEFAULT_EDITOR DEFAULT_PAGER Documentation/GIT-EXCLUDED-PROGRAMS: FORCE
@@ -2888,7 +2907,7 @@ perf: all t/helper/test-tool$X: $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS)) -t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) +t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) $(REFTABLE_TEST_LIB) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS) check-sha1:: t/helper/test-tool$X
@@ -3218,7 +3237,7 @@ cocciclean: clean: profile-clean coverage-clean cocciclean $(RM) *.res $(RM) $(OBJECTS) - $(RM) $(LIB_FILE) $(XDIFF_LIB) + $(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB) $(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X $(RM) $(TEST_PROGRAMS) $(RM) $(FUZZ_PROGRAMS)
contrib/buildsystems/CMakeLists.txt +12 -2
@@ -640,6 +640,12 @@ parse_makefile_for_sources(libxdiff_SOURCES "XDIFF_OBJS") list(TRANSFORM libxdiff_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") add_library(xdiff STATIC ${libxdiff_SOURCES}) +#reftable +parse_makefile_for_sources(reftable_SOURCES "REFTABLE_OBJS") + +list(TRANSFORM reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") +add_library(reftable STATIC ${reftable_SOURCES}) + if(WIN32) if(NOT MSVC)#use windres when compiling with gcc and clang add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/git.res
@@ -662,7 +668,7 @@ endif() #link all required libraries to common-main add_library(common-main OBJECT ${CMAKE_SOURCE_DIR}/common-main.c) -target_link_libraries(common-main libgit xdiff ${ZLIB_LIBRARIES}) +target_link_libraries(common-main libgit xdiff reftable ${ZLIB_LIBRARIES}) if(Intl_FOUND) target_link_libraries(common-main ${Intl_LIBRARIES}) endif()
@@ -902,11 +908,15 @@ if(BUILD_TESTING) add_executable(test-fake-ssh ${CMAKE_SOURCE_DIR}/t/helper/test-fake-ssh.c) target_link_libraries(test-fake-ssh common-main) +#reftable-tests +parse_makefile_for_sources(test-reftable_SOURCES "REFTABLE_TEST_OBJS") +list(TRANSFORM test-reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") + #test-tool parse_makefile_for_sources(test-tool_SOURCES "TEST_BUILTINS_OBJS") list(TRANSFORM test-tool_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/t/helper/") -add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES}) +add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES} ${test-reftable_SOURCES}) target_link_libraries(test-tool common-main) set_target_properties(test-fake-ssh test-tool
reftable/basics.c new file +128 -0
128 lines not on this page · raw message
reftable/basics.h new file +60 -0
60 lines not on this page · raw message
reftable/basics_test.c new file +98 -0
98 lines not on this page · raw message
reftable/publicbasics.c new file +58 -0
58 lines not on this page · raw message
reftable/reftable-malloc.h new file +18 -0
@@ -0,0 +1,18 @@ +/* +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 REFTABLE_H +#define REFTABLE_H + +#include <stddef.h> + +/* Overrides the functions to use for memory management. */ +void reftable_set_alloc (void *(*malloc)(size_t ), +void *(*realloc)(void *,size_t ),void (*free)(void *)); + +#endif
reftable/reftable-tests.h new file +22 -0
@@ -0,0 +1,22 @@ +/* +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 REFTABLE_TESTS_H +#define REFTABLE_TESTS_H + +int basics_test_main (int argc,const char **argv); +int block_test_main (int argc,const char **argv); +int merged_test_main (int argc,const char **argv); +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 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); + +#endif
reftable/system.h new file +24 -0
@@ -0,0 +1,24 @@ +/* +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 SYSTEM_H +#define SYSTEM_H + +// This header glues the reftable library to the rest of Git + +#include "git-compat-util.h" +#include "strbuf.h" +#include "hash.h" /* hash ID, sizes.*/ +#include "dir.h" /* remove_dir_recursively, for tests.*/ + +#include <zlib.h> + +struct strbuf ; +int hash_size (uint32_t id); + +#endif
reftable/test_framework.c new file +23 -0
@@ -0,0 +1,23 @@ +/* +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 "system.h" +#include "test_framework.h" + +#include "basics.h" + +void set_test_hash (uint8_t *p,int i) +{ +memset (p, (uint8_t )i,hash_size (GIT_SHA1_FORMAT_ID )); +} + +ssize_t strbuf_add_void (void *b,const void *data,size_t sz) +{ +strbuf_add (b, data, sz); +return sz; +}
reftable/test_framework.h new file +53 -0
53 lines not on this page · raw message
t/helper/test-reftable.c new file +9 -0
@@ -0,0 +1,9 @@ +#include "reftable/reftable-tests.h" +#include "test-tool.h" + +int cmd__reftable (int argc,const char **argv) +{ +basics_test_main (argc, argv); + +return 0 ; +}
t/helper/test-tool.c +2 -1
@@ -51,13 +51,14 @@ static struct test_cmd cmds[] = { { "pcre2-config", cmd__pcre2_config }, { "pkt-line", cmd__pkt_line }, { "prio-queue", cmd__prio_queue }, - { "proc-receive", cmd__proc_receive}, + { "proc-receive", cmd__proc_receive }, { "progress", cmd__progress }, { "reach", cmd__reach }, { "read-cache", cmd__read_cache }, { "read-graph", cmd__read_graph }, { "read-midx", cmd__read_midx }, { "ref-store", cmd__ref_store }, + { "reftable", cmd__reftable }, { "regex", cmd__regex }, { "repository", cmd__repository }, { "revision-walking", cmd__revision_walking },
t/helper/test-tool.h +1 -0
@@ -47,6 +47,7 @@ int cmd__read_cache(int argc, const char **argv);int cmd__read_graph (int argc,const char **argv);int cmd__read_midx (int argc,const char **argv);int cmd__ref_store (int argc,const char **argv); +int cmd__reftable (int argc,const char **argv);int cmd__regex (int argc,const char **argv);int cmd__repository (int argc,const char **argv);int cmd__revision_walking (int argc,const char **argv);
t/t0032-reftable-unittest.sh new file +15 -0
@@ -0,0 +1,15 @@ +#!/bin/sh +# +# Copyright (c) 2020 Google LLC +# + +test_description='reftable unittests' + +. ./test-lib.sh + +test_expect_success 'unittests' ' + TMPDIR=$(pwd) && export TMPDIR && + test-tool reftable +' + +test_done
Signature · 1 line
gitgitgadget
PATCH 6/26 reftable: add blocksource, an abstraction for random access reads
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable format is usually used with files for storage. However, we abstract away this using the blocksource data structure. This has two advantages:
* log blocks are zlib compressed, and handling them is simplified if we can discard byte segments from within the block layer.
* for unittests, it is useful to read and write in-memory. The blocksource allows us to abstract the data away from on-disk files.
--- Makefile | 1 + reftable/blocksource.c | 148 ++++++++++++++++++++++++++++++++ reftable/blocksource.h | 22 +++++ reftable/reftable-blocksource.h | 49 +++++++++++ 4 files changed, 220 insertions(+) create mode 100644 reftable/blocksource.c create mode 100644 reftable/blocksource.h create mode 100644 reftable/reftable-blocksource.h
Makefile +1 -0
@@ -2443,6 +2443,7 @@ xdiff-objs: $(XDIFF_OBJS) REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o +REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_TEST_OBJS += reftable/test_framework.o
reftable/blocksource.c new file +148 -0
148 lines not on this page · raw message
reftable/blocksource.h new file +22 -0
@@ -0,0 +1,22 @@ +/* +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 BLOCKSOURCE_H +#define BLOCKSOURCE_H + +#include "system.h" + +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/reftable-blocksource.h new file +49 -0
49 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH 8/26 Provide zlib's uncompress2 from compat/zlib-compat.c
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This will be needed for reading reflog blocks in reftable.
--- Makefile | 7 +++ ci/lib.sh | 1 + compat/.gitattributes | 1 + compat/zlib-uncompress2.c | 92 +++++++++++++++++++++++++++++++++++++++ configure.ac | 13 ++++++ 5 files changed, 114 insertions(+) create mode 100644 compat/.gitattributes create mode 100644 compat/zlib-uncompress2.c
Makefile +7 -0
@@ -256,6 +256,8 @@ all:: # # Define NO_DEFLATE_BOUND if your zlib does not have deflateBound. # +# Define NO_UNCOMPRESS2 if your zlib does not have uncompress2. +# # Define NO_NORETURN if using buggy versions of gcc 4.6+ and profile feedback, # as the compiler can crash (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49299) #
@@ -1734,6 +1736,11 @@ ifdef NO_DEFLATE_BOUND BASIC_CFLAGS += -DNO_DEFLATE_BOUND endif +ifdef NO_UNCOMPRESS2 + BASIC_CFLAGS += -DNO_UNCOMPRESS2 + LIB_OBJS += compat/zlib-uncompress2.o +endif + ifdef NO_POSIX_GOODIES BASIC_CFLAGS += -DNO_POSIX_GOODIES endif
ci/lib.sh +1 -0
@@ -224,6 +224,7 @@ linux-gcc-default) ;; Linux32) CC=gcc + MAKEFLAGS="$MAKEFLAGS NO_UNCOMPRESS2=1" ;; linux-musl) CC=gcc
compat/.gitattributes new file +1 -0
@@ -0,0 +1 @@ +/zlib-uncompress2.c whitespace=-indent-with-non-tab,-trailing-space
compat/zlib-uncompress2.c new file +92 -0
92 lines not on this page · raw message
configure.ac +13 -0
@@ -672,9 +672,22 @@ AC_LINK_IFELSE([ZLIBTEST_SRC], NO_DEFLATE_BOUND=yes]) LIBS="$old_LIBS" +AC_DEFUN([ZLIBTEST_UNCOMPRESS2_SRC], [ +AC_LANG_PROGRAM([#include <zlib.h>], + [uncompress2(NULL,NULL,NULL,NULL);])]) +AC_MSG_CHECKING([for uncompress2 in -lz]) +old_LIBS="$LIBS" +LIBS="$LIBS -lz" +AC_LINK_IFELSE([ZLIBTEST_UNCOMPRESS2_SRC], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + NO_UNCOMPRESS2=yes]) +LIBS="$old_LIBS" + GIT_UNSTASH_FLAGS($ZLIB_PATH) GIT_CONF_SUBST([NO_DEFLATE_BOUND]) +GIT_CONF_SUBST([NO_UNCOMPRESS2]) # # Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
Signature · 1 line
gitgitgadget
PATCH 7/26 reftable: (de)serialization for the polymorphic record type.
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable format is structured as a sequence of blocks, and each block contains a sequence of prefix-compressed key-value records. There are 4 types of records, and they have similarities in how they must be handled. This is achieved by introducing a polymorphic 'record' type that encapsulates ref, log, index and object records.
--- Makefile | 2 + reftable/constants.h | 21 + reftable/record.c | 1200 ++++++++++++++++++++++++++++++++++++ reftable/record.h | 139 +++++ reftable/record_test.c | 407 ++++++++++++ reftable/reftable-record.h | 114 ++++ t/helper/test-reftable.c | 2 +- 7 files changed, 1884 insertions(+), 1 deletion(-) create mode 100644 reftable/constants.h create mode 100644 reftable/record.c create mode 100644 reftable/record.h create mode 100644 reftable/record_test.c create mode 100644 reftable/reftable-record.h
Makefile +2 -0
@@ -2445,7 +2445,9 @@ REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/record.o +REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/basics_test.o
reftable/constants.h new file +21 -0
@@ -0,0 +1,21 @@ +/* +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 CONSTANTS_H +#define CONSTANTS_H + +#define BLOCK_TYPE_LOG 'g' +#define BLOCK_TYPE_INDEX 'i' +#define BLOCK_TYPE_REF 'r' +#define BLOCK_TYPE_OBJ 'o' +#define BLOCK_TYPE_ANY 0 + +#define MAX_RESTARTS ((1 << 16) - 1) +#define DEFAULT_BLOCK_SIZE 4096 + +#endif
reftable/record.c new file +1200 -0
1,200 lines not on this page · raw message
reftable/record.h new file +139 -0
139 lines not on this page · raw message
reftable/record_test.c new file +407 -0
407 lines not on this page · raw message
reftable/reftable-record.h new file +114 -0
114 lines not on this page · raw message
t/helper/test-reftable.c +1 -1
@@ -4,6 +4,6 @@int cmd__reftable (int argc,const char **argv) {basics_test_main (argc, argv); - +record_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH 10/26 reftable: a generic binary tree implementation
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable format includes support for an (OID => ref) map. This map can speed up visibility and reachability checks. In particular, various operations along the fetch/push path within Gerrit have ben sped up by using this structure.
The map is constructed with help of a binary tree. Object IDs are hashes, so they are uniformly distributed. Hence, the tree does not attempt forced rebalancing.
--- Makefile | 4 ++- reftable/tree.c | 63 ++++++++++++++++++++++++++++++++++++++++ reftable/tree.h | 34 ++++++++++++++++++++++ reftable/tree_test.c | 61 ++++++++++++++++++++++++++++++++++++++ t/helper/test-reftable.c | 1 + 5 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 reftable/tree.c create mode 100644 reftable/tree.h create mode 100644 reftable/tree_test.c
Makefile +3 -1
@@ -2454,11 +2454,13 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o +REFTABLE_OBJS += reftable/tree.o +REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o -REFTABLE_TEST_OBJS += reftable/basics_test.o +REFTABLE_TEST_OBJS += reftable/tree_test.o TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
reftable/tree.c new file +63 -0
63 lines not on this page · raw message
reftable/tree.h new file +34 -0
@@ -0,0 +1,34 @@ +/* +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 TREE_H +#define TREE_H + +/* tree_node is a generic binary search tree. */ +struct tree_node { +void *key; +struct tree_node *left, *right; +}; + +/* looks for `key` in `rootp` using `compare` as comparison function. If insert +* is set, insert the key if it's not found. Else, return NULL. +*/ +struct tree_node *tree_search (void *key,struct tree_node **rootp, +int (*compare)(const void *,const void *), +int insert); + +/* performs an infix walk of the tree. */ +void infix_walk (struct tree_node *t,void (*action)(void *arg,void *key), +void *arg); + +/* +* deallocates the tree nodes recursively. Keys should be deallocated separately +* by walking over the tree. */ +void tree_free (struct tree_node *t); + +#endif
reftable/tree_test.c new file +61 -0
61 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -6,5 +6,6 @@ int cmd__reftable(int argc, const char **argv)basics_test_main (argc, argv);block_test_main (argc, argv);record_test_main (argc, argv); +tree_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH 13/26 reftable: read reftable files
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This supports reading a single reftable file.
The commit introduces an abstract iterator type, which captures the usecases both of reading individual refs, and iterating over a segment of the ref namespace.
--- Makefile | 2 + reftable/iter.c | 194 +++++++++ reftable/iter.h | 69 ++++ reftable/reader.c | 801 +++++++++++++++++++++++++++++++++++++ reftable/reader.h | 66 +++ reftable/reftable-reader.h | 101 +++++ 6 files changed, 1233 insertions(+) create mode 100644 reftable/iter.c create mode 100644 reftable/iter.h create mode 100644 reftable/reader.c create mode 100644 reftable/reader.h create mode 100644 reftable/reftable-reader.h
Makefile +2 -0
@@ -2452,7 +2452,9 @@ REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o +REFTABLE_OBJS += reftable/iter.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/reader.o REFTABLE_OBJS += reftable/record.o REFTABLE_OBJS += reftable/refname.o REFTABLE_OBJS += reftable/generic.o
reftable/iter.c new file +194 -0
194 lines not on this page · raw message
reftable/iter.h new file +69 -0
69 lines not on this page · raw message
reftable/reader.c new file +801 -0
801 lines not on this page · raw message
reftable/reader.h new file +66 -0
66 lines not on this page · raw message
reftable/reftable-reader.h new file +101 -0
101 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH 15/26 reftable: add a heap-based priority queue for reftable records
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This is needed to create a merged view multiple reftables
--- Makefile | 2 + reftable/pq.c | 115 ++++++++++++++++++++++++++++++++++++++ reftable/pq.h | 32 +++++++++++ reftable/pq_test.c | 72 ++++++++++++++++++++++++ reftable/reftable-tests.h | 1 + t/helper/test-reftable.c | 1 + 6 files changed, 223 insertions(+) create mode 100644 reftable/pq.c create mode 100644 reftable/pq.h create mode 100644 reftable/pq_test.c
Makefile +2 -0
@@ -2454,6 +2454,7 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/iter.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/pq.o REFTABLE_OBJS += reftable/reader.o REFTABLE_OBJS += reftable/record.o REFTABLE_OBJS += reftable/refname.o
@@ -2464,6 +2465,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o +REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o
reftable/pq.c new file +115 -0
115 lines not on this page · raw message
reftable/pq.h new file +32 -0
@@ -0,0 +1,32 @@ +/* +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 PQ_H +#define PQ_H + +#include "record.h" + +struct pq_entry { +int index; +struct reftable_record rec; +}; + +struct merged_iter_pqueue { +struct pq_entry *heap; +size_t len; +size_t cap; +}; + +struct pq_entry merged_iter_pqueue_top (struct merged_iter_pqueue pq); +int merged_iter_pqueue_is_empty (struct merged_iter_pqueue pq); +void merged_iter_pqueue_check (struct merged_iter_pqueue pq); +struct pq_entry merged_iter_pqueue_remove (struct merged_iter_pqueue *pq); +void merged_iter_pqueue_add (struct merged_iter_pqueue *pq,struct pq_entry e); +void merged_iter_pqueue_release (struct merged_iter_pqueue *pq); + +#endif
reftable/pq_test.c new file +72 -0
72 lines not on this page · raw message
reftable/reftable-tests.h +1 -0
@@ -12,6 +12,7 @@ https://developers.google.com/open-source/licenses/bsdint basics_test_main (int argc,const char **argv);int block_test_main (int argc,const char **argv);int merged_test_main (int argc,const char **argv); +int pq_test_main (int argc,const char **argv);int record_test_main (int argc,const char **argv);int refname_test_main (int argc,const char **argv);int readwrite_test_main (int argc,const char **argv);
t/helper/test-reftable.c +1 -0
@@ -5,6 +5,7 @@ int cmd__reftable(int argc, const char **argv) {basics_test_main (argc, argv);block_test_main (argc, argv); +pq_test_main (argc, argv);record_test_main (argc, argv);readwrite_test_main (argc, argv);tree_test_main (argc, argv);
Signature · 1 line
gitgitgadget
PATCH 9/26 reftable: reading/writing blocks
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable format is structured as a sequence of block. Within a block, records are prefix compressed, with an index of offsets for fully expand keys to enable binary search within blocks.
This commit provides the logic to read and write these blocks.
--- Makefile | 2 + reftable/block.c | 446 +++++++++++++++++++++++++++++++++++++++ reftable/block.h | 127 +++++++++++ reftable/block_test.c | 121 +++++++++++ t/helper/test-reftable.c | 1 + 5 files changed, 697 insertions(+) create mode 100644 reftable/block.c create mode 100644 reftable/block.h create mode 100644 reftable/block_test.c
Makefile +2 -0
@@ -2450,10 +2450,12 @@ xdiff-objs: $(XDIFF_OBJS) REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o +REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o +REFTABLE_TEST_OBJS += reftable/block_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/basics_test.o
reftable/block.c new file +446 -0
446 lines not on this page · raw message
reftable/block.h new file +127 -0
127 lines not on this page · raw message
reftable/block_test.c new file +121 -0
121 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -4,6 +4,7 @@int cmd__reftable (int argc,const char **argv) {basics_test_main (argc, argv); +block_test_main (argc, argv);record_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH 11/26 reftable: write reftable files
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- Makefile | 1 + reftable/reftable-writer.h | 148 ++++++++ reftable/writer.c | 690 +++++++++++++++++++++++++++++++++++++ reftable/writer.h | 50 +++ 4 files changed, 889 insertions(+) create mode 100644 reftable/reftable-writer.h create mode 100644 reftable/writer.c create mode 100644 reftable/writer.h
Makefile +1 -0
@@ -2455,6 +2455,7 @@ REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o REFTABLE_OBJS += reftable/tree.o +REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o
reftable/reftable-writer.h new file +148 -0
148 lines not on this page · raw message
reftable/writer.c new file +690 -0
690 lines not on this page · raw message
reftable/writer.h new file +50 -0
50 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH 12/26 reftable: generic interface to tables
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- Makefile | 3 + reftable/generic.c | 169 +++++++++++++++++++++++++++++++++++ reftable/generic.h | 32 +++++++ reftable/reftable-generic.h | 47 ++++++++++ reftable/reftable-iterator.h | 39 ++++++++ reftable/reftable.c | 115 ++++++++++++++++++++++++ 6 files changed, 405 insertions(+) create mode 100644 reftable/generic.c create mode 100644 reftable/generic.h create mode 100644 reftable/reftable-generic.h create mode 100644 reftable/reftable-iterator.h create mode 100644 reftable/reftable.c
Makefile +3 -0
@@ -2454,6 +2454,9 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o +REFTABLE_OBJS += reftable/refname.o +REFTABLE_OBJS += reftable/generic.o +REFTABLE_OBJS += reftable/stack.o REFTABLE_OBJS += reftable/tree.o REFTABLE_OBJS += reftable/writer.o
reftable/generic.c new file +169 -0
169 lines not on this page · raw message
reftable/generic.h new file +32 -0
@@ -0,0 +1,32 @@ +/* +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 GENERIC_H +#define GENERIC_H + +#include "record.h" +#include "reftable-generic.h" + +/* generic interface to reftables */ +struct reftable_table_vtable { +int (*seek_record)(void *tab,struct reftable_iterator *it, +struct reftable_record *); +uint32_t (*hash_id)(void *tab); +uint64_t (*min_update_index)(void *tab); +uint64_t (*max_update_index)(void *tab); +}; + +struct reftable_iterator_vtable { +int (*next)(void *iter_arg,struct reftable_record *rec); +void (*close)(void *iter_arg); +}; + +void iterator_set_empty (struct reftable_iterator *it); +int iterator_next (struct reftable_iterator *it,struct reftable_record *rec); + +#endif
reftable/reftable-generic.h new file +47 -0
47 lines not on this page · raw message
reftable/reftable-iterator.h new file +39 -0
@@ -0,0 +1,39 @@ +/* +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 REFTABLE_ITERATOR_H +#define REFTABLE_ITERATOR_H + +#include "reftable-record.h" + +struct reftable_iterator_vtable ; + +/* iterator is the generic interface for walking over data stored in a +* reftable. +*/ +struct reftable_iterator { +struct reftable_iterator_vtable *ops; +void *iter_arg; +}; + +/* reads the next reftable_ref_record. Returns < 0 for error, 0 for OK and > 0: +* end of iteration. +*/ +int reftable_iterator_next_ref (struct reftable_iterator *it, +struct reftable_ref_record *ref); + +/* reads the next reftable_log_record. Returns < 0 for error, 0 for OK and > 0: +* end of iteration. +*/ +int reftable_iterator_next_log (struct reftable_iterator *it, +struct reftable_log_record *log); + +/* releases resources associated with an iterator. */ +void reftable_iterator_destroy (struct reftable_iterator *it); + +#endif
reftable/reftable.c new file +115 -0
115 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH 14/26 reftable: reftable file level tests
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
With support for reading and writing files in place, we can construct files (in memory) and attempt to read them back.
Because some sections of the format are optional (eg. indices, log entries), we have to exercise this code using multiple sizes of input data
--- Makefile | 1 + reftable/readwrite_test.c | 650 ++++++++++++++++++++++++++++++++++++++ reftable/reftable-tests.h | 2 +- t/helper/test-reftable.c | 1 + 4 files changed, 653 insertions(+), 1 deletion(-) create mode 100644 reftable/readwrite_test.c
Makefile +1 -0
@@ -2465,6 +2465,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o REFTABLE_TEST_OBJS += reftable/record_test.o +REFTABLE_TEST_OBJS += reftable/readwrite_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/tree_test.o
reftable/readwrite_test.c new file +650 -0
650 lines not on this page · raw message
reftable/reftable-tests.h +1 -1
@@ -14,7 +14,7 @@ int block_test_main(int argc, const char **argv);int merged_test_main (int argc,const char **argv);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 readwrite_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);
t/helper/test-reftable.c +1 -0
@@ -6,6 +6,7 @@ int cmd__reftable(int argc, const char **argv)basics_test_main (argc, argv);block_test_main (argc, argv);record_test_main (argc, argv); +readwrite_test_main (argc, argv);tree_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH 19/26 reftable: add dump utility
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
provide a command-line utility for inspecting individual tables, and inspecting a complete ref database
--- reftable/dump.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 reftable/dump.c
reftable/dump.c new file +105 -0
@@ -0,0 +1,105 @@ +/* +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 "reftable-blocksource.h" +#include "reftable-error.h" +#include "reftable-merged.h" +#include "reftable-record.h" +#include "reftable-tests.h" +#include "reftable-writer.h" +#include "reftable-iterator.h" +#include "reftable-reader.h" +#include "reftable-stack.h" +#include "reftable-generic.h" +#include "hash.h" + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +static int compact_stack (const char *stackdir) +{ +struct reftable_stack *stack =NULL ; +struct reftable_write_options cfg = {0 }; + +int err =reftable_new_stack (&stack, stackdir, cfg); +if (err <0 ) + goto done; + + err =reftable_stack_compact_all (stack,NULL ); +if (err <0 ) + goto done; +done: +if (stack) { +reftable_stack_destroy (stack); + } +return err; +} + +static void print_help (void ) +{ +printf ("usage: dump [-cst] arg\n\n" +"options: \n" +" -c compact\n" +" -t dump table\n" +" -s dump stack\n" +" -6 sha256 hash format\n" +" -h this help\n" +"\n" ); +} + +int reftable_dump_main (int argc,char *const *argv) +{ +int err =0 ; +int opt_dump_table =0 ; +int opt_dump_stack =0 ; +int opt_compact =0 ; +uint32_t opt_hash_id =GIT_SHA1_FORMAT_ID ; +const char *arg =NULL , *argv0 = argv[0 ]; + +for (; argc >1 ; argv++, argc--) +if (*argv[1 ] !='-' ) +break ; +else if (!strcmp ("-t" , argv[1 ])) + opt_dump_table =1 ; +else if (!strcmp ("-6" , argv[1 ])) + opt_hash_id =GIT_SHA256_FORMAT_ID ; +else if (!strcmp ("-s" , argv[1 ])) + opt_dump_stack =1 ; +else if (!strcmp ("-c" , argv[1 ])) + opt_compact =1 ; +else if (!strcmp ("-?" , argv[1 ]) || !strcmp ("-h" , argv[1 ])) { +print_help (); +return 2 ; + } + +if (argc !=2 ) { +fprintf (stderr,"need argument\n" ); +print_help (); +return 2 ; + } + + arg = argv[1 ]; + +if (opt_dump_table) { + err =reftable_reader_print_file (arg); + }else if (opt_dump_stack) { + err =reftable_stack_print_directory (arg, opt_hash_id); + }else if (opt_compact) { + err =compact_stack (arg); + } + +if (err <0 ) { +fprintf (stderr,"%s: %s: %s\n" , argv0, arg, +reftable_error_str (err)); +return 1 ; + } +return 0 ; +}
Signature · 1 line
gitgitgadget
PATCH 16/26 reftable: add merged table view
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This adds an abstract, read-only interface to the ref database.
This primitive is used to construct the read view of the ref database (the read view is constructed by merging several *.ref files). It also provides the mechanism to provide a unified view of the refs in the main repository and the per-worktree refs.
--- Makefile | 2 + reftable/merged.c | 362 +++++++++++++++++++++++++++++++++++++ reftable/merged.h | 35 ++++ reftable/merged_test.c | 292 ++++++++++++++++++++++++++++++ reftable/reftable-merged.h | 72 ++++++++ t/helper/test-reftable.c | 1 + 6 files changed, 764 insertions(+) create mode 100644 reftable/merged.c create mode 100644 reftable/merged.h create mode 100644 reftable/merged_test.c create mode 100644 reftable/reftable-merged.h
Makefile +2 -0
@@ -2454,6 +2454,7 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/iter.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/merged.o REFTABLE_OBJS += reftable/pq.o REFTABLE_OBJS += reftable/reader.o REFTABLE_OBJS += reftable/record.o
@@ -2465,6 +2466,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o +REFTABLE_TEST_OBJS += reftable/merged_test.o REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o
reftable/merged.c new file +362 -0
362 lines not on this page · raw message
reftable/merged.h new file +35 -0
@@ -0,0 +1,35 @@ +/* +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 MERGED_H +#define MERGED_H + +#include "pq.h" + +struct reftable_merged_table { +struct reftable_table *stack; +size_t stack_len; +uint32_t hash_id; +int suppress_deletions; + +uint64_t min; +uint64_t max; +}; + +struct merged_iter { +struct reftable_iterator *stack; +uint32_t hash_id; +size_t stack_len; +uint8_t typ; +int suppress_deletions; +struct merged_iter_pqueue pq; +}; + +void merged_table_release (struct reftable_merged_table *mt); + +#endif
reftable/merged_test.c new file +292 -0
292 lines not on this page · raw message
reftable/reftable-merged.h new file +72 -0
72 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -5,6 +5,7 @@ int cmd__reftable(int argc, const char **argv) {basics_test_main (argc, argv);block_test_main (argc, argv); +merged_test_main (argc, argv);pq_test_main (argc, argv);record_test_main (argc, argv);readwrite_test_main (argc, argv);
Signature · 1 line
gitgitgadget
PATCH 17/26 reftable: implement refname validation
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The packed/loose format has restrictions on refnames: a and a/b cannot coexist. This limitation does not apply to reftable per se, but must be maintained for interoperability. This code adds validation routines to abort transactions that are trying to add invalid names.
--- Makefile | 1 + reftable/refname.c | 209 +++++++++++++++++++++++++++++++++++++++ reftable/refname.h | 29 ++++++ reftable/refname_test.c | 102 +++++++++++++++++++ t/helper/test-reftable.c | 1 + 5 files changed, 342 insertions(+) create mode 100644 reftable/refname.c create mode 100644 reftable/refname.h create mode 100644 reftable/refname_test.c
Makefile +1 -0
@@ -2470,6 +2470,7 @@ REFTABLE_TEST_OBJS += reftable/merged_test.o REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o +REFTABLE_TEST_OBJS += reftable/refname_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/tree_test.o
reftable/refname.c new file +209 -0
209 lines not on this page · raw message
reftable/refname.h new file +29 -0
@@ -0,0 +1,29 @@ +/* +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 REFNAME_H +#define REFNAME_H + +#include "reftable-record.h" +#include "reftable-generic.h" + +struct modification { +struct reftable_table tab; + +char **add; +size_t add_len; + +char **del; +size_t del_len; +}; + +int validate_ref_record_addition (struct reftable_table tab, +struct reftable_ref_record *recs,size_t sz); + +int modification_validate (struct modification *mod); + +#endif
reftable/refname_test.c new file +102 -0
102 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -8,6 +8,7 @@ int cmd__reftable(int argc, const char **argv)merged_test_main (argc, argv);pq_test_main (argc, argv);record_test_main (argc, argv); +refname_test_main (argc, argv);readwrite_test_main (argc, argv);tree_test_main (argc, argv);return 0 ;
Signature · 1 line
gitgitgadget
PATCH 20/26 refs: RFC: Reftable support for git-core
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
For background, see Documentation/technical/reftable.txt.
This introduces the file refs/reftable-backend.c containing a reftable-powered ref storage backend.
It can be activated by setting GIT_TEST_REFTABLE in the environment. When GIT_TEST_REFTABLE is set, the test prerequisite !REFFILES is set.
There is no option to git-init for now, as the test suite still shows failures with GIT_TEST_REFTABLE=1.
Example use: see t/t0031-reftable.sh
--- Documentation/config/extensions.txt | 9 + .../technical/repository-version.txt | 7 + Makefile | 1 + builtin/clone.c | 5 +- builtin/init-db.c | 39 +- builtin/stash.c | 8 +- builtin/worktree.c | 27 +- cache.h | 8 +- config.mak.uname | 2 +- contrib/buildsystems/Generators/Vcxproj.pm | 11 +- refs.c | 26 +- refs.h | 3 + refs/refs-internal.h | 1 + refs/reftable-backend.c | 1683 +++++++++++++++++ repository.c | 2 + repository.h | 3 + setup.c | 6 + t/t0031-reftable.sh | 291 +++ t/t1409-avoid-packing-refs.sh | 6 + t/t1450-fsck.sh | 6 + t/t3210-pack-refs.sh | 6 + t/test-lib.sh | 7 +- 22 files changed, 2129 insertions(+), 28 deletions(-) create mode 100644 refs/reftable-backend.c create mode 100755 t/t0031-reftable.sh
Documentation/config/extensions.txt +9 -0
@@ -6,3 +6,12 @@ extensions.objectFormat:: Note that this setting should only be set by linkgit:git-init[1] or linkgit:git-clone[1]. Trying to change it after initialization will not work and will produce hard-to-diagnose issues. ++ +extensions.refStorage:: + Specify the ref storage mechanism to use. The acceptable values are `files` and + `reftable`. If not specified, `files` is assumed. It is an error to specify + this key unless `core.repositoryFormatVersion` is 1. ++ +Note that this setting should only be set by linkgit:git-init[1] or +linkgit:git-clone[1]. Trying to change it after initialization will not +work and will produce hard-to-diagnose issues.
Documentation/technical/repository-version.txt +7 -0
@@ -100,3 +100,10 @@ If set, by default "git config" reads from both "config" and multiple working directory mode, "config" file is shared while "config.worktree" is per-working directory (i.e., it's in GIT_COMMON_DIR/worktrees/<id>/config.worktree) + +==== `refStorage` + +Specifies the file format for the ref database. Values are `files` +(for the traditional packed + loose ref format) and `reftable` for the +binary reftable format. See https://github.com/google/reftable for +more information.
Makefile +1 -0
@@ -986,6 +986,7 @@ LIB_OBJS += reflog-walk.o LIB_OBJS += refs.o LIB_OBJS += refs/debug.o LIB_OBJS += refs/files-backend.o +LIB_OBJS += refs/reftable-backend.o LIB_OBJS += refs/iterator.o LIB_OBJS += refs/packed-backend.o LIB_OBJS += refs/ref-cache.o
builtin/clone.c +3 -2
@@ -1148,7 +1148,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) }init_db (git_dir, real_git_dir, option_template,GIT_HASH_UNKNOWN ,NULL , -INIT_DB_QUIET ); +default_ref_storage (),INIT_DB_QUIET );if (real_git_dir) git_dir = real_git_dir;
@@ -1299,7 +1299,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)* Now that we know what algorithm the remote side is using, * let's set ours to the same thing. */ -initialize_repository_version (hash_algo,1 ); +initialize_repository_version (hash_algo,1 , +default_ref_storage ());repo_set_hash_algo (the_repository, hash_algo); mapped_refs =wanted_peer_refs (refs, &remote->fetch);
builtin/init-db.c +31 -8
@@ -167,12 +167,14 @@ static int needs_work_tree_config(const char *git_dir, const char *work_tree)return 1 ; } -void initialize_repository_version (int hash_algo,int reinit) +void initialize_repository_version (int hash_algo,int reinit, +const char *ref_storage_format) {char repo_version_string[10 ];int repo_version =GIT_REPO_VERSION ; -if (hash_algo !=GIT_HASH_SHA1 ) +if (hash_algo !=GIT_HASH_SHA1 || + !strcmp (ref_storage_format,"reftable" )) repo_version =GIT_REPO_VERSION_READ ;/* This forces creation of new config file */
@@ -226,6 +228,7 @@ static int create_default_files(const char *template_path, is_bare_repository_cfg = init_is_bare_repository || !work_tree;if (init_shared_repository !=-1 )set_shared_repository (init_shared_repository); + the_repository->ref_storage_format =xstrdup (fmt->ref_storage);/* * We would have created the above under user's umask -- under
@@ -235,6 +238,24 @@ static int create_default_files(const char *template_path,adjust_shared_perm (get_git_dir ()); } +/* +* Check to see if .git/HEAD exists; this must happen before +* initializing the ref db, because we want to see if there is an +* existing HEAD. +*/ + path =git_path_buf (&buf,"HEAD" ); + reinit = (!access (path,R_OK ) || +readlink (path, junk,sizeof (junk) -1 ) !=-1 ); + +/* +* refs/heads is a file when using reftable. We can't reinitialize with +* a reftable because it will overwrite HEAD +*/ +if (reinit && (!strcmp (fmt->ref_storage,"reftable" )) == +is_directory (git_path_buf (&buf,"refs/heads" ))) { +die ("cannot switch ref storage format." ); + } +/* * We need to create a "refs" dir in any case so that older * versions of git can tell that this is a repository.
@@ -249,9 +270,6 @@ static int create_default_files(const char *template_path,* Point the HEAD symref to the initial branch with if HEAD does * not yet exist. */ - path =git_path_buf (&buf,"HEAD" ); - reinit = (!access (path,R_OK ) - ||readlink (path, junk,sizeof (junk)-1 ) !=-1 );if (!reinit) {char *ref;
@@ -268,7 +286,7 @@ static int create_default_files(const char *template_path,free (ref); } -initialize_repository_version (fmt->hash_algo,0 ); +initialize_repository_version (fmt->hash_algo,0 , fmt->ref_storage);/* Check filemode trustability */ path =git_path_buf (&buf,"config" );
@@ -383,7 +401,7 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hashint init_db (const char *git_dir,const char *real_git_dir,const char *template_dir,int hash,const char *initial_branch, -unsigned int flags) +const char *ref_storage_format,unsigned int flags) {int reinit;int exist_ok = flags &INIT_DB_EXIST_OK ;
@@ -422,6 +440,7 @@ int init_db(const char *git_dir, const char *real_git_dir,* is an attempt to reinitialize new repository with an old tool. */ check_repository_format (&repo_fmt); + repo_fmt.ref_storage =xstrdup (ref_storage_format);validate_hash_algorithm (&repo_fmt, hash);
@@ -476,6 +495,9 @@ int init_db(const char *git_dir, const char *real_git_dir,git_config_set ("receive.denyNonFastforwards" ,"true" ); } +if (!strcmp (ref_storage_format,"reftable" )) +git_config_set ("extensions.refStorage" , ref_storage_format); +if (!(flags &INIT_DB_QUIET )) {int len =strlen (git_dir);
@@ -549,6 +571,7 @@ static const char *const init_db_usage[] = {int cmd_init_db (int argc,const char **argv,const char *prefix) {const char *git_dir; +const char *ref_storage_format =default_ref_storage ();const char *real_git_dir =NULL ;const char *work_tree;const char *template_dir =NULL ;
@@ -713,5 +736,5 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) flags |=INIT_DB_EXIST_OK ;return init_db (git_dir, real_git_dir, template_dir, hash_algo, - initial_branch, flags); + initial_branch, ref_storage_format, flags); }
builtin/stash.c +7 -1
@@ -207,10 +207,16 @@ static int get_stash_info(struct stash_info *info, int argc, const char **argv)static int do_clear_stash (void ) {struct object_id obj; +int result;if (get_oid (ref_stash, &obj))return 0 ; -return delete_ref (NULL , ref_stash, &obj,0 ); + result =delete_ref (NULL , ref_stash, &obj,0 ); + +/* Ignore error; this is necessary for reftable, which keeps reflogs +* even when refs are deleted. */ +delete_reflog (ref_stash); +return result; }static int clear_stash (int argc,const char **argv,const char *prefix)
builtin/worktree.c +24 -3
@@ -13,6 +13,7 @@#include "utf8.h" #include "worktree.h" #include "quote.h" +#include "../refs/refs-internal.h" static const char *const worktree_usage[] = {N_ ("git worktree add [<options>] <path> [<commit-ish>]" ),
@@ -328,9 +329,29 @@ static int add_worktree(const char *path, const char *refname,* worktree. */ strbuf_reset (&sb); -strbuf_addf (&sb,"%s/HEAD" , sb_repo.buf); -write_file (sb.buf,"%s" ,oid_to_hex (null_oid ())); -strbuf_reset (&sb); +if (get_main_ref_store (the_repository)->be == &refs_be_reftable) { +/* XXX this is cut & paste from reftable_init_db. */ +strbuf_addf (&sb,"%s/HEAD" , sb_repo.buf); +write_file (sb.buf,"%s" ,"ref: refs/heads/.invalid\n" ); +strbuf_reset (&sb); + +strbuf_addf (&sb,"%s/refs" , sb_repo.buf); +safe_create_dir (sb.buf,1 ); +strbuf_reset (&sb); + +strbuf_addf (&sb,"%s/refs/heads" , sb_repo.buf); +write_file (sb.buf,"this repository uses the reftable format" ); +strbuf_reset (&sb); + +strbuf_addf (&sb,"%s/reftable" , sb_repo.buf); +safe_create_dir (sb.buf,1 ); +strbuf_reset (&sb); + }else { +strbuf_addf (&sb,"%s/HEAD" , sb_repo.buf); +write_file (sb.buf,"%s" ,oid_to_hex (null_oid ())); +strbuf_reset (&sb); + } +strbuf_addf (&sb,"%s/commondir" , sb_repo.buf);write_file (sb.buf,"../.." );
cache.h +5 -3
@@ -647,9 +647,10 @@ int path_inside_repo(const char *prefix, const char *path);#define INIT_DB_EXIST_OK 0x0002int init_db (const char *git_dir,const char *real_git_dir, -const char *template_dir,int hash_algo, -const char *initial_branch,unsigned int flags); -void initialize_repository_version (int hash_algo,int reinit); +const char *template_dir,int hash_algo,const char *initial_branch, +const char *ref_storage_format,unsigned int flags); +void initialize_repository_version (int hash_algo,int reinit, +const char *ref_storage_format);void sanitize_stdfds (void );int daemonize (void );
@@ -1067,6 +1068,7 @@ struct repository_format {int hash_algo;int sparse_index;char *work_tree; +char *ref_storage;struct string_list unknown_extensions;struct string_list v1_only_extensions; };
config.mak.uname +1 -1
@@ -711,7 +711,7 @@ vcxproj: # Make .vcxproj files and add them unset QUIET_GEN QUIET_BUILT_IN; \ perl contrib/buildsystems/generate -g Vcxproj - git add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj + git add -f git.sln {*,*/lib,*/libreftable,t/helper/*}/*.vcxproj # Generate the LinkOrCopyBuiltins.targets and LinkOrCopyRemoteHttp.targets file (echo '<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">' && \
contrib/buildsystems/Generators/Vcxproj.pm +10 -1
@@ -77,7 +77,7 @@ sub createProject { my $libs_release = "\n "; my $libs_debug = "\n "; if (!$static_library) { - $libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}})); + $libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib|reftable\/libreftable\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}})); $libs_debug = $libs_release; $libs_debug =~ s/zlib\.lib/zlibd\.lib/g; $libs_debug =~ s/libexpat\.lib/libexpatd\.lib/g;
@@ -232,6 +232,7 @@ EOM EOM if (!$static_library || $target =~ 'vcs-svn' || $target =~ 'xdiff') { my $uuid_libgit = $$build_structure{"LIBS_libgit_GUID"}; + my $uuid_libreftable = $$build_structure{"LIBS_reftable/libreftable_GUID"}; my $uuid_xdiff_lib = $$build_structure{"LIBS_xdiff/lib_GUID"}; print F << "EOM";
@@ -241,6 +242,14 @@ EOM <ReferenceOutputAssembly>false</ReferenceOutputAssembly> </ProjectReference> EOM + if (!($name =~ /xdiff|libreftable/)) { + print F << "EOM"; + <ProjectReference Include="$cdup\\reftable\\libreftable\\libreftable.vcxproj"> + <Project>$uuid_libreftable</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> +EOM + } if (!($name =~ 'xdiff')) { print F << "EOM"; <ProjectReference Include="$cdup\\xdiff\\lib\\xdiff_lib.vcxproj">
refs.c +18 -8
@@ -19,10 +19,15 @@#include "repository.h" #include "sigchain.h" +const char *default_ref_storage (void ) +{ +return git_env_bool ("GIT_TEST_REFTABLE" ,0 ) ?"reftable" :"files" ; +} +/* * List of all available backends */ -static struct ref_storage_be *refs_backends = &refs_be_files; +static struct ref_storage_be *refs_backends = &refs_be_reftable;static struct ref_storage_be *find_ref_storage_backend (const char *name) {
@@ -1875,13 +1880,13 @@ static struct ref_store *lookup_ref_store_map(struct hashmap *map,* Create, record, and return a ref_store instance for the specified * gitdir. */ -static struct ref_store *ref_store_init (const char *gitdir, +static struct ref_store *ref_store_init (const char *gitdir,const char *be_name,unsigned int flags) { -const char *be_name ="files" ; -struct ref_storage_be *be =find_ref_storage_backend (be_name); +struct ref_storage_be *be;struct ref_store *refs; + be =find_ref_storage_backend (be_name);if (!be)BUG ("reference backend %s is unknown" , be_name);
@@ -1897,7 +1902,11 @@ struct ref_store *get_main_ref_store(struct repository *r)if (!r->gitdir)BUG ("attempting to get main_ref_store outside of repository" ); - r->refs_private =ref_store_init (r->gitdir,REF_STORE_ALL_CAPS ); + r->refs_private =ref_store_init (r->gitdir, + r->ref_storage_format ? + r->ref_storage_format : +default_ref_storage (), +REF_STORE_ALL_CAPS ); r->refs_private =maybe_debug_wrap_ref_store (r->gitdir, r->refs_private);return r->refs_private; }
@@ -1953,7 +1962,7 @@ 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, + 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);
@@ -1967,6 +1976,7 @@ done:struct ref_store *get_worktree_ref_store (const struct worktree *wt) { +const char *format =default_ref_storage ();struct ref_store *refs;const char *id;
@@ -1980,9 +1990,9 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt)if (wt->id) refs =ref_store_init (git_common_path ("worktrees/%s" , wt->id), -REF_STORE_ALL_CAPS ); + format,REF_STORE_ALL_CAPS );else - refs =ref_store_init (get_git_common_dir (), + refs =ref_store_init (get_git_common_dir (), format,REF_STORE_ALL_CAPS );if (refs)
refs.h +3 -0
@@ -11,6 +11,9 @@ struct string_list;struct string_list_item ;struct worktree ; +/* Returns the ref storage backend to use by default. */ +const char *default_ref_storage (void ); +/* * Resolve a reference, recursively following symbolic refererences. *
refs/refs-internal.h +1 -0
@@ -672,6 +672,7 @@ struct ref_storage_be { };extern struct ref_storage_be refs_be_files; +extern struct ref_storage_be refs_be_reftable;extern struct ref_storage_be refs_be_packed;/*
refs/reftable-backend.c new file +1683 -0
1,683 lines not on this page · raw message
repository.c +2 -0
@@ -180,6 +180,8 @@ int repo_init(struct repository *repo,if (worktree)repo_set_worktree (repo, worktree); + repo->ref_storage_format =xstrdup_or_null (format.ref_storage); +clear_repository_format (&format);return 0 ;
repository.h +3 -0
@@ -82,6 +82,9 @@ struct repository {*/ struct ref_store *refs_private; +/* The format to use for the ref database. */ +char *ref_storage_format; +/* * Contains path to often used file names. */
setup.c +6 -0
@@ -498,6 +498,9 @@ static enum extension_result handle_extension(const char *var,return error ("invalid value for 'extensions.objectformat'" ); data->hash_algo = format;return EXTENSION_OK ; + }else if (!strcmp (ext,"refstorage" )) { + data->ref_storage =xstrdup (value); +return EXTENSION_OK ; }return EXTENSION_UNKNOWN ; }
@@ -648,6 +651,7 @@ void clear_repository_format(struct repository_format *format)string_list_clear (&format->v1_only_extensions,0 );free (format->work_tree);free (format->partial_clone); +free (format->ref_storage);init_repository_format (format); }
@@ -1312,6 +1316,8 @@ const char *setup_git_directory_gently(int *nongit_ok) the_repository->repository_format_partial_clone = repo_fmt.partial_clone; repo_fmt.partial_clone =NULL ; + the_repository->ref_storage_format = +xstrdup_or_null (repo_fmt.ref_storage); } }/*
t/t0031-reftable.sh new file +291 -0
291 lines not on this page · raw message
t/t1409-avoid-packing-refs.sh +6 -0
@@ -4,6 +4,12 @@ test_description='avoid rewriting packed-refs unnecessarily' . ./test-lib.sh +if test_have_prereq !REFFILES +then + skip_all='skipping pack-refs tests; need files backend' + test_done +fi + # Add an identifying mark to the packed-refs file header line. This # shouldn't upset readers, and it should be omitted if the file is # ever rewritten.
t/t1450-fsck.sh +6 -0
@@ -8,6 +8,12 @@ test_description='git fsck random collection of tests . ./test-lib.sh +if test_have_prereq !REFFILES +then + skip_all='skipping tests; incompatible with reftable' + test_done +fi + test_expect_success setup ' git config gc.auto 0 && git config i18n.commitencoding ISO-8859-1 &&
t/t3210-pack-refs.sh +6 -0
@@ -14,6 +14,12 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh +if test_have_prereq !REFFILES +then + skip_all='skipping pack-refs tests; requires files ref backend' + test_done +fi + test_expect_success 'enable reflogs' ' git config core.logallrefupdates true '
t/test-lib.sh +6 -1
@@ -1509,7 +1509,12 @@ parisc* | hppa*) ;; esac -test_set_prereq REFFILES +if test -n "$GIT_TEST_REFTABLE" +then + test_set_prereq !REFFILES +else + test_set_prereq REFFILES +fi ( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1 test -z "$NO_PERL" && test_set_prereq PERL
Signature · 1 line
gitgitgadget
PATCH 23/26 t1301: document what needs to be done for reftable
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- t/t1301-shared-repo.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
t/t1301-shared-repo.sh +5 -3
@@ -22,9 +22,10 @@ test_expect_success 'shared = 0400 (faulty permission u-w)' ' ) ' +# TODO(hanwen): for REFTABLE should inspect group-readable of .git/reftable/ for u in 002 022 do - test_expect_success POSIXPERM "shared=1 does not clear bits preset by umask $u" ' + test_expect_success REFFILES,POSIXPERM "shared=1 does not clear bits preset by umask $u" ' mkdir sub && ( cd sub && umask $u &&
@@ -114,7 +115,8 @@ test_expect_success POSIXPERM 'info/refs respects umask in unshared repo' ' test_cmp expect actual ' -test_expect_success POSIXPERM 'git reflog expire honors core.sharedRepository' ' +# For reftable, the check on .git/reftable/ is sufficient. +test_expect_success REFFILES,POSIXPERM 'git reflog expire honors core.sharedRepository' ' umask 077 && git config core.sharedRepository group && git reflog expire --all &&
@@ -201,7 +203,7 @@ test_expect_success POSIXPERM 're-init respects core.sharedrepository (remote)' test_cmp expect actual ' -test_expect_success POSIXPERM 'template can set core.sharedrepository' ' +test_expect_success REFFILES,POSIXPERM 'template can set core.sharedrepository' ' rm -rf child.git && umask 0022 && git config core.sharedrepository 0666 &&
Signature · 1 line
gitgitgadget
PATCH 24/26 t1401,t2011: parameterize HEAD.lock for REFFILES
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- t/t1401-symbolic-ref.sh | 11 +++++++++-- t/t2011-checkout-invalid-head.sh | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-)
t/t1401-symbolic-ref.sh +9 -2
@@ -102,9 +102,16 @@ test_expect_success LONG_REF 'we can parse long symbolic ref' ' test_cmp expect actual ' +if test_have_prereq REFFILES +then + HEAD_LOCK=HEAD.lock +else + HEAD_LOCK=reftable/tables.list.lock +fi + test_expect_success 'symbolic-ref reports failure in exit code' ' - test_when_finished "rm -f .git/HEAD.lock" && - >.git/HEAD.lock && + test_when_finished "rm -f .git/$HEAD_LOCK" && + >.git/$HEAD_LOCK && test_must_fail git symbolic-ref HEAD refs/heads/whatever '
t/t2011-checkout-invalid-head.sh +9 -2
@@ -22,9 +22,16 @@ test_expect_success 'checkout main from invalid HEAD' ' git checkout main -- ' +if test_have_prereq REFFILES +then + HEAD_LOCK=HEAD.lock +else + HEAD_LOCK=reftable/tables.list.lock +fi + test_expect_success 'checkout notices failure to lock HEAD' ' - test_when_finished "rm -f .git/HEAD.lock" && - >.git/HEAD.lock && + test_when_finished "rm -f .git/$HEAD_LOCK" && + >.git/$HEAD_LOCK && test_must_fail git checkout -b other '
Signature · 1 line
gitgitgadget
PATCH 25/26 t1404: annotate test cases with REFFILES
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
* Reftable for now lacks detailed error messages for directory/file conflicts. Skip message comparisons.
* Mark tests that muck with .git directly as REFFILES.
--- t/t1404-update-ref-errors.sh | 56 +++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 14 deletions(-)
t/t1404-update-ref-errors.sh +42 -14
@@ -27,7 +27,9 @@ test_update_rejected () { fi && printf "create $prefix/%s $C\n" $create >input && test_must_fail git update-ref --stdin <input 2>output.err && - test_i18ngrep -F "$error" output.err && + if test_have_prereq REFFILES ; then + test_i18ngrep -F "$error" output.err + fi && git for-each-ref $prefix >actual && test_cmp unchanged actual }
@@ -101,7 +103,9 @@ df_test() { printf "%s\n" "delete $delname" "create $addname $D" fi >commands && test_must_fail git update-ref --stdin <commands 2>output.err && - test_cmp expected-err output.err && + if test_have_prereq REFFILES ; then + test_cmp expected-err output.err + fi && printf "%s\n" "$C $delref" >expected-refs && git for-each-ref --format="%(objectname) %(refname)" $prefix/r >actual-refs && test_cmp expected-refs actual-refs
@@ -336,7 +340,9 @@ test_expect_success 'missing old value blocks update' ' EOF printf "%s\n" "update $prefix/foo $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks update' '
@@ -347,7 +353,9 @@ test_expect_success 'incorrect old value blocks update' ' EOF printf "%s\n" "update $prefix/foo $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'existing old value blocks create' '
@@ -358,7 +366,9 @@ test_expect_success 'existing old value blocks create' ' EOF printf "%s\n" "create $prefix/foo $E" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks delete' '
@@ -369,7 +379,9 @@ test_expect_success 'incorrect old value blocks delete' ' EOF printf "%s\n" "delete $prefix/foo $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'missing old value blocks indirect update' '
@@ -380,7 +392,9 @@ test_expect_success 'missing old value blocks indirect update' ' EOF printf "%s\n" "update $prefix/symref $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks indirect update' '
@@ -392,7 +406,9 @@ test_expect_success 'incorrect old value blocks indirect update' ' EOF printf "%s\n" "update $prefix/symref $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'existing old value blocks indirect create' '
@@ -404,7 +420,9 @@ test_expect_success 'existing old value blocks indirect create' ' EOF printf "%s\n" "create $prefix/symref $E" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks indirect delete' '
@@ -416,7 +434,9 @@ test_expect_success 'incorrect old value blocks indirect delete' ' EOF printf "%s\n" "delete $prefix/symref $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'missing old value blocks indirect no-deref update' '
@@ -427,7 +447,9 @@ test_expect_success 'missing old value blocks indirect no-deref update' ' EOF printf "%s\n" "option no-deref" "update $prefix/symref $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks indirect no-deref update' '
@@ -439,7 +461,9 @@ test_expect_success 'incorrect old value blocks indirect no-deref update' ' EOF printf "%s\n" "option no-deref" "update $prefix/symref $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'existing old value blocks indirect no-deref create' '
@@ -451,7 +475,9 @@ test_expect_success 'existing old value blocks indirect no-deref create' ' EOF printf "%s\n" "option no-deref" "create $prefix/symref $E" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks indirect no-deref delete' '
@@ -463,7 +489,9 @@ test_expect_success 'incorrect old value blocks indirect no-deref delete' ' EOF printf "%s\n" "option no-deref" "delete $prefix/symref $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success REFFILES 'non-empty directory blocks create' '
Signature · 1 line
gitgitgadget
PATCH 26/26 t7004: avoid direct filesystem access
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- t/t7004-tag.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
t/t7004-tag.sh +5 -2
@@ -97,7 +97,8 @@ test_expect_success 'creating a tag with --create-reflog should create reflog' ' test_when_finished "git tag -d tag_with_reflog" && git tag --create-reflog tag_with_reflog && git reflog exists refs/tags/tag_with_reflog && - sed -e "s/^.* //" .git/logs/refs/tags/tag_with_reflog >actual && + git reflog --format="format:tag: tagging %h (%s, %cd)%n" \ + --date=format:%Y-%m-%d refs/tags/tag_with_reflog >actual && test_cmp expected actual '
@@ -108,7 +109,9 @@ test_expect_success 'annotated tag with --create-reflog has correct message' ' test_when_finished "git tag -d tag_with_reflog" && git tag -m "annotated tag" --create-reflog tag_with_reflog && git reflog exists refs/tags/tag_with_reflog && - sed -e "s/^.* //" .git/logs/refs/tags/tag_with_reflog >actual && + git reflog \ + --format="format:tag: tagging %h (%s, %cd)%n" \ + --date=format:%Y-%m-%d >actual && test_cmp expected actual '
Signature · 1 line
gitgitgadget
PATCH 18/26 reftable: implement stack, a mutable database of reftable files.
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- Makefile | 1 + reftable/reftable-stack.h | 128 ++++ reftable/stack.c | 1396 +++++++++++++++++++++++++++++++++++++ reftable/stack.h | 41 ++ reftable/stack_test.c | 947 +++++++++++++++++++++++++ t/helper/test-reftable.c | 1 + 6 files changed, 2514 insertions(+) create mode 100644 reftable/reftable-stack.h create mode 100644 reftable/stack.c create mode 100644 reftable/stack.h create mode 100644 reftable/stack_test.c
Makefile +1 -0
@@ -2471,6 +2471,7 @@ REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o REFTABLE_TEST_OBJS += reftable/refname_test.o +REFTABLE_TEST_OBJS += reftable/stack_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/tree_test.o
reftable/reftable-stack.h new file +128 -0
128 lines not on this page · raw message
reftable/stack.c new file +1396 -0
1,396 lines not on this page · raw message
reftable/stack.h new file +41 -0
41 lines not on this page · raw message
reftable/stack_test.c new file +947 -0
947 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -10,6 +10,7 @@ int cmd__reftable(int argc, const char **argv)record_test_main (argc, argv);refname_test_main (argc, argv);readwrite_test_main (argc, argv); +stack_test_main (argc, argv);tree_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH 21/26 git-prompt: prepare for reftable refs backend
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: =?UTF-8?q?SZEDER=20G=C3=A1bor?= <[email protected]>
In our git-prompt script we strive to use Bash builtins wherever possible, because fork()-ing subshells for command substitutions and fork()+exec()-ing Git commands are expensive on some platforms. We even read and parse '.git/HEAD' using Bash builtins to get the name of the current branch [1]. However, the upcoming reftable refs backend won't use '.git/HEAD' at all, but will write an invalid refname as placeholder for backwards compatibility instead, which will break our git-prompt script.
Update the git-prompt script to recognize the placeholder '.git/HEAD' written by the reftable backend (its content is specified in the reftable specs), and then fall back to use 'git symbolic-ref' to get the name of the current branch.
[1] 3a43c4b5bd (bash prompt: use bash builtins to find out current
branch, 2011-03-31)
--- contrib/completion/git-prompt.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
contrib/completion/git-prompt.sh +6 -1
@@ -478,10 +478,15 @@ __git_ps1 () if ! __git_eread "$g/HEAD" head; then return $exit fi - # is it a symbolic ref? b="${head#ref: }" if [ "$head" = "$b" ]; then detached=yes + elif [ "$b" = "refs/heads/.invalid" ]; then + # Reftable + b="$(git symbolic-ref HEAD 2>/dev/null)" || + detached=yes + fi + if [ "$detached" = yes ]; then b="$( case "${GIT_PS1_DESCRIBE_STYLE-}" in (contains)
Signature · 1 line
gitgitgadget
PATCH 22/26 Add "test-tool dump-reftable" command.
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This command dumps individual tables or a stack of of tables.
--- Makefile | 1 + t/helper/test-reftable.c | 5 +++++ t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + t/t0031-reftable.sh | 6 ++++++ 5 files changed, 14 insertions(+)
Makefile +1 -0
@@ -2467,6 +2467,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o +REFTABLE_TEST_OBJS += reftable/dump.o REFTABLE_TEST_OBJS += reftable/merged_test.o REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o
t/helper/test-reftable.c +5 -0
@@ -14,3 +14,8 @@ int cmd__reftable(int argc, const char **argv)tree_test_main (argc, argv);return 0 ; } + +int cmd__dump_reftable (int argc,const char **argv) +{ +return reftable_dump_main (argc, (char *const *)argv); +}
t/helper/test-tool.c +1 -0
@@ -59,6 +59,7 @@ static struct test_cmd cmds[] = { { "read-midx", cmd__read_midx }, { "ref-store", cmd__ref_store }, { "reftable", cmd__reftable }, + { "dump-reftable", cmd__dump_reftable }, { "regex", cmd__regex }, { "repository", cmd__repository }, { "revision-walking", cmd__revision_walking },
t/helper/test-tool.h +1 -0
@@ -19,6 +19,7 @@ int cmd__dump_cache_tree(int argc, const char **argv);int cmd__dump_fsmonitor (int argc,const char **argv);int cmd__dump_split_index (int argc,const char **argv);int cmd__dump_untracked_cache (int argc,const char **argv); +int cmd__dump_reftable (int argc,const char **argv);int cmd__example_decorate (int argc,const char **argv);int cmd__fast_rebase (int argc,const char **argv);int cmd__genrandom (int argc,const char **argv);
t/t0031-reftable.sh +6 -0
@@ -288,4 +288,10 @@ test_expect_success 'FETCH_HEAD' ' test_cmp expect actual ' +test_expect_success 'dump reftable' ' + initialize && + hash_id=$(git config extensions.objectformat) && + test-tool dump-reftable $(test "${hash_id}" = "sha256" && echo "-6") -s .git/reftable +' + test_done
Signature · 1 line
gitgitgadget
v2 cover Support reftable ref backend for Git
In reply to Han-Wen Nienhuys via GitGitGadgetThis continues the work in https://github.com/git/git/pull/847, which the gitgitgadget erroneously closed.
Changes relative to last series (version 20 Jul 2021, tip: 4a5891f )
* fix HTTP serving
* fix t1501 (use absolute paths.)
* fix git-new-workdir
* fixes for FreeBSD (thanks, [email protected]!)
For the 'seen' branch, the following should be applied:
refs/reftable-backend.c +6 -7
@@ -108,7 +108,7 @@ static const char *bare_ref_name(const char *ref)static int git_reftable_read_raw_ref (struct ref_store *ref_store,const char *refname,struct object_id *oid,struct strbuf *referent, -unsigned int *type); +unsigned int *type,int *failure_errno);static void clear_reftable_log_record (struct reftable_log_record *log) {
@@ -425,13 +424,14 @@ static int fixup_symrefs(struct ref_store *ref_store,for (i =0 ; i < transaction->nr; i++) {struct ref_update *update = transaction->updates[i];struct object_id old_oid; +int failure_errno; err =git_reftable_read_raw_ref (ref_store, update->refname, &old_oid, &referent,/* mutate input, like files-backend.c */ - &update->type); -if (err <0 && errno ==ENOENT && + &update->type, &failure_errno); +if (err <0 && failure_errno ==ENOENT &&is_null_oid (&update->old_oid)) { err =0 ; }
@@ -1602,7 +1603,7 @@ static int reftable_error_to_errno(int err)static int git_reftable_read_raw_ref (struct ref_store *ref_store,const char *refname,struct object_id *oid,struct strbuf *referent, -unsigned int *type) +unsigned int *type,int *failure_errno) {struct git_reftable_ref_store *refs = (struct git_reftable_ref_store *)ref_store;
@@ -1626,13 +1627,11 @@ static int git_reftable_read_raw_ref(struct ref_store *ref_store, err =reftable_stack_read_ref (stack, refname, &ref);if (err >0 ) { - errno =ENOENT ; + *failure_errno =ENOENT ; err =-1 ; goto done; }if (err <0 ) { - errno =reftable_error_to_errno (err); - err =-1 ; goto done; }
Han-Wen Nienhuys (24):
hash.h: provide constants for the hash IDs
init-db: set the_repository->hash_algo early on
reftable: RFC: add LICENSE
reftable: add error related functionality
reftable: utility functions
reftable: add blocksource, an abstraction for random access reads
reftable: (de)serialization for the polymorphic record type. Provide zlib's uncompress2 from compat/zlib-compat.c
reftable: reading/writing blocks
reftable: a generic binary tree implementation
reftable: write reftable files
reftable: generic interface to tables
reftable: read reftable files
reftable: reftable file level tests
reftable: add a heap-based priority queue for reftable records
reftable: add merged table view
reftable: implement refname validation
reftable: implement stack, a mutable database of reftable files.
reftable: add dump utility
refs: RFC: Reftable support for git-core
Add "test-tool dump-reftable" command.
t1301: document what needs to be done for reftable t1401,t2011: parameterize HEAD.lock for REFFILES
t1404: annotate test cases with REFFILES
SZEDER Gábor (1):
git-prompt: prepare for reftable refs backend
Documentation/config/extensions.txt | 9 + .../technical/repository-version.txt | 7 + Makefile | 54 +- builtin/clone.c | 5 +- builtin/init-db.c | 60 +- builtin/stash.c | 8 +- builtin/worktree.c | 27 +- cache.h | 8 +- ci/lib.sh | 1 + compat/.gitattributes | 1 + compat/zlib-uncompress2.c | 92 + config.mak.uname | 3 +- configure.ac | 13 + contrib/buildsystems/CMakeLists.txt | 14 +- contrib/buildsystems/Generators/Vcxproj.pm | 11 +- contrib/completion/git-prompt.sh | 7 +- contrib/workdir/git-new-workdir | 2 +- hash.h | 6 + object-file.c | 7 +- refs.c | 26 +- refs.h | 3 + refs/refs-internal.h | 1 + refs/reftable-backend.c | 1686 +++++++++++++++++ reftable/LICENSE | 31 + reftable/basics.c | 128 ++ reftable/basics.h | 60 + reftable/basics_test.c | 98 + reftable/block.c | 448 +++++ reftable/block.h | 127 ++ reftable/block_test.c | 121 ++ reftable/blocksource.c | 148 ++ reftable/blocksource.h | 22 + reftable/constants.h | 21 + reftable/dump.c | 107 ++ reftable/error.c | 41 + reftable/generic.c | 169 ++ reftable/generic.h | 32 + reftable/iter.c | 194 ++ reftable/iter.h | 69 + reftable/merged.c | 362 ++++ reftable/merged.h | 35 + reftable/merged_test.c | 292 +++ reftable/pq.c | 115 ++ reftable/pq.h | 32 + reftable/pq_test.c | 72 + reftable/publicbasics.c | 58 + reftable/reader.c | 801 ++++++++ reftable/reader.h | 66 + reftable/readwrite_test.c | 651 +++++++ reftable/record.c | 1200 ++++++++++++ reftable/record.h | 139 ++ reftable/record_test.c | 408 ++++ reftable/refname.c | 209 ++ reftable/refname.h | 29 + reftable/refname_test.c | 102 + reftable/reftable-blocksource.h | 49 + reftable/reftable-error.h | 62 + reftable/reftable-generic.h | 47 + reftable/reftable-iterator.h | 39 + reftable/reftable-malloc.h | 18 + reftable/reftable-merged.h | 72 + reftable/reftable-reader.h | 101 + reftable/reftable-record.h | 114 ++ reftable/reftable-stack.h | 128 ++ reftable/reftable-tests.h | 23 + reftable/reftable-writer.h | 148 ++ reftable/reftable.c | 115 ++ reftable/stack.c | 1396 ++++++++++++++ reftable/stack.h | 41 + reftable/stack_test.c | 947 +++++++++ reftable/system.h | 24 + reftable/test_framework.c | 23 + reftable/test_framework.h | 53 + reftable/tree.c | 63 + reftable/tree.h | 34 + reftable/tree_test.c | 61 + reftable/writer.c | 690 +++++++ reftable/writer.h | 50 + repository.c | 2 + repository.h | 3 + setup.c | 8 + t/helper/test-reftable.c | 21 + t/helper/test-tool.c | 4 +- t/helper/test-tool.h | 2 + t/t0031-reftable.sh | 316 +++ t/t0032-reftable-unittest.sh | 15 + t/t1301-shared-repo.sh | 8 +- t/t1401-symbolic-ref.sh | 11 +- t/t1404-update-ref-errors.sh | 56 +- t/t1409-avoid-packing-refs.sh | 6 + t/t1450-fsck.sh | 6 + t/t2011-checkout-invalid-head.sh | 11 +- t/t3210-pack-refs.sh | 6 + t/test-lib.sh | 7 +- 94 files changed, 13156 insertions(+), 62 deletions(-) create mode 100644 compat/.gitattributes create mode 100644 compat/zlib-uncompress2.c create mode 100644 refs/reftable-backend.c create mode 100644 reftable/LICENSE create mode 100644 reftable/basics.c create mode 100644 reftable/basics.h create mode 100644 reftable/basics_test.c create mode 100644 reftable/block.c create mode 100644 reftable/block.h create mode 100644 reftable/block_test.c create mode 100644 reftable/blocksource.c create mode 100644 reftable/blocksource.h create mode 100644 reftable/constants.h create mode 100644 reftable/dump.c create mode 100644 reftable/error.c create mode 100644 reftable/generic.c create mode 100644 reftable/generic.h 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/pq_test.c create mode 100644 reftable/publicbasics.c create mode 100644 reftable/reader.c create mode 100644 reftable/reader.h create mode 100644 reftable/readwrite_test.c 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-blocksource.h create mode 100644 reftable/reftable-error.h create mode 100644 reftable/reftable-generic.h create mode 100644 reftable/reftable-iterator.h create mode 100644 reftable/reftable-malloc.h create mode 100644 reftable/reftable-merged.h create mode 100644 reftable/reftable-reader.h create mode 100644 reftable/reftable-record.h create mode 100644 reftable/reftable-stack.h create mode 100644 reftable/reftable-tests.h create mode 100644 reftable/reftable-writer.h create mode 100644 reftable/reftable.c create mode 100644 reftable/stack.c create mode 100644 reftable/stack.h create mode 100644 reftable/stack_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 100644 reftable/writer.c create mode 100644 reftable/writer.h create mode 100644 t/helper/test-reftable.c create mode 100755 t/t0031-reftable.sh create mode 100755 t/t0032-reftable-unittest.sh
base-commit: 5d213e46bb7b880238ff5ea3914e940a50ae9369
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1054%2Fhanwen%2Flibreftable-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1054/hanwen/libreftable-v2
Pull-Request: https://github.com/git/git/pull/1054
Range-diff vs v1:
1: dc24dccf041 = 1: c40393e83e1 hash.h: provide constants for the hash IDs
2: f1167669848 = 2: 49dffeeae58 init-db: set the_repository->hash_algo early on
3: 76c2a1005da = 3: dba354eca12 reftable: RFC: add LICENSE
4: 616d6ed89ee = 4: 75864034af2 reftable: add error related functionality
5: 9d2cdfe3ddd = 5: eabb25d95b3 reftable: utility functions
6: 5ef4b7040a3 = 6: ad54d17f84b reftable: add blocksource, an abstraction for random access reads
7: 13a5cbef0df ! 7: 282d8e4d817 reftable: (de)serialization for the polymorphic record type.
@@ reftable/record_test.c (new)
+
+static void test_reftable_log_record_roundtrip(void)
+{
++ int i;
+ struct reftable_log_record in[2] = {
+ {
+ .refname = xstrdup("refs/heads/master"),
@@ reftable/record_test.c (new)
+ };
+ set_test_hash(in[0].update.new_hash, 1);
+ set_test_hash(in[0].update.old_hash, 2);
-+ for (int i = 0; i < ARRAY_SIZE(in); i++) {
++ for (i = 0; i < ARRAY_SIZE(in); i++) {
+ struct reftable_record rec = { NULL };
+ struct strbuf key = STRBUF_INIT;
+ uint8_t buffer[1024] = { 0 }; 8: 27abd159658 ! 8: 893ee4ca21b Provide zlib's uncompress2 from compat/zlib-compat.c
@@ Commit message
This will be needed for reading reflog blocks in reftable.
+ Helped-by: Carlo Marcelo Arenas Belón <[email protected]>
## Makefile ##
@@ Makefile: ifdef NO_DEFLATE_BOUND
+ifdef NO_UNCOMPRESS2
+ BASIC_CFLAGS += -DNO_UNCOMPRESS2
-+ LIB_OBJS += compat/zlib-uncompress2.o
++ REFTABLE_OBJS += compat/zlib-uncompress2.o
+endif
+
ifdef NO_POSIX_GOODIES
@@ compat/zlib-uncompress2.c (new)
+ err;
+}
+ ## config.mak.uname ##
+@@ config.mak.uname: ifeq ($(uname_S),FreeBSD)
+ FILENO_IS_A_MACRO = UnfortunatelyYes
+ endif
+ ifeq ($(uname_S),OpenBSD)
++ NO_UNCOMPRESS2 = YesPlease
+ NO_STRCASESTR = YesPlease
+ NO_MEMMEM = YesPlease
+ USE_ST_TIMESPEC = YesPlease
+
## configure.ac ##
@@ configure.ac: AC_LINK_IFELSE([ZLIBTEST_SRC],
NO_DEFLATE_BOUND=yes])
9: 25aa2bf9b71 ! 9: e4da0a2ef37 reftable: reading/writing blocks
@@ reftable/block.c (new)
+#include <zlib.h>
+
+#ifdef NO_UNCOMPRESS2
-+/* This is uncompress2, which is only available in zlib as of 2017. ++/*
++ * This is uncompress2, which is only available in zlib >= 1.2.9 ++ * (released as of early 2017)
+ */
+int uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source,
+ uLong *sourceLen);
10: 92970da9cb9 = 10: 0f325881389 reftable: a generic binary tree implementation
11: 3b817f37a01 = 11: 26cbc468f1f reftable: write reftable files
12: 99708f408b0 = 12: 69129fca086 reftable: generic interface to tables
13: fa9d3b95fd4 = 13: 22599d785b7 reftable: read reftable files
14: 3eeefa5665f ! 14: 45565bfb9c4 reftable: reftable file level tests
@@ reftable/readwrite_test.c (new)
+ .block_size = 4096,
+ };
+ int err;
++ int i;
+ struct reftable_log_record log = { .refname = "refs/heads/master",
+ .update_index = 0xa,
+ .value_type = REFTABLE_LOG_UPDATE,
@@ reftable/readwrite_test.c (new)
+ hash, to ensure that the compressed part is larger than the original.
+ */
+ uint8_t hash1[GIT_SHA1_RAWSZ], hash2[GIT_SHA1_RAWSZ];
-+ for (int i = 0; i < GIT_SHA1_RAWSZ; i++) {
++ for (i = 0; i < GIT_SHA1_RAWSZ; i++) {
+ hash1[i] = (uint8_t)(rand() % 256);
+ hash2[i] = (uint8_t)(rand() % 256);
+ }
15: 4d7745e6552 = 15: 57b3e709c3e reftable: add a heap-based priority queue for reftable records
16: c906d79b341 = 16: f834cc5299f reftable: add merged table view
17: 806c2e04392 = 17: 15799d93ff7 reftable: implement refname validation
18: 67f1282469d = 18: b7728ceaef2 reftable: implement stack, a mutable database of reftable files.
19: 05e46f7e1d8 ! 19: 0f682be20bd reftable: add dump utility
@@ Commit message
inspecting a complete ref database
Signed-off-by: Han-Wen Nienhuys <[email protected]>
+ Helped-by: Carlo Marcelo Arenas Belón <[email protected]>
## reftable/dump.c (new) ##
@@
@@ reftable/dump.c (new)
+https://developers.google.com/open-source/licenses/bsd
+*/
+
++#include "git-compat-util.h"
++#include "hash.h"
++
+#include "reftable-blocksource.h"
+#include "reftable-error.h"
+#include "reftable-merged.h"
@@ reftable/dump.c (new)
+#include "reftable-reader.h"
+#include "reftable-stack.h"
+#include "reftable-generic.h"
-+#include "hash.h"
+
+#include <stddef.h>
+#include <stdio.h>
20: d1d4b2f9e9b ! 20: 754085752f4 refs: RFC: Reftable support for git-core
@@ contrib/buildsystems/Generators/Vcxproj.pm: EOM
print F << "EOM";
<ProjectReference Include="$cdup\\xdiff\\lib\\xdiff_lib.vcxproj">
+ ## contrib/workdir/git-new-workdir ##
+@@ contrib/workdir/git-new-workdir: trap cleanup $siglist
+ # create the links to the original repo. explicitly exclude index, HEAD and
+ # logs/HEAD from the list since they are purely related to the current working
+ # directory, and should not be shared.
+-for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn
++for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn reftable
+ do
+ # create a containing directory if needed
+ case $x in
+
## refs.c ##
@@
#include "repository.h"
@@ refs/reftable-backend.c (new)
+ .hash_id = the_hash_algo->format_id,
+ };
+ struct strbuf sb = STRBUF_INIT;
-+ const char *gitdir = path;
++ struct strbuf gitdir = STRBUF_INIT;
+ struct strbuf wt_buf = STRBUF_INIT;
+ int wt = 0;
+
@@ refs/reftable-backend.c (new)
+ * backend, leading to infinite recursion. */
+ wt = is_worktree(&wt_buf);
+ if (wt) {
-+ gitdir = wt_buf.buf;
++ strbuf_addbuf(&gitdir, &wt_buf);
++ } else {
++ strbuf_realpath(&gitdir, path, /*die_on_error=*/0);
+ }
+
+ base_ref_store_init(ref_store, &refs_be_reftable);
-+ ref_store->gitdir = xstrdup(gitdir);
++ ref_store->gitdir = xstrdup(gitdir.buf);
+ refs->store_flags = store_flags;
-+ strbuf_addf(&sb, "%s/reftable", gitdir);
++ strbuf_addf(&sb, "%s/reftable", gitdir.buf);
+ refs->reftable_dir = xstrdup(sb.buf);
+ strbuf_reset(&sb);
+
@@ refs/reftable-backend.c (new)
+
+ strbuf_release(&sb);
+ strbuf_release(&wt_buf);
++ strbuf_release(&gitdir);
+ return ref_store;
+}
+
@@ setup.c: const char *setup_git_directory_gently(int *nongit_ok)
}
}
/*
+@@ setup.c: void check_repository_format(struct repository_format *fmt)
+ repo_set_hash_algo(the_repository, fmt->hash_algo);
+ the_repository->repository_format_partial_clone =
+ xstrdup_or_null(fmt->partial_clone);
++ /* XXX why is repo->ref_storage_format set in multiple places?! */
++ the_repository->ref_storage_format = xstrdup_or_null(fmt->ref_storage);
+ clear_repository_format(&repo_fmt);
+ }
+
## t/t0031-reftable.sh (new) ##
@@
@@ t/t0031-reftable.sh (new)
+ test_cmp expect actual
+'
+
++. "$TEST_DIRECTORY"/lib-httpd.sh
++start_httpd
++
++REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo"
++
++test_expect_success 'serving ls-remote' '
++ GIT_TEST_REFTABLE=1 git init -b main "$REPO" &&
++ cd "$REPO" &&
++ test_commit m1 &&
++ >.git/git-daemon-export-ok &&
++ git ls-remote "http://127.0.0.1:$LIB_HTTPD_PORT/smart/repo" | cut -f 2-2 -d " " >actual &&
++ cat << EOF >expect &&
++HEAD
++refs/heads/main
++refs/tags/m1
++EOF
++ test_cmp actual expect
++'
++
+test_done
## t/t1409-avoid-packing-refs.sh ##
21: 7541a4b8d6d = 21: 79c4b90d0f4 git-prompt: prepare for reftable refs backend
22: 3c9c3a2d56d ! 22: 1f48091e549 Add "test-tool dump-reftable" command.
@@ t/t0031-reftable.sh: test_expect_success 'FETCH_HEAD' '
+ test-tool dump-reftable $(test "${hash_id}" = "sha256" && echo "-6") -s .git/reftable
+'
+
- test_done
+ . "$TEST_DIRECTORY"/lib-httpd.sh
+ start_httpd
+
23: 73eece0caac = 23: 64dc87746db t1301: document what needs to be done for reftable
24: d895736f0e1 = 24: c248b69c6e3 t1401,t2011: parameterize HEAD.lock for REFFILES
25: f0a528b9ece = 25: 9f1b792459e t1404: annotate test cases with REFFILES
26: 4a5891fa8cc < -: ----------- t7004: avoid direct filesystem accessSignature · 1 line
gitgitgadget
PATCH v2 1/25 hash.h: provide constants for the hash IDs
From: Han-Wen Nienhuys <[email protected]>
This will simplify referencing them from code that is not deeply integrated with Git, in particular, the reftable library.
--- hash.h | 6 ++++++ object-file.c | 7 ++----- 2 files changed, 8 insertions(+), 5 deletions(-)
hash.h +6 -0
@@ -95,12 +95,18 @@ static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *s/* Number of algorithms supported (including unknown). */ #define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1) +/* "sha1", big-endian */ +#define GIT_SHA1_FORMAT_ID 0x73686131 +/* The length in bytes and in hex digits of an object name (SHA-1 value). */ #define GIT_SHA1_RAWSZ 20#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)/* The block size of SHA-1. */ #define GIT_SHA1_BLKSZ 64 +/* "s256", big-endian */ +#define GIT_SHA256_FORMAT_ID 0x73323536 +/* The length in bytes and in hex digits of an object name (SHA-256 value). */ #define GIT_SHA256_RAWSZ 32#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
object-file.c +2 -5
@@ -164,7 +164,6 @@ static void git_hash_unknown_final_oid(struct object_id *oid, git_hash_ctx *ctx)BUG ("trying to finalize unknown hash" ); } -const struct git_hash_algo hash_algos[GIT_HASH_NALGOS ] = { {NULL ,
@@ -183,8 +182,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { }, {"sha1" , -/* "sha1", big-endian */ -0x73686131 , +GIT_SHA1_FORMAT_ID ,GIT_SHA1_RAWSZ ,GIT_SHA1_HEXSZ , GIT_SHA1_BLKSZ,
@@ -199,8 +197,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { }, {"sha256" , -/* "s256", big-endian */ -0x73323536 , +GIT_SHA256_FORMAT_ID ,GIT_SHA256_RAWSZ ,GIT_SHA256_HEXSZ , GIT_SHA256_BLKSZ,
Signature · 1 line
gitgitgadget
PATCH v2 2/25 init-db: set the_repository->hash_algo early on
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable backend needs to know the hash algorithm for writing the initialization hash table.
The initial reftable contains a symref HEAD => "main" (or "master"), which is agnostic to the size of hash value, but this is an exceptional circumstance, and the reftable library does not cater to this exception. It insists that all tables in the stack have a consistent format ID for the hash algorithm.
Call set_repo_hash_algo directly after calling validate_hash_algorithm() (which reads $GIT_DEFAULT_HASH).
--- builtin/init-db.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
builtin/init-db.c +21 -0
@@ -425,6 +425,27 @@ int init_db(const char *git_dir, const char *real_git_dir,validate_hash_algorithm (&repo_fmt, hash); +/* +* At this point, the_repository we have in-core does not look +* anything like one that we would see initialized in an already +* working repository after calling setup_git_directory(). +* +* Calling repository.c::initialize_the_repository() may have +* prepared the .index .objects and .parsed_objects members, but +* other members like .gitdir, .commondir, etc. have not been +* initialized. +* +* Many API functions assume they are working with the_repository +* that has sensibly been initialized, but because we haven't +* really read from an existing repository, we need to hand-craft +* the necessary members of the structure to get out of this +* chicken-and-egg situation. +* +* For now, we update the hash algorithm member to what the +* validate_hash_algorithm() call decided for us. +*/ +repo_set_hash_algo (the_repository, repo_fmt.hash_algo); + reinit =create_default_files (template_dir, original_git_dir, initial_branch, &repo_fmt, flags &INIT_DB_QUIET );
Signature · 1 line
gitgitgadget
PATCH v2 3/25 reftable: RFC: add LICENSE
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The objective of this code is to be usable as a C library, so it can be reused in libgit2.
This is currently using a BSD license as it is the liberal license I could find, but this could be changed to whatever fits the stated goal above.
This code is currently imported from github.com/hanwen/reftable. Once this code lands in git.git, the C code will be removed from github.com/hanwen/reftable, and the git.git code will be the source of truth.
--- reftable/LICENSE | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 reftable/LICENSE
reftable/LICENSE new file +31 -0
@@ -0,0 +1,31 @@ +BSD License + +Copyright (c) 2020, Google LLC +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +* Neither the name of Google LLC nor the names of its contributors may +be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Signature · 1 line
gitgitgadget
PATCH v2 4/25 reftable: add error related functionality
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable/ directory is structured as a library, so it cannot crash on misuse. Instead, it returns an error codes.
In addition, the error code can be used to signal conditions from lower levels of the library to be handled by higher levels of the library. For example, a transaction might legitimately write an empty reftable file, but in that case, we'd want to shortcut the transaction overhead.
--- reftable/error.c | 41 ++++++++++++++++++++++++++ reftable/reftable-error.h | 62 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 reftable/error.c create mode 100644 reftable/reftable-error.h
reftable/error.c new file +41 -0
@@ -0,0 +1,41 @@ +/* +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 "reftable-error.h" + +#include <stdio.h> + +const char *reftable_error_str (int err) +{ +static char buf[250 ]; +switch (err) { +case REFTABLE_IO_ERROR : +return "I/O error" ; +case REFTABLE_FORMAT_ERROR : +return "corrupt reftable file" ; +case REFTABLE_NOT_EXIST_ERROR : +return "file does not exist" ; +case REFTABLE_LOCK_ERROR : +return "data is outdated" ; +case REFTABLE_API_ERROR : +return "misuse of the reftable API" ; +case REFTABLE_ZLIB_ERROR : +return "zlib failure" ; +case REFTABLE_NAME_CONFLICT : +return "file/directory conflict" ; +case REFTABLE_EMPTY_TABLE_ERROR : +return "wrote empty table" ; +case REFTABLE_REFNAME_ERROR : +return "invalid refname" ; +case -1 : +return "general error" ; +default : +snprintf (buf,sizeof (buf),"unknown error code %d" , err); +return buf; + } +}
reftable/reftable-error.h new file +62 -0
62 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v2 5/25 reftable: utility functions
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This commit provides basic utility classes for the reftable library.
--- Makefile | 25 +++++- contrib/buildsystems/CMakeLists.txt | 14 ++- reftable/basics.c | 128 ++++++++++++++++++++++++++++ reftable/basics.h | 60 +++++++++++++ reftable/basics_test.c | 98 +++++++++++++++++++++ reftable/publicbasics.c | 58 +++++++++++++ reftable/reftable-malloc.h | 18 ++++ reftable/reftable-tests.h | 22 +++++ reftable/system.h | 24 ++++++ reftable/test_framework.c | 23 +++++ reftable/test_framework.h | 53 ++++++++++++ t/helper/test-reftable.c | 9 ++ t/helper/test-tool.c | 3 +- t/helper/test-tool.h | 1 + t/t0032-reftable-unittest.sh | 15 ++++ 15 files changed, 545 insertions(+), 6 deletions(-) create mode 100644 reftable/basics.c create mode 100644 reftable/basics.h create mode 100644 reftable/basics_test.c create mode 100644 reftable/publicbasics.c create mode 100644 reftable/reftable-malloc.h create mode 100644 reftable/reftable-tests.h create mode 100644 reftable/system.h create mode 100644 reftable/test_framework.c create mode 100644 reftable/test_framework.h create mode 100644 t/helper/test-reftable.c create mode 100755 t/t0032-reftable-unittest.sh
Makefile +22 -3
@@ -743,6 +743,7 @@ TEST_BUILTINS_OBJS += test-read-cache.o TEST_BUILTINS_OBJS += test-read-graph.o TEST_BUILTINS_OBJS += test-read-midx.o TEST_BUILTINS_OBJS += test-ref-store.o +TEST_BUILTINS_OBJS += test-reftable.o TEST_BUILTINS_OBJS += test-regex.o TEST_BUILTINS_OBJS += test-repository.o TEST_BUILTINS_OBJS += test-revision-walking.o
@@ -821,6 +822,8 @@ TEST_SHELL_PATH = $(SHELL_PATH) LIB_FILE = libgit.a XDIFF_LIB = xdiff/lib.a +REFTABLE_LIB = reftable/libreftable.a +REFTABLE_TEST_LIB = reftable/libreftable_test.a GENERATED_H += command-list.h GENERATED_H += config-list.h
@@ -1195,7 +1198,7 @@ THIRD_PARTY_SOURCES += compat/regex/% THIRD_PARTY_SOURCES += sha1collisiondetection/% THIRD_PARTY_SOURCES += sha1dc/% -GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) +GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) EXTLIBS = GIT_USER_AGENT = git/$(GIT_VERSION)
@@ -2442,7 +2445,15 @@ XDIFF_OBJS += xdiff/xutils.o .PHONY: xdiff-objs xdiff-objs: $(XDIFF_OBJS) +REFTABLE_OBJS += reftable/basics.o +REFTABLE_OBJS += reftable/error.o +REFTABLE_OBJS += reftable/publicbasics.o + +REFTABLE_TEST_OBJS += reftable/test_framework.o +REFTABLE_TEST_OBJS += reftable/basics_test.o + TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS)) + .PHONY: test-objs test-objs: $(TEST_OBJS)
@@ -2458,6 +2469,8 @@ OBJECTS += $(PROGRAM_OBJS) OBJECTS += $(TEST_OBJS) OBJECTS += $(XDIFF_OBJS) OBJECTS += $(FUZZ_OBJS) +OBJECTS += $(REFTABLE_OBJS) $(REFTABLE_TEST_OBJS) + ifndef NO_CURL OBJECTS += http.o http-walker.o remote-curl.o endif
@@ -2608,6 +2621,12 @@ $(LIB_FILE): $(LIB_OBJS) $(XDIFF_LIB): $(XDIFF_OBJS) $(QUIET_AR)$(AR) $(ARFLAGS) $@ $^ +$(REFTABLE_LIB): $(REFTABLE_OBJS) + $(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^ + +$(REFTABLE_TEST_LIB): $(REFTABLE_TEST_OBJS) + $(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^ + export DEFAULT_EDITOR DEFAULT_PAGER Documentation/GIT-EXCLUDED-PROGRAMS: FORCE
@@ -2895,7 +2914,7 @@ perf: all t/helper/test-tool$X: $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS)) -t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) +t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) $(REFTABLE_TEST_LIB) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS) check-sha1:: t/helper/test-tool$X
@@ -3225,7 +3244,7 @@ cocciclean: clean: profile-clean coverage-clean cocciclean $(RM) *.res $(RM) $(OBJECTS) - $(RM) $(LIB_FILE) $(XDIFF_LIB) + $(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB) $(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X $(RM) $(TEST_PROGRAMS) $(RM) $(FUZZ_PROGRAMS)
contrib/buildsystems/CMakeLists.txt +12 -2
@@ -640,6 +640,12 @@ parse_makefile_for_sources(libxdiff_SOURCES "XDIFF_OBJS") list(TRANSFORM libxdiff_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") add_library(xdiff STATIC ${libxdiff_SOURCES}) +#reftable +parse_makefile_for_sources(reftable_SOURCES "REFTABLE_OBJS") + +list(TRANSFORM reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") +add_library(reftable STATIC ${reftable_SOURCES}) + if(WIN32) if(NOT MSVC)#use windres when compiling with gcc and clang add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/git.res
@@ -662,7 +668,7 @@ endif() #link all required libraries to common-main add_library(common-main OBJECT ${CMAKE_SOURCE_DIR}/common-main.c) -target_link_libraries(common-main libgit xdiff ${ZLIB_LIBRARIES}) +target_link_libraries(common-main libgit xdiff reftable ${ZLIB_LIBRARIES}) if(Intl_FOUND) target_link_libraries(common-main ${Intl_LIBRARIES}) endif()
@@ -902,11 +908,15 @@ if(BUILD_TESTING) add_executable(test-fake-ssh ${CMAKE_SOURCE_DIR}/t/helper/test-fake-ssh.c) target_link_libraries(test-fake-ssh common-main) +#reftable-tests +parse_makefile_for_sources(test-reftable_SOURCES "REFTABLE_TEST_OBJS") +list(TRANSFORM test-reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") + #test-tool parse_makefile_for_sources(test-tool_SOURCES "TEST_BUILTINS_OBJS") list(TRANSFORM test-tool_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/t/helper/") -add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES}) +add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES} ${test-reftable_SOURCES}) target_link_libraries(test-tool common-main) set_target_properties(test-fake-ssh test-tool
reftable/basics.c new file +128 -0
128 lines not on this page · raw message
reftable/basics.h new file +60 -0
60 lines not on this page · raw message
reftable/basics_test.c new file +98 -0
98 lines not on this page · raw message
reftable/publicbasics.c new file +58 -0
58 lines not on this page · raw message
reftable/reftable-malloc.h new file +18 -0
@@ -0,0 +1,18 @@ +/* +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 REFTABLE_H +#define REFTABLE_H + +#include <stddef.h> + +/* Overrides the functions to use for memory management. */ +void reftable_set_alloc (void *(*malloc)(size_t ), +void *(*realloc)(void *,size_t ),void (*free)(void *)); + +#endif
reftable/reftable-tests.h new file +22 -0
@@ -0,0 +1,22 @@ +/* +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 REFTABLE_TESTS_H +#define REFTABLE_TESTS_H + +int basics_test_main (int argc,const char **argv); +int block_test_main (int argc,const char **argv); +int merged_test_main (int argc,const char **argv); +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 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); + +#endif
reftable/system.h new file +24 -0
@@ -0,0 +1,24 @@ +/* +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 SYSTEM_H +#define SYSTEM_H + +// This header glues the reftable library to the rest of Git + +#include "git-compat-util.h" +#include "strbuf.h" +#include "hash.h" /* hash ID, sizes.*/ +#include "dir.h" /* remove_dir_recursively, for tests.*/ + +#include <zlib.h> + +struct strbuf ; +int hash_size (uint32_t id); + +#endif
reftable/test_framework.c new file +23 -0
@@ -0,0 +1,23 @@ +/* +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 "system.h" +#include "test_framework.h" + +#include "basics.h" + +void set_test_hash (uint8_t *p,int i) +{ +memset (p, (uint8_t )i,hash_size (GIT_SHA1_FORMAT_ID )); +} + +ssize_t strbuf_add_void (void *b,const void *data,size_t sz) +{ +strbuf_add (b, data, sz); +return sz; +}
reftable/test_framework.h new file +53 -0
53 lines not on this page · raw message
t/helper/test-reftable.c new file +9 -0
@@ -0,0 +1,9 @@ +#include "reftable/reftable-tests.h" +#include "test-tool.h" + +int cmd__reftable (int argc,const char **argv) +{ +basics_test_main (argc, argv); + +return 0 ; +}
t/helper/test-tool.c +2 -1
@@ -53,13 +53,14 @@ static struct test_cmd cmds[] = { { "pcre2-config", cmd__pcre2_config }, { "pkt-line", cmd__pkt_line }, { "prio-queue", cmd__prio_queue }, - { "proc-receive", cmd__proc_receive}, + { "proc-receive", cmd__proc_receive }, { "progress", cmd__progress }, { "reach", cmd__reach }, { "read-cache", cmd__read_cache }, { "read-graph", cmd__read_graph }, { "read-midx", cmd__read_midx }, { "ref-store", cmd__ref_store }, + { "reftable", cmd__reftable }, { "regex", cmd__regex }, { "repository", cmd__repository }, { "revision-walking", cmd__revision_walking },
t/helper/test-tool.h +1 -0
@@ -49,6 +49,7 @@ int cmd__read_cache(int argc, const char **argv);int cmd__read_graph (int argc,const char **argv);int cmd__read_midx (int argc,const char **argv);int cmd__ref_store (int argc,const char **argv); +int cmd__reftable (int argc,const char **argv);int cmd__regex (int argc,const char **argv);int cmd__repository (int argc,const char **argv);int cmd__revision_walking (int argc,const char **argv);
t/t0032-reftable-unittest.sh new file +15 -0
@@ -0,0 +1,15 @@ +#!/bin/sh +# +# Copyright (c) 2020 Google LLC +# + +test_description='reftable unittests' + +. ./test-lib.sh + +test_expect_success 'unittests' ' + TMPDIR=$(pwd) && export TMPDIR && + test-tool reftable +' + +test_done
Signature · 1 line
gitgitgadget
PATCH v2 6/25 reftable: add blocksource, an abstraction for random access reads
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable format is usually used with files for storage. However, we abstract away this using the blocksource data structure. This has two advantages:
* log blocks are zlib compressed, and handling them is simplified if we can discard byte segments from within the block layer.
* for unittests, it is useful to read and write in-memory. The blocksource allows us to abstract the data away from on-disk files.
--- Makefile | 1 + reftable/blocksource.c | 148 ++++++++++++++++++++++++++++++++ reftable/blocksource.h | 22 +++++ reftable/reftable-blocksource.h | 49 +++++++++++ 4 files changed, 220 insertions(+) create mode 100644 reftable/blocksource.c create mode 100644 reftable/blocksource.h create mode 100644 reftable/reftable-blocksource.h
Makefile +1 -0
@@ -2447,6 +2447,7 @@ xdiff-objs: $(XDIFF_OBJS) REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o +REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_TEST_OBJS += reftable/test_framework.o
reftable/blocksource.c new file +148 -0
148 lines not on this page · raw message
reftable/blocksource.h new file +22 -0
@@ -0,0 +1,22 @@ +/* +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 BLOCKSOURCE_H +#define BLOCKSOURCE_H + +#include "system.h" + +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/reftable-blocksource.h new file +49 -0
49 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v2 8/25 Provide zlib's uncompress2 from compat/zlib-compat.c
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This will be needed for reading reflog blocks in reftable.
--- Makefile | 7 +++ ci/lib.sh | 1 + compat/.gitattributes | 1 + compat/zlib-uncompress2.c | 92 +++++++++++++++++++++++++++++++++++++++ config.mak.uname | 1 + configure.ac | 13 ++++++ 6 files changed, 115 insertions(+) create mode 100644 compat/.gitattributes create mode 100644 compat/zlib-uncompress2.c
Makefile +7 -0
@@ -256,6 +256,8 @@ all:: # # Define NO_DEFLATE_BOUND if your zlib does not have deflateBound. # +# Define NO_UNCOMPRESS2 if your zlib does not have uncompress2. +# # Define NO_NORETURN if using buggy versions of gcc 4.6+ and profile feedback, # as the compiler can crash (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49299) #
@@ -1738,6 +1740,11 @@ ifdef NO_DEFLATE_BOUND BASIC_CFLAGS += -DNO_DEFLATE_BOUND endif +ifdef NO_UNCOMPRESS2 + BASIC_CFLAGS += -DNO_UNCOMPRESS2 + REFTABLE_OBJS += compat/zlib-uncompress2.o +endif + ifdef NO_POSIX_GOODIES BASIC_CFLAGS += -DNO_POSIX_GOODIES endif
ci/lib.sh +1 -0
@@ -224,6 +224,7 @@ linux-gcc-default) ;; Linux32) CC=gcc + MAKEFLAGS="$MAKEFLAGS NO_UNCOMPRESS2=1" ;; linux-musl) CC=gcc
compat/.gitattributes new file +1 -0
@@ -0,0 +1 @@ +/zlib-uncompress2.c whitespace=-indent-with-non-tab,-trailing-space
compat/zlib-uncompress2.c new file +92 -0
92 lines not on this page · raw message
config.mak.uname +1 -0
@@ -256,6 +256,7 @@ ifeq ($(uname_S),FreeBSD) FILENO_IS_A_MACRO = UnfortunatelyYes endif ifeq ($(uname_S),OpenBSD) + NO_UNCOMPRESS2 = YesPlease NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease USE_ST_TIMESPEC = YesPlease
configure.ac +13 -0
@@ -672,9 +672,22 @@ AC_LINK_IFELSE([ZLIBTEST_SRC], NO_DEFLATE_BOUND=yes]) LIBS="$old_LIBS" +AC_DEFUN([ZLIBTEST_UNCOMPRESS2_SRC], [ +AC_LANG_PROGRAM([#include <zlib.h>], + [uncompress2(NULL,NULL,NULL,NULL);])]) +AC_MSG_CHECKING([for uncompress2 in -lz]) +old_LIBS="$LIBS" +LIBS="$LIBS -lz" +AC_LINK_IFELSE([ZLIBTEST_UNCOMPRESS2_SRC], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + NO_UNCOMPRESS2=yes]) +LIBS="$old_LIBS" + GIT_UNSTASH_FLAGS($ZLIB_PATH) GIT_CONF_SUBST([NO_DEFLATE_BOUND]) +GIT_CONF_SUBST([NO_UNCOMPRESS2]) # # Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
Signature · 1 line
gitgitgadget
PATCH v2 7/25 reftable: (de)serialization for the polymorphic record type.
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable format is structured as a sequence of blocks, and each block contains a sequence of prefix-compressed key-value records. There are 4 types of records, and they have similarities in how they must be handled. This is achieved by introducing a polymorphic 'record' type that encapsulates ref, log, index and object records.
--- Makefile | 2 + reftable/constants.h | 21 + reftable/record.c | 1200 ++++++++++++++++++++++++++++++++++++ reftable/record.h | 139 +++++ reftable/record_test.c | 408 ++++++++++++ reftable/reftable-record.h | 114 ++++ t/helper/test-reftable.c | 2 +- 7 files changed, 1885 insertions(+), 1 deletion(-) create mode 100644 reftable/constants.h create mode 100644 reftable/record.c create mode 100644 reftable/record.h create mode 100644 reftable/record_test.c create mode 100644 reftable/reftable-record.h
Makefile +2 -0
@@ -2449,7 +2449,9 @@ REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/record.o +REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/basics_test.o
reftable/constants.h new file +21 -0
@@ -0,0 +1,21 @@ +/* +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 CONSTANTS_H +#define CONSTANTS_H + +#define BLOCK_TYPE_LOG 'g' +#define BLOCK_TYPE_INDEX 'i' +#define BLOCK_TYPE_REF 'r' +#define BLOCK_TYPE_OBJ 'o' +#define BLOCK_TYPE_ANY 0 + +#define MAX_RESTARTS ((1 << 16) - 1) +#define DEFAULT_BLOCK_SIZE 4096 + +#endif
reftable/record.c new file +1200 -0
1,200 lines not on this page · raw message
reftable/record.h new file +139 -0
139 lines not on this page · raw message
reftable/record_test.c new file +408 -0
408 lines not on this page · raw message
reftable/reftable-record.h new file +114 -0
114 lines not on this page · raw message
t/helper/test-reftable.c +1 -1
@@ -4,6 +4,6 @@int cmd__reftable (int argc,const char **argv) {basics_test_main (argc, argv); - +record_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH v2 9/25 reftable: reading/writing blocks
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable format is structured as a sequence of block. Within a block, records are prefix compressed, with an index of offsets for fully expand keys to enable binary search within blocks.
This commit provides the logic to read and write these blocks.
--- Makefile | 2 + reftable/block.c | 448 +++++++++++++++++++++++++++++++++++++++ reftable/block.h | 127 +++++++++++ reftable/block_test.c | 121 +++++++++++ t/helper/test-reftable.c | 1 + 5 files changed, 699 insertions(+) create mode 100644 reftable/block.c create mode 100644 reftable/block.h create mode 100644 reftable/block_test.c
Makefile +2 -0
@@ -2454,10 +2454,12 @@ xdiff-objs: $(XDIFF_OBJS) REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o +REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o +REFTABLE_TEST_OBJS += reftable/block_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/basics_test.o
reftable/block.c new file +448 -0
448 lines not on this page · raw message
reftable/block.h new file +127 -0
127 lines not on this page · raw message
reftable/block_test.c new file +121 -0
121 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -4,6 +4,7 @@int cmd__reftable (int argc,const char **argv) {basics_test_main (argc, argv); +block_test_main (argc, argv);record_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH v2 10/25 reftable: a generic binary tree implementation
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable format includes support for an (OID => ref) map. This map can speed up visibility and reachability checks. In particular, various operations along the fetch/push path within Gerrit have ben sped up by using this structure.
The map is constructed with help of a binary tree. Object IDs are hashes, so they are uniformly distributed. Hence, the tree does not attempt forced rebalancing.
--- Makefile | 4 ++- reftable/tree.c | 63 ++++++++++++++++++++++++++++++++++++++++ reftable/tree.h | 34 ++++++++++++++++++++++ reftable/tree_test.c | 61 ++++++++++++++++++++++++++++++++++++++ t/helper/test-reftable.c | 1 + 5 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 reftable/tree.c create mode 100644 reftable/tree.h create mode 100644 reftable/tree_test.c
Makefile +3 -1
@@ -2458,11 +2458,13 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o +REFTABLE_OBJS += reftable/tree.o +REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o -REFTABLE_TEST_OBJS += reftable/basics_test.o +REFTABLE_TEST_OBJS += reftable/tree_test.o TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
reftable/tree.c new file +63 -0
63 lines not on this page · raw message
reftable/tree.h new file +34 -0
@@ -0,0 +1,34 @@ +/* +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 TREE_H +#define TREE_H + +/* tree_node is a generic binary search tree. */ +struct tree_node { +void *key; +struct tree_node *left, *right; +}; + +/* looks for `key` in `rootp` using `compare` as comparison function. If insert +* is set, insert the key if it's not found. Else, return NULL. +*/ +struct tree_node *tree_search (void *key,struct tree_node **rootp, +int (*compare)(const void *,const void *), +int insert); + +/* performs an infix walk of the tree. */ +void infix_walk (struct tree_node *t,void (*action)(void *arg,void *key), +void *arg); + +/* +* deallocates the tree nodes recursively. Keys should be deallocated separately +* by walking over the tree. */ +void tree_free (struct tree_node *t); + +#endif
reftable/tree_test.c new file +61 -0
61 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -6,5 +6,6 @@ int cmd__reftable(int argc, const char **argv)basics_test_main (argc, argv);block_test_main (argc, argv);record_test_main (argc, argv); +tree_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH v2 11/25 reftable: write reftable files
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- Makefile | 1 + reftable/reftable-writer.h | 148 ++++++++ reftable/writer.c | 690 +++++++++++++++++++++++++++++++++++++ reftable/writer.h | 50 +++ 4 files changed, 889 insertions(+) create mode 100644 reftable/reftable-writer.h create mode 100644 reftable/writer.c create mode 100644 reftable/writer.h
Makefile +1 -0
@@ -2459,6 +2459,7 @@ REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o REFTABLE_OBJS += reftable/tree.o +REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o
reftable/reftable-writer.h new file +148 -0
148 lines not on this page · raw message
reftable/writer.c new file +690 -0
690 lines not on this page · raw message
reftable/writer.h new file +50 -0
50 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v2 12/25 reftable: generic interface to tables
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- Makefile | 3 + reftable/generic.c | 169 +++++++++++++++++++++++++++++++++++ reftable/generic.h | 32 +++++++ reftable/reftable-generic.h | 47 ++++++++++ reftable/reftable-iterator.h | 39 ++++++++ reftable/reftable.c | 115 ++++++++++++++++++++++++ 6 files changed, 405 insertions(+) create mode 100644 reftable/generic.c create mode 100644 reftable/generic.h create mode 100644 reftable/reftable-generic.h create mode 100644 reftable/reftable-iterator.h create mode 100644 reftable/reftable.c
Makefile +3 -0
@@ -2458,6 +2458,9 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o +REFTABLE_OBJS += reftable/refname.o +REFTABLE_OBJS += reftable/generic.o +REFTABLE_OBJS += reftable/stack.o REFTABLE_OBJS += reftable/tree.o REFTABLE_OBJS += reftable/writer.o
reftable/generic.c new file +169 -0
169 lines not on this page · raw message
reftable/generic.h new file +32 -0
@@ -0,0 +1,32 @@ +/* +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 GENERIC_H +#define GENERIC_H + +#include "record.h" +#include "reftable-generic.h" + +/* generic interface to reftables */ +struct reftable_table_vtable { +int (*seek_record)(void *tab,struct reftable_iterator *it, +struct reftable_record *); +uint32_t (*hash_id)(void *tab); +uint64_t (*min_update_index)(void *tab); +uint64_t (*max_update_index)(void *tab); +}; + +struct reftable_iterator_vtable { +int (*next)(void *iter_arg,struct reftable_record *rec); +void (*close)(void *iter_arg); +}; + +void iterator_set_empty (struct reftable_iterator *it); +int iterator_next (struct reftable_iterator *it,struct reftable_record *rec); + +#endif
reftable/reftable-generic.h new file +47 -0
47 lines not on this page · raw message
reftable/reftable-iterator.h new file +39 -0
@@ -0,0 +1,39 @@ +/* +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 REFTABLE_ITERATOR_H +#define REFTABLE_ITERATOR_H + +#include "reftable-record.h" + +struct reftable_iterator_vtable ; + +/* iterator is the generic interface for walking over data stored in a +* reftable. +*/ +struct reftable_iterator { +struct reftable_iterator_vtable *ops; +void *iter_arg; +}; + +/* reads the next reftable_ref_record. Returns < 0 for error, 0 for OK and > 0: +* end of iteration. +*/ +int reftable_iterator_next_ref (struct reftable_iterator *it, +struct reftable_ref_record *ref); + +/* reads the next reftable_log_record. Returns < 0 for error, 0 for OK and > 0: +* end of iteration. +*/ +int reftable_iterator_next_log (struct reftable_iterator *it, +struct reftable_log_record *log); + +/* releases resources associated with an iterator. */ +void reftable_iterator_destroy (struct reftable_iterator *it); + +#endif
reftable/reftable.c new file +115 -0
115 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v2 13/25 reftable: read reftable files
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This supports reading a single reftable file.
The commit introduces an abstract iterator type, which captures the usecases both of reading individual refs, and iterating over a segment of the ref namespace.
--- Makefile | 2 + reftable/iter.c | 194 +++++++++ reftable/iter.h | 69 ++++ reftable/reader.c | 801 +++++++++++++++++++++++++++++++++++++ reftable/reader.h | 66 +++ reftable/reftable-reader.h | 101 +++++ 6 files changed, 1233 insertions(+) create mode 100644 reftable/iter.c create mode 100644 reftable/iter.h create mode 100644 reftable/reader.c create mode 100644 reftable/reader.h create mode 100644 reftable/reftable-reader.h
Makefile +2 -0
@@ -2456,7 +2456,9 @@ REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o +REFTABLE_OBJS += reftable/iter.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/reader.o REFTABLE_OBJS += reftable/record.o REFTABLE_OBJS += reftable/refname.o REFTABLE_OBJS += reftable/generic.o
reftable/iter.c new file +194 -0
194 lines not on this page · raw message
reftable/iter.h new file +69 -0
69 lines not on this page · raw message
reftable/reader.c new file +801 -0
801 lines not on this page · raw message
reftable/reader.h new file +66 -0
66 lines not on this page · raw message
reftable/reftable-reader.h new file +101 -0
101 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v2 14/25 reftable: reftable file level tests
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
With support for reading and writing files in place, we can construct files (in memory) and attempt to read them back.
Because some sections of the format are optional (eg. indices, log entries), we have to exercise this code using multiple sizes of input data
--- Makefile | 1 + reftable/readwrite_test.c | 651 ++++++++++++++++++++++++++++++++++++++ reftable/reftable-tests.h | 2 +- t/helper/test-reftable.c | 1 + 4 files changed, 654 insertions(+), 1 deletion(-) create mode 100644 reftable/readwrite_test.c
Makefile +1 -0
@@ -2469,6 +2469,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o REFTABLE_TEST_OBJS += reftable/record_test.o +REFTABLE_TEST_OBJS += reftable/readwrite_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/tree_test.o
reftable/readwrite_test.c new file +651 -0
651 lines not on this page · raw message
reftable/reftable-tests.h +1 -1
@@ -14,7 +14,7 @@ int block_test_main(int argc, const char **argv);int merged_test_main (int argc,const char **argv);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 readwrite_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);
t/helper/test-reftable.c +1 -0
@@ -6,6 +6,7 @@ int cmd__reftable(int argc, const char **argv)basics_test_main (argc, argv);block_test_main (argc, argv);record_test_main (argc, argv); +readwrite_test_main (argc, argv);tree_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH v2 15/25 reftable: add a heap-based priority queue for reftable records
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This is needed to create a merged view multiple reftables
--- Makefile | 2 + reftable/pq.c | 115 ++++++++++++++++++++++++++++++++++++++ reftable/pq.h | 32 +++++++++++ reftable/pq_test.c | 72 ++++++++++++++++++++++++ reftable/reftable-tests.h | 1 + t/helper/test-reftable.c | 1 + 6 files changed, 223 insertions(+) create mode 100644 reftable/pq.c create mode 100644 reftable/pq.h create mode 100644 reftable/pq_test.c
Makefile +2 -0
@@ -2458,6 +2458,7 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/iter.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/pq.o REFTABLE_OBJS += reftable/reader.o REFTABLE_OBJS += reftable/record.o REFTABLE_OBJS += reftable/refname.o
@@ -2468,6 +2469,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o +REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o
reftable/pq.c new file +115 -0
115 lines not on this page · raw message
reftable/pq.h new file +32 -0
@@ -0,0 +1,32 @@ +/* +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 PQ_H +#define PQ_H + +#include "record.h" + +struct pq_entry { +int index; +struct reftable_record rec; +}; + +struct merged_iter_pqueue { +struct pq_entry *heap; +size_t len; +size_t cap; +}; + +struct pq_entry merged_iter_pqueue_top (struct merged_iter_pqueue pq); +int merged_iter_pqueue_is_empty (struct merged_iter_pqueue pq); +void merged_iter_pqueue_check (struct merged_iter_pqueue pq); +struct pq_entry merged_iter_pqueue_remove (struct merged_iter_pqueue *pq); +void merged_iter_pqueue_add (struct merged_iter_pqueue *pq,struct pq_entry e); +void merged_iter_pqueue_release (struct merged_iter_pqueue *pq); + +#endif
reftable/pq_test.c new file +72 -0
72 lines not on this page · raw message
reftable/reftable-tests.h +1 -0
@@ -12,6 +12,7 @@ https://developers.google.com/open-source/licenses/bsdint basics_test_main (int argc,const char **argv);int block_test_main (int argc,const char **argv);int merged_test_main (int argc,const char **argv); +int pq_test_main (int argc,const char **argv);int record_test_main (int argc,const char **argv);int refname_test_main (int argc,const char **argv);int readwrite_test_main (int argc,const char **argv);
t/helper/test-reftable.c +1 -0
@@ -5,6 +5,7 @@ int cmd__reftable(int argc, const char **argv) {basics_test_main (argc, argv);block_test_main (argc, argv); +pq_test_main (argc, argv);record_test_main (argc, argv);readwrite_test_main (argc, argv);tree_test_main (argc, argv);
Signature · 1 line
gitgitgadget
PATCH v2 16/25 reftable: add merged table view
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This adds an abstract, read-only interface to the ref database.
This primitive is used to construct the read view of the ref database (the read view is constructed by merging several *.ref files). It also provides the mechanism to provide a unified view of the refs in the main repository and the per-worktree refs.
--- Makefile | 2 + reftable/merged.c | 362 +++++++++++++++++++++++++++++++++++++ reftable/merged.h | 35 ++++ reftable/merged_test.c | 292 ++++++++++++++++++++++++++++++ reftable/reftable-merged.h | 72 ++++++++ t/helper/test-reftable.c | 1 + 6 files changed, 764 insertions(+) create mode 100644 reftable/merged.c create mode 100644 reftable/merged.h create mode 100644 reftable/merged_test.c create mode 100644 reftable/reftable-merged.h
Makefile +2 -0
@@ -2458,6 +2458,7 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/iter.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/merged.o REFTABLE_OBJS += reftable/pq.o REFTABLE_OBJS += reftable/reader.o REFTABLE_OBJS += reftable/record.o
@@ -2469,6 +2470,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o +REFTABLE_TEST_OBJS += reftable/merged_test.o REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o
reftable/merged.c new file +362 -0
362 lines not on this page · raw message
reftable/merged.h new file +35 -0
@@ -0,0 +1,35 @@ +/* +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 MERGED_H +#define MERGED_H + +#include "pq.h" + +struct reftable_merged_table { +struct reftable_table *stack; +size_t stack_len; +uint32_t hash_id; +int suppress_deletions; + +uint64_t min; +uint64_t max; +}; + +struct merged_iter { +struct reftable_iterator *stack; +uint32_t hash_id; +size_t stack_len; +uint8_t typ; +int suppress_deletions; +struct merged_iter_pqueue pq; +}; + +void merged_table_release (struct reftable_merged_table *mt); + +#endif
reftable/merged_test.c new file +292 -0
292 lines not on this page · raw message
reftable/reftable-merged.h new file +72 -0
72 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -5,6 +5,7 @@ int cmd__reftable(int argc, const char **argv) {basics_test_main (argc, argv);block_test_main (argc, argv); +merged_test_main (argc, argv);pq_test_main (argc, argv);record_test_main (argc, argv);readwrite_test_main (argc, argv);
Signature · 1 line
gitgitgadget
PATCH v2 17/25 reftable: implement refname validation
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The packed/loose format has restrictions on refnames: a and a/b cannot coexist. This limitation does not apply to reftable per se, but must be maintained for interoperability. This code adds validation routines to abort transactions that are trying to add invalid names.
--- Makefile | 1 + reftable/refname.c | 209 +++++++++++++++++++++++++++++++++++++++ reftable/refname.h | 29 ++++++ reftable/refname_test.c | 102 +++++++++++++++++++ t/helper/test-reftable.c | 1 + 5 files changed, 342 insertions(+) create mode 100644 reftable/refname.c create mode 100644 reftable/refname.h create mode 100644 reftable/refname_test.c
Makefile +1 -0
@@ -2474,6 +2474,7 @@ REFTABLE_TEST_OBJS += reftable/merged_test.o REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o +REFTABLE_TEST_OBJS += reftable/refname_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/tree_test.o
reftable/refname.c new file +209 -0
209 lines not on this page · raw message
reftable/refname.h new file +29 -0
@@ -0,0 +1,29 @@ +/* +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 REFNAME_H +#define REFNAME_H + +#include "reftable-record.h" +#include "reftable-generic.h" + +struct modification { +struct reftable_table tab; + +char **add; +size_t add_len; + +char **del; +size_t del_len; +}; + +int validate_ref_record_addition (struct reftable_table tab, +struct reftable_ref_record *recs,size_t sz); + +int modification_validate (struct modification *mod); + +#endif
reftable/refname_test.c new file +102 -0
102 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -8,6 +8,7 @@ int cmd__reftable(int argc, const char **argv)merged_test_main (argc, argv);pq_test_main (argc, argv);record_test_main (argc, argv); +refname_test_main (argc, argv);readwrite_test_main (argc, argv);tree_test_main (argc, argv);return 0 ;
Signature · 1 line
gitgitgadget
PATCH v2 18/25 reftable: implement stack, a mutable database of reftable files.
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- Makefile | 1 + reftable/reftable-stack.h | 128 ++++ reftable/stack.c | 1396 +++++++++++++++++++++++++++++++++++++ reftable/stack.h | 41 ++ reftable/stack_test.c | 947 +++++++++++++++++++++++++ t/helper/test-reftable.c | 1 + 6 files changed, 2514 insertions(+) create mode 100644 reftable/reftable-stack.h create mode 100644 reftable/stack.c create mode 100644 reftable/stack.h create mode 100644 reftable/stack_test.c
Makefile +1 -0
@@ -2475,6 +2475,7 @@ REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o REFTABLE_TEST_OBJS += reftable/refname_test.o +REFTABLE_TEST_OBJS += reftable/stack_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/tree_test.o
reftable/reftable-stack.h new file +128 -0
128 lines not on this page · raw message
reftable/stack.c new file +1396 -0
1,396 lines not on this page · raw message
reftable/stack.h new file +41 -0
41 lines not on this page · raw message
reftable/stack_test.c new file +947 -0
947 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -10,6 +10,7 @@ int cmd__reftable(int argc, const char **argv)record_test_main (argc, argv);refname_test_main (argc, argv);readwrite_test_main (argc, argv); +stack_test_main (argc, argv);tree_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH v2 19/25 reftable: add dump utility
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
provide a command-line utility for inspecting individual tables, and inspecting a complete ref database
--- reftable/dump.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 reftable/dump.c
reftable/dump.c new file +107 -0
@@ -0,0 +1,107 @@ +/* +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 "git-compat-util.h" +#include "hash.h" + +#include "reftable-blocksource.h" +#include "reftable-error.h" +#include "reftable-merged.h" +#include "reftable-record.h" +#include "reftable-tests.h" +#include "reftable-writer.h" +#include "reftable-iterator.h" +#include "reftable-reader.h" +#include "reftable-stack.h" +#include "reftable-generic.h" + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +static int compact_stack (const char *stackdir) +{ +struct reftable_stack *stack =NULL ; +struct reftable_write_options cfg = {0 }; + +int err =reftable_new_stack (&stack, stackdir, cfg); +if (err <0 ) + goto done; + + err =reftable_stack_compact_all (stack,NULL ); +if (err <0 ) + goto done; +done: +if (stack) { +reftable_stack_destroy (stack); + } +return err; +} + +static void print_help (void ) +{ +printf ("usage: dump [-cst] arg\n\n" +"options: \n" +" -c compact\n" +" -t dump table\n" +" -s dump stack\n" +" -6 sha256 hash format\n" +" -h this help\n" +"\n" ); +} + +int reftable_dump_main (int argc,char *const *argv) +{ +int err =0 ; +int opt_dump_table =0 ; +int opt_dump_stack =0 ; +int opt_compact =0 ; +uint32_t opt_hash_id =GIT_SHA1_FORMAT_ID ; +const char *arg =NULL , *argv0 = argv[0 ]; + +for (; argc >1 ; argv++, argc--) +if (*argv[1 ] !='-' ) +break ; +else if (!strcmp ("-t" , argv[1 ])) + opt_dump_table =1 ; +else if (!strcmp ("-6" , argv[1 ])) + opt_hash_id =GIT_SHA256_FORMAT_ID ; +else if (!strcmp ("-s" , argv[1 ])) + opt_dump_stack =1 ; +else if (!strcmp ("-c" , argv[1 ])) + opt_compact =1 ; +else if (!strcmp ("-?" , argv[1 ]) || !strcmp ("-h" , argv[1 ])) { +print_help (); +return 2 ; + } + +if (argc !=2 ) { +fprintf (stderr,"need argument\n" ); +print_help (); +return 2 ; + } + + arg = argv[1 ]; + +if (opt_dump_table) { + err =reftable_reader_print_file (arg); + }else if (opt_dump_stack) { + err =reftable_stack_print_directory (arg, opt_hash_id); + }else if (opt_compact) { + err =compact_stack (arg); + } + +if (err <0 ) { +fprintf (stderr,"%s: %s: %s\n" , argv0, arg, +reftable_error_str (err)); +return 1 ; + } +return 0 ; +}
Signature · 1 line
gitgitgadget
PATCH v2 21/25 git-prompt: prepare for reftable refs backend
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: =?UTF-8?q?SZEDER=20G=C3=A1bor?= <[email protected]>
In our git-prompt script we strive to use Bash builtins wherever possible, because fork()-ing subshells for command substitutions and fork()+exec()-ing Git commands are expensive on some platforms. We even read and parse '.git/HEAD' using Bash builtins to get the name of the current branch [1]. However, the upcoming reftable refs backend won't use '.git/HEAD' at all, but will write an invalid refname as placeholder for backwards compatibility instead, which will break our git-prompt script.
Update the git-prompt script to recognize the placeholder '.git/HEAD' written by the reftable backend (its content is specified in the reftable specs), and then fall back to use 'git symbolic-ref' to get the name of the current branch.
[1] 3a43c4b5bd (bash prompt: use bash builtins to find out current
branch, 2011-03-31)
--- contrib/completion/git-prompt.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
contrib/completion/git-prompt.sh +6 -1
@@ -478,10 +478,15 @@ __git_ps1 () if ! __git_eread "$g/HEAD" head; then return $exit fi - # is it a symbolic ref? b="${head#ref: }" if [ "$head" = "$b" ]; then detached=yes + elif [ "$b" = "refs/heads/.invalid" ]; then + # Reftable + b="$(git symbolic-ref HEAD 2>/dev/null)" || + detached=yes + fi + if [ "$detached" = yes ]; then b="$( case "${GIT_PS1_DESCRIBE_STYLE-}" in (contains)
Signature · 1 line
gitgitgadget
PATCH v2 20/25 refs: RFC: Reftable support for git-core
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
For background, see Documentation/technical/reftable.txt.
This introduces the file refs/reftable-backend.c containing a reftable-powered ref storage backend.
It can be activated by setting GIT_TEST_REFTABLE in the environment. When GIT_TEST_REFTABLE is set, the test prerequisite !REFFILES is set.
There is no option to git-init for now, as the test suite still shows failures with GIT_TEST_REFTABLE=1.
Example use: see t/t0031-reftable.sh
--- Documentation/config/extensions.txt | 9 + .../technical/repository-version.txt | 7 + Makefile | 1 + builtin/clone.c | 5 +- builtin/init-db.c | 39 +- builtin/stash.c | 8 +- builtin/worktree.c | 27 +- cache.h | 8 +- config.mak.uname | 2 +- contrib/buildsystems/Generators/Vcxproj.pm | 11 +- contrib/workdir/git-new-workdir | 2 +- refs.c | 26 +- refs.h | 3 + refs/refs-internal.h | 1 + refs/reftable-backend.c | 1686 +++++++++++++++++ repository.c | 2 + repository.h | 3 + setup.c | 8 + t/t0031-reftable.sh | 310 +++ t/t1409-avoid-packing-refs.sh | 6 + t/t1450-fsck.sh | 6 + t/t3210-pack-refs.sh | 6 + t/test-lib.sh | 7 +- 23 files changed, 2154 insertions(+), 29 deletions(-) create mode 100644 refs/reftable-backend.c create mode 100755 t/t0031-reftable.sh
Documentation/config/extensions.txt +9 -0
@@ -6,3 +6,12 @@ extensions.objectFormat:: Note that this setting should only be set by linkgit:git-init[1] or linkgit:git-clone[1]. Trying to change it after initialization will not work and will produce hard-to-diagnose issues. ++ +extensions.refStorage:: + Specify the ref storage mechanism to use. The acceptable values are `files` and + `reftable`. If not specified, `files` is assumed. It is an error to specify + this key unless `core.repositoryFormatVersion` is 1. ++ +Note that this setting should only be set by linkgit:git-init[1] or +linkgit:git-clone[1]. Trying to change it after initialization will not +work and will produce hard-to-diagnose issues.
Documentation/technical/repository-version.txt +7 -0
@@ -100,3 +100,10 @@ If set, by default "git config" reads from both "config" and multiple working directory mode, "config" file is shared while "config.worktree" is per-working directory (i.e., it's in GIT_COMMON_DIR/worktrees/<id>/config.worktree) + +==== `refStorage` + +Specifies the file format for the ref database. Values are `files` +(for the traditional packed + loose ref format) and `reftable` for the +binary reftable format. See https://github.com/google/reftable for +more information.
Makefile +1 -0
@@ -990,6 +990,7 @@ LIB_OBJS += reflog-walk.o LIB_OBJS += refs.o LIB_OBJS += refs/debug.o LIB_OBJS += refs/files-backend.o +LIB_OBJS += refs/reftable-backend.o LIB_OBJS += refs/iterator.o LIB_OBJS += refs/packed-backend.o LIB_OBJS += refs/ref-cache.o
builtin/clone.c +3 -2
@@ -1148,7 +1148,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) }init_db (git_dir, real_git_dir, option_template,GIT_HASH_UNKNOWN ,NULL , -INIT_DB_QUIET ); +default_ref_storage (),INIT_DB_QUIET );if (real_git_dir) git_dir = real_git_dir;
@@ -1299,7 +1299,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)* Now that we know what algorithm the remote side is using, * let's set ours to the same thing. */ -initialize_repository_version (hash_algo,1 ); +initialize_repository_version (hash_algo,1 , +default_ref_storage ());repo_set_hash_algo (the_repository, hash_algo); mapped_refs =wanted_peer_refs (refs, &remote->fetch);
builtin/init-db.c +31 -8
@@ -167,12 +167,14 @@ static int needs_work_tree_config(const char *git_dir, const char *work_tree)return 1 ; } -void initialize_repository_version (int hash_algo,int reinit) +void initialize_repository_version (int hash_algo,int reinit, +const char *ref_storage_format) {char repo_version_string[10 ];int repo_version =GIT_REPO_VERSION ; -if (hash_algo !=GIT_HASH_SHA1 ) +if (hash_algo !=GIT_HASH_SHA1 || + !strcmp (ref_storage_format,"reftable" )) repo_version =GIT_REPO_VERSION_READ ;/* This forces creation of new config file */
@@ -226,6 +228,7 @@ static int create_default_files(const char *template_path, is_bare_repository_cfg = init_is_bare_repository || !work_tree;if (init_shared_repository !=-1 )set_shared_repository (init_shared_repository); + the_repository->ref_storage_format =xstrdup (fmt->ref_storage);/* * We would have created the above under user's umask -- under
@@ -235,6 +238,24 @@ static int create_default_files(const char *template_path,adjust_shared_perm (get_git_dir ()); } +/* +* Check to see if .git/HEAD exists; this must happen before +* initializing the ref db, because we want to see if there is an +* existing HEAD. +*/ + path =git_path_buf (&buf,"HEAD" ); + reinit = (!access (path,R_OK ) || +readlink (path, junk,sizeof (junk) -1 ) !=-1 ); + +/* +* refs/heads is a file when using reftable. We can't reinitialize with +* a reftable because it will overwrite HEAD +*/ +if (reinit && (!strcmp (fmt->ref_storage,"reftable" )) == +is_directory (git_path_buf (&buf,"refs/heads" ))) { +die ("cannot switch ref storage format." ); + } +/* * We need to create a "refs" dir in any case so that older * versions of git can tell that this is a repository.
@@ -249,9 +270,6 @@ static int create_default_files(const char *template_path,* Point the HEAD symref to the initial branch with if HEAD does * not yet exist. */ - path =git_path_buf (&buf,"HEAD" ); - reinit = (!access (path,R_OK ) - ||readlink (path, junk,sizeof (junk)-1 ) !=-1 );if (!reinit) {char *ref;
@@ -268,7 +286,7 @@ static int create_default_files(const char *template_path,free (ref); } -initialize_repository_version (fmt->hash_algo,0 ); +initialize_repository_version (fmt->hash_algo,0 , fmt->ref_storage);/* Check filemode trustability */ path =git_path_buf (&buf,"config" );
@@ -383,7 +401,7 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hashint init_db (const char *git_dir,const char *real_git_dir,const char *template_dir,int hash,const char *initial_branch, -unsigned int flags) +const char *ref_storage_format,unsigned int flags) {int reinit;int exist_ok = flags &INIT_DB_EXIST_OK ;
@@ -422,6 +440,7 @@ int init_db(const char *git_dir, const char *real_git_dir,* is an attempt to reinitialize new repository with an old tool. */ check_repository_format (&repo_fmt); + repo_fmt.ref_storage =xstrdup (ref_storage_format);validate_hash_algorithm (&repo_fmt, hash);
@@ -476,6 +495,9 @@ int init_db(const char *git_dir, const char *real_git_dir,git_config_set ("receive.denyNonFastforwards" ,"true" ); } +if (!strcmp (ref_storage_format,"reftable" )) +git_config_set ("extensions.refStorage" , ref_storage_format); +if (!(flags &INIT_DB_QUIET )) {int len =strlen (git_dir);
@@ -549,6 +571,7 @@ static const char *const init_db_usage[] = {int cmd_init_db (int argc,const char **argv,const char *prefix) {const char *git_dir; +const char *ref_storage_format =default_ref_storage ();const char *real_git_dir =NULL ;const char *work_tree;const char *template_dir =NULL ;
@@ -713,5 +736,5 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) flags |=INIT_DB_EXIST_OK ;return init_db (git_dir, real_git_dir, template_dir, hash_algo, - initial_branch, flags); + initial_branch, ref_storage_format, flags); }
builtin/stash.c +7 -1
@@ -207,10 +207,16 @@ static int get_stash_info(struct stash_info *info, int argc, const char **argv)static int do_clear_stash (void ) {struct object_id obj; +int result;if (get_oid (ref_stash, &obj))return 0 ; -return delete_ref (NULL , ref_stash, &obj,0 ); + result =delete_ref (NULL , ref_stash, &obj,0 ); + +/* Ignore error; this is necessary for reftable, which keeps reflogs +* even when refs are deleted. */ +delete_reflog (ref_stash); +return result; }static int clear_stash (int argc,const char **argv,const char *prefix)
builtin/worktree.c +24 -3
@@ -13,6 +13,7 @@#include "utf8.h" #include "worktree.h" #include "quote.h" +#include "../refs/refs-internal.h" static const char *const worktree_usage[] = {N_ ("git worktree add [<options>] <path> [<commit-ish>]" ),
@@ -328,9 +329,29 @@ static int add_worktree(const char *path, const char *refname,* worktree. */ strbuf_reset (&sb); -strbuf_addf (&sb,"%s/HEAD" , sb_repo.buf); -write_file (sb.buf,"%s" ,oid_to_hex (null_oid ())); -strbuf_reset (&sb); +if (get_main_ref_store (the_repository)->be == &refs_be_reftable) { +/* XXX this is cut & paste from reftable_init_db. */ +strbuf_addf (&sb,"%s/HEAD" , sb_repo.buf); +write_file (sb.buf,"%s" ,"ref: refs/heads/.invalid\n" ); +strbuf_reset (&sb); + +strbuf_addf (&sb,"%s/refs" , sb_repo.buf); +safe_create_dir (sb.buf,1 ); +strbuf_reset (&sb); + +strbuf_addf (&sb,"%s/refs/heads" , sb_repo.buf); +write_file (sb.buf,"this repository uses the reftable format" ); +strbuf_reset (&sb); + +strbuf_addf (&sb,"%s/reftable" , sb_repo.buf); +safe_create_dir (sb.buf,1 ); +strbuf_reset (&sb); + }else { +strbuf_addf (&sb,"%s/HEAD" , sb_repo.buf); +write_file (sb.buf,"%s" ,oid_to_hex (null_oid ())); +strbuf_reset (&sb); + } +strbuf_addf (&sb,"%s/commondir" , sb_repo.buf);write_file (sb.buf,"../.." );
cache.h +5 -3
@@ -656,9 +656,10 @@ int path_inside_repo(const char *prefix, const char *path);#define INIT_DB_EXIST_OK 0x0002int init_db (const char *git_dir,const char *real_git_dir, -const char *template_dir,int hash_algo, -const char *initial_branch,unsigned int flags); -void initialize_repository_version (int hash_algo,int reinit); +const char *template_dir,int hash_algo,const char *initial_branch, +const char *ref_storage_format,unsigned int flags); +void initialize_repository_version (int hash_algo,int reinit, +const char *ref_storage_format);void sanitize_stdfds (void );int daemonize (void );
@@ -1076,6 +1077,7 @@ struct repository_format {int hash_algo;int sparse_index;char *work_tree; +char *ref_storage;struct string_list unknown_extensions;struct string_list v1_only_extensions; };
config.mak.uname +1 -1
@@ -712,7 +712,7 @@ vcxproj: # Make .vcxproj files and add them unset QUIET_GEN QUIET_BUILT_IN; \ perl contrib/buildsystems/generate -g Vcxproj - git add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj + git add -f git.sln {*,*/lib,*/libreftable,t/helper/*}/*.vcxproj # Generate the LinkOrCopyBuiltins.targets and LinkOrCopyRemoteHttp.targets file (echo '<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">' && \
contrib/buildsystems/Generators/Vcxproj.pm +10 -1
@@ -77,7 +77,7 @@ sub createProject { my $libs_release = "\n "; my $libs_debug = "\n "; if (!$static_library) { - $libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}})); + $libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib|reftable\/libreftable\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}})); $libs_debug = $libs_release; $libs_debug =~ s/zlib\.lib/zlibd\.lib/g; $libs_debug =~ s/libexpat\.lib/libexpatd\.lib/g;
@@ -232,6 +232,7 @@ EOM EOM if (!$static_library || $target =~ 'vcs-svn' || $target =~ 'xdiff') { my $uuid_libgit = $$build_structure{"LIBS_libgit_GUID"}; + my $uuid_libreftable = $$build_structure{"LIBS_reftable/libreftable_GUID"}; my $uuid_xdiff_lib = $$build_structure{"LIBS_xdiff/lib_GUID"}; print F << "EOM";
@@ -241,6 +242,14 @@ EOM <ReferenceOutputAssembly>false</ReferenceOutputAssembly> </ProjectReference> EOM + if (!($name =~ /xdiff|libreftable/)) { + print F << "EOM"; + <ProjectReference Include="$cdup\\reftable\\libreftable\\libreftable.vcxproj"> + <Project>$uuid_libreftable</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> +EOM + } if (!($name =~ 'xdiff')) { print F << "EOM"; <ProjectReference Include="$cdup\\xdiff\\lib\\xdiff_lib.vcxproj">
contrib/workdir/git-new-workdir +1 -1
@@ -79,7 +79,7 @@ trap cleanup $siglist # create the links to the original repo. explicitly exclude index, HEAD and # logs/HEAD from the list since they are purely related to the current working # directory, and should not be shared. -for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn +for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn reftable do # create a containing directory if needed case $x in
refs.c +18 -8
@@ -19,10 +19,15 @@#include "repository.h" #include "sigchain.h" +const char *default_ref_storage (void ) +{ +return git_env_bool ("GIT_TEST_REFTABLE" ,0 ) ?"reftable" :"files" ; +} +/* * List of all available backends */ -static struct ref_storage_be *refs_backends = &refs_be_files; +static struct ref_storage_be *refs_backends = &refs_be_reftable;static struct ref_storage_be *find_ref_storage_backend (const char *name) {
@@ -1875,13 +1880,13 @@ static struct ref_store *lookup_ref_store_map(struct hashmap *map,* Create, record, and return a ref_store instance for the specified * gitdir. */ -static struct ref_store *ref_store_init (const char *gitdir, +static struct ref_store *ref_store_init (const char *gitdir,const char *be_name,unsigned int flags) { -const char *be_name ="files" ; -struct ref_storage_be *be =find_ref_storage_backend (be_name); +struct ref_storage_be *be;struct ref_store *refs; + be =find_ref_storage_backend (be_name);if (!be)BUG ("reference backend %s is unknown" , be_name);
@@ -1897,7 +1902,11 @@ struct ref_store *get_main_ref_store(struct repository *r)if (!r->gitdir)BUG ("attempting to get main_ref_store outside of repository" ); - r->refs_private =ref_store_init (r->gitdir,REF_STORE_ALL_CAPS ); + r->refs_private =ref_store_init (r->gitdir, + r->ref_storage_format ? + r->ref_storage_format : +default_ref_storage (), +REF_STORE_ALL_CAPS ); r->refs_private =maybe_debug_wrap_ref_store (r->gitdir, r->refs_private);return r->refs_private; }
@@ -1953,7 +1962,7 @@ 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, + 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);
@@ -1967,6 +1976,7 @@ done:struct ref_store *get_worktree_ref_store (const struct worktree *wt) { +const char *format =default_ref_storage ();struct ref_store *refs;const char *id;
@@ -1980,9 +1990,9 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt)if (wt->id) refs =ref_store_init (git_common_path ("worktrees/%s" , wt->id), -REF_STORE_ALL_CAPS ); + format,REF_STORE_ALL_CAPS );else - refs =ref_store_init (get_git_common_dir (), + refs =ref_store_init (get_git_common_dir (), format,REF_STORE_ALL_CAPS );if (refs)
refs.h +3 -0
@@ -11,6 +11,9 @@ struct string_list;struct string_list_item ;struct worktree ; +/* Returns the ref storage backend to use by default. */ +const char *default_ref_storage (void ); +/* * Resolve a reference, recursively following symbolic refererences. *
refs/refs-internal.h +1 -0
@@ -672,6 +672,7 @@ struct ref_storage_be { };extern struct ref_storage_be refs_be_files; +extern struct ref_storage_be refs_be_reftable;extern struct ref_storage_be refs_be_packed;/*
refs/reftable-backend.c new file +1686 -0
1,686 lines not on this page · raw message
repository.c +2 -0
@@ -180,6 +180,8 @@ int repo_init(struct repository *repo,if (worktree)repo_set_worktree (repo, worktree); + repo->ref_storage_format =xstrdup_or_null (format.ref_storage); +clear_repository_format (&format);return 0 ;
repository.h +3 -0
@@ -82,6 +82,9 @@ struct repository {*/ struct ref_store *refs_private; +/* The format to use for the ref database. */ +char *ref_storage_format; +/* * Contains path to often used file names. */
setup.c +8 -0
@@ -498,6 +498,9 @@ static enum extension_result handle_extension(const char *var,return error ("invalid value for 'extensions.objectformat'" ); data->hash_algo = format;return EXTENSION_OK ; + }else if (!strcmp (ext,"refstorage" )) { + data->ref_storage =xstrdup (value); +return EXTENSION_OK ; }return EXTENSION_UNKNOWN ; }
@@ -648,6 +651,7 @@ void clear_repository_format(struct repository_format *format)string_list_clear (&format->v1_only_extensions,0 );free (format->work_tree);free (format->partial_clone); +free (format->ref_storage);init_repository_format (format); }
@@ -1312,6 +1316,8 @@ const char *setup_git_directory_gently(int *nongit_ok) the_repository->repository_format_partial_clone = repo_fmt.partial_clone; repo_fmt.partial_clone =NULL ; + the_repository->ref_storage_format = +xstrdup_or_null (repo_fmt.ref_storage); } }/*
@@ -1399,6 +1405,8 @@ void check_repository_format(struct repository_format *fmt)repo_set_hash_algo (the_repository, fmt->hash_algo); the_repository->repository_format_partial_clone =xstrdup_or_null (fmt->partial_clone); +/* XXX why is repo->ref_storage_format set in multiple places?! */ + the_repository->ref_storage_format =xstrdup_or_null (fmt->ref_storage);clear_repository_format (&repo_fmt); }
t/t0031-reftable.sh new file +310 -0
310 lines not on this page · raw message
t/t1409-avoid-packing-refs.sh +6 -0
@@ -4,6 +4,12 @@ test_description='avoid rewriting packed-refs unnecessarily' . ./test-lib.sh +if test_have_prereq !REFFILES +then + skip_all='skipping pack-refs tests; need files backend' + test_done +fi + # Add an identifying mark to the packed-refs file header line. This # shouldn't upset readers, and it should be omitted if the file is # ever rewritten.
t/t1450-fsck.sh +6 -0
@@ -8,6 +8,12 @@ test_description='git fsck random collection of tests . ./test-lib.sh +if test_have_prereq !REFFILES +then + skip_all='skipping tests; incompatible with reftable' + test_done +fi + test_expect_success setup ' git config gc.auto 0 && git config i18n.commitencoding ISO-8859-1 &&
t/t3210-pack-refs.sh +6 -0
@@ -14,6 +14,12 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh +if test_have_prereq !REFFILES +then + skip_all='skipping pack-refs tests; requires files ref backend' + test_done +fi + test_expect_success 'enable reflogs' ' git config core.logallrefupdates true '
t/test-lib.sh +6 -1
@@ -1524,7 +1524,12 @@ parisc* | hppa*) ;; esac -test_set_prereq REFFILES +if test -n "$GIT_TEST_REFTABLE" +then + test_set_prereq !REFFILES +else + test_set_prereq REFFILES +fi ( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1 test -z "$NO_PERL" && test_set_prereq PERL
Signature · 1 line
gitgitgadget
PATCH v2 22/25 Add "test-tool dump-reftable" command.
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This command dumps individual tables or a stack of of tables.
--- Makefile | 1 + t/helper/test-reftable.c | 5 +++++ t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + t/t0031-reftable.sh | 6 ++++++ 5 files changed, 14 insertions(+)
Makefile +1 -0
@@ -2471,6 +2471,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o +REFTABLE_TEST_OBJS += reftable/dump.o REFTABLE_TEST_OBJS += reftable/merged_test.o REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o
t/helper/test-reftable.c +5 -0
@@ -14,3 +14,8 @@ int cmd__reftable(int argc, const char **argv)tree_test_main (argc, argv);return 0 ; } + +int cmd__dump_reftable (int argc,const char **argv) +{ +return reftable_dump_main (argc, (char *const *)argv); +}
t/helper/test-tool.c +1 -0
@@ -61,6 +61,7 @@ static struct test_cmd cmds[] = { { "read-midx", cmd__read_midx }, { "ref-store", cmd__ref_store }, { "reftable", cmd__reftable }, + { "dump-reftable", cmd__dump_reftable }, { "regex", cmd__regex }, { "repository", cmd__repository }, { "revision-walking", cmd__revision_walking },
t/helper/test-tool.h +1 -0
@@ -19,6 +19,7 @@ int cmd__dump_cache_tree(int argc, const char **argv);int cmd__dump_fsmonitor (int argc,const char **argv);int cmd__dump_split_index (int argc,const char **argv);int cmd__dump_untracked_cache (int argc,const char **argv); +int cmd__dump_reftable (int argc,const char **argv);int cmd__example_decorate (int argc,const char **argv);int cmd__fast_rebase (int argc,const char **argv);int cmd__genrandom (int argc,const char **argv);
t/t0031-reftable.sh +6 -0
@@ -288,6 +288,12 @@ test_expect_success 'FETCH_HEAD' ' test_cmp expect actual ' +test_expect_success 'dump reftable' ' + initialize && + hash_id=$(git config extensions.objectformat) && + test-tool dump-reftable $(test "${hash_id}" = "sha256" && echo "-6") -s .git/reftable +' + . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd
Signature · 1 line
gitgitgadget
PATCH v2 23/25 t1301: document what needs to be done for reftable
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- t/t1301-shared-repo.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
t/t1301-shared-repo.sh +5 -3
@@ -22,9 +22,10 @@ test_expect_success 'shared = 0400 (faulty permission u-w)' ' ) ' +# TODO(hanwen): for REFTABLE should inspect group-readable of .git/reftable/ for u in 002 022 do - test_expect_success POSIXPERM "shared=1 does not clear bits preset by umask $u" ' + test_expect_success REFFILES,POSIXPERM "shared=1 does not clear bits preset by umask $u" ' mkdir sub && ( cd sub && umask $u &&
@@ -114,7 +115,8 @@ test_expect_success POSIXPERM 'info/refs respects umask in unshared repo' ' test_cmp expect actual ' -test_expect_success POSIXPERM 'git reflog expire honors core.sharedRepository' ' +# For reftable, the check on .git/reftable/ is sufficient. +test_expect_success REFFILES,POSIXPERM 'git reflog expire honors core.sharedRepository' ' umask 077 && git config core.sharedRepository group && git reflog expire --all &&
@@ -201,7 +203,7 @@ test_expect_success POSIXPERM 're-init respects core.sharedrepository (remote)' test_cmp expect actual ' -test_expect_success POSIXPERM 'template can set core.sharedrepository' ' +test_expect_success REFFILES,POSIXPERM 'template can set core.sharedrepository' ' rm -rf child.git && umask 0022 && git config core.sharedrepository 0666 &&
Signature · 1 line
gitgitgadget
PATCH v2 24/25 t1401,t2011: parameterize HEAD.lock for REFFILES
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- t/t1401-symbolic-ref.sh | 11 +++++++++-- t/t2011-checkout-invalid-head.sh | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-)
t/t1401-symbolic-ref.sh +9 -2
@@ -102,9 +102,16 @@ test_expect_success LONG_REF 'we can parse long symbolic ref' ' test_cmp expect actual ' +if test_have_prereq REFFILES +then + HEAD_LOCK=HEAD.lock +else + HEAD_LOCK=reftable/tables.list.lock +fi + test_expect_success 'symbolic-ref reports failure in exit code' ' - test_when_finished "rm -f .git/HEAD.lock" && - >.git/HEAD.lock && + test_when_finished "rm -f .git/$HEAD_LOCK" && + >.git/$HEAD_LOCK && test_must_fail git symbolic-ref HEAD refs/heads/whatever '
t/t2011-checkout-invalid-head.sh +9 -2
@@ -22,9 +22,16 @@ test_expect_success 'checkout main from invalid HEAD' ' git checkout main -- ' +if test_have_prereq REFFILES +then + HEAD_LOCK=HEAD.lock +else + HEAD_LOCK=reftable/tables.list.lock +fi + test_expect_success 'checkout notices failure to lock HEAD' ' - test_when_finished "rm -f .git/HEAD.lock" && - >.git/HEAD.lock && + test_when_finished "rm -f .git/$HEAD_LOCK" && + >.git/$HEAD_LOCK && test_must_fail git checkout -b other '
Signature · 1 line
gitgitgadget
PATCH v2 25/25 t1404: annotate test cases with REFFILES
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
* Reftable for now lacks detailed error messages for directory/file conflicts. Skip message comparisons.
* Mark tests that muck with .git directly as REFFILES.
--- t/t1404-update-ref-errors.sh | 56 +++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 14 deletions(-)
t/t1404-update-ref-errors.sh +42 -14
@@ -27,7 +27,9 @@ test_update_rejected () { fi && printf "create $prefix/%s $C\n" $create >input && test_must_fail git update-ref --stdin <input 2>output.err && - test_i18ngrep -F "$error" output.err && + if test_have_prereq REFFILES ; then + test_i18ngrep -F "$error" output.err + fi && git for-each-ref $prefix >actual && test_cmp unchanged actual }
@@ -101,7 +103,9 @@ df_test() { printf "%s\n" "delete $delname" "create $addname $D" fi >commands && test_must_fail git update-ref --stdin <commands 2>output.err && - test_cmp expected-err output.err && + if test_have_prereq REFFILES ; then + test_cmp expected-err output.err + fi && printf "%s\n" "$C $delref" >expected-refs && git for-each-ref --format="%(objectname) %(refname)" $prefix/r >actual-refs && test_cmp expected-refs actual-refs
@@ -336,7 +340,9 @@ test_expect_success 'missing old value blocks update' ' EOF printf "%s\n" "update $prefix/foo $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks update' '
@@ -347,7 +353,9 @@ test_expect_success 'incorrect old value blocks update' ' EOF printf "%s\n" "update $prefix/foo $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'existing old value blocks create' '
@@ -358,7 +366,9 @@ test_expect_success 'existing old value blocks create' ' EOF printf "%s\n" "create $prefix/foo $E" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks delete' '
@@ -369,7 +379,9 @@ test_expect_success 'incorrect old value blocks delete' ' EOF printf "%s\n" "delete $prefix/foo $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'missing old value blocks indirect update' '
@@ -380,7 +392,9 @@ test_expect_success 'missing old value blocks indirect update' ' EOF printf "%s\n" "update $prefix/symref $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks indirect update' '
@@ -392,7 +406,9 @@ test_expect_success 'incorrect old value blocks indirect update' ' EOF printf "%s\n" "update $prefix/symref $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'existing old value blocks indirect create' '
@@ -404,7 +420,9 @@ test_expect_success 'existing old value blocks indirect create' ' EOF printf "%s\n" "create $prefix/symref $E" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks indirect delete' '
@@ -416,7 +434,9 @@ test_expect_success 'incorrect old value blocks indirect delete' ' EOF printf "%s\n" "delete $prefix/symref $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'missing old value blocks indirect no-deref update' '
@@ -427,7 +447,9 @@ test_expect_success 'missing old value blocks indirect no-deref update' ' EOF printf "%s\n" "option no-deref" "update $prefix/symref $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks indirect no-deref update' '
@@ -439,7 +461,9 @@ test_expect_success 'incorrect old value blocks indirect no-deref update' ' EOF printf "%s\n" "option no-deref" "update $prefix/symref $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'existing old value blocks indirect no-deref create' '
@@ -451,7 +475,9 @@ test_expect_success 'existing old value blocks indirect no-deref create' ' EOF printf "%s\n" "option no-deref" "create $prefix/symref $E" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks indirect no-deref delete' '
@@ -463,7 +489,9 @@ test_expect_success 'incorrect old value blocks indirect no-deref delete' ' EOF printf "%s\n" "option no-deref" "delete $prefix/symref $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success REFFILES 'non-empty directory blocks create' '
Signature · 1 line
gitgitgadget
Quoted 9 lines · Han-Wen Nienhuys via GitGitGadget
This continues the work in https://github.com/git/git/pull/847, which the gitgitgadget erroneously closed.
Changes relative to last series (version 20 Jul 2021, tip: 4a5891f )
* fix HTTP serving
* fix t1501 (use absolute paths.)
* fix git-new-workdir
* fixes for FreeBSD (thanks, [email protected]!)
Thanks, will take a look later after the release is done; nice to see these fix-up changes already applied in the series.
Re: [PATCH v2 07/25] reftable: (de)serialization for the polymorphic record type.
In reply to Han-Wen Nienhuys via GitGitGadgetQuoted 1 line · Han-Wen Nienhuys via GitGitGadget
From: Han-Wen Nienhuys <[email protected]>
...
Review
Quoted 11 lines
(quoted diff) +11
-0+ union { + struct { + uint8_t *new_hash; + uint8_t *old_hash; + char *name; + char *email; + uint64_t time; + int16_t tz_offset; + char *message; + } update; + };
the use of an anonymous union here (which requires C11) could be made C89 compatible without any impact AFAIK by doing instead:
reftable/reftable-record.h +9 -11
@@ -84,17 +84,15 @@ struct reftable_log_record {#define REFTABLE_NR_LOG_VALUETYPES 2 } value_type; -union { -struct { -uint8_t *new_hash; -uint8_t *old_hash; -char *name; -char *email; -uint64_t time; -int16_t tz_offset; -char *message; - } update; - }; +struct { +uint8_t *new_hash; +uint8_t *old_hash; +char *name; +char *email; +uint64_t time; +int16_t tz_offset; +char *message; + } update; };/* returns whether 'ref' represents the deletion of a log record. */
PATCH v3 1/25 hash.h: provide constants for the hash IDs
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This will simplify referencing them from code that is not deeply integrated with Git, in particular, the reftable library.
--- hash.h | 6 ++++++ object-file.c | 7 ++----- 2 files changed, 8 insertions(+), 5 deletions(-)
hash.h +6 -0
@@ -95,12 +95,18 @@ static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *s/* Number of algorithms supported (including unknown). */ #define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1) +/* "sha1", big-endian */ +#define GIT_SHA1_FORMAT_ID 0x73686131 +/* The length in bytes and in hex digits of an object name (SHA-1 value). */ #define GIT_SHA1_RAWSZ 20#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)/* The block size of SHA-1. */ #define GIT_SHA1_BLKSZ 64 +/* "s256", big-endian */ +#define GIT_SHA256_FORMAT_ID 0x73323536 +/* The length in bytes and in hex digits of an object name (SHA-256 value). */ #define GIT_SHA256_RAWSZ 32#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
object-file.c +2 -5
@@ -164,7 +164,6 @@ static void git_hash_unknown_final_oid(struct object_id *oid, git_hash_ctx *ctx)BUG ("trying to finalize unknown hash" ); } -const struct git_hash_algo hash_algos[GIT_HASH_NALGOS ] = { {NULL ,
@@ -183,8 +182,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { }, {"sha1" , -/* "sha1", big-endian */ -0x73686131 , +GIT_SHA1_FORMAT_ID ,GIT_SHA1_RAWSZ ,GIT_SHA1_HEXSZ , GIT_SHA1_BLKSZ,
@@ -199,8 +197,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { }, {"sha256" , -/* "s256", big-endian */ -0x73323536 , +GIT_SHA256_FORMAT_ID ,GIT_SHA256_RAWSZ ,GIT_SHA256_HEXSZ , GIT_SHA256_BLKSZ,
Signature · 1 line
gitgitgadget
PATCH v3 6/25 reftable: add blocksource, an abstraction for random access reads
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable format is usually used with files for storage. However, we abstract away this using the blocksource data structure. This has two advantages:
* log blocks are zlib compressed, and handling them is simplified if we can discard byte segments from within the block layer.
* for unittests, it is useful to read and write in-memory. The blocksource allows us to abstract the data away from on-disk files.
--- Makefile | 1 + reftable/blocksource.c | 148 ++++++++++++++++++++++++++++++++ reftable/blocksource.h | 22 +++++ reftable/reftable-blocksource.h | 49 +++++++++++ 4 files changed, 220 insertions(+) create mode 100644 reftable/blocksource.c create mode 100644 reftable/blocksource.h create mode 100644 reftable/reftable-blocksource.h
Makefile +1 -0
@@ -2447,6 +2447,7 @@ xdiff-objs: $(XDIFF_OBJS) REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o +REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_TEST_OBJS += reftable/test_framework.o
reftable/blocksource.c new file +148 -0
148 lines not on this page · raw message
reftable/blocksource.h new file +22 -0
@@ -0,0 +1,22 @@ +/* +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 BLOCKSOURCE_H +#define BLOCKSOURCE_H + +#include "system.h" + +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/reftable-blocksource.h new file +49 -0
49 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v3 8/25 Provide zlib's uncompress2 from compat/zlib-compat.c
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This will be needed for reading reflog blocks in reftable.
--- Makefile | 7 +++ ci/lib.sh | 1 + compat/.gitattributes | 1 + compat/zlib-uncompress2.c | 92 +++++++++++++++++++++++++++++++++++++++ config.mak.uname | 1 + configure.ac | 13 ++++++ 6 files changed, 115 insertions(+) create mode 100644 compat/.gitattributes create mode 100644 compat/zlib-uncompress2.c
Makefile +7 -0
@@ -256,6 +256,8 @@ all:: # # Define NO_DEFLATE_BOUND if your zlib does not have deflateBound. # +# Define NO_UNCOMPRESS2 if your zlib does not have uncompress2. +# # Define NO_NORETURN if using buggy versions of gcc 4.6+ and profile feedback, # as the compiler can crash (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49299) #
@@ -1738,6 +1740,11 @@ ifdef NO_DEFLATE_BOUND BASIC_CFLAGS += -DNO_DEFLATE_BOUND endif +ifdef NO_UNCOMPRESS2 + BASIC_CFLAGS += -DNO_UNCOMPRESS2 + REFTABLE_OBJS += compat/zlib-uncompress2.o +endif + ifdef NO_POSIX_GOODIES BASIC_CFLAGS += -DNO_POSIX_GOODIES endif
ci/lib.sh +1 -0
@@ -224,6 +224,7 @@ linux-gcc-default) ;; Linux32) CC=gcc + MAKEFLAGS="$MAKEFLAGS NO_UNCOMPRESS2=1" ;; linux-musl) CC=gcc
compat/.gitattributes new file +1 -0
@@ -0,0 +1 @@ +/zlib-uncompress2.c whitespace=-indent-with-non-tab,-trailing-space
compat/zlib-uncompress2.c new file +92 -0
92 lines not on this page · raw message
config.mak.uname +1 -0
@@ -256,6 +256,7 @@ ifeq ($(uname_S),FreeBSD) FILENO_IS_A_MACRO = UnfortunatelyYes endif ifeq ($(uname_S),OpenBSD) + NO_UNCOMPRESS2 = YesPlease NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease USE_ST_TIMESPEC = YesPlease
configure.ac +13 -0
@@ -672,9 +672,22 @@ AC_LINK_IFELSE([ZLIBTEST_SRC], NO_DEFLATE_BOUND=yes]) LIBS="$old_LIBS" +AC_DEFUN([ZLIBTEST_UNCOMPRESS2_SRC], [ +AC_LANG_PROGRAM([#include <zlib.h>], + [uncompress2(NULL,NULL,NULL,NULL);])]) +AC_MSG_CHECKING([for uncompress2 in -lz]) +old_LIBS="$LIBS" +LIBS="$LIBS -lz" +AC_LINK_IFELSE([ZLIBTEST_UNCOMPRESS2_SRC], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + NO_UNCOMPRESS2=yes]) +LIBS="$old_LIBS" + GIT_UNSTASH_FLAGS($ZLIB_PATH) GIT_CONF_SUBST([NO_DEFLATE_BOUND]) +GIT_CONF_SUBST([NO_UNCOMPRESS2]) # # Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
Signature · 1 line
gitgitgadget
PATCH v3 9/25 reftable: reading/writing blocks
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable format is structured as a sequence of block. Within a block, records are prefix compressed, with an index of offsets for fully expand keys to enable binary search within blocks.
This commit provides the logic to read and write these blocks.
--- Makefile | 2 + reftable/block.c | 448 +++++++++++++++++++++++++++++++++++++++ reftable/block.h | 127 +++++++++++ reftable/block_test.c | 120 +++++++++++ t/helper/test-reftable.c | 1 + 5 files changed, 698 insertions(+) create mode 100644 reftable/block.c create mode 100644 reftable/block.h create mode 100644 reftable/block_test.c
Makefile +2 -0
@@ -2454,10 +2454,12 @@ xdiff-objs: $(XDIFF_OBJS) REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o +REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o +REFTABLE_TEST_OBJS += reftable/block_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/basics_test.o
reftable/block.c new file +448 -0
448 lines not on this page · raw message
reftable/block.h new file +127 -0
127 lines not on this page · raw message
reftable/block_test.c new file +120 -0
120 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -4,6 +4,7 @@int cmd__reftable (int argc,const char **argv) {basics_test_main (argc, argv); +block_test_main (argc, argv);record_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH v3 5/25 reftable: utility functions
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This commit provides basic utility classes for the reftable library.
--- Makefile | 25 +++++- contrib/buildsystems/CMakeLists.txt | 14 ++- reftable/basics.c | 128 ++++++++++++++++++++++++++++ reftable/basics.h | 60 +++++++++++++ reftable/basics_test.c | 98 +++++++++++++++++++++ reftable/publicbasics.c | 58 +++++++++++++ reftable/reftable-malloc.h | 18 ++++ reftable/reftable-tests.h | 22 +++++ reftable/system.h | 24 ++++++ reftable/test_framework.c | 23 +++++ reftable/test_framework.h | 53 ++++++++++++ t/helper/test-reftable.c | 9 ++ t/helper/test-tool.c | 3 +- t/helper/test-tool.h | 1 + t/t0032-reftable-unittest.sh | 15 ++++ 15 files changed, 545 insertions(+), 6 deletions(-) create mode 100644 reftable/basics.c create mode 100644 reftable/basics.h create mode 100644 reftable/basics_test.c create mode 100644 reftable/publicbasics.c create mode 100644 reftable/reftable-malloc.h create mode 100644 reftable/reftable-tests.h create mode 100644 reftable/system.h create mode 100644 reftable/test_framework.c create mode 100644 reftable/test_framework.h create mode 100644 t/helper/test-reftable.c create mode 100755 t/t0032-reftable-unittest.sh
Makefile +22 -3
@@ -743,6 +743,7 @@ TEST_BUILTINS_OBJS += test-read-cache.o TEST_BUILTINS_OBJS += test-read-graph.o TEST_BUILTINS_OBJS += test-read-midx.o TEST_BUILTINS_OBJS += test-ref-store.o +TEST_BUILTINS_OBJS += test-reftable.o TEST_BUILTINS_OBJS += test-regex.o TEST_BUILTINS_OBJS += test-repository.o TEST_BUILTINS_OBJS += test-revision-walking.o
@@ -821,6 +822,8 @@ TEST_SHELL_PATH = $(SHELL_PATH) LIB_FILE = libgit.a XDIFF_LIB = xdiff/lib.a +REFTABLE_LIB = reftable/libreftable.a +REFTABLE_TEST_LIB = reftable/libreftable_test.a GENERATED_H += command-list.h GENERATED_H += config-list.h
@@ -1195,7 +1198,7 @@ THIRD_PARTY_SOURCES += compat/regex/% THIRD_PARTY_SOURCES += sha1collisiondetection/% THIRD_PARTY_SOURCES += sha1dc/% -GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) +GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) EXTLIBS = GIT_USER_AGENT = git/$(GIT_VERSION)
@@ -2442,7 +2445,15 @@ XDIFF_OBJS += xdiff/xutils.o .PHONY: xdiff-objs xdiff-objs: $(XDIFF_OBJS) +REFTABLE_OBJS += reftable/basics.o +REFTABLE_OBJS += reftable/error.o +REFTABLE_OBJS += reftable/publicbasics.o + +REFTABLE_TEST_OBJS += reftable/test_framework.o +REFTABLE_TEST_OBJS += reftable/basics_test.o + TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS)) + .PHONY: test-objs test-objs: $(TEST_OBJS)
@@ -2458,6 +2469,8 @@ OBJECTS += $(PROGRAM_OBJS) OBJECTS += $(TEST_OBJS) OBJECTS += $(XDIFF_OBJS) OBJECTS += $(FUZZ_OBJS) +OBJECTS += $(REFTABLE_OBJS) $(REFTABLE_TEST_OBJS) + ifndef NO_CURL OBJECTS += http.o http-walker.o remote-curl.o endif
@@ -2608,6 +2621,12 @@ $(LIB_FILE): $(LIB_OBJS) $(XDIFF_LIB): $(XDIFF_OBJS) $(QUIET_AR)$(AR) $(ARFLAGS) $@ $^ +$(REFTABLE_LIB): $(REFTABLE_OBJS) + $(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^ + +$(REFTABLE_TEST_LIB): $(REFTABLE_TEST_OBJS) + $(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^ + export DEFAULT_EDITOR DEFAULT_PAGER Documentation/GIT-EXCLUDED-PROGRAMS: FORCE
@@ -2895,7 +2914,7 @@ perf: all t/helper/test-tool$X: $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS)) -t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) +t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) $(REFTABLE_TEST_LIB) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS) check-sha1:: t/helper/test-tool$X
@@ -3225,7 +3244,7 @@ cocciclean: clean: profile-clean coverage-clean cocciclean $(RM) *.res $(RM) $(OBJECTS) - $(RM) $(LIB_FILE) $(XDIFF_LIB) + $(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB) $(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X $(RM) $(TEST_PROGRAMS) $(RM) $(FUZZ_PROGRAMS)
contrib/buildsystems/CMakeLists.txt +12 -2
@@ -640,6 +640,12 @@ parse_makefile_for_sources(libxdiff_SOURCES "XDIFF_OBJS") list(TRANSFORM libxdiff_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") add_library(xdiff STATIC ${libxdiff_SOURCES}) +#reftable +parse_makefile_for_sources(reftable_SOURCES "REFTABLE_OBJS") + +list(TRANSFORM reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") +add_library(reftable STATIC ${reftable_SOURCES}) + if(WIN32) if(NOT MSVC)#use windres when compiling with gcc and clang add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/git.res
@@ -662,7 +668,7 @@ endif() #link all required libraries to common-main add_library(common-main OBJECT ${CMAKE_SOURCE_DIR}/common-main.c) -target_link_libraries(common-main libgit xdiff ${ZLIB_LIBRARIES}) +target_link_libraries(common-main libgit xdiff reftable ${ZLIB_LIBRARIES}) if(Intl_FOUND) target_link_libraries(common-main ${Intl_LIBRARIES}) endif()
@@ -902,11 +908,15 @@ if(BUILD_TESTING) add_executable(test-fake-ssh ${CMAKE_SOURCE_DIR}/t/helper/test-fake-ssh.c) target_link_libraries(test-fake-ssh common-main) +#reftable-tests +parse_makefile_for_sources(test-reftable_SOURCES "REFTABLE_TEST_OBJS") +list(TRANSFORM test-reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") + #test-tool parse_makefile_for_sources(test-tool_SOURCES "TEST_BUILTINS_OBJS") list(TRANSFORM test-tool_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/t/helper/") -add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES}) +add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES} ${test-reftable_SOURCES}) target_link_libraries(test-tool common-main) set_target_properties(test-fake-ssh test-tool
reftable/basics.c new file +128 -0
128 lines not on this page · raw message
reftable/basics.h new file +60 -0
60 lines not on this page · raw message
reftable/basics_test.c new file +98 -0
98 lines not on this page · raw message
reftable/publicbasics.c new file +58 -0
58 lines not on this page · raw message
reftable/reftable-malloc.h new file +18 -0
@@ -0,0 +1,18 @@ +/* +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 REFTABLE_H +#define REFTABLE_H + +#include <stddef.h> + +/* Overrides the functions to use for memory management. */ +void reftable_set_alloc (void *(*malloc)(size_t ), +void *(*realloc)(void *,size_t ),void (*free)(void *)); + +#endif
reftable/reftable-tests.h new file +22 -0
@@ -0,0 +1,22 @@ +/* +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 REFTABLE_TESTS_H +#define REFTABLE_TESTS_H + +int basics_test_main (int argc,const char **argv); +int block_test_main (int argc,const char **argv); +int merged_test_main (int argc,const char **argv); +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 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); + +#endif
reftable/system.h new file +24 -0
@@ -0,0 +1,24 @@ +/* +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 SYSTEM_H +#define SYSTEM_H + +/* This header glues the reftable library to the rest of Git */ + +#include "git-compat-util.h" +#include "strbuf.h" +#include "hash.h" /* hash ID, sizes.*/ +#include "dir.h" /* remove_dir_recursively, for tests.*/ + +#include <zlib.h> + +struct strbuf ; +int hash_size (uint32_t id); + +#endif
reftable/test_framework.c new file +23 -0
@@ -0,0 +1,23 @@ +/* +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 "system.h" +#include "test_framework.h" + +#include "basics.h" + +void set_test_hash (uint8_t *p,int i) +{ +memset (p, (uint8_t )i,hash_size (GIT_SHA1_FORMAT_ID )); +} + +ssize_t strbuf_add_void (void *b,const void *data,size_t sz) +{ +strbuf_add (b, data, sz); +return sz; +}
reftable/test_framework.h new file +53 -0
53 lines not on this page · raw message
t/helper/test-reftable.c new file +9 -0
@@ -0,0 +1,9 @@ +#include "reftable/reftable-tests.h" +#include "test-tool.h" + +int cmd__reftable (int argc,const char **argv) +{ +basics_test_main (argc, argv); + +return 0 ; +}
t/helper/test-tool.c +2 -1
@@ -53,13 +53,14 @@ static struct test_cmd cmds[] = { { "pcre2-config", cmd__pcre2_config }, { "pkt-line", cmd__pkt_line }, { "prio-queue", cmd__prio_queue }, - { "proc-receive", cmd__proc_receive}, + { "proc-receive", cmd__proc_receive }, { "progress", cmd__progress }, { "reach", cmd__reach }, { "read-cache", cmd__read_cache }, { "read-graph", cmd__read_graph }, { "read-midx", cmd__read_midx }, { "ref-store", cmd__ref_store }, + { "reftable", cmd__reftable }, { "regex", cmd__regex }, { "repository", cmd__repository }, { "revision-walking", cmd__revision_walking },
t/helper/test-tool.h +1 -0
@@ -49,6 +49,7 @@ int cmd__read_cache(int argc, const char **argv);int cmd__read_graph (int argc,const char **argv);int cmd__read_midx (int argc,const char **argv);int cmd__ref_store (int argc,const char **argv); +int cmd__reftable (int argc,const char **argv);int cmd__regex (int argc,const char **argv);int cmd__repository (int argc,const char **argv);int cmd__revision_walking (int argc,const char **argv);
t/t0032-reftable-unittest.sh new file +15 -0
@@ -0,0 +1,15 @@ +#!/bin/sh +# +# Copyright (c) 2020 Google LLC +# + +test_description='reftable unittests' + +. ./test-lib.sh + +test_expect_success 'unittests' ' + TMPDIR=$(pwd) && export TMPDIR && + test-tool reftable +' + +test_done
Signature · 1 line
gitgitgadget
PATCH v3 3/25 reftable: RFC: add LICENSE
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The objective of this code is to be usable as a C library, so it can be reused in libgit2.
This is currently using a BSD license as it is the liberal license I could find, but this could be changed to whatever fits the stated goal above.
This code is currently imported from github.com/hanwen/reftable. Once this code lands in git.git, the C code will be removed from github.com/hanwen/reftable, and the git.git code will be the source of truth.
--- reftable/LICENSE | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 reftable/LICENSE
reftable/LICENSE new file +31 -0
@@ -0,0 +1,31 @@ +BSD License + +Copyright (c) 2020, Google LLC +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +* Neither the name of Google LLC nor the names of its contributors may +be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Signature · 1 line
gitgitgadget
PATCH v3 4/25 reftable: add error related functionality
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable/ directory is structured as a library, so it cannot crash on misuse. Instead, it returns an error codes.
In addition, the error code can be used to signal conditions from lower levels of the library to be handled by higher levels of the library. For example, a transaction might legitimately write an empty reftable file, but in that case, we'd want to shortcut the transaction overhead.
--- reftable/error.c | 41 ++++++++++++++++++++++++++ reftable/reftable-error.h | 62 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 reftable/error.c create mode 100644 reftable/reftable-error.h
reftable/error.c new file +41 -0
@@ -0,0 +1,41 @@ +/* +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 "reftable-error.h" + +#include <stdio.h> + +const char *reftable_error_str (int err) +{ +static char buf[250 ]; +switch (err) { +case REFTABLE_IO_ERROR : +return "I/O error" ; +case REFTABLE_FORMAT_ERROR : +return "corrupt reftable file" ; +case REFTABLE_NOT_EXIST_ERROR : +return "file does not exist" ; +case REFTABLE_LOCK_ERROR : +return "data is outdated" ; +case REFTABLE_API_ERROR : +return "misuse of the reftable API" ; +case REFTABLE_ZLIB_ERROR : +return "zlib failure" ; +case REFTABLE_NAME_CONFLICT : +return "file/directory conflict" ; +case REFTABLE_EMPTY_TABLE_ERROR : +return "wrote empty table" ; +case REFTABLE_REFNAME_ERROR : +return "invalid refname" ; +case -1 : +return "general error" ; +default : +snprintf (buf,sizeof (buf),"unknown error code %d" , err); +return buf; + } +}
reftable/reftable-error.h new file +62 -0
62 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v3 7/25 reftable: (de)serialization for the polymorphic record type.
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable format is structured as a sequence of blocks, and each block contains a sequence of prefix-compressed key-value records. There are 4 types of records, and they have similarities in how they must be handled. This is achieved by introducing a polymorphic 'record' type that encapsulates ref, log, index and object records.
--- Makefile | 2 + reftable/constants.h | 21 + reftable/record.c | 1212 ++++++++++++++++++++++++++++++++++++ reftable/record.h | 139 +++++ reftable/record_test.c | 412 ++++++++++++ reftable/reftable-record.h | 114 ++++ t/helper/test-reftable.c | 2 +- 7 files changed, 1901 insertions(+), 1 deletion(-) create mode 100644 reftable/constants.h create mode 100644 reftable/record.c create mode 100644 reftable/record.h create mode 100644 reftable/record_test.c create mode 100644 reftable/reftable-record.h
Makefile +2 -0
@@ -2449,7 +2449,9 @@ REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/record.o +REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/basics_test.o
reftable/constants.h new file +21 -0
@@ -0,0 +1,21 @@ +/* +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 CONSTANTS_H +#define CONSTANTS_H + +#define BLOCK_TYPE_LOG 'g' +#define BLOCK_TYPE_INDEX 'i' +#define BLOCK_TYPE_REF 'r' +#define BLOCK_TYPE_OBJ 'o' +#define BLOCK_TYPE_ANY 0 + +#define MAX_RESTARTS ((1 << 16) - 1) +#define DEFAULT_BLOCK_SIZE 4096 + +#endif
reftable/record.c new file +1212 -0
1,212 lines not on this page · raw message
reftable/record.h new file +139 -0
139 lines not on this page · raw message
reftable/record_test.c new file +412 -0
412 lines not on this page · raw message
reftable/reftable-record.h new file +114 -0
114 lines not on this page · raw message
t/helper/test-reftable.c +1 -1
@@ -4,6 +4,6 @@int cmd__reftable (int argc,const char **argv) {basics_test_main (argc, argv); - +record_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH v3 12/25 reftable: generic interface to tables
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- Makefile | 3 + reftable/generic.c | 169 +++++++++++++++++++++++++++++++++++ reftable/generic.h | 32 +++++++ reftable/reftable-generic.h | 47 ++++++++++ reftable/reftable-iterator.h | 39 ++++++++ reftable/reftable.c | 115 ++++++++++++++++++++++++ 6 files changed, 405 insertions(+) create mode 100644 reftable/generic.c create mode 100644 reftable/generic.h create mode 100644 reftable/reftable-generic.h create mode 100644 reftable/reftable-iterator.h create mode 100644 reftable/reftable.c
Makefile +3 -0
@@ -2458,6 +2458,9 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o +REFTABLE_OBJS += reftable/refname.o +REFTABLE_OBJS += reftable/generic.o +REFTABLE_OBJS += reftable/stack.o REFTABLE_OBJS += reftable/tree.o REFTABLE_OBJS += reftable/writer.o
reftable/generic.c new file +169 -0
169 lines not on this page · raw message
reftable/generic.h new file +32 -0
@@ -0,0 +1,32 @@ +/* +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 GENERIC_H +#define GENERIC_H + +#include "record.h" +#include "reftable-generic.h" + +/* generic interface to reftables */ +struct reftable_table_vtable { +int (*seek_record)(void *tab,struct reftable_iterator *it, +struct reftable_record *); +uint32_t (*hash_id)(void *tab); +uint64_t (*min_update_index)(void *tab); +uint64_t (*max_update_index)(void *tab); +}; + +struct reftable_iterator_vtable { +int (*next)(void *iter_arg,struct reftable_record *rec); +void (*close)(void *iter_arg); +}; + +void iterator_set_empty (struct reftable_iterator *it); +int iterator_next (struct reftable_iterator *it,struct reftable_record *rec); + +#endif
reftable/reftable-generic.h new file +47 -0
47 lines not on this page · raw message
reftable/reftable-iterator.h new file +39 -0
@@ -0,0 +1,39 @@ +/* +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 REFTABLE_ITERATOR_H +#define REFTABLE_ITERATOR_H + +#include "reftable-record.h" + +struct reftable_iterator_vtable ; + +/* iterator is the generic interface for walking over data stored in a +* reftable. +*/ +struct reftable_iterator { +struct reftable_iterator_vtable *ops; +void *iter_arg; +}; + +/* reads the next reftable_ref_record. Returns < 0 for error, 0 for OK and > 0: +* end of iteration. +*/ +int reftable_iterator_next_ref (struct reftable_iterator *it, +struct reftable_ref_record *ref); + +/* reads the next reftable_log_record. Returns < 0 for error, 0 for OK and > 0: +* end of iteration. +*/ +int reftable_iterator_next_log (struct reftable_iterator *it, +struct reftable_log_record *log); + +/* releases resources associated with an iterator. */ +void reftable_iterator_destroy (struct reftable_iterator *it); + +#endif
reftable/reftable.c new file +115 -0
115 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v3 11/25 reftable: write reftable files
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- Makefile | 1 + reftable/reftable-writer.h | 148 ++++++++ reftable/writer.c | 690 +++++++++++++++++++++++++++++++++++++ reftable/writer.h | 50 +++ 4 files changed, 889 insertions(+) create mode 100644 reftable/reftable-writer.h create mode 100644 reftable/writer.c create mode 100644 reftable/writer.h
Makefile +1 -0
@@ -2459,6 +2459,7 @@ REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o REFTABLE_OBJS += reftable/tree.o +REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o
reftable/reftable-writer.h new file +148 -0
148 lines not on this page · raw message
reftable/writer.c new file +690 -0
690 lines not on this page · raw message
reftable/writer.h new file +50 -0
50 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v3 10/25 reftable: a generic binary tree implementation
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The reftable format includes support for an (OID => ref) map. This map can speed up visibility and reachability checks. In particular, various operations along the fetch/push path within Gerrit have ben sped up by using this structure.
The map is constructed with help of a binary tree. Object IDs are hashes, so they are uniformly distributed. Hence, the tree does not attempt forced rebalancing.
--- Makefile | 4 ++- reftable/tree.c | 63 ++++++++++++++++++++++++++++++++++++++++ reftable/tree.h | 34 ++++++++++++++++++++++ reftable/tree_test.c | 61 ++++++++++++++++++++++++++++++++++++++ t/helper/test-reftable.c | 1 + 5 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 reftable/tree.c create mode 100644 reftable/tree.h create mode 100644 reftable/tree_test.c
Makefile +3 -1
@@ -2458,11 +2458,13 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o +REFTABLE_OBJS += reftable/tree.o +REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o -REFTABLE_TEST_OBJS += reftable/basics_test.o +REFTABLE_TEST_OBJS += reftable/tree_test.o TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
reftable/tree.c new file +63 -0
63 lines not on this page · raw message
reftable/tree.h new file +34 -0
@@ -0,0 +1,34 @@ +/* +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 TREE_H +#define TREE_H + +/* tree_node is a generic binary search tree. */ +struct tree_node { +void *key; +struct tree_node *left, *right; +}; + +/* looks for `key` in `rootp` using `compare` as comparison function. If insert +* is set, insert the key if it's not found. Else, return NULL. +*/ +struct tree_node *tree_search (void *key,struct tree_node **rootp, +int (*compare)(const void *,const void *), +int insert); + +/* performs an infix walk of the tree. */ +void infix_walk (struct tree_node *t,void (*action)(void *arg,void *key), +void *arg); + +/* +* deallocates the tree nodes recursively. Keys should be deallocated separately +* by walking over the tree. */ +void tree_free (struct tree_node *t); + +#endif
reftable/tree_test.c new file +61 -0
61 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -6,5 +6,6 @@ int cmd__reftable(int argc, const char **argv)basics_test_main (argc, argv);block_test_main (argc, argv);record_test_main (argc, argv); +tree_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH v3 21/25 git-prompt: prepare for reftable refs backend
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: =?UTF-8?q?SZEDER=20G=C3=A1bor?= <[email protected]>
In our git-prompt script we strive to use Bash builtins wherever possible, because fork()-ing subshells for command substitutions and fork()+exec()-ing Git commands are expensive on some platforms. We even read and parse '.git/HEAD' using Bash builtins to get the name of the current branch [1]. However, the upcoming reftable refs backend won't use '.git/HEAD' at all, but will write an invalid refname as placeholder for backwards compatibility instead, which will break our git-prompt script.
Update the git-prompt script to recognize the placeholder '.git/HEAD' written by the reftable backend (its content is specified in the reftable specs), and then fall back to use 'git symbolic-ref' to get the name of the current branch.
[1] 3a43c4b5bd (bash prompt: use bash builtins to find out current
branch, 2011-03-31)
--- contrib/completion/git-prompt.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
contrib/completion/git-prompt.sh +6 -1
@@ -478,10 +478,15 @@ __git_ps1 () if ! __git_eread "$g/HEAD" head; then return $exit fi - # is it a symbolic ref? b="${head#ref: }" if [ "$head" = "$b" ]; then detached=yes + elif [ "$b" = "refs/heads/.invalid" ]; then + # Reftable + b="$(git symbolic-ref HEAD 2>/dev/null)" || + detached=yes + fi + if [ "$detached" = yes ]; then b="$( case "${GIT_PS1_DESCRIBE_STYLE-}" in (contains)
Signature · 1 line
gitgitgadget
PATCH v3 20/25 refs: RFC: Reftable support for git-core
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
For background, see Documentation/technical/reftable.txt.
This introduces the file refs/reftable-backend.c containing a reftable-powered ref storage backend.
It can be activated by setting GIT_TEST_REFTABLE in the environment. When GIT_TEST_REFTABLE is set, the test prerequisite !REFFILES is set.
There is no option to git-init for now, as the test suite still shows failures with GIT_TEST_REFTABLE=1.
Example use: see t/t0031-reftable.sh
--- Documentation/config/extensions.txt | 9 + .../technical/repository-version.txt | 7 + Makefile | 1 + builtin/clone.c | 5 +- builtin/init-db.c | 39 +- builtin/stash.c | 8 +- builtin/worktree.c | 27 +- cache.h | 8 +- config.mak.uname | 2 +- contrib/buildsystems/Generators/Vcxproj.pm | 11 +- contrib/workdir/git-new-workdir | 2 +- refs.c | 26 +- refs.h | 3 + refs/refs-internal.h | 1 + refs/reftable-backend.c | 1691 +++++++++++++++++ repository.c | 2 + repository.h | 3 + setup.c | 8 + t/t0031-reftable.sh | 310 +++ t/t1409-avoid-packing-refs.sh | 6 + t/t1450-fsck.sh | 6 + t/t3210-pack-refs.sh | 6 + t/test-lib.sh | 7 +- 23 files changed, 2159 insertions(+), 29 deletions(-) create mode 100644 refs/reftable-backend.c create mode 100755 t/t0031-reftable.sh
Documentation/config/extensions.txt +9 -0
@@ -6,3 +6,12 @@ extensions.objectFormat:: Note that this setting should only be set by linkgit:git-init[1] or linkgit:git-clone[1]. Trying to change it after initialization will not work and will produce hard-to-diagnose issues. ++ +extensions.refStorage:: + Specify the ref storage mechanism to use. The acceptable values are `files` and + `reftable`. If not specified, `files` is assumed. It is an error to specify + this key unless `core.repositoryFormatVersion` is 1. ++ +Note that this setting should only be set by linkgit:git-init[1] or +linkgit:git-clone[1]. Trying to change it after initialization will not +work and will produce hard-to-diagnose issues.
Documentation/technical/repository-version.txt +7 -0
@@ -100,3 +100,10 @@ If set, by default "git config" reads from both "config" and multiple working directory mode, "config" file is shared while "config.worktree" is per-working directory (i.e., it's in GIT_COMMON_DIR/worktrees/<id>/config.worktree) + +==== `refStorage` + +Specifies the file format for the ref database. Values are `files` +(for the traditional packed + loose ref format) and `reftable` for the +binary reftable format. See https://github.com/google/reftable for +more information.
Makefile +1 -0
@@ -990,6 +990,7 @@ LIB_OBJS += reflog-walk.o LIB_OBJS += refs.o LIB_OBJS += refs/debug.o LIB_OBJS += refs/files-backend.o +LIB_OBJS += refs/reftable-backend.o LIB_OBJS += refs/iterator.o LIB_OBJS += refs/packed-backend.o LIB_OBJS += refs/ref-cache.o
builtin/clone.c +3 -2
@@ -1148,7 +1148,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) }init_db (git_dir, real_git_dir, option_template,GIT_HASH_UNKNOWN ,NULL , -INIT_DB_QUIET ); +default_ref_storage (),INIT_DB_QUIET );if (real_git_dir) git_dir = real_git_dir;
@@ -1299,7 +1299,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)* Now that we know what algorithm the remote side is using, * let's set ours to the same thing. */ -initialize_repository_version (hash_algo,1 ); +initialize_repository_version (hash_algo,1 , +default_ref_storage ());repo_set_hash_algo (the_repository, hash_algo); mapped_refs =wanted_peer_refs (refs, &remote->fetch);
builtin/init-db.c +31 -8
@@ -167,12 +167,14 @@ static int needs_work_tree_config(const char *git_dir, const char *work_tree)return 1 ; } -void initialize_repository_version (int hash_algo,int reinit) +void initialize_repository_version (int hash_algo,int reinit, +const char *ref_storage_format) {char repo_version_string[10 ];int repo_version =GIT_REPO_VERSION ; -if (hash_algo !=GIT_HASH_SHA1 ) +if (hash_algo !=GIT_HASH_SHA1 || + !strcmp (ref_storage_format,"reftable" )) repo_version =GIT_REPO_VERSION_READ ;/* This forces creation of new config file */
@@ -226,6 +228,7 @@ static int create_default_files(const char *template_path, is_bare_repository_cfg = init_is_bare_repository || !work_tree;if (init_shared_repository !=-1 )set_shared_repository (init_shared_repository); + the_repository->ref_storage_format =xstrdup (fmt->ref_storage);/* * We would have created the above under user's umask -- under
@@ -235,6 +238,24 @@ static int create_default_files(const char *template_path,adjust_shared_perm (get_git_dir ()); } +/* +* Check to see if .git/HEAD exists; this must happen before +* initializing the ref db, because we want to see if there is an +* existing HEAD. +*/ + path =git_path_buf (&buf,"HEAD" ); + reinit = (!access (path,R_OK ) || +readlink (path, junk,sizeof (junk) -1 ) !=-1 ); + +/* +* refs/heads is a file when using reftable. We can't reinitialize with +* a reftable because it will overwrite HEAD +*/ +if (reinit && (!strcmp (fmt->ref_storage,"reftable" )) == +is_directory (git_path_buf (&buf,"refs/heads" ))) { +die ("cannot switch ref storage format." ); + } +/* * We need to create a "refs" dir in any case so that older * versions of git can tell that this is a repository.
@@ -249,9 +270,6 @@ static int create_default_files(const char *template_path,* Point the HEAD symref to the initial branch with if HEAD does * not yet exist. */ - path =git_path_buf (&buf,"HEAD" ); - reinit = (!access (path,R_OK ) - ||readlink (path, junk,sizeof (junk)-1 ) !=-1 );if (!reinit) {char *ref;
@@ -268,7 +286,7 @@ static int create_default_files(const char *template_path,free (ref); } -initialize_repository_version (fmt->hash_algo,0 ); +initialize_repository_version (fmt->hash_algo,0 , fmt->ref_storage);/* Check filemode trustability */ path =git_path_buf (&buf,"config" );
@@ -383,7 +401,7 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hashint init_db (const char *git_dir,const char *real_git_dir,const char *template_dir,int hash,const char *initial_branch, -unsigned int flags) +const char *ref_storage_format,unsigned int flags) {int reinit;int exist_ok = flags &INIT_DB_EXIST_OK ;
@@ -422,6 +440,7 @@ int init_db(const char *git_dir, const char *real_git_dir,* is an attempt to reinitialize new repository with an old tool. */ check_repository_format (&repo_fmt); + repo_fmt.ref_storage =xstrdup (ref_storage_format);validate_hash_algorithm (&repo_fmt, hash);
@@ -476,6 +495,9 @@ int init_db(const char *git_dir, const char *real_git_dir,git_config_set ("receive.denyNonFastforwards" ,"true" ); } +if (!strcmp (ref_storage_format,"reftable" )) +git_config_set ("extensions.refStorage" , ref_storage_format); +if (!(flags &INIT_DB_QUIET )) {int len =strlen (git_dir);
@@ -549,6 +571,7 @@ static const char *const init_db_usage[] = {int cmd_init_db (int argc,const char **argv,const char *prefix) {const char *git_dir; +const char *ref_storage_format =default_ref_storage ();const char *real_git_dir =NULL ;const char *work_tree;const char *template_dir =NULL ;
@@ -713,5 +736,5 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) flags |=INIT_DB_EXIST_OK ;return init_db (git_dir, real_git_dir, template_dir, hash_algo, - initial_branch, flags); + initial_branch, ref_storage_format, flags); }
builtin/stash.c +7 -1
@@ -207,10 +207,16 @@ static int get_stash_info(struct stash_info *info, int argc, const char **argv)static int do_clear_stash (void ) {struct object_id obj; +int result;if (get_oid (ref_stash, &obj))return 0 ; -return delete_ref (NULL , ref_stash, &obj,0 ); + result =delete_ref (NULL , ref_stash, &obj,0 ); + +/* Ignore error; this is necessary for reftable, which keeps reflogs +* even when refs are deleted. */ +delete_reflog (ref_stash); +return result; }static int clear_stash (int argc,const char **argv,const char *prefix)
builtin/worktree.c +24 -3
@@ -13,6 +13,7 @@#include "utf8.h" #include "worktree.h" #include "quote.h" +#include "../refs/refs-internal.h" static const char *const worktree_usage[] = {N_ ("git worktree add [<options>] <path> [<commit-ish>]" ),
@@ -328,9 +329,29 @@ static int add_worktree(const char *path, const char *refname,* worktree. */ strbuf_reset (&sb); -strbuf_addf (&sb,"%s/HEAD" , sb_repo.buf); -write_file (sb.buf,"%s" ,oid_to_hex (null_oid ())); -strbuf_reset (&sb); +if (get_main_ref_store (the_repository)->be == &refs_be_reftable) { +/* XXX this is cut & paste from reftable_init_db. */ +strbuf_addf (&sb,"%s/HEAD" , sb_repo.buf); +write_file (sb.buf,"%s" ,"ref: refs/heads/.invalid\n" ); +strbuf_reset (&sb); + +strbuf_addf (&sb,"%s/refs" , sb_repo.buf); +safe_create_dir (sb.buf,1 ); +strbuf_reset (&sb); + +strbuf_addf (&sb,"%s/refs/heads" , sb_repo.buf); +write_file (sb.buf,"this repository uses the reftable format" ); +strbuf_reset (&sb); + +strbuf_addf (&sb,"%s/reftable" , sb_repo.buf); +safe_create_dir (sb.buf,1 ); +strbuf_reset (&sb); + }else { +strbuf_addf (&sb,"%s/HEAD" , sb_repo.buf); +write_file (sb.buf,"%s" ,oid_to_hex (null_oid ())); +strbuf_reset (&sb); + } +strbuf_addf (&sb,"%s/commondir" , sb_repo.buf);write_file (sb.buf,"../.." );
cache.h +5 -3
@@ -656,9 +656,10 @@ int path_inside_repo(const char *prefix, const char *path);#define INIT_DB_EXIST_OK 0x0002int init_db (const char *git_dir,const char *real_git_dir, -const char *template_dir,int hash_algo, -const char *initial_branch,unsigned int flags); -void initialize_repository_version (int hash_algo,int reinit); +const char *template_dir,int hash_algo,const char *initial_branch, +const char *ref_storage_format,unsigned int flags); +void initialize_repository_version (int hash_algo,int reinit, +const char *ref_storage_format);void sanitize_stdfds (void );int daemonize (void );
@@ -1076,6 +1077,7 @@ struct repository_format {int hash_algo;int sparse_index;char *work_tree; +char *ref_storage;struct string_list unknown_extensions;struct string_list v1_only_extensions; };
config.mak.uname +1 -1
@@ -712,7 +712,7 @@ vcxproj: # Make .vcxproj files and add them unset QUIET_GEN QUIET_BUILT_IN; \ perl contrib/buildsystems/generate -g Vcxproj - git add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj + git add -f git.sln {*,*/lib,*/libreftable,t/helper/*}/*.vcxproj # Generate the LinkOrCopyBuiltins.targets and LinkOrCopyRemoteHttp.targets file (echo '<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">' && \
contrib/buildsystems/Generators/Vcxproj.pm +10 -1
@@ -77,7 +77,7 @@ sub createProject { my $libs_release = "\n "; my $libs_debug = "\n "; if (!$static_library) { - $libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}})); + $libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib|reftable\/libreftable\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}})); $libs_debug = $libs_release; $libs_debug =~ s/zlib\.lib/zlibd\.lib/g; $libs_debug =~ s/libexpat\.lib/libexpatd\.lib/g;
@@ -232,6 +232,7 @@ EOM EOM if (!$static_library || $target =~ 'vcs-svn' || $target =~ 'xdiff') { my $uuid_libgit = $$build_structure{"LIBS_libgit_GUID"}; + my $uuid_libreftable = $$build_structure{"LIBS_reftable/libreftable_GUID"}; my $uuid_xdiff_lib = $$build_structure{"LIBS_xdiff/lib_GUID"}; print F << "EOM";
@@ -241,6 +242,14 @@ EOM <ReferenceOutputAssembly>false</ReferenceOutputAssembly> </ProjectReference> EOM + if (!($name =~ /xdiff|libreftable/)) { + print F << "EOM"; + <ProjectReference Include="$cdup\\reftable\\libreftable\\libreftable.vcxproj"> + <Project>$uuid_libreftable</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> +EOM + } if (!($name =~ 'xdiff')) { print F << "EOM"; <ProjectReference Include="$cdup\\xdiff\\lib\\xdiff_lib.vcxproj">
contrib/workdir/git-new-workdir +1 -1
@@ -79,7 +79,7 @@ trap cleanup $siglist # create the links to the original repo. explicitly exclude index, HEAD and # logs/HEAD from the list since they are purely related to the current working # directory, and should not be shared. -for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn +for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn reftable do # create a containing directory if needed case $x in
refs.c +18 -8
@@ -19,10 +19,15 @@#include "repository.h" #include "sigchain.h" +const char *default_ref_storage (void ) +{ +return git_env_bool ("GIT_TEST_REFTABLE" ,0 ) ?"reftable" :"files" ; +} +/* * List of all available backends */ -static struct ref_storage_be *refs_backends = &refs_be_files; +static struct ref_storage_be *refs_backends = &refs_be_reftable;static struct ref_storage_be *find_ref_storage_backend (const char *name) {
@@ -1875,13 +1880,13 @@ static struct ref_store *lookup_ref_store_map(struct hashmap *map,* Create, record, and return a ref_store instance for the specified * gitdir. */ -static struct ref_store *ref_store_init (const char *gitdir, +static struct ref_store *ref_store_init (const char *gitdir,const char *be_name,unsigned int flags) { -const char *be_name ="files" ; -struct ref_storage_be *be =find_ref_storage_backend (be_name); +struct ref_storage_be *be;struct ref_store *refs; + be =find_ref_storage_backend (be_name);if (!be)BUG ("reference backend %s is unknown" , be_name);
@@ -1897,7 +1902,11 @@ struct ref_store *get_main_ref_store(struct repository *r)if (!r->gitdir)BUG ("attempting to get main_ref_store outside of repository" ); - r->refs_private =ref_store_init (r->gitdir,REF_STORE_ALL_CAPS ); + r->refs_private =ref_store_init (r->gitdir, + r->ref_storage_format ? + r->ref_storage_format : +default_ref_storage (), +REF_STORE_ALL_CAPS ); r->refs_private =maybe_debug_wrap_ref_store (r->gitdir, r->refs_private);return r->refs_private; }
@@ -1953,7 +1962,7 @@ 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, + 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);
@@ -1967,6 +1976,7 @@ done:struct ref_store *get_worktree_ref_store (const struct worktree *wt) { +const char *format =default_ref_storage ();struct ref_store *refs;const char *id;
@@ -1980,9 +1990,9 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt)if (wt->id) refs =ref_store_init (git_common_path ("worktrees/%s" , wt->id), -REF_STORE_ALL_CAPS ); + format,REF_STORE_ALL_CAPS );else - refs =ref_store_init (get_git_common_dir (), + refs =ref_store_init (get_git_common_dir (), format,REF_STORE_ALL_CAPS );if (refs)
refs.h +3 -0
@@ -11,6 +11,9 @@ struct string_list;struct string_list_item ;struct worktree ; +/* Returns the ref storage backend to use by default. */ +const char *default_ref_storage (void ); +/* * Resolve a reference, recursively following symbolic refererences. *
refs/refs-internal.h +1 -0
@@ -672,6 +672,7 @@ struct ref_storage_be { };extern struct ref_storage_be refs_be_files; +extern struct ref_storage_be refs_be_reftable;extern struct ref_storage_be refs_be_packed;/*
refs/reftable-backend.c new file +1691 -0
1,691 lines not on this page · raw message
repository.c +2 -0
@@ -180,6 +180,8 @@ int repo_init(struct repository *repo,if (worktree)repo_set_worktree (repo, worktree); + repo->ref_storage_format =xstrdup_or_null (format.ref_storage); +clear_repository_format (&format);return 0 ;
repository.h +3 -0
@@ -82,6 +82,9 @@ struct repository {*/ struct ref_store *refs_private; +/* The format to use for the ref database. */ +char *ref_storage_format; +/* * Contains path to often used file names. */
setup.c +8 -0
@@ -498,6 +498,9 @@ static enum extension_result handle_extension(const char *var,return error ("invalid value for 'extensions.objectformat'" ); data->hash_algo = format;return EXTENSION_OK ; + }else if (!strcmp (ext,"refstorage" )) { + data->ref_storage =xstrdup (value); +return EXTENSION_OK ; }return EXTENSION_UNKNOWN ; }
@@ -648,6 +651,7 @@ void clear_repository_format(struct repository_format *format)string_list_clear (&format->v1_only_extensions,0 );free (format->work_tree);free (format->partial_clone); +free (format->ref_storage);init_repository_format (format); }
@@ -1312,6 +1316,8 @@ const char *setup_git_directory_gently(int *nongit_ok) the_repository->repository_format_partial_clone = repo_fmt.partial_clone; repo_fmt.partial_clone =NULL ; + the_repository->ref_storage_format = +xstrdup_or_null (repo_fmt.ref_storage); } }/*
@@ -1399,6 +1405,8 @@ void check_repository_format(struct repository_format *fmt)repo_set_hash_algo (the_repository, fmt->hash_algo); the_repository->repository_format_partial_clone =xstrdup_or_null (fmt->partial_clone); +/* XXX why is repo->ref_storage_format set in multiple places?! */ + the_repository->ref_storage_format =xstrdup_or_null (fmt->ref_storage);clear_repository_format (&repo_fmt); }
t/t0031-reftable.sh new file +310 -0
310 lines not on this page · raw message
t/t1409-avoid-packing-refs.sh +6 -0
@@ -4,6 +4,12 @@ test_description='avoid rewriting packed-refs unnecessarily' . ./test-lib.sh +if test_have_prereq !REFFILES +then + skip_all='skipping pack-refs tests; need files backend' + test_done +fi + # Add an identifying mark to the packed-refs file header line. This # shouldn't upset readers, and it should be omitted if the file is # ever rewritten.
t/t1450-fsck.sh +6 -0
@@ -8,6 +8,12 @@ test_description='git fsck random collection of tests . ./test-lib.sh +if test_have_prereq !REFFILES +then + skip_all='skipping tests; incompatible with reftable' + test_done +fi + test_expect_success setup ' git config gc.auto 0 && git config i18n.commitencoding ISO-8859-1 &&
t/t3210-pack-refs.sh +6 -0
@@ -14,6 +14,12 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh +if test_have_prereq !REFFILES +then + skip_all='skipping pack-refs tests; requires files ref backend' + test_done +fi + test_expect_success 'enable reflogs' ' git config core.logallrefupdates true '
t/test-lib.sh +6 -1
@@ -1524,7 +1524,12 @@ parisc* | hppa*) ;; esac -test_set_prereq REFFILES +if test -n "$GIT_TEST_REFTABLE" +then + test_set_prereq !REFFILES +else + test_set_prereq REFFILES +fi ( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1 test -z "$NO_PERL" && test_set_prereq PERL
Signature · 1 line
gitgitgadget
PATCH v3 19/25 reftable: add dump utility
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
provide a command-line utility for inspecting individual tables, and inspecting a complete ref database
--- reftable/dump.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 reftable/dump.c
reftable/dump.c new file +107 -0
@@ -0,0 +1,107 @@ +/* +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 "git-compat-util.h" +#include "hash.h" + +#include "reftable-blocksource.h" +#include "reftable-error.h" +#include "reftable-merged.h" +#include "reftable-record.h" +#include "reftable-tests.h" +#include "reftable-writer.h" +#include "reftable-iterator.h" +#include "reftable-reader.h" +#include "reftable-stack.h" +#include "reftable-generic.h" + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +static int compact_stack (const char *stackdir) +{ +struct reftable_stack *stack =NULL ; +struct reftable_write_options cfg = {0 }; + +int err =reftable_new_stack (&stack, stackdir, cfg); +if (err <0 ) + goto done; + + err =reftable_stack_compact_all (stack,NULL ); +if (err <0 ) + goto done; +done: +if (stack) { +reftable_stack_destroy (stack); + } +return err; +} + +static void print_help (void ) +{ +printf ("usage: dump [-cst] arg\n\n" +"options: \n" +" -c compact\n" +" -t dump table\n" +" -s dump stack\n" +" -6 sha256 hash format\n" +" -h this help\n" +"\n" ); +} + +int reftable_dump_main (int argc,char *const *argv) +{ +int err =0 ; +int opt_dump_table =0 ; +int opt_dump_stack =0 ; +int opt_compact =0 ; +uint32_t opt_hash_id =GIT_SHA1_FORMAT_ID ; +const char *arg =NULL , *argv0 = argv[0 ]; + +for (; argc >1 ; argv++, argc--) +if (*argv[1 ] !='-' ) +break ; +else if (!strcmp ("-t" , argv[1 ])) + opt_dump_table =1 ; +else if (!strcmp ("-6" , argv[1 ])) + opt_hash_id =GIT_SHA256_FORMAT_ID ; +else if (!strcmp ("-s" , argv[1 ])) + opt_dump_stack =1 ; +else if (!strcmp ("-c" , argv[1 ])) + opt_compact =1 ; +else if (!strcmp ("-?" , argv[1 ]) || !strcmp ("-h" , argv[1 ])) { +print_help (); +return 2 ; + } + +if (argc !=2 ) { +fprintf (stderr,"need argument\n" ); +print_help (); +return 2 ; + } + + arg = argv[1 ]; + +if (opt_dump_table) { + err =reftable_reader_print_file (arg); + }else if (opt_dump_stack) { + err =reftable_stack_print_directory (arg, opt_hash_id); + }else if (opt_compact) { + err =compact_stack (arg); + } + +if (err <0 ) { +fprintf (stderr,"%s: %s: %s\n" , argv0, arg, +reftable_error_str (err)); +return 1 ; + } +return 0 ; +}
Signature · 1 line
gitgitgadget
PATCH v3 13/25 reftable: read reftable files
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This supports reading a single reftable file.
The commit introduces an abstract iterator type, which captures the usecases both of reading individual refs, and iterating over a segment of the ref namespace.
--- Makefile | 2 + reftable/iter.c | 194 +++++++++ reftable/iter.h | 69 ++++ reftable/reader.c | 801 +++++++++++++++++++++++++++++++++++++ reftable/reader.h | 66 +++ reftable/reftable-reader.h | 101 +++++ 6 files changed, 1233 insertions(+) create mode 100644 reftable/iter.c create mode 100644 reftable/iter.h create mode 100644 reftable/reader.c create mode 100644 reftable/reader.h create mode 100644 reftable/reftable-reader.h
Makefile +2 -0
@@ -2456,7 +2456,9 @@ REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o +REFTABLE_OBJS += reftable/iter.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/reader.o REFTABLE_OBJS += reftable/record.o REFTABLE_OBJS += reftable/refname.o REFTABLE_OBJS += reftable/generic.o
reftable/iter.c new file +194 -0
194 lines not on this page · raw message
reftable/iter.h new file +69 -0
69 lines not on this page · raw message
reftable/reader.c new file +801 -0
801 lines not on this page · raw message
reftable/reader.h new file +66 -0
66 lines not on this page · raw message
reftable/reftable-reader.h new file +101 -0
101 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v3 15/25 reftable: add a heap-based priority queue for reftable records
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This is needed to create a merged view multiple reftables
--- Makefile | 2 + reftable/pq.c | 115 ++++++++++++++++++++++++++++++++++++++ reftable/pq.h | 32 +++++++++++ reftable/pq_test.c | 72 ++++++++++++++++++++++++ reftable/reftable-tests.h | 1 + t/helper/test-reftable.c | 1 + 6 files changed, 223 insertions(+) create mode 100644 reftable/pq.c create mode 100644 reftable/pq.h create mode 100644 reftable/pq_test.c
Makefile +2 -0
@@ -2458,6 +2458,7 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/iter.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/pq.o REFTABLE_OBJS += reftable/reader.o REFTABLE_OBJS += reftable/record.o REFTABLE_OBJS += reftable/refname.o
@@ -2468,6 +2469,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o +REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o
reftable/pq.c new file +115 -0
115 lines not on this page · raw message
reftable/pq.h new file +32 -0
@@ -0,0 +1,32 @@ +/* +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 PQ_H +#define PQ_H + +#include "record.h" + +struct pq_entry { +int index; +struct reftable_record rec; +}; + +struct merged_iter_pqueue { +struct pq_entry *heap; +size_t len; +size_t cap; +}; + +struct pq_entry merged_iter_pqueue_top (struct merged_iter_pqueue pq); +int merged_iter_pqueue_is_empty (struct merged_iter_pqueue pq); +void merged_iter_pqueue_check (struct merged_iter_pqueue pq); +struct pq_entry merged_iter_pqueue_remove (struct merged_iter_pqueue *pq); +void merged_iter_pqueue_add (struct merged_iter_pqueue *pq,struct pq_entry e); +void merged_iter_pqueue_release (struct merged_iter_pqueue *pq); + +#endif
reftable/pq_test.c new file +72 -0
72 lines not on this page · raw message
reftable/reftable-tests.h +1 -0
@@ -12,6 +12,7 @@ https://developers.google.com/open-source/licenses/bsdint basics_test_main (int argc,const char **argv);int block_test_main (int argc,const char **argv);int merged_test_main (int argc,const char **argv); +int pq_test_main (int argc,const char **argv);int record_test_main (int argc,const char **argv);int refname_test_main (int argc,const char **argv);int readwrite_test_main (int argc,const char **argv);
t/helper/test-reftable.c +1 -0
@@ -5,6 +5,7 @@ int cmd__reftable(int argc, const char **argv) {basics_test_main (argc, argv);block_test_main (argc, argv); +pq_test_main (argc, argv);record_test_main (argc, argv);readwrite_test_main (argc, argv);tree_test_main (argc, argv);
Signature · 1 line
gitgitgadget
PATCH v3 25/25 t1404: annotate test cases with REFFILES
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
* Reftable for now lacks detailed error messages for directory/file conflicts. Skip message comparisons.
* Mark tests that muck with .git directly as REFFILES.
--- t/t1404-update-ref-errors.sh | 56 +++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 14 deletions(-)
t/t1404-update-ref-errors.sh +42 -14
@@ -27,7 +27,9 @@ test_update_rejected () { fi && printf "create $prefix/%s $C\n" $create >input && test_must_fail git update-ref --stdin <input 2>output.err && - test_i18ngrep -F "$error" output.err && + if test_have_prereq REFFILES ; then + test_i18ngrep -F "$error" output.err + fi && git for-each-ref $prefix >actual && test_cmp unchanged actual }
@@ -101,7 +103,9 @@ df_test() { printf "%s\n" "delete $delname" "create $addname $D" fi >commands && test_must_fail git update-ref --stdin <commands 2>output.err && - test_cmp expected-err output.err && + if test_have_prereq REFFILES ; then + test_cmp expected-err output.err + fi && printf "%s\n" "$C $delref" >expected-refs && git for-each-ref --format="%(objectname) %(refname)" $prefix/r >actual-refs && test_cmp expected-refs actual-refs
@@ -336,7 +340,9 @@ test_expect_success 'missing old value blocks update' ' EOF printf "%s\n" "update $prefix/foo $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks update' '
@@ -347,7 +353,9 @@ test_expect_success 'incorrect old value blocks update' ' EOF printf "%s\n" "update $prefix/foo $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'existing old value blocks create' '
@@ -358,7 +366,9 @@ test_expect_success 'existing old value blocks create' ' EOF printf "%s\n" "create $prefix/foo $E" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks delete' '
@@ -369,7 +379,9 @@ test_expect_success 'incorrect old value blocks delete' ' EOF printf "%s\n" "delete $prefix/foo $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'missing old value blocks indirect update' '
@@ -380,7 +392,9 @@ test_expect_success 'missing old value blocks indirect update' ' EOF printf "%s\n" "update $prefix/symref $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks indirect update' '
@@ -392,7 +406,9 @@ test_expect_success 'incorrect old value blocks indirect update' ' EOF printf "%s\n" "update $prefix/symref $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'existing old value blocks indirect create' '
@@ -404,7 +420,9 @@ test_expect_success 'existing old value blocks indirect create' ' EOF printf "%s\n" "create $prefix/symref $E" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks indirect delete' '
@@ -416,7 +434,9 @@ test_expect_success 'incorrect old value blocks indirect delete' ' EOF printf "%s\n" "delete $prefix/symref $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'missing old value blocks indirect no-deref update' '
@@ -427,7 +447,9 @@ test_expect_success 'missing old value blocks indirect no-deref update' ' EOF printf "%s\n" "option no-deref" "update $prefix/symref $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks indirect no-deref update' '
@@ -439,7 +461,9 @@ test_expect_success 'incorrect old value blocks indirect no-deref update' ' EOF printf "%s\n" "option no-deref" "update $prefix/symref $E $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'existing old value blocks indirect no-deref create' '
@@ -451,7 +475,9 @@ test_expect_success 'existing old value blocks indirect no-deref create' ' EOF printf "%s\n" "option no-deref" "create $prefix/symref $E" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success 'incorrect old value blocks indirect no-deref delete' '
@@ -463,7 +489,9 @@ test_expect_success 'incorrect old value blocks indirect no-deref delete' ' EOF printf "%s\n" "option no-deref" "delete $prefix/symref $D" | test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err + if test_have_prereq REFFILES ; then + test_cmp expected output.err + fi ' test_expect_success REFFILES 'non-empty directory blocks create' '
Signature · 1 line
gitgitgadget
PATCH v3 16/25 reftable: add merged table view
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This adds an abstract, read-only interface to the ref database.
This primitive is used to construct the read view of the ref database (the read view is constructed by merging several *.ref files). It also provides the mechanism to provide a unified view of the refs in the main repository and the per-worktree refs.
--- Makefile | 2 + reftable/merged.c | 362 +++++++++++++++++++++++++++++++++++++ reftable/merged.h | 35 ++++ reftable/merged_test.c | 292 ++++++++++++++++++++++++++++++ reftable/reftable-merged.h | 72 ++++++++ t/helper/test-reftable.c | 1 + 6 files changed, 764 insertions(+) create mode 100644 reftable/merged.c create mode 100644 reftable/merged.h create mode 100644 reftable/merged_test.c create mode 100644 reftable/reftable-merged.h
Makefile +2 -0
@@ -2458,6 +2458,7 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/iter.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/merged.o REFTABLE_OBJS += reftable/pq.o REFTABLE_OBJS += reftable/reader.o REFTABLE_OBJS += reftable/record.o
@@ -2469,6 +2470,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o +REFTABLE_TEST_OBJS += reftable/merged_test.o REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o
reftable/merged.c new file +362 -0
362 lines not on this page · raw message
reftable/merged.h new file +35 -0
@@ -0,0 +1,35 @@ +/* +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 MERGED_H +#define MERGED_H + +#include "pq.h" + +struct reftable_merged_table { +struct reftable_table *stack; +size_t stack_len; +uint32_t hash_id; +int suppress_deletions; + +uint64_t min; +uint64_t max; +}; + +struct merged_iter { +struct reftable_iterator *stack; +uint32_t hash_id; +size_t stack_len; +uint8_t typ; +int suppress_deletions; +struct merged_iter_pqueue pq; +}; + +void merged_table_release (struct reftable_merged_table *mt); + +#endif
reftable/merged_test.c new file +292 -0
292 lines not on this page · raw message
reftable/reftable-merged.h new file +72 -0
72 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -5,6 +5,7 @@ int cmd__reftable(int argc, const char **argv) {basics_test_main (argc, argv);block_test_main (argc, argv); +merged_test_main (argc, argv);pq_test_main (argc, argv);record_test_main (argc, argv);readwrite_test_main (argc, argv);
Signature · 1 line
gitgitgadget
PATCH v3 18/25 reftable: implement stack, a mutable database of reftable files.
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- Makefile | 1 + reftable/reftable-stack.h | 128 ++++ reftable/stack.c | 1396 +++++++++++++++++++++++++++++++++++++ reftable/stack.h | 41 ++ reftable/stack_test.c | 948 +++++++++++++++++++++++++ t/helper/test-reftable.c | 1 + 6 files changed, 2515 insertions(+) create mode 100644 reftable/reftable-stack.h create mode 100644 reftable/stack.c create mode 100644 reftable/stack.h create mode 100644 reftable/stack_test.c
Makefile +1 -0
@@ -2475,6 +2475,7 @@ REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o REFTABLE_TEST_OBJS += reftable/refname_test.o +REFTABLE_TEST_OBJS += reftable/stack_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/tree_test.o
reftable/reftable-stack.h new file +128 -0
128 lines not on this page · raw message
reftable/stack.c new file +1396 -0
1,396 lines not on this page · raw message
reftable/stack.h new file +41 -0
41 lines not on this page · raw message
reftable/stack_test.c new file +948 -0
948 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -10,6 +10,7 @@ int cmd__reftable(int argc, const char **argv)record_test_main (argc, argv);refname_test_main (argc, argv);readwrite_test_main (argc, argv); +stack_test_main (argc, argv);tree_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH v3 24/25 t1401,t2011: parameterize HEAD.lock for REFFILES
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- t/t1401-symbolic-ref.sh | 11 +++++++++-- t/t2011-checkout-invalid-head.sh | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-)
t/t1401-symbolic-ref.sh +9 -2
@@ -102,9 +102,16 @@ test_expect_success LONG_REF 'we can parse long symbolic ref' ' test_cmp expect actual ' +if test_have_prereq REFFILES +then + HEAD_LOCK=HEAD.lock +else + HEAD_LOCK=reftable/tables.list.lock +fi + test_expect_success 'symbolic-ref reports failure in exit code' ' - test_when_finished "rm -f .git/HEAD.lock" && - >.git/HEAD.lock && + test_when_finished "rm -f .git/$HEAD_LOCK" && + >.git/$HEAD_LOCK && test_must_fail git symbolic-ref HEAD refs/heads/whatever '
t/t2011-checkout-invalid-head.sh +9 -2
@@ -22,9 +22,16 @@ test_expect_success 'checkout main from invalid HEAD' ' git checkout main -- ' +if test_have_prereq REFFILES +then + HEAD_LOCK=HEAD.lock +else + HEAD_LOCK=reftable/tables.list.lock +fi + test_expect_success 'checkout notices failure to lock HEAD' ' - test_when_finished "rm -f .git/HEAD.lock" && - >.git/HEAD.lock && + test_when_finished "rm -f .git/$HEAD_LOCK" && + >.git/$HEAD_LOCK && test_must_fail git checkout -b other '
Signature · 1 line
gitgitgadget
PATCH v3 22/25 Add "test-tool dump-reftable" command.
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
This command dumps individual tables or a stack of of tables.
--- Makefile | 1 + t/helper/test-reftable.c | 5 +++++ t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + t/t0031-reftable.sh | 6 ++++++ 5 files changed, 14 insertions(+)
Makefile +1 -0
@@ -2471,6 +2471,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o +REFTABLE_TEST_OBJS += reftable/dump.o REFTABLE_TEST_OBJS += reftable/merged_test.o REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o
t/helper/test-reftable.c +5 -0
@@ -14,3 +14,8 @@ int cmd__reftable(int argc, const char **argv)tree_test_main (argc, argv);return 0 ; } + +int cmd__dump_reftable (int argc,const char **argv) +{ +return reftable_dump_main (argc, (char *const *)argv); +}
t/helper/test-tool.c +1 -0
@@ -61,6 +61,7 @@ static struct test_cmd cmds[] = { { "read-midx", cmd__read_midx }, { "ref-store", cmd__ref_store }, { "reftable", cmd__reftable }, + { "dump-reftable", cmd__dump_reftable }, { "regex", cmd__regex }, { "repository", cmd__repository }, { "revision-walking", cmd__revision_walking },
t/helper/test-tool.h +1 -0
@@ -19,6 +19,7 @@ int cmd__dump_cache_tree(int argc, const char **argv);int cmd__dump_fsmonitor (int argc,const char **argv);int cmd__dump_split_index (int argc,const char **argv);int cmd__dump_untracked_cache (int argc,const char **argv); +int cmd__dump_reftable (int argc,const char **argv);int cmd__example_decorate (int argc,const char **argv);int cmd__fast_rebase (int argc,const char **argv);int cmd__genrandom (int argc,const char **argv);
t/t0031-reftable.sh +6 -0
@@ -288,6 +288,12 @@ test_expect_success 'FETCH_HEAD' ' test_cmp expect actual ' +test_expect_success 'dump reftable' ' + initialize && + hash_id=$(git config extensions.objectformat) && + test-tool dump-reftable $(test "${hash_id}" = "sha256" && echo "-6") -s .git/reftable +' + . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd
Signature · 1 line
gitgitgadget
PATCH v3 17/25 reftable: implement refname validation
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
The packed/loose format has restrictions on refnames: a and a/b cannot coexist. This limitation does not apply to reftable per se, but must be maintained for interoperability. This code adds validation routines to abort transactions that are trying to add invalid names.
--- Makefile | 1 + reftable/refname.c | 209 +++++++++++++++++++++++++++++++++++++++ reftable/refname.h | 29 ++++++ reftable/refname_test.c | 102 +++++++++++++++++++ t/helper/test-reftable.c | 1 + 5 files changed, 342 insertions(+) create mode 100644 reftable/refname.c create mode 100644 reftable/refname.h create mode 100644 reftable/refname_test.c
Makefile +1 -0
@@ -2474,6 +2474,7 @@ REFTABLE_TEST_OBJS += reftable/merged_test.o REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o +REFTABLE_TEST_OBJS += reftable/refname_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/tree_test.o
reftable/refname.c new file +209 -0
209 lines not on this page · raw message
reftable/refname.h new file +29 -0
@@ -0,0 +1,29 @@ +/* +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 REFNAME_H +#define REFNAME_H + +#include "reftable-record.h" +#include "reftable-generic.h" + +struct modification { +struct reftable_table tab; + +char **add; +size_t add_len; + +char **del; +size_t del_len; +}; + +int validate_ref_record_addition (struct reftable_table tab, +struct reftable_ref_record *recs,size_t sz); + +int modification_validate (struct modification *mod); + +#endif
reftable/refname_test.c new file +102 -0
102 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -8,6 +8,7 @@ int cmd__reftable(int argc, const char **argv)merged_test_main (argc, argv);pq_test_main (argc, argv);record_test_main (argc, argv); +refname_test_main (argc, argv);readwrite_test_main (argc, argv);tree_test_main (argc, argv);return 0 ;
Signature · 1 line
gitgitgadget
PATCH v3 23/25 t1301: document what needs to be done for reftable
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
--- t/t1301-shared-repo.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
t/t1301-shared-repo.sh +5 -3
@@ -22,9 +22,10 @@ test_expect_success 'shared = 0400 (faulty permission u-w)' ' ) ' +# TODO(hanwen): for REFTABLE should inspect group-readable of .git/reftable/ for u in 002 022 do - test_expect_success POSIXPERM "shared=1 does not clear bits preset by umask $u" ' + test_expect_success REFFILES,POSIXPERM "shared=1 does not clear bits preset by umask $u" ' mkdir sub && ( cd sub && umask $u &&
@@ -114,7 +115,8 @@ test_expect_success POSIXPERM 'info/refs respects umask in unshared repo' ' test_cmp expect actual ' -test_expect_success POSIXPERM 'git reflog expire honors core.sharedRepository' ' +# For reftable, the check on .git/reftable/ is sufficient. +test_expect_success REFFILES,POSIXPERM 'git reflog expire honors core.sharedRepository' ' umask 077 && git config core.sharedRepository group && git reflog expire --all &&
@@ -201,7 +203,7 @@ test_expect_success POSIXPERM 're-init respects core.sharedrepository (remote)' test_cmp expect actual ' -test_expect_success POSIXPERM 'template can set core.sharedrepository' ' +test_expect_success REFFILES,POSIXPERM 'template can set core.sharedrepository' ' rm -rf child.git && umask 0022 && git config core.sharedrepository 0666 &&
Signature · 1 line
gitgitgadget
PATCH v3 14/25 reftable: reftable file level tests
In reply to Han-Wen Nienhuys via GitGitGadgetFrom: Han-Wen Nienhuys <[email protected]>
With support for reading and writing files in place, we can construct files (in memory) and attempt to read them back.
Because some sections of the format are optional (eg. indices, log entries), we have to exercise this code using multiple sizes of input data
--- Makefile | 1 + reftable/readwrite_test.c | 652 ++++++++++++++++++++++++++++++++++++++ reftable/reftable-tests.h | 2 +- t/helper/test-reftable.c | 1 + 4 files changed, 655 insertions(+), 1 deletion(-) create mode 100644 reftable/readwrite_test.c
Makefile +1 -0
@@ -2469,6 +2469,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o REFTABLE_TEST_OBJS += reftable/record_test.o +REFTABLE_TEST_OBJS += reftable/readwrite_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/tree_test.o
reftable/readwrite_test.c new file +652 -0
652 lines not on this page · raw message
reftable/reftable-tests.h +1 -1
@@ -14,7 +14,7 @@ int block_test_main(int argc, const char **argv);int merged_test_main (int argc,const char **argv);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 readwrite_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);
t/helper/test-reftable.c +1 -0
@@ -6,6 +6,7 @@ int cmd__reftable(int argc, const char **argv)basics_test_main (argc, argv);block_test_main (argc, argv);record_test_main (argc, argv); +readwrite_test_main (argc, argv);tree_test_main (argc, argv);return 0 ; }
Signature · 1 line
gitgitgadget
v3 cover Support reftable ref backend for Git
In reply to Han-Wen Nienhuys via GitGitGadgetThis continues the work in https://github.com/git/git/pull/847, which the gitgitgadget erroneously closed.
Changes relative to last series (version 20 Jul 2021, tip: 4a5891f )
* fix HTTP serving
* fix t1501 (use absolute paths.)
* fix git-new-workdir
* fixes for FreeBSD (thanks, [email protected]!)
For the 'seen' branch, the following should be applied:
refs/reftable-backend.c +6 -7
@@ -108,7 +108,7 @@ static const char *bare_ref_name(const char *ref)static int git_reftable_read_raw_ref (struct ref_store *ref_store,const char *refname,struct object_id *oid,struct strbuf *referent, -unsigned int *type); +unsigned int *type,int *failure_errno);static void clear_reftable_log_record (struct reftable_log_record *log) {
@@ -425,13 +424,14 @@ static int fixup_symrefs(struct ref_store *ref_store,for (i =0 ; i < transaction->nr; i++) {struct ref_update *update = transaction->updates[i];struct object_id old_oid; +int failure_errno; err =git_reftable_read_raw_ref (ref_store, update->refname, &old_oid, &referent,/* mutate input, like files-backend.c */ - &update->type); -if (err <0 && errno ==ENOENT && + &update->type, &failure_errno); +if (err <0 && failure_errno ==ENOENT &&is_null_oid (&update->old_oid)) { err =0 ; }
@@ -1602,7 +1603,7 @@ static int reftable_error_to_errno(int err)static int git_reftable_read_raw_ref (struct ref_store *ref_store,const char *refname,struct object_id *oid,struct strbuf *referent, -unsigned int *type) +unsigned int *type,int *failure_errno) {struct git_reftable_ref_store *refs = (struct git_reftable_ref_store *)ref_store;
@@ -1626,13 +1627,11 @@ static int git_reftable_read_raw_ref(struct ref_store *ref_store, err =reftable_stack_read_ref (stack, refname, &ref);if (err >0 ) { - errno =ENOENT ; + *failure_errno =ENOENT ; err =-1 ; goto done; }if (err <0 ) { - errno =reftable_error_to_errno (err); - err =-1 ; goto done; }
Han-Wen Nienhuys (24):
hash.h: provide constants for the hash IDs
init-db: set the_repository->hash_algo early on
reftable: RFC: add LICENSE
reftable: add error related functionality
reftable: utility functions
reftable: add blocksource, an abstraction for random access reads
reftable: (de)serialization for the polymorphic record type. Provide zlib's uncompress2 from compat/zlib-compat.c
reftable: reading/writing blocks
reftable: a generic binary tree implementation
reftable: write reftable files
reftable: generic interface to tables
reftable: read reftable files
reftable: reftable file level tests
reftable: add a heap-based priority queue for reftable records
reftable: add merged table view
reftable: implement refname validation
reftable: implement stack, a mutable database of reftable files.
reftable: add dump utility
refs: RFC: Reftable support for git-core
Add "test-tool dump-reftable" command.
t1301: document what needs to be done for reftable t1401,t2011: parameterize HEAD.lock for REFFILES
t1404: annotate test cases with REFFILES
SZEDER Gábor (1):
git-prompt: prepare for reftable refs backend
Documentation/config/extensions.txt | 9 + .../technical/repository-version.txt | 7 + Makefile | 54 +- builtin/clone.c | 5 +- builtin/init-db.c | 60 +- builtin/stash.c | 8 +- builtin/worktree.c | 27 +- cache.h | 8 +- ci/lib.sh | 1 + compat/.gitattributes | 1 + compat/zlib-uncompress2.c | 92 + config.mak.uname | 3 +- configure.ac | 13 + contrib/buildsystems/CMakeLists.txt | 14 +- contrib/buildsystems/Generators/Vcxproj.pm | 11 +- contrib/completion/git-prompt.sh | 7 +- contrib/workdir/git-new-workdir | 2 +- hash.h | 6 + object-file.c | 7 +- refs.c | 26 +- refs.h | 3 + refs/refs-internal.h | 1 + refs/reftable-backend.c | 1691 +++++++++++++++++ reftable/LICENSE | 31 + reftable/basics.c | 128 ++ reftable/basics.h | 60 + reftable/basics_test.c | 98 + reftable/block.c | 448 +++++ reftable/block.h | 127 ++ reftable/block_test.c | 120 ++ reftable/blocksource.c | 148 ++ reftable/blocksource.h | 22 + reftable/constants.h | 21 + reftable/dump.c | 107 ++ reftable/error.c | 41 + reftable/generic.c | 169 ++ reftable/generic.h | 32 + reftable/iter.c | 194 ++ reftable/iter.h | 69 + reftable/merged.c | 362 ++++ reftable/merged.h | 35 + reftable/merged_test.c | 292 +++ reftable/pq.c | 115 ++ reftable/pq.h | 32 + reftable/pq_test.c | 72 + reftable/publicbasics.c | 58 + reftable/reader.c | 801 ++++++++ reftable/reader.h | 66 + reftable/readwrite_test.c | 652 +++++++ reftable/record.c | 1212 ++++++++++++ reftable/record.h | 139 ++ reftable/record_test.c | 412 ++++ reftable/refname.c | 209 ++ reftable/refname.h | 29 + reftable/refname_test.c | 102 + reftable/reftable-blocksource.h | 49 + reftable/reftable-error.h | 62 + reftable/reftable-generic.h | 47 + reftable/reftable-iterator.h | 39 + reftable/reftable-malloc.h | 18 + reftable/reftable-merged.h | 72 + reftable/reftable-reader.h | 101 + reftable/reftable-record.h | 114 ++ reftable/reftable-stack.h | 128 ++ reftable/reftable-tests.h | 23 + reftable/reftable-writer.h | 148 ++ reftable/reftable.c | 115 ++ reftable/stack.c | 1396 ++++++++++++++ reftable/stack.h | 41 + reftable/stack_test.c | 948 +++++++++ reftable/system.h | 24 + reftable/test_framework.c | 23 + reftable/test_framework.h | 53 + reftable/tree.c | 63 + reftable/tree.h | 34 + reftable/tree_test.c | 61 + reftable/writer.c | 690 +++++++ reftable/writer.h | 50 + repository.c | 2 + repository.h | 3 + setup.c | 8 + t/helper/test-reftable.c | 21 + t/helper/test-tool.c | 4 +- t/helper/test-tool.h | 2 + t/t0031-reftable.sh | 316 +++ t/t0032-reftable-unittest.sh | 15 + t/t1301-shared-repo.sh | 8 +- t/t1401-symbolic-ref.sh | 11 +- t/t1404-update-ref-errors.sh | 56 +- t/t1409-avoid-packing-refs.sh | 6 + t/t1450-fsck.sh | 6 + t/t2011-checkout-invalid-head.sh | 11 +- t/t3210-pack-refs.sh | 6 + t/test-lib.sh | 7 +- 94 files changed, 13178 insertions(+), 62 deletions(-) create mode 100644 compat/.gitattributes create mode 100644 compat/zlib-uncompress2.c create mode 100644 refs/reftable-backend.c create mode 100644 reftable/LICENSE create mode 100644 reftable/basics.c create mode 100644 reftable/basics.h create mode 100644 reftable/basics_test.c create mode 100644 reftable/block.c create mode 100644 reftable/block.h create mode 100644 reftable/block_test.c create mode 100644 reftable/blocksource.c create mode 100644 reftable/blocksource.h create mode 100644 reftable/constants.h create mode 100644 reftable/dump.c create mode 100644 reftable/error.c create mode 100644 reftable/generic.c create mode 100644 reftable/generic.h 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/pq_test.c create mode 100644 reftable/publicbasics.c create mode 100644 reftable/reader.c create mode 100644 reftable/reader.h create mode 100644 reftable/readwrite_test.c 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-blocksource.h create mode 100644 reftable/reftable-error.h create mode 100644 reftable/reftable-generic.h create mode 100644 reftable/reftable-iterator.h create mode 100644 reftable/reftable-malloc.h create mode 100644 reftable/reftable-merged.h create mode 100644 reftable/reftable-reader.h create mode 100644 reftable/reftable-record.h create mode 100644 reftable/reftable-stack.h create mode 100644 reftable/reftable-tests.h create mode 100644 reftable/reftable-writer.h create mode 100644 reftable/reftable.c create mode 100644 reftable/stack.c create mode 100644 reftable/stack.h create mode 100644 reftable/stack_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 100644 reftable/writer.c create mode 100644 reftable/writer.h create mode 100644 t/helper/test-reftable.c create mode 100755 t/t0031-reftable.sh create mode 100755 t/t0032-reftable-unittest.sh
base-commit: 225bc32a989d7a22fa6addafd4ce7dcd04675dbf
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1054%2Fhanwen%2Flibreftable-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1054/hanwen/libreftable-v3
Pull-Request: https://github.com/git/git/pull/1054
Range-diff vs v2:
1: c40393e83e1 = 1: cad3c4835a2 hash.h: provide constants for the hash IDs
2: 49dffeeae58 = 2: 97aba3ae406 init-db: set the_repository->hash_algo early on
3: dba354eca12 = 3: fca162dd676 reftable: RFC: add LICENSE
4: 75864034af2 = 4: 44923074a5a reftable: add error related functionality
5: eabb25d95b3 ! 5: 2f2beb70078 reftable: utility functions
@@ reftable/system.h (new)
+#ifndef SYSTEM_H
+#define SYSTEM_H
+
-+// This header glues the reftable library to the rest of Git
++/* This header glues the reftable library to the rest of Git */
+
+#include "git-compat-util.h"
+#include "strbuf.h"
6: ad54d17f84b = 6: 79d4a23764d reftable: add blocksource, an abstraction for random access reads
7: 282d8e4d817 ! 7: 2c143c75cd5 reftable: (de)serialization for the polymorphic record type.
@@ reftable/record.c (new)
+ break;
+ case REFTABLE_LOG_UPDATE:
+ printf("log{%s(%" PRIu64 ") %s <%s> %" PRIu64 " %04d\n",
-+ log->refname, log->update_index, log->update.name,
-+ log->update.email, log->update.time,
-+ log->update.tz_offset);
-+ hex_format(hex, log->update.old_hash, hash_size(hash_id));
++ log->refname, log->update_index, log->value.update.name,
++ log->value.update.email, log->value.update.time,
++ log->value.update.tz_offset);
++ hex_format(hex, log->value.update.old_hash, hash_size(hash_id));
+ printf("%s => ", hex);
-+ hex_format(hex, log->update.new_hash, hash_size(hash_id));
-+ printf("%s\n\n%s\n}\n", hex, log->update.message);
++ hex_format(hex, log->value.update.new_hash, hash_size(hash_id));
++ printf("%s\n\n%s\n}\n", hex, log->value.update.message);
+ break;
+ }
+}
@@ reftable/record.c (new)
+ case REFTABLE_LOG_DELETION:
+ break;
+ case REFTABLE_LOG_UPDATE:
-+ if (dst->update.email) {
-+ dst->update.email = xstrdup(dst->update.email);
++ if (dst->value.update.email) {
++ dst->value.update.email =
++ xstrdup(dst->value.update.email);
+ }
-+ if (dst->update.name) {
-+ dst->update.name = xstrdup(dst->update.name);
++ if (dst->value.update.name) {
++ dst->value.update.name =
++ xstrdup(dst->value.update.name);
+ }
-+ if (dst->update.message) {
-+ dst->update.message = xstrdup(dst->update.message);
++ if (dst->value.update.message) {
++ dst->value.update.message =
++ xstrdup(dst->value.update.message);
+ }
+
-+ if (dst->update.new_hash) {
-+ dst->update.new_hash = reftable_malloc(hash_size);
-+ memcpy(dst->update.new_hash, src->update.new_hash,
-+ hash_size);
++ if (dst->value.update.new_hash) {
++ dst->value.update.new_hash = reftable_malloc(hash_size);
++ memcpy(dst->value.update.new_hash,
++ src->value.update.new_hash, hash_size);
+ }
-+ if (dst->update.old_hash) {
-+ dst->update.old_hash = reftable_malloc(hash_size);
-+ memcpy(dst->update.old_hash, src->update.old_hash,
-+ hash_size);
++ if (dst->value.update.old_hash) {
++ dst->value.update.old_hash = reftable_malloc(hash_size);
++ memcpy(dst->value.update.old_hash,
++ src->value.update.old_hash, hash_size);
+ }
+ break;
+ }
@@ reftable/record.c (new)
+ case REFTABLE_LOG_DELETION:
+ break;
+ case REFTABLE_LOG_UPDATE:
-+ reftable_free(r->update.new_hash);
-+ reftable_free(r->update.old_hash);
-+ reftable_free(r->update.name);
-+ reftable_free(r->update.email);
-+ reftable_free(r->update.message);
++ reftable_free(r->value.update.new_hash);
++ reftable_free(r->value.update.old_hash);
++ reftable_free(r->value.update.name);
++ reftable_free(r->value.update.email);
++ reftable_free(r->value.update.message);
+ break;
+ }
+ memset(r, 0, sizeof(struct reftable_log_record));
@@ reftable/record.c (new)
+ if (reftable_log_record_is_deletion(r))
+ return 0;
+
-+ oldh = r->update.old_hash;
-+ newh = r->update.new_hash;
++ oldh = r->value.update.old_hash;
++ newh = r->value.update.new_hash;
+ if (!oldh) {
+ oldh = zero;
+ }
@@ reftable/record.c (new)
+ memcpy(s.buf + hash_size, newh, hash_size);
+ string_view_consume(&s, 2 * hash_size);
+
-+ n = encode_string(r->update.name ? r->update.name : "", s);
++ n = encode_string(r->value.update.name ? r->value.update.name : "", s);
+ if (n < 0)
+ return -1;
+ string_view_consume(&s, n);
+
-+ n = encode_string(r->update.email ? r->update.email : "", s);
++ n = encode_string(r->value.update.email ? r->value.update.email : "",
++ s);
+ if (n < 0)
+ return -1;
+ string_view_consume(&s, n);
+
-+ n = put_var_int(&s, r->update.time);
++ n = put_var_int(&s, r->value.update.time);
+ if (n < 0)
+ return -1;
+ string_view_consume(&s, n);
@@ reftable/record.c (new)
+ if (s.len < 2)
+ return -1;
+
-+ put_be16(s.buf, r->update.tz_offset);
++ put_be16(s.buf, r->value.update.tz_offset);
+ string_view_consume(&s, 2);
+
-+ n = encode_string(r->update.message ? r->update.message : "", s);
++ n = encode_string(
++ r->value.update.message ? r->value.update.message : "", s);
+ if (n < 0)
+ return -1;
+ string_view_consume(&s, n);
@@ reftable/record.c (new)
+ if (val_type != r->value_type) {
+ switch (r->value_type) {
+ case REFTABLE_LOG_UPDATE:
-+ FREE_AND_NULL(r->update.old_hash);
-+ FREE_AND_NULL(r->update.new_hash);
-+ FREE_AND_NULL(r->update.message);
-+ FREE_AND_NULL(r->update.email);
-+ FREE_AND_NULL(r->update.name);
++ FREE_AND_NULL(r->value.update.old_hash);
++ FREE_AND_NULL(r->value.update.new_hash);
++ FREE_AND_NULL(r->value.update.message);
++ FREE_AND_NULL(r->value.update.email);
++ FREE_AND_NULL(r->value.update.name);
+ break;
+ case REFTABLE_LOG_DELETION:
+ break;
@@ reftable/record.c (new)
+ if (in.len < 2 * hash_size)
+ return REFTABLE_FORMAT_ERROR;
+
-+ r->update.old_hash = reftable_realloc(r->update.old_hash, hash_size);
-+ r->update.new_hash = reftable_realloc(r->update.new_hash, hash_size);
++ r->value.update.old_hash =
++ reftable_realloc(r->value.update.old_hash, hash_size);
++ r->value.update.new_hash =
++ reftable_realloc(r->value.update.new_hash, hash_size);
+
-+ memcpy(r->update.old_hash, in.buf, hash_size);
-+ memcpy(r->update.new_hash, in.buf + hash_size, hash_size);
++ memcpy(r->value.update.old_hash, in.buf, hash_size);
++ memcpy(r->value.update.new_hash, in.buf + hash_size, hash_size);
+
+ string_view_consume(&in, 2 * hash_size);
+
@@ reftable/record.c (new)
+ goto done;
+ string_view_consume(&in, n);
+
-+ r->update.name = reftable_realloc(r->update.name, dest.len + 1);
-+ memcpy(r->update.name, dest.buf, dest.len);
-+ r->update.name[dest.len] = 0;
++ r->value.update.name =
++ reftable_realloc(r->value.update.name, dest.len + 1);
++ memcpy(r->value.update.name, dest.buf, dest.len);
++ r->value.update.name[dest.len] = 0;
+
+ strbuf_reset(&dest);
+ n = decode_string(&dest, in);
@@ reftable/record.c (new)
+ goto done;
+ string_view_consume(&in, n);
+
-+ r->update.email = reftable_realloc(r->update.email, dest.len + 1);
-+ memcpy(r->update.email, dest.buf, dest.len);
-+ r->update.email[dest.len] = 0;
++ r->value.update.email =
++ reftable_realloc(r->value.update.email, dest.len + 1);
++ memcpy(r->value.update.email, dest.buf, dest.len);
++ r->value.update.email[dest.len] = 0;
+
+ ts = 0;
+ n = get_var_int(&ts, &in);
+ if (n < 0)
+ goto done;
+ string_view_consume(&in, n);
-+ r->update.time = ts;
++ r->value.update.time = ts;
+ if (in.len < 2)
+ goto done;
+
-+ r->update.tz_offset = get_be16(in.buf);
++ r->value.update.tz_offset = get_be16(in.buf);
+ string_view_consume(&in, 2);
+
+ strbuf_reset(&dest);
@@ reftable/record.c (new)
+ goto done;
+ string_view_consume(&in, n);
+
-+ r->update.message = reftable_realloc(r->update.message, dest.len + 1);
-+ memcpy(r->update.message, dest.buf, dest.len);
-+ r->update.message[dest.len] = 0;
++ r->value.update.message =
++ reftable_realloc(r->value.update.message, dest.len + 1);
++ memcpy(r->value.update.message, dest.buf, dest.len);
++ r->value.update.message[dest.len] = 0;
+
+ strbuf_release(&dest);
+ return start.len - in.len;
@@ reftable/record.c (new)
+ case REFTABLE_LOG_DELETION:
+ return 1;
+ case REFTABLE_LOG_UPDATE:
-+ return null_streq(a->update.name, b->update.name) &&
-+ a->update.time == b->update.time &&
-+ a->update.tz_offset == b->update.tz_offset &&
-+ null_streq(a->update.email, b->update.email) &&
-+ null_streq(a->update.message, b->update.message) &&
-+ zero_hash_eq(a->update.old_hash, b->update.old_hash,
-+ hash_size) &&
-+ zero_hash_eq(a->update.new_hash, b->update.new_hash,
-+ hash_size);
++ return null_streq(a->value.update.name, b->value.update.name) &&
++ a->value.update.time == b->value.update.time &&
++ a->value.update.tz_offset == b->value.update.tz_offset &&
++ null_streq(a->value.update.email,
++ b->value.update.email) &&
++ null_streq(a->value.update.message,
++ b->value.update.message) &&
++ zero_hash_eq(a->value.update.old_hash,
++ b->value.update.old_hash, hash_size) &&
++ zero_hash_eq(a->value.update.new_hash,
++ b->value.update.new_hash, hash_size);
+ }
+
+ abort();
@@ reftable/record_test.c (new)
+ .refname = xstrdup("refs/heads/master"),
+ .update_index = 42,
+ .value_type = REFTABLE_LOG_UPDATE,
-+ .update = {
-+ .old_hash = reftable_malloc(GIT_SHA1_RAWSZ),
-+ .new_hash = reftable_malloc(GIT_SHA1_RAWSZ),
-+ .name = xstrdup("han-wen"),
-+ .email = xstrdup("[email protected]"),
-+ .message = xstrdup("test"),
-+ .time = 1577123507,
-+ .tz_offset = 100,
++ .value = {
++ .update = {
++ .old_hash = reftable_malloc(GIT_SHA1_RAWSZ),
++ .new_hash = reftable_malloc(GIT_SHA1_RAWSZ),
++ .name = xstrdup("han-wen"),
++ .email = xstrdup("[email protected]"),
++ .message = xstrdup("test"),
++ .time = 1577123507,
++ .tz_offset = 100,
++ },
+ }
+ },
+ {
@@ reftable/record_test.c (new)
+ .value_type = REFTABLE_LOG_DELETION,
+ }
+ };
-+ set_test_hash(in[0].update.new_hash, 1);
-+ set_test_hash(in[0].update.old_hash, 2);
++ set_test_hash(in[0].value.update.new_hash, 1);
++ set_test_hash(in[0].value.update.old_hash, 2);
+ for (i = 0; i < ARRAY_SIZE(in); i++) {
+ struct reftable_record rec = { NULL };
+ struct strbuf key = STRBUF_INIT;
@@ reftable/record_test.c (new)
+ struct reftable_log_record out = {
+ .refname = xstrdup("old name"),
+ .value_type = REFTABLE_LOG_UPDATE,
-+ .update = {
-+ .new_hash = reftable_calloc(GIT_SHA1_RAWSZ),
-+ .old_hash = reftable_calloc(GIT_SHA1_RAWSZ),
-+ .name = xstrdup("old name"),
-+ .email = xstrdup("old@email"),
-+ .message = xstrdup("old message"),
++ .value = {
++ .update = {
++ .new_hash = reftable_calloc(GIT_SHA1_RAWSZ),
++ .old_hash = reftable_calloc(GIT_SHA1_RAWSZ),
++ .name = xstrdup("old name"),
++ .email = xstrdup("old@email"),
++ .message = xstrdup("old message"),
++ },
+ },
+ };
+ struct reftable_record rec_out = { NULL };
@@ reftable/reftable-record.h (new)
+ int16_t tz_offset;
+ char *message;
+ } update;
-+ };
++ } value;
+};
+
+/* returns whether 'ref' represents the deletion of a log record. */
8: 893ee4ca21b = 8: d92338467d6 Provide zlib's uncompress2 from compat/zlib-compat.c
9: e4da0a2ef37 ! 9: 74ac0b135fa reftable: reading/writing blocks
@@ reftable/block_test.c (new)
+#include "block.h"
+
+#include "system.h"
-+
+#include "blocksource.h"
+#include "basics.h"
+#include "constants.h"
10: 0f325881389 = 10: a2219670079 reftable: a generic binary tree implementation
11: 26cbc468f1f ! 11: ac3063fd08c reftable: write reftable files
@@ reftable/writer.c (new)
+ if (log->refname == NULL)
+ return REFTABLE_API_ERROR;
+
-+ input_log_message = log->update.message;
-+ if (!w->opts.exact_log_message && log->update.message) {
-+ strbuf_addstr(&cleaned_message, log->update.message);
++ input_log_message = log->value.update.message;
++ if (!w->opts.exact_log_message && log->value.update.message) {
++ strbuf_addstr(&cleaned_message, log->value.update.message);
+ while (cleaned_message.len &&
+ cleaned_message.buf[cleaned_message.len - 1] == '\n')
+ strbuf_setlen(&cleaned_message,
+ cleaned_message.len - 1);
+ if (strchr(cleaned_message.buf, '\n')) {
-+ // multiple lines not allowed.
++ /* multiple lines not allowed. */
+ err = REFTABLE_API_ERROR;
+ goto done;
+ }
+ strbuf_addstr(&cleaned_message, "\n");
-+ log->update.message = cleaned_message.buf;
++ log->value.update.message = cleaned_message.buf;
+ }
+
+ err = reftable_writer_add_log_verbatim(w, log);
-+ log->update.message = input_log_message;
++ log->value.update.message = input_log_message;
+done:
+ strbuf_release(&cleaned_message);
+ return err;
12: 69129fca086 = 12: e0f3476555e reftable: generic interface to tables
13: 22599d785b7 = 13: f1fe338f67e reftable: read reftable files
14: 45565bfb9c4 ! 14: 7da9a85c1db reftable: reftable file level tests
@@ reftable/readwrite_test.c (new)
+ log.refname = name;
+ log.update_index = update_index;
+ log.value_type = REFTABLE_LOG_UPDATE;
-+ log.update.new_hash = hash;
-+ log.update.message = "message";
++ log.value.update.new_hash = hash;
++ log.value.update.message = "message";
+
+ n = reftable_writer_add_log(w, &log);
+ EXPECT(n == 0);
@@ reftable/readwrite_test.c (new)
+ for (i = 0; i < stats->ref_stats.blocks; i++) {
+ int off = i * opts.block_size;
+ if (off == 0) {
-+ off = header_size((hash_id == GIT_SHA256_FORMAT_ID) ? 2 :
-+ 1);
++ off = header_size(
++ (hash_id == GIT_SHA256_FORMAT_ID) ? 2 : 1);
+ }
+ EXPECT(buf->buf[off] == 'r');
+ }
@@ reftable/readwrite_test.c (new)
+ };
+ int err;
+ int i;
-+ struct reftable_log_record log = { .refname = "refs/heads/master",
-+ .update_index = 0xa,
-+ .value_type = REFTABLE_LOG_UPDATE,
-+ .update = {
-+ .name = "Han-Wen Nienhuys",
-+ .email = "[email protected]",
-+ .tz_offset = 100,
-+ .time = 0x5e430672,
-+ .message = "commit: 9\n",
-+ } };
++ struct reftable_log_record
++ log = { .refname = "refs/heads/master",
++ .update_index = 0xa,
++ .value_type = REFTABLE_LOG_UPDATE,
++ .value = { .update = {
++ .name = "Han-Wen Nienhuys",
++ .email = "[email protected]",
++ .tz_offset = 100,
++ .time = 0x5e430672,
++ .message = "commit: 9\n",
++ } } };
+ struct reftable_writer *w =
+ reftable_new_writer(&strbuf_add_void, &buf, &opts);
+
@@ reftable/readwrite_test.c (new)
+ hash1[i] = (uint8_t)(rand() % 256);
+ hash2[i] = (uint8_t)(rand() % 256);
+ }
-+ log.update.old_hash = hash1;
-+ log.update.new_hash = hash2;
++ log.value.update.old_hash = hash1;
++ log.value.update.new_hash = hash2;
+ reftable_writer_set_limits(w, update_index, update_index);
+ err = reftable_writer_add_log(w, &log);
+ EXPECT_ERR(err);
@@ reftable/readwrite_test.c (new)
+ log.refname = names[i];
+ log.update_index = i;
+ log.value_type = REFTABLE_LOG_UPDATE;
-+ log.update.old_hash = hash1;
-+ log.update.new_hash = hash2;
++ log.value.update.old_hash = hash1;
++ log.value.update.new_hash = hash2;
+
+ err = reftable_writer_add_log(w, &log);
+ EXPECT_ERR(err);
15: 57b3e709c3e = 15: 953590034a8 reftable: add a heap-based priority queue for reftable records
16: f834cc5299f = 16: 64fe3c8edc5 reftable: add merged table view
17: 15799d93ff7 = 17: acb0d435a20 reftable: implement refname validation
18: b7728ceaef2 ! 18: 764d45fccd4 reftable: implement stack, a mutable database of reftable files.
@@ reftable/stack.c (new)
+ reftable_reader_free(st->readers[i]);
+
+ if (filename.len) {
-+ // On Windows, can only unlink after closing.
++ /* On Windows, can only unlink after closing. */
+ unlink(filename.buf);
+ }
+ }
@@ reftable/stack.c (new)
+ reader_close(cur[i]);
+ reftable_reader_free(cur[i]);
+
-+ // On Windows, can only unlink after closing.
++ /* On Windows, can only unlink after closing. */
+ unlink(filename.buf);
+
+ strbuf_release(&filename);
@@ reftable/stack.c (new)
+ }
+
+ if (config && config->time > 0 &&
-+ log.update.time < config->time) {
++ log.value.update.time < config->time) {
+ continue;
+ }
+
@@ reftable/stack_test.c (new)
+ logs[i].update_index = N + i + 1;
+ logs[i].value_type = REFTABLE_LOG_UPDATE;
+
-+ logs[i].update.new_hash = reftable_malloc(GIT_SHA1_RAWSZ);
-+ logs[i].update.email = xstrdup("identity@invalid");
-+ set_test_hash(logs[i].update.new_hash, i);
++ logs[i].value.update.new_hash = reftable_malloc(GIT_SHA1_RAWSZ);
++ logs[i].value.update.email = xstrdup("identity@invalid");
++ set_test_hash(logs[i].value.update.new_hash, i);
+ }
+
+ for (i = 0; i < N; i++) {
@@ reftable/stack_test.c (new)
+ struct reftable_log_record input = { .refname = "branch",
+ .update_index = 1,
+ .value_type = REFTABLE_LOG_UPDATE,
-+ .update = {
-+ .new_hash = h1,
-+ .old_hash = h2,
-+ } };
++ .value = { .update = {
++ .new_hash = h1,
++ .old_hash = h2,
++ } } };
+ struct reftable_log_record dest = {
+ .update_index = 0,
+ };
@@ reftable/stack_test.c (new)
+ err = reftable_new_stack(&st, dir, cfg);
+ EXPECT_ERR(err);
+
-+ input.update.message = "one\ntwo";
++ input.value.update.message = "one\ntwo";
+ err = reftable_stack_add(st, &write_test_log, &arg);
+ EXPECT(err == REFTABLE_API_ERROR);
+
-+ input.update.message = "one";
++ input.value.update.message = "one";
+ err = reftable_stack_add(st, &write_test_log, &arg);
+ EXPECT_ERR(err);
+
+ err = reftable_stack_read_log(st, input.refname, &dest);
+ EXPECT_ERR(err);
-+ EXPECT(0 == strcmp(dest.update.message, "one\n"));
++ EXPECT(0 == strcmp(dest.value.update.message, "one\n"));
+
-+ input.update.message = "two\n";
++ input.value.update.message = "two\n";
+ arg.update_index = 2;
+ err = reftable_stack_add(st, &write_test_log, &arg);
+ EXPECT_ERR(err);
+ err = reftable_stack_read_log(st, input.refname, &dest);
+ EXPECT_ERR(err);
-+ EXPECT(0 == strcmp(dest.update.message, "two\n"));
++ EXPECT(0 == strcmp(dest.value.update.message, "two\n"));
+
+ /* cleanup */
+ reftable_stack_destroy(st);
@@ reftable/stack_test.c (new)
+ logs[i].update_index = 42;
+ if (i % 2 == 0) {
+ logs[i].value_type = REFTABLE_LOG_UPDATE;
-+ logs[i].update.new_hash =
++ logs[i].value.update.new_hash =
+ reftable_malloc(GIT_SHA1_RAWSZ);
-+ set_test_hash(logs[i].update.new_hash, i);
-+ logs[i].update.email = xstrdup("identity@invalid");
++ set_test_hash(logs[i].value.update.new_hash, i);
++ logs[i].value.update.email =
++ xstrdup("identity@invalid");
+ }
+ }
+ for (i = 0; i < N; i++) {
@@ reftable/stack_test.c (new)
+ logs[i].refname = xstrdup(buf);
+ logs[i].update_index = i;
+ logs[i].value_type = REFTABLE_LOG_UPDATE;
-+ logs[i].update.time = i;
-+ logs[i].update.new_hash = reftable_malloc(GIT_SHA1_RAWSZ);
-+ logs[i].update.email = xstrdup("identity@invalid");
-+ set_test_hash(logs[i].update.new_hash, i);
++ logs[i].value.update.time = i;
++ logs[i].value.update.new_hash = reftable_malloc(GIT_SHA1_RAWSZ);
++ logs[i].value.update.email = xstrdup("identity@invalid");
++ set_test_hash(logs[i].value.update.new_hash, i);
+ }
+
+ for (i = 1; i <= N; i++) {
19: 0f682be20bd = 19: 88dbab683dc reftable: add dump utility
20: 754085752f4 ! 20: 3d57f7c4430 refs: RFC: Reftable support for git-core
@@ refs/reftable-backend.c (new)
+ log->refname = NULL;
+ switch (log->value_type) {
+ case REFTABLE_LOG_UPDATE:
-+ log->update.old_hash = NULL;
-+ log->update.new_hash = NULL;
-+ log->update.message = NULL;
++ log->value.update.old_hash = NULL;
++ log->value.update.new_hash = NULL;
++ log->value.update.message = NULL;
+ break;
+ case REFTABLE_LOG_DELETION:
+ break;
@@ refs/reftable-backend.c (new)
+
+ reftable_log_record_release(log);
+ log->value_type = REFTABLE_LOG_UPDATE;
-+ log->update.name =
++ log->value.update.name =
+ xstrndup(split.name_begin, split.name_end - split.name_begin);
-+ log->update.email =
++ log->value.update.email =
+ xstrndup(split.mail_begin, split.mail_end - split.mail_begin);
-+ log->update.time = atol(split.date_begin);
++ log->value.update.time = atol(split.date_begin);
+ if (*split.tz_begin == '-') {
+ sign = -1;
+ split.tz_begin++;
@@ refs/reftable-backend.c (new)
+ split.tz_begin++;
+ }
+
-+ log->update.tz_offset = sign * atoi(split.tz_begin);
++ log->value.update.tz_offset = sign * atoi(split.tz_begin);
+}
+
+static int has_suffix(struct strbuf *b, const char *suffix)
@@ refs/reftable-backend.c (new)
+ log->update_index = ts;
+ log->value_type = REFTABLE_LOG_UPDATE;
+ log->refname = (char *)u->refname;
-+ log->update.new_hash = u->new_oid.hash;
-+ log->update.message = u->msg;
++ log->value.update.new_hash = u->new_oid.hash;
++ log->value.update.message = u->msg;
+
+ err = reftable_table_read_ref(&tab, u->refname, &ref);
+ if (err < 0)
@@ refs/reftable-backend.c (new)
+
+ /* XXX fold together with the old_id check below? */
+
-+ log->update.old_hash = old_id.hash;
++ log->value.update.old_hash = old_id.hash;
+ if (u->flags & REF_LOG_ONLY) {
+ continue;
+ }
@@ refs/reftable-backend.c (new)
+ log.update_index = ts;
+ log.refname = (char *)arg->refnames->items[i].string;
+
-+ log.update.message = xstrdup(arg->logmsg);
-+ log.update.new_hash = NULL;
-+ log.update.old_hash = NULL;
++ log.value.update.message = xstrdup(arg->logmsg);
++ log.value.update.new_hash = NULL;
++ log.value.update.old_hash = NULL;
+ if (reftable_stack_read_ref(arg->stack, log.refname,
+ ¤t) == 0) {
-+ log.update.old_hash =
++ log.value.update.old_hash =
+ reftable_ref_record_val1(¤t);
+ }
+ err = reftable_writer_add_log(writer, &log);
-+ log.update.old_hash = NULL;
++ log.value.update.old_hash = NULL;
+ reftable_ref_record_release(¤t);
+
+ clear_reftable_log_record(&log);
@@ refs/reftable-backend.c (new)
+ fill_reftable_log_record(&log);
+ log.refname = (char *)create->refname;
+ log.update_index = ts;
-+ log.update.message = (char *)create->logmsg;
++ log.value.update.message = (char *)create->logmsg;
+ if (refs_resolve_ref_unsafe(
+ (struct ref_store *)create->refs, create->refname,
+ RESOLVE_REF_READING, &old_oid, NULL) != NULL) {
-+ log.update.old_hash = old_oid.hash;
++ log.value.update.old_hash = old_oid.hash;
+ }
+
+ if (refs_resolve_ref_unsafe((struct ref_store *)create->refs,
+ create->target, RESOLVE_REF_READING,
+ &new_oid, NULL) != NULL) {
-+ log.update.new_hash = new_oid.hash;
++ log.value.update.new_hash = new_oid.hash;
+ }
+
-+ if (log.update.old_hash != NULL ||
-+ log.update.new_hash != NULL) {
++ if (log.value.update.old_hash != NULL ||
++ log.value.update.new_hash != NULL) {
+ err = reftable_writer_add_log(writer, &log);
+ }
+ log.refname = NULL;
-+ log.update.message = NULL;
-+ log.update.old_hash = NULL;
-+ log.update.new_hash = NULL;
++ log.value.update.message = NULL;
++ log.value.update.old_hash = NULL;
++ log.value.update.new_hash = NULL;
+ clear_reftable_log_record(&log);
+ }
+ return err;
@@ refs/reftable-backend.c (new)
+
+ todo[0].refname = (char *)arg->oldname;
+ todo[0].update_index = ts;
-+ todo[0].update.message = (char *)arg->logmsg;
-+ todo[0].update.old_hash = val1;
-+ todo[0].update.new_hash = NULL;
++ todo[0].value.update.message = (char *)arg->logmsg;
++ todo[0].value.update.old_hash = val1;
++ todo[0].value.update.new_hash = NULL;
+
+ todo[1].refname = (char *)arg->newname;
+ todo[1].update_index = ts;
-+ todo[1].update.old_hash = NULL;
-+ todo[1].update.new_hash = val1;
-+ todo[1].update.message = (char *)arg->logmsg;
++ todo[1].value.update.old_hash = NULL;
++ todo[1].value.update.new_hash = val1;
++ todo[1].value.update.message = (char *)arg->logmsg;
+
+ err = reftable_writer_add_logs(writer, todo, 2);
+
@@ refs/reftable-backend.c (new)
+
+ free(ri->last_name);
+ ri->last_name = xstrdup(ri->log.refname);
-+ oidread(&ri->oid, ri->log.update.new_hash);
++ oidread(&ri->oid, ri->log.value.update.new_hash);
+ return ITER_OK;
+ }
+}
@@ refs/reftable-backend.c (new)
+ break;
+ }
+
-+ oidread(&old_oid, log.update.old_hash);
-+ oidread(&new_oid, log.update.new_hash);
++ oidread(&old_oid, log.value.update.old_hash);
++ oidread(&new_oid, log.value.update.new_hash);
+
-+ full_committer = fmt_ident(log.update.name, log.update.email,
++ full_committer = fmt_ident(log.value.update.name,
++ log.value.update.email,
+ WANT_COMMITTER_IDENT,
+ /*date*/ NULL, IDENT_NO_DATE);
-+ err = fn(&old_oid, &new_oid, full_committer, log.update.time,
-+ log.update.tz_offset, log.update.message, cb_data);
++ err = fn(&old_oid, &new_oid, full_committer,
++ log.value.update.time, log.value.update.tz_offset,
++ log.value.update.message, cb_data);
+ if (err)
+ break;
+ }
@@ refs/reftable-backend.c (new)
+ struct object_id new_oid;
+ const char *full_committer = "";
+
-+ oidread(&old_oid, log->update.old_hash);
-+ oidread(&new_oid, log->update.new_hash);
++ oidread(&old_oid, log->value.update.old_hash);
++ oidread(&new_oid, log->value.update.new_hash);
+
-+ full_committer = fmt_ident(log->update.name, log->update.email,
++ full_committer = fmt_ident(log->value.update.name,
++ log->value.update.email,
+ WANT_COMMITTER_IDENT, NULL,
+ IDENT_NO_DATE);
-+ err = fn(&old_oid, &new_oid, full_committer, log->update.time,
-+ log->update.tz_offset, log->update.message, cb_data);
++ err = fn(&old_oid, &new_oid, full_committer,
++ log->value.update.time, log->value.update.tz_offset,
++ log->value.update.message, cb_data);
+ if (err) {
+ break;
+ }
@@ refs/reftable-backend.c (new)
+ struct reftable_log_record *dest = &rewritten[i];
+
+ *dest = logs[i];
-+ oidread(&ooid, logs[i].update.old_hash);
-+ oidread(&noid, logs[i].update.new_hash);
-+
-+ if (should_prune_fn(&ooid, &noid, logs[i].update.email,
-+ (timestamp_t)logs[i].update.time,
-+ logs[i].update.tz_offset,
-+ logs[i].update.message, policy_cb_data)) {
++ oidread(&ooid, logs[i].value.update.old_hash);
++ oidread(&noid, logs[i].value.update.new_hash);
++
++ if (should_prune_fn(&ooid, &noid, logs[i].value.update.email,
++ (timestamp_t)logs[i].value.update.time,
++ logs[i].value.update.tz_offset,
++ logs[i].value.update.message,
++ policy_cb_data)) {
+ dest->value_type = REFTABLE_LOG_DELETION;
+ } else {
+ if ((flags & EXPIRE_REFLOGS_REWRITE) &&
+ last_hash != NULL) {
-+ dest->update.old_hash = last_hash;
++ dest->value.update.old_hash = last_hash;
+ }
-+ last_hash = logs[i].update.new_hash;
++ last_hash = logs[i].value.update.new_hash;
+ }
+ }
+
21: 79c4b90d0f4 = 21: 460658a13cb git-prompt: prepare for reftable refs backend
22: 1f48091e549 = 22: b305fcd49f1 Add "test-tool dump-reftable" command.
23: 64dc87746db = 23: a44956d7b08 t1301: document what needs to be done for reftable
24: c248b69c6e3 = 24: f0b7b1e2380 t1401,t2011: parameterize HEAD.lock for REFFILES
25: 9f1b792459e = 25: 3110d6e6758 t1404: annotate test cases with REFFILESSignature · 1 line
gitgitgadget
PATCH v3 2/25 init-db: set the_repository->hash_algo early on
From: Han-Wen Nienhuys <[email protected]>
The reftable backend needs to know the hash algorithm for writing the initialization hash table.
The initial reftable contains a symref HEAD => "main" (or "master"), which is agnostic to the size of hash value, but this is an exceptional circumstance, and the reftable library does not cater to this exception. It insists that all tables in the stack have a consistent format ID for the hash algorithm.
Call set_repo_hash_algo directly after calling validate_hash_algorithm() (which reads $GIT_DEFAULT_HASH).
--- builtin/init-db.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
builtin/init-db.c +21 -0
@@ -425,6 +425,27 @@ int init_db(const char *git_dir, const char *real_git_dir,validate_hash_algorithm (&repo_fmt, hash); +/* +* At this point, the_repository we have in-core does not look +* anything like one that we would see initialized in an already +* working repository after calling setup_git_directory(). +* +* Calling repository.c::initialize_the_repository() may have +* prepared the .index .objects and .parsed_objects members, but +* other members like .gitdir, .commondir, etc. have not been +* initialized. +* +* Many API functions assume they are working with the_repository +* that has sensibly been initialized, but because we haven't +* really read from an existing repository, we need to hand-craft +* the necessary members of the structure to get out of this +* chicken-and-egg situation. +* +* For now, we update the hash algorithm member to what the +* validate_hash_algorithm() call decided for us. +*/ +repo_set_hash_algo (the_repository, repo_fmt.hash_algo); + reinit =create_default_files (template_dir, original_git_dir, initial_branch, &repo_fmt, flags &INIT_DB_QUIET );
Signature · 1 line
gitgitgadget
Re: [PATCH v2 07/25] reftable: (de)serialization for the polymorphic record type.
In reply to Carlo Marcelo Arenas BelónQuoted 16 lines · Carlo Marcelo Arenas Belón
Quoted 1 line · Han-Wen Nienhuys via GitGitGadget
From: Han-Wen Nienhuys <[email protected]>
...
reftable/reftable-record.h struct reftable_log_record {
Quoted 11 lines
reftable/reftable-record.h +11
-0+union { +struct { +uint8_t *new_hash; +uint8_t *old_hash; +char *name; +char *email; +uint64_t time; +int16_t tz_offset; +char *message; + } update; + };
Quoted 2 lines
the use of an anonymous union here (which requires C11) could be made C89 compatible without any impact AFAIK by doing instead:
Thanks for the pointer. I opted to do it the C89 way instead, for consistency with reftable_ref_record.
Signature · 11 lines
Han-Wen Nienhuys - Google Munich I work 80%. Don't expect answers from me on Fridays. -- Google Germany GmbH, Erika-Mann-Strasse 33, 80636 Munich Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg Geschäftsführer: Paul Manicle, Halimah DeLaine Prado
Quoted 8 lines · Junio C Hamano
Quoted 5 lines · Han-Wen Nienhuys via GitGitGadget
This continues the work in https://github.com/git/git/pull/847, which the gitgitgadget erroneously closed.
Changes relative to last series (version 20 Jul 2021, tip: 4a5891f )
Quoted 7 lines
Quoted 4 lines
* fix HTTP serving
* fix t1501 (use absolute paths.)
* fix git-new-workdir
* fixes for FreeBSD (thanks, [email protected]!)Thanks, will take a look later after the release is done; nice to see these fix-up changes already applied in the series.
You're welcome.
Slight tangent: for the series, the bottom-most commit (which introduces the hash identifiers) could be a separate topic which graduates sooner.
Signature · 11 lines
Han-Wen Nienhuys - Google Munich I work 80%. Don't expect answers from me on Fridays. -- Google Germany GmbH, Erika-Mann-Strasse 33, 80636 Munich Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg Geschäftsführer: Paul Manicle, Halimah DeLaine Prado
Re: [PATCH v3 08/25] Provide zlib's uncompress2 from compat/zlib-compat.c
In reply to Han-Wen Nienhuys via GitGitGadgetQuoted 3 lines · Han-Wen Nienhuys via GitGitGadget
From: Han-Wen Nienhuys <[email protected]>
This will be needed for reading reflog blocks in reftable.
How large might the reftable become? In particular will it exceed the 32bit Long limit on Windows?
I ask as the Zlib library is one of (among many) the constraints on beating the 4GB [backward compatibility] size limit from 32 bit Windows.
Quoted 94 lines
Signed-off-by Han-Wen Nienhuys <[email protected]>--- Makefile | 7 +++ ci/lib.sh | 1 + compat/.gitattributes | 1 + compat/zlib-uncompress2.c | 92 +++++++++++++++++++++++++++++++++++++++ config.mak.uname | 1 + configure.ac | 13 ++++++ 6 files changed, 115 insertions(+) create mode 100644 compat/.gitattributes create mode 100644 compat/zlib-uncompress2.cMakefile +7
-0@@ -256,6 +256,8 @@ all:: # # Define NO_DEFLATE_BOUND if your zlib does not have deflateBound. # +# Define NO_UNCOMPRESS2 if your zlib does not have uncompress2. +# # Define NO_NORETURN if using buggy versions of gcc 4.6+ and profile feedback, # as the compiler can crash (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49299) #@@ -1738,6 +1740,11 @@ ifdef NO_DEFLATE_BOUND BASIC_CFLAGS += -DNO_DEFLATE_BOUND endif +ifdef NO_UNCOMPRESS2 + BASIC_CFLAGS += -DNO_UNCOMPRESS2 + REFTABLE_OBJS += compat/zlib-uncompress2.o +endif + ifdef NO_POSIX_GOODIES BASIC_CFLAGS += -DNO_POSIX_GOODIES endifci/lib.sh +1
-0@@ -224,6 +224,7 @@ linux-gcc-default) ;; Linux32) CC=gcc + MAKEFLAGS="$MAKEFLAGS NO_UNCOMPRESS2=1" ;; linux-musl) CC=gcccompat/.gitattributes new file +1
-0@@ -0,0 +1 @@ +/zlib-uncompress2.c whitespace=-indent-with-non-tab,-trailing-spacecompat/zlib-uncompress2.c new file +30
-0@@ -0,0 +1,92 @@ +/* taken from zlib's uncompr.c + +commit cacf7f1d4e3d44d871b605da3b647f07d718623f +Author: Mark Adler <[email protected]> +Date: Sun Jan 15 09:18:46 2017 -0800 + +zlib 1.2.11 + +*/ + +/* +* Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler +* For conditions of distribution and use, see copyright notice in zlib.h +*/ + +#include <zlib.h> + +/* clang-format off */ + +/* =========================================================================== +Decompresses the source buffer into the destination buffer. *sourceLen is +the byte length of the source buffer. Upon entry, *destLen is the total size +of the destination buffer, which must be large enough to hold the entire +uncompressed data. (The size of the uncompressed data must have been saved +previously by the compressor and transmitted to the decompressor by some +mechanism outside the scope of this compression library.) Upon exit, +*destLen is the size of the decompressed data and *sourceLen is the number +of source bytes consumed. Upon return, source + *sourceLen points to the +first unused input byte. +
compat/zlib-uncompress2.c line 40
Quoted 10 lines
compat/zlib-uncompress2.c new file +10
-0+uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough +memory, Z_BUF_ERROR if there was not enough room in the output buffer, or +Z_DATA_ERROR if the input data was corrupted, including if the input data is +an incomplete zlib stream. +*/ +int ZEXPORT uncompress2 ( +Bytef *dest, +uLongf *destLen, +const Bytef *source, +uLong *sourceLen) {
Length is limited to 4GB on Windows (the pointer itself will be implicitly size_t, but ...)
Quoted 81 lines
compat/zlib-uncompress2.c new file +52
-0+z_stream stream; +int err; +const uInt max = (uInt)-1 ; +uLong len, left; +Byte buf[1 ];/* for detection of incomplete stream when *destLen == 0 */ + + len = *sourceLen; +if (*destLen) { + left = *destLen; + *destLen =0 ; + } +else { + left =1 ; + dest = buf; + } + + stream.next_in = (z_const Bytef *)source; + stream.avail_in =0 ; + stream.zalloc = (alloc_func )0 ; + stream.zfree = (free_func )0 ; + stream.opaque = (voidpf )0 ; + + err =inflateInit (&stream); +if (err !=Z_OK )return err; + + stream.next_out = dest; + stream.avail_out =0 ; + +do { +if (stream.avail_out ==0 ) { + stream.avail_out = left > (uLong )max ? max : (uInt )left; + left -= stream.avail_out; + } +if (stream.avail_in ==0 ) { + stream.avail_in = len > (uLong )max ? max : (uInt )len; + len -= stream.avail_in; + } + err =inflate (&stream,Z_NO_FLUSH ); + }while (err ==Z_OK ); + + *sourceLen -= len + stream.avail_in; +if (dest != buf) + *destLen = stream.total_out; +else if (stream.total_out && err ==Z_BUF_ERROR ) + left =1 ; + +inflateEnd (&stream); +return err ==Z_STREAM_END ?Z_OK : + err ==Z_NEED_DICT ?Z_DATA_ERROR : + err ==Z_BUF_ERROR && left + stream.avail_out ?Z_DATA_ERROR : + err; +}config.mak.uname +1
-0@@ -256,6 +256,7 @@ ifeq ($(uname_S),FreeBSD) FILENO_IS_A_MACRO = UnfortunatelyYes endif ifeq ($(uname_S),OpenBSD) + NO_UNCOMPRESS2 = YesPlease NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease USE_ST_TIMESPEC = YesPleaseconfigure.ac +9
-0@@ -672,9 +672,22 @@ AC_LINK_IFELSE([ZLIBTEST_SRC], NO_DEFLATE_BOUND=yes]) LIBS="$old_LIBS" +AC_DEFUN([ZLIBTEST_UNCOMPRESS2_SRC], [ +AC_LANG_PROGRAM([#include <zlib.h>], + [uncompress2(NULL,NULL,NULL,NULL);])]) +AC_MSG_CHECKING([for uncompress2 in -lz]) +old_LIBS="$LIBS" +LIBS="$LIBS -lz" +AC_LINK_IFELSE([ZLIBTEST_UNCOMPRESS2_SRC], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no])
configure.ac AC_LINK_IFELSE([ZLIBTEST_SRC], · line 693
Quoted 10 lines
configure.ac +4
-0+ NO_UNCOMPRESS2=yes]) +LIBS="$old_LIBS" + GIT_UNSTASH_FLAGS($ZLIB_PATH) GIT_CONF_SUBST([NO_DEFLATE_BOUND]) +GIT_CONF_SUBST([NO_UNCOMPRESS2]) # # Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
--
Philip
Re: [PATCH v3 08/25] Provide zlib's uncompress2 from compat/zlib-compat.c
Quoted 8 lines · Philip Oakley
Quoted 3 lines · Han-Wen Nienhuys via GitGitGadget
From: Han-Wen Nienhuys <[email protected]>
This will be needed for reading reflog blocks in reftable.
How large might the reftable become? In particular will it exceed the 32bit Long limit on Windows?
A reftable file is organized as a sequence of blocks. Each block has max size 2^24, and the zlib compression is done per-block. So zlib should not introduce a new 4G limit. The intra-file offsets for the blocks themselves are encoded either as varint (index values) or as uint64 (file footer), so reftable files beyond 4G should be no problem.
Signature · 11 lines
Han-Wen Nienhuys - Google Munich I work 80%. Don't expect answers from me on Fridays. -- Google Germany GmbH, Erika-Mann-Strasse 33, 80636 Munich Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg Geschäftsführer: Paul Manicle, Halimah DeLaine Prado
Re: [PATCH v3 08/25] Provide zlib's uncompress2 from compat/zlib-compat.c
Quoted 5 lines · Han-Wen Nienhuys
Quoted 4 lines · Philip Oakley
Quoted 3 lines · Han-Wen Nienhuys via GitGitGadget
From: Han-Wen Nienhuys <[email protected]>
This will be needed for reading reflog blocks in reftable.
Quoted 9 lines
Quoted 2 lines
How large might the reftable become? In particular will it exceed the 32bit Long limit on Windows?
A reftable file is organized as a sequence of blocks. Each block has max size 2^24, and the zlib compression is done per-block. So zlib should not introduce a new 4G limit. The intra-file offsets for the blocks themselves are encoded either as varint (index values) or as uint64 (file footer), so reftable files beyond 4G should be no problem.
Thanks, that's good to know for planning any Git upgrade to cope with 4GB file sizes on Windows.
Philip
Quoted 10 lines · Han-Wen Nienhuys via GitGitGadget
This continues the work in https://github.com/git/git/pull/847, which the gitgitgadget erroneously closed.
Changes relative to last series (version 20 Jul 2021, tip: 4a5891f )
* fix HTTP serving
* fix t1501 (use absolute paths.)
* fix git-new-workdir
* fixes for FreeBSD (thanks, [email protected]!)
What's the overall status of this topic vis-a-vis whether it's being proposed to be integrated or is in more RFC form?
Since we discussed the non-working GIT_TEST_REFTABLE=true in [1] & [2] there's been fixes to the REFFILES for the tests which has already landed as c9780bb2ca8 (Merge branch 'hn/prep-tests-for-reftable', 2021-07-13).
But e.g. running t1410-reflog.sh reveals an assert failure() in this library's own code:
git: reftable/record.c:1075: reftable_record_copy_from: Assertion `src->ops->type == rec->ops->type' failed.
(A *lot* of things in the test suite still fail, I didn't look in any detail. Just highlighting that it's not just remaining failures due to hardcoding of .git/refs/*).
I took your reply in [2] to mean that you were on board with the plan I proposed in [1], but aside from the limited REFFILES fixes the structure of what's here seems relatively unchanged.
So is this series still considered RFC-esque, or what's the plan to move this forward at this point?
1. https://lore.kernel.org/git/[email protected]
2. https://lore.kernel.org/git/CAFQ2z_P8vgY0RRT+XSH9K3VDQt39FLqXx6qfeZqaZPkwhq1w+A@mail.gmail.com
Re: [PATCH v3 01/25] hash.h: provide constants for the hash IDs
In reply to Han-Wen Nienhuys via GitGitGadgetobject-file.c static void git_hash_unknown_final_oid(struct object_id *oid, git_hash_ctx *ctx) · line 169
Quoted 8 lines · Han-Wen Nienhuys via GitGitGadget
object-file.c +0
-1@@ -164,7 +164,6 @@ static void git_hash_unknown_final_oid(struct object_id *oid, git_hash_ctx *ctx)BUG ("trying to finalize unknown hash" ); } -const struct git_hash_algo hash_algos[GIT_HASH_NALGOS ] = { {NULL ,
Nit: stray whitespace change that snuck in?
Re: [PATCH v3 20/25] refs: RFC: Reftable support for git-core
In reply to Han-Wen Nienhuys via GitGitGadgetQuoted 5 lines · Han-Wen Nienhuys via GitGitGadget
[...]
refs/reftable-backend.c new file +4
-0+if (len == cap) { + cap =2 * cap +1 ; + logs =realloc (logs, cap *sizeof (*logs)); + }
refs/reftable-backend.c line 1336
Quoted 10 lines
refs/reftable-backend.c new file +9
-0+ + logs[len++] = log; +if (logs_len >= logs_cap) { +int new_cap = logs_cap *2 +1 ; + logs =realloc (logs, new_cap *sizeof (*logs)); + logs_cap = new_cap; + } + logs[logs_len++] = log; + }
Elsewhere in this series we use the ARRAY_SIZE() macro from git-compat-util.h, can't we also use REALLOC_ARRAY() from the same header here?
refs/reftable-backend.c line 1574
Quoted 7 lines
[...]
refs/reftable-backend.c new file +6
-0+if (!(flags &EXPIRE_REFLOGS_DRY_RUN )) { +/* XXX - skip writing records that were not changed. */ + err =reftable_addition_commit (add); + }else { +/* XXX - print something */ + }
Aren't these comments covered by some of the failing tests under GIT_TEST_REFTABLE=true? I.e. what I mentioned
https://lore.kernel.org/git/[email protected]/
refs/reftable-backend.c line 1645
Quoted 6 lines
[...]
refs/reftable-backend.c new file +5
-0+if (err <0 ) { + errno =reftable_error_to_errno (err); + err =-1 ; + goto done; + }
In your proposed fixup for the merger of our topics in
https://lore.kernel.org/git/[email protected]/
you have the call to reftable_error_to_errno() here deleted, so isn't this also redundant at this point (and then the reftable_error_to_errno() function can be deleted), or is this errno setting still needed with some of my changes?
t/t0031-reftable.sh line 14
Quoted 4 lines
[...]
t/t0031-reftable.sh new file +3
-0+git_init () { + git init -b primary "$@" +}
Can't later tests just use "main" instead of primary with a GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main, then we can drop this "git_init" wrapper?
t/t0031-reftable.sh line 17
Quoted 2 lines
t/t0031-reftable.sh new file +2
-0+initialize () { + rm -rf .git &&
Should instead set up a test_when_finished "rm -rf .git" ?
t/t0031-reftable.sh line 18
Quoted 1 line
t/t0031-reftable.sh new file +1
-0+ (GIT_TEST_REFTABLE=1; export GIT_TEST_REFTABLE; git_init) &&
This export before calling git_init can surely go away if git_init goes, but alo why export beforehand here, but in later tests in this file we just do a plain:
(GIT_TEST_REFTABLE=1 git_init) &&
?
t/t0031-reftable.sh line 19
Quoted 1 line
t/t0031-reftable.sh new file +1
-0+ mv .git/hooks .git/hooks-disabled
Is this "mv" cargo-culted from what test_create_repo() used to do before my-f0d4d398e28 (test-lib: split up and deprecate test_create_repo(), 2021-05-10)? In any case templated hooks are disabled by default (named *.sample), so I don't think this is needed.
t/t0031-reftable.sh line 93
Quoted 1 line
t/t0031-reftable.sh new file +1
-0+ echo hoi >> file.t &&
Nit: >>file.t, not ">> file.t".
t/t0031-reftable.sh line 104
Quoted 1 line
t/t0031-reftable.sh new file +1
-0+ git show-ref | sed s/before/after/g > expected &&
Don't have "git" on the LHS of a pipe, it'll hide a segfault. Should use a temporary file. Also "s/ > />/g" like above (and in some places below, will stop noting it...).
t/t0031-reftable.sh line 114
Quoted 5 lines
t/t0031-reftable.sh new file +5
-0+test_expect_success 'SHA256 support, env' ' + rm -rf .git && + GIT_DEFAULT_HASH=sha256 && export GIT_DEFAULT_HASH && + (GIT_TEST_REFTABLE=1 git_init) && + mv .git/hooks .git/hooks-disabled &&
Comments about this .git/hooks-disabled not being needed aside, this seems to be duplicating the initialize() function. I.e. should we not skip the "rm -rf" and "mv" here, and just set GIT_DEFAULT_HASH=sha256 and call initialize?
(Better yet, if we get rid of that "git init" wrapper as I noted above, this can just be an argument to "git init", no?
t/t0031-reftable.sh line 121
Quoted 4 lines
[...]
t/t0031-reftable.sh new file +3
-0+ rm -rf .git && + (GIT_TEST_REFTABLE=1 git_init --object-format=sha256) && + mv .git/hooks .git/hooks-disabled &&
ditto.
t/t0031-reftable.sh line 131
Quoted 1 line
t/t0031-reftable.sh new file +1
-0+ ! git update-ref -d refs/tags/file $INVALID_SHA1 &&
Always "test_must_fail git", not "! git".
t/t0031-reftable.sh line 143
Quoted 5 lines
[...]
t/t0031-reftable.sh new file +4
-0+test_expect_success 'clone calls transaction_initial_commit' ' + test_commit message1 file1 && + git clone . cloned && + (test -f cloned/file1 || echo "Fixme.")
So this test really tests nothing much, and we should skip the "Fixme" here and have this be test_expect_failure() or something instead?
t/t0031-reftable.sh line 151
Quoted 2 lines
[...]
t/t0031-reftable.sh new file +1
-0+ git show-ref | cut -f2 -d" " >actual &&
Git on LHS of a pipe again.
Quoted 5 lines
t/t0031-reftable.sh new file +5
-0+# This matches show-ref's output +print_ref() { + echo "$(git rev-parse "$1") $1" +} +
t/t0031-reftable.sh line 201
Quoted 10 lines
t/t0031-reftable.sh new file +10
-0+test_expect_success 'peeled tags are stored' ' + initialize && + test_commit file && + git tag -m "annotated tag" test_tag HEAD && + { + print_ref "refs/heads/primary" && + print_ref "refs/tags/file" && + print_ref "refs/tags/test_tag" && + print_ref "refs/tags/test_tag^{}" + } >expect &&
Maybe I'm missing something, but wouldn't this print_ref() helper be better as a "git for-each-ref --format" of some sort?
t/t0031-reftable.sh line 294
Quoted 5 lines
[...]
+. "$TEST_DIRECTORY"/lib-httpd.sht/t0031-reftable.sh new file +3
-0+start_httpd + +REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo"
Let's split these httpd-needing tests into another test file, see
https://lore.kernel.org/git/[email protected]/ for why.
t/t1409-avoid-packing-refs.sh test_description='avoid rewriting packed-refs unnecessarily' · line 11
Quoted 6 lines
[...]
t/t1409-avoid-packing-refs.sh +5
-0+if test_have_prereq !REFFILES +then + skip_all='skipping pack-refs tests; need files backend' + test_done +fi
Indent with spaces?
t/t1450-fsck.sh test_description='git fsck random collection of tests · line 16
Quoted 6 lines
t/t1450-fsck.sh +6
-0+if test_have_prereq !REFFILES +then + skip_all='skipping tests; incompatible with reftable' + test_done +fi +
Ditto.
(In general for issues noted above, I saw many more of some of them, including but not limited to this space formatting issue, but elided the patch after the first occurrences).
v4 cover Support reftable ref backend for Git
In reply to Han-Wen Nienhuys via GitGitGadgetThis is a version of the reftable series queued on top of my just-re-rolled fixes to the refs APIs, which it can make use of. For the base topics see:
https://lore.kernel.org/git/[email protected]/ https://lore.kernel.org/git/[email protected]/
For Han-Wen's v3 of this see:
https://lore.kernel.org/git/[email protected]/
I've got no desire to take over the reftable topic in its entirety, but think given the rationale in
https://lore.kernel.org/git/[email protected]/
(summarized in
https://lore.kernel.org/git/[email protected]/) that having the refs API fixes I noted above wait on the still-unstable reftable doesn't make sense.
I think that plan came about due to my non-responsiveness for the past couple of weeks (I was on vacation).
So I'm submitting this so Junio has something to pick up and put in hn/reftable which compiles and passes tests, this should clear up the outstanding issues in the "seen" branch.
As the range-diff shows the only changes are the addition of three new patches at the end. Those patches clearly need to be squashed into their respective preceding commits.
I'll let Han-Wen deal with that squashing in a presumed future v5 of this, assuming of course that Junio's happy with the plan of basing hn/reftable on the refs API fixes above.
I'm not sure that the fix I have in 27/28 is the right one, perhaps we've already got information about what the tip OID of the refname is at that point in git_reftable_reflog_expire() via some API I missed, but that fix works, and is clearly more correct than the outstanding segfault.
Han-Wen Nienhuys (24):
hash.h: provide constants for the hash IDs
init-db: set the_repository->hash_algo early on
reftable: RFC: add LICENSE
reftable: add error related functionality
reftable: utility functions
reftable: add blocksource, an abstraction for random access reads
reftable: (de)serialization for the polymorphic record type. Provide zlib's uncompress2 from compat/zlib-compat.c
reftable: reading/writing blocks
reftable: a generic binary tree implementation
reftable: write reftable files
reftable: generic interface to tables
reftable: read reftable files
reftable: reftable file level tests
reftable: add a heap-based priority queue for reftable records
reftable: add merged table view
reftable: implement refname validation
reftable: implement stack, a mutable database of reftable files.
reftable: add dump utility
refs: RFC: Reftable support for git-core
Add "test-tool dump-reftable" command.
t1301: document what needs to be done for reftable t1401,t2011: parameterize HEAD.lock for REFFILES
t1404: annotate test cases with REFFILES
SZEDER Gábor (1):
git-prompt: prepare for reftable refs backend
Ævar Arnfjörð Bjarmason (3):
reftable: fixup for new base topic 1/3
reftable: fixup for new base topic 2/3
reftable: fixup for new base topic 3/3
Documentation/config/extensions.txt | 9 + .../technical/repository-version.txt | 7 + Makefile | 54 +- builtin/clone.c | 5 +- builtin/init-db.c | 60 +- builtin/stash.c | 8 +- builtin/worktree.c | 27 +- cache.h | 8 +- ci/lib.sh | 1 + compat/.gitattributes | 1 + compat/zlib-uncompress2.c | 92 + config.mak.uname | 3 +- configure.ac | 13 + contrib/buildsystems/CMakeLists.txt | 14 +- contrib/buildsystems/Generators/Vcxproj.pm | 11 +- contrib/completion/git-prompt.sh | 7 +- contrib/workdir/git-new-workdir | 2 +- hash.h | 6 + object-file.c | 7 +- refs.c | 26 +- refs.h | 3 + refs/refs-internal.h | 1 + refs/reftable-backend.c | 1687 +++++++++++++++++ reftable/LICENSE | 31 + reftable/basics.c | 128 ++ reftable/basics.h | 60 + reftable/basics_test.c | 98 + reftable/block.c | 448 +++++ reftable/block.h | 127 ++ reftable/block_test.c | 120 ++ reftable/blocksource.c | 148 ++ reftable/blocksource.h | 22 + reftable/constants.h | 21 + reftable/dump.c | 107 ++ reftable/error.c | 41 + reftable/generic.c | 169 ++ reftable/generic.h | 32 + reftable/iter.c | 194 ++ reftable/iter.h | 69 + reftable/merged.c | 362 ++++ reftable/merged.h | 35 + reftable/merged_test.c | 292 +++ reftable/pq.c | 115 ++ reftable/pq.h | 32 + reftable/pq_test.c | 72 + reftable/publicbasics.c | 58 + reftable/reader.c | 801 ++++++++ reftable/reader.h | 66 + reftable/readwrite_test.c | 652 +++++++ reftable/record.c | 1212 ++++++++++++ reftable/record.h | 139 ++ reftable/record_test.c | 412 ++++ reftable/refname.c | 209 ++ reftable/refname.h | 29 + reftable/refname_test.c | 102 + reftable/reftable-blocksource.h | 49 + reftable/reftable-error.h | 62 + reftable/reftable-generic.h | 47 + reftable/reftable-iterator.h | 39 + reftable/reftable-malloc.h | 18 + reftable/reftable-merged.h | 72 + reftable/reftable-reader.h | 101 + reftable/reftable-record.h | 114 ++ reftable/reftable-stack.h | 128 ++ reftable/reftable-tests.h | 23 + reftable/reftable-writer.h | 148 ++ reftable/reftable.c | 115 ++ reftable/stack.c | 1396 ++++++++++++++ reftable/stack.h | 41 + reftable/stack_test.c | 948 +++++++++ reftable/system.h | 24 + reftable/test_framework.c | 23 + reftable/test_framework.h | 53 + reftable/tree.c | 63 + reftable/tree.h | 34 + reftable/tree_test.c | 61 + reftable/writer.c | 690 +++++++ reftable/writer.h | 50 + repository.c | 2 + repository.h | 3 + setup.c | 8 + t/helper/test-reftable.c | 21 + t/helper/test-tool.c | 4 +- t/helper/test-tool.h | 2 + t/t0031-reftable.sh | 316 +++ t/t0032-reftable-unittest.sh | 15 + t/t1301-shared-repo.sh | 8 +- t/t1401-symbolic-ref.sh | 11 +- t/t1404-update-ref-errors.sh | 56 +- t/t1409-avoid-packing-refs.sh | 6 + t/t1450-fsck.sh | 6 + t/t2011-checkout-invalid-head.sh | 11 +- t/t3210-pack-refs.sh | 6 + t/test-lib.sh | 7 +- 94 files changed, 13174 insertions(+), 62 deletions(-) create mode 100644 compat/.gitattributes create mode 100644 compat/zlib-uncompress2.c create mode 100644 refs/reftable-backend.c create mode 100644 reftable/LICENSE create mode 100644 reftable/basics.c create mode 100644 reftable/basics.h create mode 100644 reftable/basics_test.c create mode 100644 reftable/block.c create mode 100644 reftable/block.h create mode 100644 reftable/block_test.c create mode 100644 reftable/blocksource.c create mode 100644 reftable/blocksource.h create mode 100644 reftable/constants.h create mode 100644 reftable/dump.c create mode 100644 reftable/error.c create mode 100644 reftable/generic.c create mode 100644 reftable/generic.h 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/pq_test.c create mode 100644 reftable/publicbasics.c create mode 100644 reftable/reader.c create mode 100644 reftable/reader.h create mode 100644 reftable/readwrite_test.c 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-blocksource.h create mode 100644 reftable/reftable-error.h create mode 100644 reftable/reftable-generic.h create mode 100644 reftable/reftable-iterator.h create mode 100644 reftable/reftable-malloc.h create mode 100644 reftable/reftable-merged.h create mode 100644 reftable/reftable-reader.h create mode 100644 reftable/reftable-record.h create mode 100644 reftable/reftable-stack.h create mode 100644 reftable/reftable-tests.h create mode 100644 reftable/reftable-writer.h create mode 100644 reftable/reftable.c create mode 100644 reftable/stack.c create mode 100644 reftable/stack.h create mode 100644 reftable/stack_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 100644 reftable/writer.c create mode 100644 reftable/writer.h create mode 100644 t/helper/test-reftable.c create mode 100755 t/t0031-reftable.sh create mode 100755 t/t0032-reftable-unittest.sh
Range-diff against v3:
1: cad3c4835a2 = 1: 295ccff312f hash.h: provide constants for the hash IDs 2: 97aba3ae406 = 2: 2fb0fb20282 init-db: set the_repository->hash_algo early on 3: fca162dd676 = 3: 6cf0b244fc5 reftable: RFC: add LICENSE 4: 44923074a5a = 4: a0686356c11 reftable: add error related functionality 5: 2f2beb70078 = 5: 23ceb2e5723 reftable: utility functions 6: 79d4a23764d = 6: 9429aaf7c76 reftable: add blocksource, an abstraction for random access reads 7: 2c143c75cd5 = 7: f4cebccb9e0 reftable: (de)serialization for the polymorphic record type. 8: d92338467d6 = 8: e2f2729443b Provide zlib's uncompress2 from compat/zlib-compat.c 9: 74ac0b135fa = 9: 9d468fbdd07 reftable: reading/writing blocks 10: a2219670079 = 10: 7d8b8e3b76a reftable: a generic binary tree implementation 11: ac3063fd08c = 11: 7ec422318eb reftable: write reftable files 12: e0f3476555e = 12: df4fae30ceb reftable: generic interface to tables 13: f1fe338f67e = 13: 7e8a613206f reftable: read reftable files 14: 7da9a85c1db = 14: ebe55aa6295 reftable: reftable file level tests 15: 953590034a8 = 15: a9880fc1a10 reftable: add a heap-based priority queue for reftable records 16: 64fe3c8edc5 = 16: c073be56a6b reftable: add merged table view 17: acb0d435a20 = 17: 092b9715672 reftable: implement refname validation 18: 764d45fccd4 = 18: 374c22efbd9 reftable: implement stack, a mutable database of reftable files. 19: 88dbab683dc = 19: 007c9359f42 reftable: add dump utility 20: 3d57f7c4430 = 20: 8f948c0b257 refs: RFC: Reftable support for git-core 21: 460658a13cb = 21: 443bdebfb5d git-prompt: prepare for reftable refs backend 22: b305fcd49f1 = 22: f76e7a7bd10 Add "test-tool dump-reftable" command. 23: a44956d7b08 = 23: 6b62a8c52ae t1301: document what needs to be done for reftable 24: f0b7b1e2380 = 24: c926f1526aa t1401,t2011: parameterize HEAD.lock for REFFILES 25: 3110d6e6758 = 25: 0b3db9fc2d6 t1404: annotate test cases with REFFILES -: ----------- > 26: dde80a982c1 reftable: fixup for new base topic 1/3 -: ----------- > 27: c4f9fb42d9e reftable: fixup for new base topic 2/3 -: ----------- > 28: c863b03201c reftable: fixup for new base topic 3/3
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 1/28 hash.h: provide constants for the hash IDs
From: Han-Wen Nienhuys <[email protected]>
This will simplify referencing them from code that is not deeply integrated with Git, in particular, the reftable library.
--- hash.h | 6 ++++++ object-file.c | 7 ++----- 2 files changed, 8 insertions(+), 5 deletions(-)
hash.h +6 -0
@@ -95,12 +95,18 @@ static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *s/* Number of algorithms supported (including unknown). */ #define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1) +/* "sha1", big-endian */ +#define GIT_SHA1_FORMAT_ID 0x73686131 +/* The length in bytes and in hex digits of an object name (SHA-1 value). */ #define GIT_SHA1_RAWSZ 20#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)/* The block size of SHA-1. */ #define GIT_SHA1_BLKSZ 64 +/* "s256", big-endian */ +#define GIT_SHA256_FORMAT_ID 0x73323536 +/* The length in bytes and in hex digits of an object name (SHA-256 value). */ #define GIT_SHA256_RAWSZ 32#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
object-file.c +2 -5
@@ -164,7 +164,6 @@ static void git_hash_unknown_final_oid(struct object_id *oid, git_hash_ctx *ctx)BUG ("trying to finalize unknown hash" ); } -const struct git_hash_algo hash_algos[GIT_HASH_NALGOS ] = { {NULL ,
@@ -183,8 +182,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { }, {"sha1" , -/* "sha1", big-endian */ -0x73686131 , +GIT_SHA1_FORMAT_ID ,GIT_SHA1_RAWSZ ,GIT_SHA1_HEXSZ , GIT_SHA1_BLKSZ,
@@ -199,8 +197,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { }, {"sha256" , -/* "s256", big-endian */ -0x73323536 , +GIT_SHA256_FORMAT_ID ,GIT_SHA256_RAWSZ ,GIT_SHA256_HEXSZ , GIT_SHA256_BLKSZ,
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 2/28 init-db: set the_repository->hash_algo early on
In reply to Ævar Arnfjörð BjarmasonFrom: Han-Wen Nienhuys <[email protected]>
The reftable backend needs to know the hash algorithm for writing the initialization hash table.
The initial reftable contains a symref HEAD => "main" (or "master"), which is agnostic to the size of hash value, but this is an exceptional circumstance, and the reftable library does not cater to this exception. It insists that all tables in the stack have a consistent format ID for the hash algorithm.
Call set_repo_hash_algo directly after calling validate_hash_algorithm() (which reads $GIT_DEFAULT_HASH).
--- builtin/init-db.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
builtin/init-db.c +21 -0
@@ -425,6 +425,27 @@ int init_db(const char *git_dir, const char *real_git_dir,validate_hash_algorithm (&repo_fmt, hash); +/* +* At this point, the_repository we have in-core does not look +* anything like one that we would see initialized in an already +* working repository after calling setup_git_directory(). +* +* Calling repository.c::initialize_the_repository() may have +* prepared the .index .objects and .parsed_objects members, but +* other members like .gitdir, .commondir, etc. have not been +* initialized. +* +* Many API functions assume they are working with the_repository +* that has sensibly been initialized, but because we haven't +* really read from an existing repository, we need to hand-craft +* the necessary members of the structure to get out of this +* chicken-and-egg situation. +* +* For now, we update the hash algorithm member to what the +* validate_hash_algorithm() call decided for us. +*/ +repo_set_hash_algo (the_repository, repo_fmt.hash_algo); + reinit =create_default_files (template_dir, original_git_dir, initial_branch, &repo_fmt, flags &INIT_DB_QUIET );
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 3/28 reftable: RFC: add LICENSE
In reply to Ævar Arnfjörð BjarmasonFrom: Han-Wen Nienhuys <[email protected]>
The objective of this code is to be usable as a C library, so it can be reused in libgit2.
This is currently using a BSD license as it is the liberal license I could find, but this could be changed to whatever fits the stated goal above.
This code is currently imported from github.com/hanwen/reftable. Once this code lands in git.git, the C code will be removed from github.com/hanwen/reftable, and the git.git code will be the source of truth.
--- reftable/LICENSE | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 reftable/LICENSE
reftable/LICENSE new file +31 -0
@@ -0,0 +1,31 @@ +BSD License + +Copyright (c) 2020, Google LLC +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +* Neither the name of Google LLC nor the names of its contributors may +be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 4/28 reftable: add error related functionality
In reply to Ævar Arnfjörð BjarmasonFrom: Han-Wen Nienhuys <[email protected]>
The reftable/ directory is structured as a library, so it cannot crash on misuse. Instead, it returns an error codes.
In addition, the error code can be used to signal conditions from lower levels of the library to be handled by higher levels of the library. For example, a transaction might legitimately write an empty reftable file, but in that case, we'd want to shortcut the transaction overhead.
--- reftable/error.c | 41 ++++++++++++++++++++++++++ reftable/reftable-error.h | 62 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 reftable/error.c create mode 100644 reftable/reftable-error.h
reftable/error.c new file +41 -0
@@ -0,0 +1,41 @@ +/* +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 "reftable-error.h" + +#include <stdio.h> + +const char *reftable_error_str (int err) +{ +static char buf[250 ]; +switch (err) { +case REFTABLE_IO_ERROR : +return "I/O error" ; +case REFTABLE_FORMAT_ERROR : +return "corrupt reftable file" ; +case REFTABLE_NOT_EXIST_ERROR : +return "file does not exist" ; +case REFTABLE_LOCK_ERROR : +return "data is outdated" ; +case REFTABLE_API_ERROR : +return "misuse of the reftable API" ; +case REFTABLE_ZLIB_ERROR : +return "zlib failure" ; +case REFTABLE_NAME_CONFLICT : +return "file/directory conflict" ; +case REFTABLE_EMPTY_TABLE_ERROR : +return "wrote empty table" ; +case REFTABLE_REFNAME_ERROR : +return "invalid refname" ; +case -1 : +return "general error" ; +default : +snprintf (buf,sizeof (buf),"unknown error code %d" , err); +return buf; + } +}
reftable/reftable-error.h new file +62 -0
62 lines not on this page · raw message
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 5/28 reftable: utility functions
In reply to Ævar Arnfjörð BjarmasonFrom: Han-Wen Nienhuys <[email protected]>
This commit provides basic utility classes for the reftable library.
--- Makefile | 25 +++++- contrib/buildsystems/CMakeLists.txt | 14 ++- reftable/basics.c | 128 ++++++++++++++++++++++++++++ reftable/basics.h | 60 +++++++++++++ reftable/basics_test.c | 98 +++++++++++++++++++++ reftable/publicbasics.c | 58 +++++++++++++ reftable/reftable-malloc.h | 18 ++++ reftable/reftable-tests.h | 22 +++++ reftable/system.h | 24 ++++++ reftable/test_framework.c | 23 +++++ reftable/test_framework.h | 53 ++++++++++++ t/helper/test-reftable.c | 9 ++ t/helper/test-tool.c | 3 +- t/helper/test-tool.h | 1 + t/t0032-reftable-unittest.sh | 15 ++++ 15 files changed, 545 insertions(+), 6 deletions(-) create mode 100644 reftable/basics.c create mode 100644 reftable/basics.h create mode 100644 reftable/basics_test.c create mode 100644 reftable/publicbasics.c create mode 100644 reftable/reftable-malloc.h create mode 100644 reftable/reftable-tests.h create mode 100644 reftable/system.h create mode 100644 reftable/test_framework.c create mode 100644 reftable/test_framework.h create mode 100644 t/helper/test-reftable.c create mode 100755 t/t0032-reftable-unittest.sh
Makefile +22 -3
@@ -743,6 +743,7 @@ TEST_BUILTINS_OBJS += test-read-cache.o TEST_BUILTINS_OBJS += test-read-graph.o TEST_BUILTINS_OBJS += test-read-midx.o TEST_BUILTINS_OBJS += test-ref-store.o +TEST_BUILTINS_OBJS += test-reftable.o TEST_BUILTINS_OBJS += test-regex.o TEST_BUILTINS_OBJS += test-repository.o TEST_BUILTINS_OBJS += test-revision-walking.o
@@ -821,6 +822,8 @@ TEST_SHELL_PATH = $(SHELL_PATH) LIB_FILE = libgit.a XDIFF_LIB = xdiff/lib.a +REFTABLE_LIB = reftable/libreftable.a +REFTABLE_TEST_LIB = reftable/libreftable_test.a GENERATED_H += command-list.h GENERATED_H += config-list.h
@@ -1195,7 +1198,7 @@ THIRD_PARTY_SOURCES += compat/regex/% THIRD_PARTY_SOURCES += sha1collisiondetection/% THIRD_PARTY_SOURCES += sha1dc/% -GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) +GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) EXTLIBS = GIT_USER_AGENT = git/$(GIT_VERSION)
@@ -2442,7 +2445,15 @@ XDIFF_OBJS += xdiff/xutils.o .PHONY: xdiff-objs xdiff-objs: $(XDIFF_OBJS) +REFTABLE_OBJS += reftable/basics.o +REFTABLE_OBJS += reftable/error.o +REFTABLE_OBJS += reftable/publicbasics.o + +REFTABLE_TEST_OBJS += reftable/test_framework.o +REFTABLE_TEST_OBJS += reftable/basics_test.o + TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS)) + .PHONY: test-objs test-objs: $(TEST_OBJS)
@@ -2458,6 +2469,8 @@ OBJECTS += $(PROGRAM_OBJS) OBJECTS += $(TEST_OBJS) OBJECTS += $(XDIFF_OBJS) OBJECTS += $(FUZZ_OBJS) +OBJECTS += $(REFTABLE_OBJS) $(REFTABLE_TEST_OBJS) + ifndef NO_CURL OBJECTS += http.o http-walker.o remote-curl.o endif
@@ -2608,6 +2621,12 @@ $(LIB_FILE): $(LIB_OBJS) $(XDIFF_LIB): $(XDIFF_OBJS) $(QUIET_AR)$(AR) $(ARFLAGS) $@ $^ +$(REFTABLE_LIB): $(REFTABLE_OBJS) + $(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^ + +$(REFTABLE_TEST_LIB): $(REFTABLE_TEST_OBJS) + $(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^ + export DEFAULT_EDITOR DEFAULT_PAGER Documentation/GIT-EXCLUDED-PROGRAMS: FORCE
@@ -2895,7 +2914,7 @@ perf: all t/helper/test-tool$X: $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS)) -t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) +t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) $(REFTABLE_TEST_LIB) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS) check-sha1:: t/helper/test-tool$X
@@ -3225,7 +3244,7 @@ cocciclean: clean: profile-clean coverage-clean cocciclean $(RM) *.res $(RM) $(OBJECTS) - $(RM) $(LIB_FILE) $(XDIFF_LIB) + $(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB) $(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X $(RM) $(TEST_PROGRAMS) $(RM) $(FUZZ_PROGRAMS)
contrib/buildsystems/CMakeLists.txt +12 -2
@@ -640,6 +640,12 @@ parse_makefile_for_sources(libxdiff_SOURCES "XDIFF_OBJS") list(TRANSFORM libxdiff_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") add_library(xdiff STATIC ${libxdiff_SOURCES}) +#reftable +parse_makefile_for_sources(reftable_SOURCES "REFTABLE_OBJS") + +list(TRANSFORM reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") +add_library(reftable STATIC ${reftable_SOURCES}) + if(WIN32) if(NOT MSVC)#use windres when compiling with gcc and clang add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/git.res
@@ -662,7 +668,7 @@ endif() #link all required libraries to common-main add_library(common-main OBJECT ${CMAKE_SOURCE_DIR}/common-main.c) -target_link_libraries(common-main libgit xdiff ${ZLIB_LIBRARIES}) +target_link_libraries(common-main libgit xdiff reftable ${ZLIB_LIBRARIES}) if(Intl_FOUND) target_link_libraries(common-main ${Intl_LIBRARIES}) endif()
@@ -902,11 +908,15 @@ if(BUILD_TESTING) add_executable(test-fake-ssh ${CMAKE_SOURCE_DIR}/t/helper/test-fake-ssh.c) target_link_libraries(test-fake-ssh common-main) +#reftable-tests +parse_makefile_for_sources(test-reftable_SOURCES "REFTABLE_TEST_OBJS") +list(TRANSFORM test-reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") + #test-tool parse_makefile_for_sources(test-tool_SOURCES "TEST_BUILTINS_OBJS") list(TRANSFORM test-tool_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/t/helper/") -add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES}) +add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES} ${test-reftable_SOURCES}) target_link_libraries(test-tool common-main) set_target_properties(test-fake-ssh test-tool
reftable/basics.c new file +128 -0
128 lines not on this page · raw message
reftable/basics.h new file +60 -0
60 lines not on this page · raw message
reftable/basics_test.c new file +98 -0
98 lines not on this page · raw message
reftable/publicbasics.c new file +58 -0
58 lines not on this page · raw message
reftable/reftable-malloc.h new file +18 -0
@@ -0,0 +1,18 @@ +/* +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 REFTABLE_H +#define REFTABLE_H + +#include <stddef.h> + +/* Overrides the functions to use for memory management. */ +void reftable_set_alloc (void *(*malloc)(size_t ), +void *(*realloc)(void *,size_t ),void (*free)(void *)); + +#endif
reftable/reftable-tests.h new file +22 -0
@@ -0,0 +1,22 @@ +/* +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 REFTABLE_TESTS_H +#define REFTABLE_TESTS_H + +int basics_test_main (int argc,const char **argv); +int block_test_main (int argc,const char **argv); +int merged_test_main (int argc,const char **argv); +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 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); + +#endif
reftable/system.h new file +24 -0
@@ -0,0 +1,24 @@ +/* +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 SYSTEM_H +#define SYSTEM_H + +/* This header glues the reftable library to the rest of Git */ + +#include "git-compat-util.h" +#include "strbuf.h" +#include "hash.h" /* hash ID, sizes.*/ +#include "dir.h" /* remove_dir_recursively, for tests.*/ + +#include <zlib.h> + +struct strbuf ; +int hash_size (uint32_t id); + +#endif
reftable/test_framework.c new file +23 -0
@@ -0,0 +1,23 @@ +/* +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 "system.h" +#include "test_framework.h" + +#include "basics.h" + +void set_test_hash (uint8_t *p,int i) +{ +memset (p, (uint8_t )i,hash_size (GIT_SHA1_FORMAT_ID )); +} + +ssize_t strbuf_add_void (void *b,const void *data,size_t sz) +{ +strbuf_add (b, data, sz); +return sz; +}
reftable/test_framework.h new file +53 -0
53 lines not on this page · raw message
t/helper/test-reftable.c new file +9 -0
@@ -0,0 +1,9 @@ +#include "reftable/reftable-tests.h" +#include "test-tool.h" + +int cmd__reftable (int argc,const char **argv) +{ +basics_test_main (argc, argv); + +return 0 ; +}
t/helper/test-tool.c +2 -1
@@ -53,13 +53,14 @@ static struct test_cmd cmds[] = { { "pcre2-config", cmd__pcre2_config }, { "pkt-line", cmd__pkt_line }, { "prio-queue", cmd__prio_queue }, - { "proc-receive", cmd__proc_receive}, + { "proc-receive", cmd__proc_receive }, { "progress", cmd__progress }, { "reach", cmd__reach }, { "read-cache", cmd__read_cache }, { "read-graph", cmd__read_graph }, { "read-midx", cmd__read_midx }, { "ref-store", cmd__ref_store }, + { "reftable", cmd__reftable }, { "regex", cmd__regex }, { "repository", cmd__repository }, { "revision-walking", cmd__revision_walking },
t/helper/test-tool.h +1 -0
@@ -49,6 +49,7 @@ int cmd__read_cache(int argc, const char **argv);int cmd__read_graph (int argc,const char **argv);int cmd__read_midx (int argc,const char **argv);int cmd__ref_store (int argc,const char **argv); +int cmd__reftable (int argc,const char **argv);int cmd__regex (int argc,const char **argv);int cmd__repository (int argc,const char **argv);int cmd__revision_walking (int argc,const char **argv);
t/t0032-reftable-unittest.sh new file +15 -0
@@ -0,0 +1,15 @@ +#!/bin/sh +# +# Copyright (c) 2020 Google LLC +# + +test_description='reftable unittests' + +. ./test-lib.sh + +test_expect_success 'unittests' ' + TMPDIR=$(pwd) && export TMPDIR && + test-tool reftable +' + +test_done
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 6/28 reftable: add blocksource, an abstraction for random access reads
In reply to Ævar Arnfjörð BjarmasonFrom: Han-Wen Nienhuys <[email protected]>
The reftable format is usually used with files for storage. However, we abstract away this using the blocksource data structure. This has two advantages:
* log blocks are zlib compressed, and handling them is simplified if we can discard byte segments from within the block layer.
* for unittests, it is useful to read and write in-memory. The blocksource allows us to abstract the data away from on-disk files.
--- Makefile | 1 + reftable/blocksource.c | 148 ++++++++++++++++++++++++++++++++ reftable/blocksource.h | 22 +++++ reftable/reftable-blocksource.h | 49 +++++++++++ 4 files changed, 220 insertions(+) create mode 100644 reftable/blocksource.c create mode 100644 reftable/blocksource.h create mode 100644 reftable/reftable-blocksource.h
Makefile +1 -0
@@ -2447,6 +2447,7 @@ xdiff-objs: $(XDIFF_OBJS) REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o +REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_TEST_OBJS += reftable/test_framework.o
reftable/blocksource.c new file +148 -0
148 lines not on this page · raw message
reftable/blocksource.h new file +22 -0
@@ -0,0 +1,22 @@ +/* +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 BLOCKSOURCE_H +#define BLOCKSOURCE_H + +#include "system.h" + +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/reftable-blocksource.h new file +49 -0
49 lines not on this page · raw message
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 7/28 reftable: (de)serialization for the polymorphic record type.
In reply to Ævar Arnfjörð BjarmasonFrom: Han-Wen Nienhuys <[email protected]>
The reftable format is structured as a sequence of blocks, and each block contains a sequence of prefix-compressed key-value records. There are 4 types of records, and they have similarities in how they must be handled. This is achieved by introducing a polymorphic 'record' type that encapsulates ref, log, index and object records.
--- Makefile | 2 + reftable/constants.h | 21 + reftable/record.c | 1212 ++++++++++++++++++++++++++++++++++++ reftable/record.h | 139 +++++ reftable/record_test.c | 412 ++++++++++++ reftable/reftable-record.h | 114 ++++ t/helper/test-reftable.c | 2 +- 7 files changed, 1901 insertions(+), 1 deletion(-) create mode 100644 reftable/constants.h create mode 100644 reftable/record.c create mode 100644 reftable/record.h create mode 100644 reftable/record_test.c create mode 100644 reftable/reftable-record.h
Makefile +2 -0
@@ -2449,7 +2449,9 @@ REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/record.o +REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/basics_test.o
reftable/constants.h new file +21 -0
@@ -0,0 +1,21 @@ +/* +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 CONSTANTS_H +#define CONSTANTS_H + +#define BLOCK_TYPE_LOG 'g' +#define BLOCK_TYPE_INDEX 'i' +#define BLOCK_TYPE_REF 'r' +#define BLOCK_TYPE_OBJ 'o' +#define BLOCK_TYPE_ANY 0 + +#define MAX_RESTARTS ((1 << 16) - 1) +#define DEFAULT_BLOCK_SIZE 4096 + +#endif
reftable/record.c new file +1212 -0
1,212 lines not on this page · raw message
reftable/record.h new file +139 -0
139 lines not on this page · raw message
reftable/record_test.c new file +412 -0
412 lines not on this page · raw message
reftable/reftable-record.h new file +114 -0
114 lines not on this page · raw message
t/helper/test-reftable.c +1 -1
@@ -4,6 +4,6 @@int cmd__reftable (int argc,const char **argv) {basics_test_main (argc, argv); - +record_test_main (argc, argv);return 0 ; }
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 8/28 Provide zlib's uncompress2 from compat/zlib-compat.c
In reply to Ævar Arnfjörð BjarmasonFrom: Han-Wen Nienhuys <[email protected]>
This will be needed for reading reflog blocks in reftable.
--- Makefile | 7 +++ ci/lib.sh | 1 + compat/.gitattributes | 1 + compat/zlib-uncompress2.c | 92 +++++++++++++++++++++++++++++++++++++++ config.mak.uname | 1 + configure.ac | 13 ++++++ 6 files changed, 115 insertions(+) create mode 100644 compat/.gitattributes create mode 100644 compat/zlib-uncompress2.c
Makefile +7 -0
@@ -256,6 +256,8 @@ all:: # # Define NO_DEFLATE_BOUND if your zlib does not have deflateBound. # +# Define NO_UNCOMPRESS2 if your zlib does not have uncompress2. +# # Define NO_NORETURN if using buggy versions of gcc 4.6+ and profile feedback, # as the compiler can crash (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49299) #
@@ -1738,6 +1740,11 @@ ifdef NO_DEFLATE_BOUND BASIC_CFLAGS += -DNO_DEFLATE_BOUND endif +ifdef NO_UNCOMPRESS2 + BASIC_CFLAGS += -DNO_UNCOMPRESS2 + REFTABLE_OBJS += compat/zlib-uncompress2.o +endif + ifdef NO_POSIX_GOODIES BASIC_CFLAGS += -DNO_POSIX_GOODIES endif
ci/lib.sh +1 -0
@@ -224,6 +224,7 @@ linux-gcc-default) ;; Linux32) CC=gcc + MAKEFLAGS="$MAKEFLAGS NO_UNCOMPRESS2=1" ;; linux-musl) CC=gcc
compat/.gitattributes new file +1 -0
@@ -0,0 +1 @@ +/zlib-uncompress2.c whitespace=-indent-with-non-tab,-trailing-space
compat/zlib-uncompress2.c new file +92 -0
92 lines not on this page · raw message
config.mak.uname +1 -0
@@ -256,6 +256,7 @@ ifeq ($(uname_S),FreeBSD) FILENO_IS_A_MACRO = UnfortunatelyYes endif ifeq ($(uname_S),OpenBSD) + NO_UNCOMPRESS2 = YesPlease NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease USE_ST_TIMESPEC = YesPlease
configure.ac +13 -0
@@ -672,9 +672,22 @@ AC_LINK_IFELSE([ZLIBTEST_SRC], NO_DEFLATE_BOUND=yes]) LIBS="$old_LIBS" +AC_DEFUN([ZLIBTEST_UNCOMPRESS2_SRC], [ +AC_LANG_PROGRAM([#include <zlib.h>], + [uncompress2(NULL,NULL,NULL,NULL);])]) +AC_MSG_CHECKING([for uncompress2 in -lz]) +old_LIBS="$LIBS" +LIBS="$LIBS -lz" +AC_LINK_IFELSE([ZLIBTEST_UNCOMPRESS2_SRC], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + NO_UNCOMPRESS2=yes]) +LIBS="$old_LIBS" + GIT_UNSTASH_FLAGS($ZLIB_PATH) GIT_CONF_SUBST([NO_DEFLATE_BOUND]) +GIT_CONF_SUBST([NO_UNCOMPRESS2]) # # Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 9/28 reftable: reading/writing blocks
In reply to Ævar Arnfjörð BjarmasonFrom: Han-Wen Nienhuys <[email protected]>
The reftable format is structured as a sequence of block. Within a block, records are prefix compressed, with an index of offsets for fully expand keys to enable binary search within blocks.
This commit provides the logic to read and write these blocks.
--- Makefile | 2 + reftable/block.c | 448 +++++++++++++++++++++++++++++++++++++++ reftable/block.h | 127 +++++++++++ reftable/block_test.c | 120 +++++++++++ t/helper/test-reftable.c | 1 + 5 files changed, 698 insertions(+) create mode 100644 reftable/block.c create mode 100644 reftable/block.h create mode 100644 reftable/block_test.c
Makefile +2 -0
@@ -2454,10 +2454,12 @@ xdiff-objs: $(XDIFF_OBJS) REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o +REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o +REFTABLE_TEST_OBJS += reftable/block_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/basics_test.o
reftable/block.c new file +448 -0
448 lines not on this page · raw message
reftable/block.h new file +127 -0
127 lines not on this page · raw message
reftable/block_test.c new file +120 -0
120 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -4,6 +4,7 @@int cmd__reftable (int argc,const char **argv) {basics_test_main (argc, argv); +block_test_main (argc, argv);record_test_main (argc, argv);return 0 ; }
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 10/28 reftable: a generic binary tree implementation
In reply to Ævar Arnfjörð BjarmasonFrom: Han-Wen Nienhuys <[email protected]>
The reftable format includes support for an (OID => ref) map. This map can speed up visibility and reachability checks. In particular, various operations along the fetch/push path within Gerrit have ben sped up by using this structure.
The map is constructed with help of a binary tree. Object IDs are hashes, so they are uniformly distributed. Hence, the tree does not attempt forced rebalancing.
--- Makefile | 4 ++- reftable/tree.c | 63 ++++++++++++++++++++++++++++++++++++++++ reftable/tree.h | 34 ++++++++++++++++++++++ reftable/tree_test.c | 61 ++++++++++++++++++++++++++++++++++++++ t/helper/test-reftable.c | 1 + 5 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 reftable/tree.c create mode 100644 reftable/tree.h create mode 100644 reftable/tree_test.c
Makefile +3 -1
@@ -2458,11 +2458,13 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o +REFTABLE_OBJS += reftable/tree.o +REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o -REFTABLE_TEST_OBJS += reftable/basics_test.o +REFTABLE_TEST_OBJS += reftable/tree_test.o TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
reftable/tree.c new file +63 -0
63 lines not on this page · raw message
reftable/tree.h new file +34 -0
@@ -0,0 +1,34 @@ +/* +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 TREE_H +#define TREE_H + +/* tree_node is a generic binary search tree. */ +struct tree_node { +void *key; +struct tree_node *left, *right; +}; + +/* looks for `key` in `rootp` using `compare` as comparison function. If insert +* is set, insert the key if it's not found. Else, return NULL. +*/ +struct tree_node *tree_search (void *key,struct tree_node **rootp, +int (*compare)(const void *,const void *), +int insert); + +/* performs an infix walk of the tree. */ +void infix_walk (struct tree_node *t,void (*action)(void *arg,void *key), +void *arg); + +/* +* deallocates the tree nodes recursively. Keys should be deallocated separately +* by walking over the tree. */ +void tree_free (struct tree_node *t); + +#endif
reftable/tree_test.c new file +61 -0
61 lines not on this page · raw message
t/helper/test-reftable.c +1 -0
@@ -6,5 +6,6 @@ int cmd__reftable(int argc, const char **argv)basics_test_main (argc, argv);block_test_main (argc, argv);record_test_main (argc, argv); +tree_test_main (argc, argv);return 0 ; }
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 12/28 reftable: generic interface to tables
In reply to Ævar Arnfjörð BjarmasonFrom: Han-Wen Nienhuys <[email protected]>
--- Makefile | 3 + reftable/generic.c | 169 +++++++++++++++++++++++++++++++++++ reftable/generic.h | 32 +++++++ reftable/reftable-generic.h | 47 ++++++++++ reftable/reftable-iterator.h | 39 ++++++++ reftable/reftable.c | 115 ++++++++++++++++++++++++ 6 files changed, 405 insertions(+) create mode 100644 reftable/generic.c create mode 100644 reftable/generic.h create mode 100644 reftable/reftable-generic.h create mode 100644 reftable/reftable-iterator.h create mode 100644 reftable/reftable.c
Makefile +3 -0
@@ -2458,6 +2458,9 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/record.o +REFTABLE_OBJS += reftable/refname.o +REFTABLE_OBJS += reftable/generic.o +REFTABLE_OBJS += reftable/stack.o REFTABLE_OBJS += reftable/tree.o REFTABLE_OBJS += reftable/writer.o
reftable/generic.c new file +169 -0
169 lines not on this page · raw message
reftable/generic.h new file +32 -0
@@ -0,0 +1,32 @@ +/* +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 GENERIC_H +#define GENERIC_H + +#include "record.h" +#include "reftable-generic.h" + +/* generic interface to reftables */ +struct reftable_table_vtable { +int (*seek_record)(void *tab,struct reftable_iterator *it, +struct reftable_record *); +uint32_t (*hash_id)(void *tab); +uint64_t (*min_update_index)(void *tab); +uint64_t (*max_update_index)(void *tab); +}; + +struct reftable_iterator_vtable { +int (*next)(void *iter_arg,struct reftable_record *rec); +void (*close)(void *iter_arg); +}; + +void iterator_set_empty (struct reftable_iterator *it); +int iterator_next (struct reftable_iterator *it,struct reftable_record *rec); + +#endif
reftable/reftable-generic.h new file +47 -0
47 lines not on this page · raw message
reftable/reftable-iterator.h new file +39 -0
@@ -0,0 +1,39 @@ +/* +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 REFTABLE_ITERATOR_H +#define REFTABLE_ITERATOR_H + +#include "reftable-record.h" + +struct reftable_iterator_vtable ; + +/* iterator is the generic interface for walking over data stored in a +* reftable. +*/ +struct reftable_iterator { +struct reftable_iterator_vtable *ops; +void *iter_arg; +}; + +/* reads the next reftable_ref_record. Returns < 0 for error, 0 for OK and > 0: +* end of iteration. +*/ +int reftable_iterator_next_ref (struct reftable_iterator *it, +struct reftable_ref_record *ref); + +/* reads the next reftable_log_record. Returns < 0 for error, 0 for OK and > 0: +* end of iteration. +*/ +int reftable_iterator_next_log (struct reftable_iterator *it, +struct reftable_log_record *log); + +/* releases resources associated with an iterator. */ +void reftable_iterator_destroy (struct reftable_iterator *it); + +#endif
reftable/reftable.c new file +115 -0
115 lines not on this page · raw message
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 13/28 reftable: read reftable files
In reply to Ævar Arnfjörð BjarmasonFrom: Han-Wen Nienhuys <[email protected]>
This supports reading a single reftable file.
The commit introduces an abstract iterator type, which captures the usecases both of reading individual refs, and iterating over a segment of the ref namespace.
--- Makefile | 2 + reftable/iter.c | 194 +++++++++ reftable/iter.h | 69 ++++ reftable/reader.c | 801 +++++++++++++++++++++++++++++++++++++ reftable/reader.h | 66 +++ reftable/reftable-reader.h | 101 +++++ 6 files changed, 1233 insertions(+) create mode 100644 reftable/iter.c create mode 100644 reftable/iter.h create mode 100644 reftable/reader.c create mode 100644 reftable/reader.h create mode 100644 reftable/reftable-reader.h
Makefile +2 -0
@@ -2456,7 +2456,9 @@ REFTABLE_OBJS += reftable/basics.o REFTABLE_OBJS += reftable/error.o REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o +REFTABLE_OBJS += reftable/iter.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/reader.o REFTABLE_OBJS += reftable/record.o REFTABLE_OBJS += reftable/refname.o REFTABLE_OBJS += reftable/generic.o
reftable/iter.c new file +194 -0
194 lines not on this page · raw message
reftable/iter.h new file +69 -0
69 lines not on this page · raw message
reftable/reader.c new file +801 -0
801 lines not on this page · raw message
reftable/reader.h new file +66 -0
66 lines not on this page · raw message
reftable/reftable-reader.h new file +101 -0
101 lines not on this page · raw message
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 14/28 reftable: reftable file level tests
In reply to Ævar Arnfjörð BjarmasonFrom: Han-Wen Nienhuys <[email protected]>
With support for reading and writing files in place, we can construct files (in memory) and attempt to read them back.
Because some sections of the format are optional (eg. indices, log entries), we have to exercise this code using multiple sizes of input data
--- Makefile | 1 + reftable/readwrite_test.c | 652 ++++++++++++++++++++++++++++++++++++++ reftable/reftable-tests.h | 2 +- t/helper/test-reftable.c | 1 + 4 files changed, 655 insertions(+), 1 deletion(-) create mode 100644 reftable/readwrite_test.c
Makefile +1 -0
@@ -2469,6 +2469,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o REFTABLE_TEST_OBJS += reftable/record_test.o +REFTABLE_TEST_OBJS += reftable/readwrite_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o REFTABLE_TEST_OBJS += reftable/tree_test.o
reftable/readwrite_test.c new file +652 -0
652 lines not on this page · raw message
reftable/reftable-tests.h +1 -1
@@ -14,7 +14,7 @@ int block_test_main(int argc, const char **argv);int merged_test_main (int argc,const char **argv);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 readwrite_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);
t/helper/test-reftable.c +1 -0
@@ -6,6 +6,7 @@ int cmd__reftable(int argc, const char **argv)basics_test_main (argc, argv);block_test_main (argc, argv);record_test_main (argc, argv); +readwrite_test_main (argc, argv);tree_test_main (argc, argv);return 0 ; }
Signature · 1 line
2.33.0.662.gbaddc25a55e
PATCH v4 15/28 reftable: add a heap-based priority queue for reftable records
In reply to Ævar Arnfjörð BjarmasonFrom: Han-Wen Nienhuys <[email protected]>
This is needed to create a merged view multiple reftables
--- Makefile | 2 + reftable/pq.c | 115 ++++++++++++++++++++++++++++++++++++++ reftable/pq.h | 32 +++++++++++ reftable/pq_test.c | 72 ++++++++++++++++++++++++ reftable/reftable-tests.h | 1 + t/helper/test-reftable.c | 1 + 6 files changed, 223 insertions(+) create mode 100644 reftable/pq.c create mode 100644 reftable/pq.h create mode 100644 reftable/pq_test.c
Makefile +2 -0
@@ -2458,6 +2458,7 @@ REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/iter.o REFTABLE_OBJS += reftable/publicbasics.o +REFTABLE_OBJS += reftable/pq.o REFTABLE_OBJS += reftable/reader.o REFTABLE_OBJS += reftable/record.o REFTABLE_OBJS += reftable/refname.o
@@ -2468,6 +2469,7 @@ REFTABLE_OBJS += reftable/writer.o REFTABLE_TEST_OBJS += reftable/basics_test.o REFTABLE_TEST_OBJS += reftable/block_test.o +REFTABLE_TEST_OBJS += reftable/pq_test.o REFTABLE_TEST_OBJS += reftable/record_test.o REFTABLE_TEST_OBJS += reftable/readwrite_test.o REFTABLE_TEST_OBJS += reftable/test_framework.o
reftable/pq.c new file +115 -0
115 lines not on this page · raw message
reftable/pq.h new file +32 -0
@@ -0,0 +1,32 @@ +/* +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 PQ_H +#define PQ_H + +#include "record.h" + +struct pq_entry { +int index; +struct reftable_record rec; +}; + +struct merged_iter_pqueue { +struct pq_entry *heap; +size_t len; +size_t cap; +}; + +struct pq_entry merged_iter_pqueue_top (struct merged_iter_pqueue pq); +int merged_iter_pqueue_is_empty (struct merged_iter_pqueue pq); +void merged_iter_pqueue_check (struct merged_iter_pqueue pq); +struct pq_entry merged_iter_pqueue_remove (struct merged_iter_pqueue *pq); +void merged_iter_pqueue_add (struct merged_iter_pqueue *pq,struct pq_entry e); +void merged_iter_pqueue_release (struct merged_iter_pqueue *pq); + +#endif
reftable/pq_test.c new file +72 -0
72 lines not on this page · raw message
reftable/reftable-tests.h +1 -0
@@ -12,6 +12,7 @@ license that can be found in the LICENSE file or atint basics_test_main (int argc,const char **argv);int block_test_main (int argc,const char **argv);int merged_test_main (int argc,const char **argv); +int pq_test_main (int argc,const char **argv);int record_test_main (int argc,const char **argv);int refname_test_main (int argc,const char **argv);int readwrite_test_main (int argc,const char **argv);
t/helper/test-reftable.c +1 -0
@@ -5,6 +5,7 @@ int cmd__reftable(int argc, const char **argv) {basics_test_main (argc, argv);block_test_main (argc, argv); +pq_test_main (argc, argv);record_test_main (argc, argv);readwrite_test_main (argc, argv);tree_test_main (argc, argv);
Signature · 1 line
2.33.0.662.gbaddc25a55e