Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: git/git
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 35f40385e441d5aa885f5aa813539d5ed9dc2d26
Choose a base ref
...
head repository: git/git
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 988e7f5e952bbb7b6ae885f4da744f536f22693f
Choose a head ref
  • 8 commits
  • 37 files changed
  • 2 contributors

Commits on Oct 23, 2024

  1. Merge branch 'ps/reftable-strbuf' into ps/reftable-detach

    * ps/reftable-strbuf:
      reftable: handle trivial `reftable_buf` errors
      reftable/stack: adapt `stack_filename()` to handle allocation failures
      reftable/record: adapt `reftable_record_key()` to handle allocation failures
      reftable/stack: adapt `format_name()` to handle allocation failures
      t/unit-tests: check for `reftable_buf` allocation errors
      reftable/blocksource: adapt interface name
      reftable: convert from `strbuf` to `reftable_buf`
      reftable/basics: provide new `reftable_buf` interface
      reftable: stop using `strbuf_addf()`
      reftable: stop using `strbuf_addbuf()`
    ttaylorr committed Oct 23, 2024
    Copy the full SHA
    88d21e3 View commit details

Commits on Nov 19, 2024

  1. reftable/system: move "dir.h" to its only user

    We still include "dir.h" in "reftable/system.h" even though it is not
    used by anything but by a single unit test. Move it over into that unit
    test so that we don't accidentally use any functionality provided by it
    in the reftable codebase.
    
    Signed-off-by: Patrick Steinhardt <ps@pks.im>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    pks-t authored and gitster committed Nov 19, 2024
    Copy the full SHA
    17e8039 View commit details
  2. reftable: explicitly handle hash format IDs

    The hash format IDs are used for two different things across the
    reftable codebase:
    
      - They are used as a 32 bit unsigned integer when reading and writing
        the header in order to identify the hash function.
    
      - They are used internally to identify which hash function is in use.
    
    When one only considers the second usecase one might think that one can
    easily change the representation of those hash IDs. But because those
    IDs end up in the reftable header and footer on disk it is important
    that those never change.
    
    Create separate constants `REFTABLE_FORMAT_ID_*` and use them in
    contexts where we read or write reftable headers. This serves multiple
    purposes:
    
      - It allows us to more easily discern cases where we actually use
        those constants for the on-disk format.
    
      - It detangles us from the same constants that are defined in
        libgit.a, which is another required step to convert the reftable
        library to become standalone.
    
      - It makes the next step easier where we stop using `GIT_*_FORMAT_ID`
        constants in favor of a custom enum.
    
    Signed-off-by: Patrick Steinhardt <ps@pks.im>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    pks-t authored and gitster committed Nov 19, 2024
    Copy the full SHA
    88e2972 View commit details
  3. reftable/system: stop depending on "hash.h"

    We include "hash.h" in "reftable/system.h" such that we can use hash
    format IDs as well as the raw size of SHA1 and SHA256. As we are in the
    process of converting the reftable library to become standalone we of
    course cannot rely on those constants anymore.
    
    Introduce a new `enum reftable_hash` to replace internal uses of the
    hash format IDs and new constants that replace internal uses of the hash
    size. Adapt the reftable backend to set up the correct hash function.
    
    Signed-off-by: Patrick Steinhardt <ps@pks.im>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    pks-t authored and gitster committed Nov 19, 2024
    Copy the full SHA
    c2f0823 View commit details
  4. reftable/stack: stop using fsync_component() directly

    We're executing `fsync_component()` directly in the reftable library so
    that we can fsync data to disk depending on "core.fsync". But as we're
    in the process of converting the reftable library to become standalone
    we cannot use that function in the library anymore.
    
    Refactor the code such that users of the library can inject a custom
    fsync function via the write options. This allows us to get rid of the
    dependency on "write-or-die.h".
    
    Signed-off-by: Patrick Steinhardt <ps@pks.im>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    pks-t authored and gitster committed Nov 19, 2024
    Copy the full SHA
    86b770b View commit details
  5. reftable/system: provide thin wrapper for tempfile subsystem

    We use the tempfile subsystem to write temporary tables, but given that
    we're in the process of converting the reftable library to become
    standalone we cannot use this subsystem directly anymore. While we could
    in theory convert the code to use mkstemp(3p) instead, we'd lose access
    to our infrastructure that automatically prunes tempfiles via atexit(3p)
    or signal handlers.
    
    Provide a thin wrapper for the tempfile subsystem instead. Like this,
    the compatibility shim is fully self-contained in "reftable/system.c".
    Downstream users of the reftable library would have to implement their
    own tempfile shims by replacing "system.c" with a custom version.
    
    Signed-off-by: Patrick Steinhardt <ps@pks.im>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    pks-t authored and gitster committed Nov 19, 2024
    Copy the full SHA
    01e4994 View commit details
  6. reftable/stack: drop only use of get_locked_file_path()

    We've got a single callsite where we call `get_locked_file_path()`. As
    we're about to convert our usage of the lockfile subsystem to instead be
    used via a compatibility shim we'd have to implement more logic for this
    single callsite. While that would be okay if Git was the only supposed
    user of the reftable library, it's a bit more awkward when considering
    that we have to reimplement this functionality for every user of the
    library eventually.
    
    Refactor the code such that we don't call `get_locked_file_path()`
    anymore.
    
    Signed-off-by: Patrick Steinhardt <ps@pks.im>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    pks-t authored and gitster committed Nov 19, 2024
    Copy the full SHA
    6361226 View commit details
  7. reftable/system: provide thin wrapper for lockfile subsystem

    We use the lockfile subsystem to write lockfiles for "tables.list". As
    with the tempfile subsystem, the lockfile subsystem also hooks into our
    infrastructure to prune stale locks via atexit(3p) or signal handlers.
    
    Furthermore, the lockfile subsystem also handles locking timeouts, which
    do add quite a bit of logic. Having to reimplement that in the context
    of Git wouldn't make a whole lot of sense, and it is quite likely that
    downstream users of the reftable library may have a better idea for how
    exactly to implement timeouts.
    
    So again, provide a thin wrapper for the lockfile subsystem instead such
    that the compatibility shim is fully self-contained.
    
    Signed-off-by: Patrick Steinhardt <ps@pks.im>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    pks-t authored and gitster committed Nov 19, 2024
    Copy the full SHA
    988e7f5 View commit details
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -2722,6 +2722,7 @@ REFTABLE_OBJS += reftable/pq.o
REFTABLE_OBJS += reftable/reader.o
REFTABLE_OBJS += reftable/record.o
REFTABLE_OBJS += reftable/stack.o
REFTABLE_OBJS += reftable/system.o
REFTABLE_OBJS += reftable/tree.o
REFTABLE_OBJS += reftable/writer.o

19 changes: 18 additions & 1 deletion refs/reftable-backend.c
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
#include "../object.h"
#include "../path.h"
#include "../refs.h"
#include "../reftable/reftable-basics.h"
#include "../reftable/reftable-stack.h"
#include "../reftable/reftable-record.h"
#include "../reftable/reftable-error.h"
@@ -23,6 +24,7 @@
#include "../setup.h"
#include "../strmap.h"
#include "../trace2.h"
#include "../write-or-die.h"
#include "parse.h"
#include "refs-internal.h"

@@ -272,6 +274,11 @@ static int reftable_be_config(const char *var, const char *value,
return 0;
}

static int reftable_be_fsync(int fd)
{
return fsync_component(FSYNC_COMPONENT_REFERENCE, fd);
}

static struct ref_store *reftable_be_init(struct repository *repo,
const char *gitdir,
unsigned int store_flags)
@@ -289,11 +296,21 @@ static struct ref_store *reftable_be_init(struct repository *repo,
refs->store_flags = store_flags;
refs->log_all_ref_updates = repo_settings_get_log_all_ref_updates(repo);

refs->write_options.hash_id = repo->hash_algo->format_id;
switch (repo->hash_algo->format_id) {
case GIT_SHA1_FORMAT_ID:
refs->write_options.hash_id = REFTABLE_HASH_SHA1;
break;
case GIT_SHA256_FORMAT_ID:
refs->write_options.hash_id = REFTABLE_HASH_SHA256;
break;
default:
BUG("unknown hash algorithm %d", repo->hash_algo->format_id);
}
refs->write_options.default_permissions = calc_shared_perm(0666 & ~mask);
refs->write_options.disable_auto_compact =
!git_env_bool("GIT_TEST_REFTABLE_AUTOCOMPACTION", 1);
refs->write_options.lock_timeout_ms = 100;
refs->write_options.fsync = reftable_be_fsync;

git_config(reftable_be_config, &refs->write_options);

89 changes: 82 additions & 7 deletions reftable/basics.c
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ license that can be found in the LICENSE file or at
#define REFTABLE_ALLOW_BANNED_ALLOCATORS
#include "basics.h"
#include "reftable-basics.h"
#include "reftable-error.h"

static void *(*reftable_malloc_ptr)(size_t sz);
static void *(*reftable_realloc_ptr)(void *, size_t);
@@ -69,6 +70,79 @@ void reftable_set_alloc(void *(*malloc)(size_t),
reftable_free_ptr = free;
}

void reftable_buf_init(struct reftable_buf *buf)
{
struct reftable_buf empty = REFTABLE_BUF_INIT;
*buf = empty;
}

void reftable_buf_release(struct reftable_buf *buf)
{
reftable_free(buf->buf);
reftable_buf_init(buf);
}

void reftable_buf_reset(struct reftable_buf *buf)
{
if (buf->alloc) {
buf->len = 0;
buf->buf[0] = '\0';
}
}

int reftable_buf_setlen(struct reftable_buf *buf, size_t len)
{
if (len > buf->len)
return -1;
if (len == buf->len)
return 0;
buf->buf[len] = '\0';
buf->len = len;
return 0;
}

int reftable_buf_cmp(const struct reftable_buf *a, const struct reftable_buf *b)
{
size_t len = a->len < b->len ? a->len : b->len;
if (len) {
int cmp = memcmp(a->buf, b->buf, len);
if (cmp)
return cmp;
}
return a->len < b->len ? -1 : a->len != b->len;
}

int reftable_buf_add(struct reftable_buf *buf, const void *data, size_t len)
{
size_t newlen = buf->len + len;

if (newlen + 1 > buf->alloc) {
char *reallocated = buf->buf;
REFTABLE_ALLOC_GROW(reallocated, newlen + 1, buf->alloc);
if (!reallocated)
return REFTABLE_OUT_OF_MEMORY_ERROR;
buf->buf = reallocated;
}

memcpy(buf->buf + buf->len, data, len);
buf->buf[newlen] = '\0';
buf->len = newlen;

return 0;
}

int reftable_buf_addstr(struct reftable_buf *buf, const char *s)
{
return reftable_buf_add(buf, s, strlen(s));
}

char *reftable_buf_detach(struct reftable_buf *buf)
{
char *result = buf->buf;
reftable_buf_init(buf);
return result;
}

void put_be24(uint8_t *out, uint32_t i)
{
out[0] = (uint8_t)((i >> 16) & 0xff);
@@ -186,7 +260,7 @@ int names_equal(const char **a, const char **b)
return a[i] == b[i];
}

int common_prefix_size(struct strbuf *a, struct strbuf *b)
int common_prefix_size(struct reftable_buf *a, struct reftable_buf *b)
{
int p = 0;
for (; p < a->len && p < b->len; p++) {
@@ -197,14 +271,15 @@ int common_prefix_size(struct strbuf *a, struct strbuf *b)
return p;
}

int hash_size(uint32_t id)
int hash_size(enum reftable_hash id)
{
if (!id)
return REFTABLE_HASH_SIZE_SHA1;
switch (id) {
case 0:
case GIT_SHA1_FORMAT_ID:
return GIT_SHA1_RAWSZ;
case GIT_SHA256_FORMAT_ID:
return GIT_SHA256_RAWSZ;
case REFTABLE_HASH_SHA1:
return REFTABLE_HASH_SIZE_SHA1;
case REFTABLE_HASH_SHA256:
return REFTABLE_HASH_SIZE_SHA256;
}
abort();
}
71 changes: 68 additions & 3 deletions reftable/basics.h
Original file line number Diff line number Diff line change
@@ -16,6 +16,64 @@ license that can be found in the LICENSE file or at
#include "system.h"
#include "reftable-basics.h"

struct reftable_buf {
size_t alloc;
size_t len;
char *buf;
};
#define REFTABLE_BUF_INIT { 0 }

/*
* Initialize the buffer such that it is ready for use. This is equivalent to
* using REFTABLE_BUF_INIT for stack-allocated variables.
*/
void reftable_buf_init(struct reftable_buf *buf);

/*
* Release memory associated with the buffer. The buffer is reinitialized such
* that it can be reused for subsequent operations.
*/
void reftable_buf_release(struct reftable_buf *buf);

/*
* Reset the buffer such that it is effectively empty, without releasing the
* memory that this structure holds on to. This is equivalent to calling
* `reftable_buf_setlen(buf, 0)`.
*/
void reftable_buf_reset(struct reftable_buf *buf);

/*
* Trim the buffer to a shorter length by updating the `len` member and writing
* a NUL byte to `buf[len]`. Returns 0 on success, -1 when `len` points outside
* of the array.
*/
int reftable_buf_setlen(struct reftable_buf *buf, size_t len);

/*
* Lexicographically compare the two buffers. Returns 0 when both buffers have
* the same contents, -1 when `a` is lexicographically smaller than `b`, and 1
* otherwise.
*/
int reftable_buf_cmp(const struct reftable_buf *a, const struct reftable_buf *b);

/*
* Append `len` bytes from `data` to the buffer. This function works with
* arbitrary byte sequences, including ones that contain embedded NUL
* characters. As such, we use `void *` as input type. Returns 0 on success,
* REFTABLE_OUT_OF_MEMORY_ERROR on allocation failure.
*/
int reftable_buf_add(struct reftable_buf *buf, const void *data, size_t len);

/* Equivalent to `reftable_buf_add(buf, s, strlen(s))`. */
int reftable_buf_addstr(struct reftable_buf *buf, const char *s);

/*
* Detach the buffer from the structure such that the underlying memory is now
* owned by the caller. The buffer is reinitialized such that it can be reused
* for subsequent operations.
*/
char *reftable_buf_detach(struct reftable_buf *buf);

/* Bigendian en/decoding of integers */

void put_be24(uint8_t *out, uint32_t i);
@@ -88,9 +146,16 @@ char *reftable_strdup(const char *str);
#endif

/* Find the longest shared prefix size of `a` and `b` */
struct strbuf;
int common_prefix_size(struct strbuf *a, struct strbuf *b);
int common_prefix_size(struct reftable_buf *a, struct reftable_buf *b);

int hash_size(uint32_t id);
int hash_size(enum reftable_hash id);

/*
* Format IDs that identify the hash function used by a reftable. Note that
* these constants end up on disk and thus mustn't change. The format IDs are
* "sha1" and "s256" in big endian, respectively.
*/
#define REFTABLE_FORMAT_ID_SHA1 ((uint32_t) 0x73686131)
#define REFTABLE_FORMAT_ID_SHA256 ((uint32_t) 0x73323536)

#endif
Loading