Merge branch 'ps/refs-onbranch-fixes'
Reference backend configuration has been updated to load lazily to avoid recursive calls during repository initialization when 'onbranch' configuration conditions are evaluated. This has also fixed a memory leak and allowed the unused `chdir_notify_reparent()` machinery to be dropped. * ps/refs-onbranch-fixes: refs: protect against chicken-and-egg recursion refs/reftable: lazy-load configuration to fix chicken-and-egg reftable: split up write options refs/files: lazy-load configuration to fix chicken-and-egg refs: move parsing of "core.logAllRefUpdates" back into ref stores repository: free main reference database chdir-notify: drop unused `chdir_notify_reparent()` refs: unregister reference stores from "chdir_notify" setup: don't apply "GIT_REFERENCE_BACKEND" without a repository setup: stop applying repository format twice setup: inline `check_and_apply_repository_format()`main
commit
3442a0fb79
|
|
@ -952,10 +952,13 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
|
|||
const char *old_desc, *reflog_msg;
|
||||
if (opts->new_branch) {
|
||||
if (opts->new_orphan_branch) {
|
||||
enum log_refs_config log_all_ref_updates =
|
||||
repo_settings_get_log_all_ref_updates(the_repository);
|
||||
enum log_refs_config log_all_ref_updates = LOG_REFS_UNSET;
|
||||
const char *value;
|
||||
char *refname;
|
||||
|
||||
if (!repo_config_get_string_tmp(the_repository, "core.logallrefupdates", &value))
|
||||
log_all_ref_updates = refs_parse_log_all_ref_updates_config(value);
|
||||
|
||||
refname = mkpathdup("refs/heads/%s", opts->new_orphan_branch);
|
||||
if (opts->new_branch_log &&
|
||||
!should_autocreate_reflog(log_all_ref_updates, refname)) {
|
||||
|
|
|
|||
|
|
@ -43,32 +43,6 @@ void chdir_notify_unregister(const char *name, chdir_notify_callback cb,
|
|||
}
|
||||
}
|
||||
|
||||
static void reparent_cb(const char *name,
|
||||
const char *old_cwd,
|
||||
const char *new_cwd,
|
||||
void *data)
|
||||
{
|
||||
char **path = data;
|
||||
char *tmp = *path;
|
||||
|
||||
if (!tmp)
|
||||
return;
|
||||
|
||||
*path = reparent_relative_path(old_cwd, new_cwd, tmp);
|
||||
free(tmp);
|
||||
|
||||
if (name) {
|
||||
trace_printf_key(&trace_setup_key,
|
||||
"setup: reparent %s to '%s'",
|
||||
name, *path);
|
||||
}
|
||||
}
|
||||
|
||||
void chdir_notify_reparent(const char *name, char **path)
|
||||
{
|
||||
chdir_notify_register(name, reparent_cb, path);
|
||||
}
|
||||
|
||||
int chdir_notify(const char *new_cwd)
|
||||
{
|
||||
struct strbuf old_cwd = STRBUF_INIT;
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@
|
|||
* chdir_notify_register("description", foo, data);
|
||||
*
|
||||
* In practice most callers will want to move a relative path to the new root;
|
||||
* they can use the reparent_relative_path() helper for that. If that's all
|
||||
* you're doing, you can also use the convenience function:
|
||||
*
|
||||
* chdir_notify_reparent("description", &my_path);
|
||||
* they can use the reparent_relative_path() helper for that.
|
||||
*
|
||||
* Whenever a chdir event occurs, that will update my_path (if it's relative)
|
||||
* to adjust for the new cwd by freeing any existing string and allocating a
|
||||
|
|
@ -43,7 +40,6 @@ typedef void (*chdir_notify_callback)(const char *name,
|
|||
void chdir_notify_register(const char *name, chdir_notify_callback cb, void *data);
|
||||
void chdir_notify_unregister(const char *name, chdir_notify_callback cb,
|
||||
void *data);
|
||||
void chdir_notify_reparent(const char *name, char **path);
|
||||
|
||||
/*
|
||||
*
|
||||
|
|
|
|||
17
refs.c
17
refs.c
|
|
@ -1053,6 +1053,15 @@ static char *normalize_reflog_message(const char *msg)
|
|||
return strbuf_detach(&sb, NULL);
|
||||
}
|
||||
|
||||
enum log_refs_config refs_parse_log_all_ref_updates_config(const char *value)
|
||||
{
|
||||
if (value && !strcasecmp(value, "always"))
|
||||
return LOG_REFS_ALWAYS;
|
||||
else if (git_config_bool("core.logallrefupdates", value))
|
||||
return LOG_REFS_NORMAL;
|
||||
return LOG_REFS_NONE;
|
||||
}
|
||||
|
||||
int should_autocreate_reflog(enum log_refs_config log_all_ref_updates,
|
||||
const char *refname)
|
||||
{
|
||||
|
|
@ -2327,7 +2336,6 @@ static struct ref_store *ref_store_init(struct repository *repo,
|
|||
struct ref_store *refs;
|
||||
struct ref_store_init_options opts = {
|
||||
.access_flags = flags,
|
||||
.log_all_ref_updates = repo_settings_get_log_all_ref_updates(repo),
|
||||
};
|
||||
|
||||
be = find_ref_storage_backend(format);
|
||||
|
|
@ -2351,15 +2359,22 @@ void ref_store_release(struct ref_store *ref_store)
|
|||
|
||||
struct ref_store *get_main_ref_store(struct repository *r)
|
||||
{
|
||||
static bool initializing;
|
||||
|
||||
if (r->refs_private)
|
||||
return r->refs_private;
|
||||
|
||||
if (!r->gitdir)
|
||||
BUG("attempting to get main_ref_store outside of repository");
|
||||
if (initializing)
|
||||
BUG("initialization of main ref store is recursing");
|
||||
|
||||
initializing = true;
|
||||
r->refs_private = ref_store_init(r, r->ref_storage_format,
|
||||
r->gitdir, REF_STORE_ALL_CAPS);
|
||||
r->refs_private = maybe_debug_wrap_ref_store(r->gitdir, r->refs_private);
|
||||
initializing = false;
|
||||
|
||||
return r->refs_private;
|
||||
}
|
||||
|
||||
|
|
|
|||
9
refs.h
9
refs.h
|
|
@ -146,6 +146,15 @@ enum ref_transaction_error refs_verify_refname_available(struct ref_store *refs,
|
|||
|
||||
int refs_ref_exists(struct ref_store *refs, const char *refname);
|
||||
|
||||
enum log_refs_config {
|
||||
LOG_REFS_UNSET = -1,
|
||||
LOG_REFS_NONE = 0,
|
||||
LOG_REFS_NORMAL,
|
||||
LOG_REFS_ALWAYS
|
||||
};
|
||||
|
||||
enum log_refs_config refs_parse_log_all_ref_updates_config(const char *value);
|
||||
|
||||
int should_autocreate_reflog(enum log_refs_config log_all_ref_updates,
|
||||
const char *refname);
|
||||
|
||||
|
|
|
|||
|
|
@ -84,12 +84,21 @@ struct files_ref_store {
|
|||
unsigned int store_flags;
|
||||
|
||||
char *gitcommondir;
|
||||
enum log_refs_config log_all_ref_updates;
|
||||
int prefer_symlink_refs;
|
||||
|
||||
struct ref_cache *loose;
|
||||
|
||||
struct ref_store *packed_ref_store;
|
||||
|
||||
/*
|
||||
* Options used when writing references. These are parsed from the
|
||||
* config lazily on first use via `files_ref_store_write_options()` so
|
||||
* that we don't have to access the configuration when initializing the
|
||||
* ref store. Do not access these fields directly, but use the accessor
|
||||
* instead.
|
||||
*/
|
||||
struct files_ref_store_write_options {
|
||||
enum log_refs_config log_all_ref_updates;
|
||||
int prefer_symlink_refs;
|
||||
bool initialized;
|
||||
} write_opts_lazy_loaded;
|
||||
};
|
||||
|
||||
static void clear_loose_ref_cache(struct files_ref_store *refs)
|
||||
|
|
@ -100,6 +109,52 @@ static void clear_loose_ref_cache(struct files_ref_store *refs)
|
|||
}
|
||||
}
|
||||
|
||||
static void files_ref_store_reparent(const char *name UNUSED,
|
||||
const char *old_cwd,
|
||||
const char *new_cwd,
|
||||
void *payload)
|
||||
{
|
||||
struct files_ref_store *refs = payload;
|
||||
char *tmp;
|
||||
|
||||
tmp = reparent_relative_path(old_cwd, new_cwd, refs->base.gitdir);
|
||||
free(refs->base.gitdir);
|
||||
refs->base.gitdir = tmp;
|
||||
|
||||
tmp = reparent_relative_path(old_cwd, new_cwd, refs->gitcommondir);
|
||||
free(refs->gitcommondir);
|
||||
refs->gitcommondir = tmp;
|
||||
}
|
||||
|
||||
static int files_ref_store_config(const char *var, const char *value,
|
||||
const struct config_context *ctx UNUSED,
|
||||
void *payload)
|
||||
{
|
||||
struct files_ref_store_write_options *opts = payload;
|
||||
|
||||
if (!strcmp(var, "core.prefersymlinkrefs")) {
|
||||
opts->prefer_symlink_refs = git_config_bool(var, value);
|
||||
} else if (!strcmp(var, "core.logallrefupdates")) {
|
||||
opts->log_all_ref_updates = refs_parse_log_all_ref_updates_config(value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct files_ref_store_write_options *files_ref_store_write_options(struct files_ref_store *refs)
|
||||
{
|
||||
struct files_ref_store_write_options *opts = &refs->write_opts_lazy_loaded;
|
||||
|
||||
if (opts->initialized)
|
||||
return opts;
|
||||
|
||||
opts->log_all_ref_updates = LOG_REFS_UNSET;
|
||||
repo_config(refs->base.repo, files_ref_store_config, opts);
|
||||
|
||||
opts->initialized = true;
|
||||
return opts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new submodule ref cache and add it to the internal
|
||||
* set of caches.
|
||||
|
|
@ -124,13 +179,8 @@ static struct ref_store *files_ref_store_init(struct repository *repo,
|
|||
refs->packed_ref_store =
|
||||
packed_ref_store_init(repo, NULL, refs->gitcommondir, opts);
|
||||
refs->store_flags = opts->access_flags;
|
||||
refs->log_all_ref_updates = opts->log_all_ref_updates;
|
||||
|
||||
repo_config_get_bool(repo, "core.prefersymlinkrefs", &refs->prefer_symlink_refs);
|
||||
|
||||
chdir_notify_reparent("files-backend $GIT_DIR", &refs->base.gitdir);
|
||||
chdir_notify_reparent("files-backend $GIT_COMMONDIR",
|
||||
&refs->gitcommondir);
|
||||
chdir_notify_register(NULL, files_ref_store_reparent, refs);
|
||||
|
||||
strbuf_release(&refdir);
|
||||
|
||||
|
|
@ -182,6 +232,7 @@ static void files_ref_store_release(struct ref_store *ref_store)
|
|||
free(refs->gitcommondir);
|
||||
ref_store_release(refs->packed_ref_store);
|
||||
free(refs->packed_ref_store);
|
||||
chdir_notify_unregister(NULL, files_ref_store_reparent, refs);
|
||||
}
|
||||
|
||||
static void files_reflog_path(struct files_ref_store *refs,
|
||||
|
|
@ -1860,7 +1911,7 @@ static int log_ref_setup(struct files_ref_store *refs,
|
|||
const char *refname, int force_create,
|
||||
int *logfd, struct strbuf *err)
|
||||
{
|
||||
enum log_refs_config log_refs_cfg = refs->log_all_ref_updates;
|
||||
enum log_refs_config log_refs_cfg = files_ref_store_write_options(refs)->log_all_ref_updates;
|
||||
struct strbuf logfile_sb = STRBUF_INIT;
|
||||
char *logfile;
|
||||
|
||||
|
|
@ -3271,6 +3322,7 @@ static int files_transaction_finish(struct ref_store *ref_store,
|
|||
{
|
||||
struct files_ref_store *refs =
|
||||
files_downcast(ref_store, 0, "ref_transaction_finish");
|
||||
const struct files_ref_store_write_options *write_opts = files_ref_store_write_options(refs);
|
||||
size_t i;
|
||||
int ret = 0;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
|
|
@ -3310,7 +3362,7 @@ static int files_transaction_finish(struct ref_store *ref_store,
|
|||
* We try creating a symlink, if that succeeds we continue to the
|
||||
* next update. If not, we try and create a regular symref.
|
||||
*/
|
||||
if (update->new_target && refs->prefer_symlink_refs)
|
||||
if (update->new_target && write_opts->prefer_symlink_refs)
|
||||
/*
|
||||
* By using the `NOT_CONSTANT()` trick, we can avoid
|
||||
* errors by `clang`'s `-Wunreachable` logic that would
|
||||
|
|
|
|||
|
|
@ -211,6 +211,19 @@ static size_t snapshot_hexsz(const struct snapshot *snapshot)
|
|||
return snapshot->refs->base.repo->hash_algo->hexsz;
|
||||
}
|
||||
|
||||
static void packed_ref_store_reparent(const char *name UNUSED,
|
||||
const char *old_cwd,
|
||||
const char *new_cwd,
|
||||
void *payload)
|
||||
{
|
||||
struct packed_ref_store *refs = payload;
|
||||
char *tmp;
|
||||
|
||||
tmp = reparent_relative_path(old_cwd, new_cwd, refs->path);
|
||||
free(refs->path);
|
||||
refs->path = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since packed-refs is only stored in the common dir, don't parse the
|
||||
* payload and rely on the files-backend to set 'gitdir' correctly.
|
||||
|
|
@ -229,7 +242,7 @@ struct ref_store *packed_ref_store_init(struct repository *repo,
|
|||
|
||||
strbuf_addf(&sb, "%s/packed-refs", gitdir);
|
||||
refs->path = strbuf_detach(&sb, NULL);
|
||||
chdir_notify_reparent("packed-refs", &refs->path);
|
||||
chdir_notify_register(NULL, packed_ref_store_reparent, refs);
|
||||
return ref_store;
|
||||
}
|
||||
|
||||
|
|
@ -274,6 +287,7 @@ static void packed_ref_store_release(struct ref_store *ref_store)
|
|||
clear_snapshot(refs);
|
||||
rollback_lock_file(&refs->lock);
|
||||
delete_tempfile(&refs->tempfile);
|
||||
chdir_notify_unregister(NULL, packed_ref_store_reparent, refs);
|
||||
free(refs->path);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -406,12 +406,6 @@ struct ref_store;
|
|||
struct ref_store_init_options {
|
||||
/* The kind of operations that the ref_store is allowed to perform. */
|
||||
unsigned int access_flags;
|
||||
|
||||
/*
|
||||
* Denotes under what conditions reflogs should be created when updating
|
||||
* references.
|
||||
*/
|
||||
enum log_refs_config log_all_ref_updates;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@ static void reftable_backend_on_reload(void *payload)
|
|||
|
||||
static int reftable_backend_init(struct reftable_backend *be,
|
||||
const char *path,
|
||||
const struct reftable_write_options *_opts)
|
||||
const struct reftable_stack_options *_opts)
|
||||
{
|
||||
struct reftable_write_options opts = *_opts;
|
||||
struct reftable_stack_options opts = *_opts;
|
||||
opts.on_reload = reftable_backend_on_reload;
|
||||
opts.on_reload_payload = be;
|
||||
return reftable_new_stack(&be->stack, path, &opts);
|
||||
|
|
@ -138,10 +138,22 @@ struct reftable_ref_store {
|
|||
* is populated lazily when we try to resolve `worktrees/$worktree` refs.
|
||||
*/
|
||||
struct strmap worktree_backends;
|
||||
struct reftable_write_options write_options;
|
||||
struct reftable_stack_options stack_options;
|
||||
|
||||
/*
|
||||
* Options used when writing to or compacting the reftable stacks.
|
||||
* These are parsed from the configuration lazily on first use via
|
||||
* `reftable_be_write_options()` so that we don't have to access the
|
||||
* configuration when initializing the ref store. Do not access these
|
||||
* fields directly, but use the accessor instead.
|
||||
*/
|
||||
struct reftable_be_write_options {
|
||||
struct reftable_write_options opts;
|
||||
enum log_refs_config log_all_ref_updates;
|
||||
bool initialized;
|
||||
} write_opts_lazy_loaded;
|
||||
|
||||
unsigned int store_flags;
|
||||
enum log_refs_config log_all_ref_updates;
|
||||
int err;
|
||||
};
|
||||
|
||||
|
|
@ -188,7 +200,7 @@ static int backend_for_worktree(struct reftable_backend **out,
|
|||
|
||||
CALLOC_ARRAY(*out, 1);
|
||||
store->err = ret = reftable_backend_init(*out, worktree_dir.buf,
|
||||
&store->write_options);
|
||||
&store->stack_options);
|
||||
if (ret < 0) {
|
||||
free(*out);
|
||||
goto out;
|
||||
|
|
@ -282,26 +294,6 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int should_write_log(struct reftable_ref_store *refs, const char *refname)
|
||||
{
|
||||
enum log_refs_config log_refs_cfg = refs->log_all_ref_updates;
|
||||
if (log_refs_cfg == LOG_REFS_UNSET)
|
||||
log_refs_cfg = is_bare_repository(refs->base.repo) ? LOG_REFS_NONE : LOG_REFS_NORMAL;
|
||||
|
||||
switch (log_refs_cfg) {
|
||||
case LOG_REFS_NONE:
|
||||
return refs_reflog_exists(&refs->base, refname);
|
||||
case LOG_REFS_ALWAYS:
|
||||
return 1;
|
||||
case LOG_REFS_NORMAL:
|
||||
if (should_autocreate_reflog(log_refs_cfg, refname))
|
||||
return 1;
|
||||
return refs_reflog_exists(&refs->base, refname);
|
||||
default:
|
||||
BUG("unhandled core.logAllRefUpdates value %d", log_refs_cfg);
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_reftable_log_record(struct reftable_log_record *log, const struct ident_split *split)
|
||||
{
|
||||
const char *tz_begin;
|
||||
|
|
@ -330,39 +322,88 @@ static void fill_reftable_log_record(struct reftable_log_record *log, const stru
|
|||
|
||||
static int reftable_be_config(const char *var, const char *value,
|
||||
const struct config_context *ctx,
|
||||
void *_opts)
|
||||
void *payload)
|
||||
{
|
||||
struct reftable_write_options *opts = _opts;
|
||||
struct reftable_ref_store *refs = payload;
|
||||
struct reftable_be_write_options *opts = &refs->write_opts_lazy_loaded;
|
||||
|
||||
if (!strcmp(var, "reftable.blocksize")) {
|
||||
unsigned long block_size = git_config_ulong(var, value, ctx->kvi);
|
||||
if (block_size > 16777215)
|
||||
die("reftable block size cannot exceed 16MB");
|
||||
opts->block_size = block_size;
|
||||
opts->opts.block_size = block_size;
|
||||
} else if (!strcmp(var, "reftable.restartinterval")) {
|
||||
unsigned long restart_interval = git_config_ulong(var, value, ctx->kvi);
|
||||
if (restart_interval > UINT16_MAX)
|
||||
die("reftable block size cannot exceed %u", (unsigned)UINT16_MAX);
|
||||
opts->restart_interval = restart_interval;
|
||||
opts->opts.restart_interval = restart_interval;
|
||||
} else if (!strcmp(var, "reftable.indexobjects")) {
|
||||
opts->skip_index_objects = !git_config_bool(var, value);
|
||||
opts->opts.skip_index_objects = !git_config_bool(var, value);
|
||||
} else if (!strcmp(var, "reftable.geometricfactor")) {
|
||||
unsigned long factor = git_config_ulong(var, value, ctx->kvi);
|
||||
if (factor > UINT8_MAX)
|
||||
die("reftable geometric factor cannot exceed %u", (unsigned)UINT8_MAX);
|
||||
opts->auto_compaction_factor = factor;
|
||||
opts->opts.auto_compaction_factor = factor;
|
||||
} else if (!strcmp(var, "reftable.locktimeout")) {
|
||||
int64_t lock_timeout = git_config_int64(var, value, ctx->kvi);
|
||||
if (lock_timeout > LONG_MAX)
|
||||
die("reftable lock timeout cannot exceed %"PRIdMAX, (intmax_t)LONG_MAX);
|
||||
if (lock_timeout < 0 && lock_timeout != -1)
|
||||
die("reftable lock timeout does not support negative values other than -1");
|
||||
opts->lock_timeout_ms = lock_timeout;
|
||||
opts->opts.lock_timeout_ms = lock_timeout;
|
||||
} else if (!strcmp(var, "core.logallrefupdates")) {
|
||||
opts->log_all_ref_updates = refs_parse_log_all_ref_updates_config(value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct reftable_be_write_options *reftable_be_write_options(struct reftable_ref_store *refs)
|
||||
{
|
||||
struct reftable_be_write_options *opts = &refs->write_opts_lazy_loaded;
|
||||
mode_t mask;
|
||||
|
||||
if (opts->initialized)
|
||||
return opts;
|
||||
|
||||
mask = umask(0);
|
||||
umask(mask);
|
||||
|
||||
opts->opts.default_permissions = calc_shared_perm(refs->base.repo, 0666 & ~mask);
|
||||
opts->opts.disable_auto_compact =
|
||||
!git_env_bool("GIT_TEST_REFTABLE_AUTOCOMPACTION", 1);
|
||||
opts->opts.lock_timeout_ms = 100;
|
||||
opts->log_all_ref_updates = LOG_REFS_UNSET;
|
||||
|
||||
repo_config(refs->base.repo, reftable_be_config, refs);
|
||||
|
||||
/*
|
||||
* It is somewhat unfortunate that we have to mirror the default block
|
||||
* size of the reftable library here. But given that the write options
|
||||
* wouldn't be updated by the library here, and given that we require
|
||||
* the proper block size to trim reflog message so that they fit, we
|
||||
* must set up a proper value here.
|
||||
*/
|
||||
if (!opts->opts.block_size)
|
||||
opts->opts.block_size = 4096;
|
||||
|
||||
opts->initialized = true;
|
||||
return opts;
|
||||
}
|
||||
|
||||
static void reftable_be_reparent(const char *name UNUSED,
|
||||
const char *old_cwd,
|
||||
const char *new_cwd,
|
||||
void *payload)
|
||||
{
|
||||
struct reftable_ref_store *refs = payload;
|
||||
char *tmp;
|
||||
|
||||
tmp = reparent_relative_path(old_cwd, new_cwd, refs->base.gitdir);
|
||||
free(refs->base.gitdir);
|
||||
refs->base.gitdir = tmp;
|
||||
}
|
||||
|
||||
static struct ref_store *reftable_be_init(struct repository *repo,
|
||||
const char *payload,
|
||||
const char *gitdir,
|
||||
|
|
@ -373,45 +414,24 @@ static struct ref_store *reftable_be_init(struct repository *repo,
|
|||
struct strbuf refdir = STRBUF_INIT;
|
||||
struct strbuf path = STRBUF_INIT;
|
||||
bool is_worktree;
|
||||
mode_t mask;
|
||||
|
||||
mask = umask(0);
|
||||
umask(mask);
|
||||
|
||||
refs_compute_filesystem_location(gitdir, payload, &is_worktree, &refdir,
|
||||
&ref_common_dir);
|
||||
|
||||
base_ref_store_init(&refs->base, repo, refdir.buf, &refs_be_reftable);
|
||||
strmap_init(&refs->worktree_backends);
|
||||
refs->log_all_ref_updates = opts->log_all_ref_updates;
|
||||
refs->store_flags = opts->access_flags;
|
||||
|
||||
switch (repo->hash_algo->format_id) {
|
||||
case GIT_SHA1_FORMAT_ID:
|
||||
refs->write_options.hash_id = REFTABLE_HASH_SHA1;
|
||||
refs->stack_options.hash_id = REFTABLE_HASH_SHA1;
|
||||
break;
|
||||
case GIT_SHA256_FORMAT_ID:
|
||||
refs->write_options.hash_id = REFTABLE_HASH_SHA256;
|
||||
refs->stack_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(repo, 0666 & ~mask);
|
||||
refs->write_options.disable_auto_compact =
|
||||
!git_env_bool("GIT_TEST_REFTABLE_AUTOCOMPACTION", 1);
|
||||
refs->write_options.lock_timeout_ms = 100;
|
||||
|
||||
repo_config(repo, reftable_be_config, &refs->write_options);
|
||||
|
||||
/*
|
||||
* It is somewhat unfortunate that we have to mirror the default block
|
||||
* size of the reftable library here. But given that the write options
|
||||
* wouldn't be updated by the library here, and given that we require
|
||||
* the proper block size to trim reflog message so that they fit, we
|
||||
* must set up a proper value here.
|
||||
*/
|
||||
if (!refs->write_options.block_size)
|
||||
refs->write_options.block_size = 4096;
|
||||
|
||||
/*
|
||||
* Set up the main reftable stack that is hosted in GIT_COMMON_DIR.
|
||||
|
|
@ -424,7 +444,7 @@ static struct ref_store *reftable_be_init(struct repository *repo,
|
|||
}
|
||||
strbuf_addstr(&path, "/reftable");
|
||||
refs->err = reftable_backend_init(&refs->main_backend, path.buf,
|
||||
&refs->write_options);
|
||||
&refs->stack_options);
|
||||
if (refs->err)
|
||||
goto done;
|
||||
|
||||
|
|
@ -440,12 +460,12 @@ static struct ref_store *reftable_be_init(struct repository *repo,
|
|||
strbuf_addstr(&refdir, "/reftable");
|
||||
|
||||
refs->err = reftable_backend_init(&refs->worktree_backend, refdir.buf,
|
||||
&refs->write_options);
|
||||
&refs->stack_options);
|
||||
if (refs->err)
|
||||
goto done;
|
||||
}
|
||||
|
||||
chdir_notify_reparent("reftables-backend $GIT_DIR", &refs->base.gitdir);
|
||||
chdir_notify_register(NULL, reftable_be_reparent, refs);
|
||||
|
||||
done:
|
||||
assert(refs->err != REFTABLE_API_ERROR);
|
||||
|
|
@ -472,6 +492,7 @@ static void reftable_be_release(struct ref_store *ref_store)
|
|||
free(be);
|
||||
}
|
||||
strmap_clear(&refs->worktree_backends, 0);
|
||||
chdir_notify_unregister(NULL, reftable_be_reparent, refs);
|
||||
}
|
||||
|
||||
static int reftable_be_create_on_disk(struct ref_store *ref_store,
|
||||
|
|
@ -979,6 +1000,7 @@ static int prepare_transaction_update(struct write_transaction_table_arg **out,
|
|||
struct reftable_addition *addition;
|
||||
|
||||
ret = reftable_stack_new_addition(&addition, be->stack,
|
||||
&reftable_be_write_options(refs)->opts,
|
||||
REFTABLE_STACK_NEW_ADDITION_RELOAD);
|
||||
if (ret) {
|
||||
if (ret == REFTABLE_LOCK_ERROR)
|
||||
|
|
@ -1417,6 +1439,26 @@ static int transaction_update_cmp(const void *a, const void *b)
|
|||
return strcmp(update_a->update->refname, update_b->update->refname);
|
||||
}
|
||||
|
||||
static int should_write_log(struct reftable_ref_store *refs, const char *refname)
|
||||
{
|
||||
enum log_refs_config log_refs_cfg = reftable_be_write_options(refs)->log_all_ref_updates;
|
||||
if (log_refs_cfg == LOG_REFS_UNSET)
|
||||
log_refs_cfg = is_bare_repository(refs->base.repo) ? LOG_REFS_NONE : LOG_REFS_NORMAL;
|
||||
|
||||
switch (log_refs_cfg) {
|
||||
case LOG_REFS_NONE:
|
||||
return refs_reflog_exists(&refs->base, refname);
|
||||
case LOG_REFS_ALWAYS:
|
||||
return 1;
|
||||
case LOG_REFS_NORMAL:
|
||||
if (should_autocreate_reflog(log_refs_cfg, refname))
|
||||
return 1;
|
||||
return refs_reflog_exists(&refs->base, refname);
|
||||
default:
|
||||
BUG("unhandled core.logAllRefUpdates value %d", log_refs_cfg);
|
||||
}
|
||||
}
|
||||
|
||||
static int write_transaction_table(struct reftable_writer *writer, void *cb_data)
|
||||
{
|
||||
struct write_transaction_table_arg *arg = cb_data;
|
||||
|
|
@ -1551,7 +1593,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data
|
|||
memcpy(log->value.update.old_hash,
|
||||
tx_update->current_oid.hash, GIT_MAX_RAWSZ);
|
||||
log->value.update.message =
|
||||
xstrndup(u->msg, arg->refs->write_options.block_size / 2);
|
||||
xstrndup(u->msg, reftable_be_write_options(arg->refs)->opts.block_size / 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1667,9 +1709,9 @@ static int reftable_be_optimize(struct ref_store *ref_store,
|
|||
stack = refs->main_backend.stack;
|
||||
|
||||
if (opts->flags & REFS_OPTIMIZE_AUTO)
|
||||
ret = reftable_stack_auto_compact(stack);
|
||||
ret = reftable_stack_auto_compact(stack, &reftable_be_write_options(refs)->opts);
|
||||
else
|
||||
ret = reftable_stack_compact_all(stack, NULL);
|
||||
ret = reftable_stack_compact_all(stack, &reftable_be_write_options(refs)->opts, NULL);
|
||||
if (ret < 0) {
|
||||
ret = error(_("unable to compact stack: %s"),
|
||||
reftable_error_str(ret));
|
||||
|
|
@ -1703,8 +1745,8 @@ static int reftable_be_optimize_required(struct ref_store *ref_store,
|
|||
if (opts->flags & REFS_OPTIMIZE_AUTO)
|
||||
use_heuristics = true;
|
||||
|
||||
return reftable_stack_compaction_required(stack, use_heuristics,
|
||||
required);
|
||||
return reftable_stack_compaction_required(stack, &reftable_be_write_options(refs)->opts,
|
||||
use_heuristics, required);
|
||||
}
|
||||
|
||||
struct write_create_symref_arg {
|
||||
|
|
@ -1823,7 +1865,7 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data)
|
|||
logs[logs_nr].refname = xstrdup(arg->newname);
|
||||
logs[logs_nr].update_index = deletion_ts;
|
||||
logs[logs_nr].value.update.message =
|
||||
xstrndup(arg->logmsg, arg->refs->write_options.block_size / 2);
|
||||
xstrndup(arg->logmsg, reftable_be_write_options(arg->refs)->opts.block_size / 2);
|
||||
memcpy(logs[logs_nr].value.update.old_hash, old_ref.value.val1, GIT_MAX_RAWSZ);
|
||||
logs_nr++;
|
||||
|
||||
|
|
@ -1862,7 +1904,7 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data)
|
|||
logs[logs_nr].refname = xstrdup(arg->newname);
|
||||
logs[logs_nr].update_index = creation_ts;
|
||||
logs[logs_nr].value.update.message =
|
||||
xstrndup(arg->logmsg, arg->refs->write_options.block_size / 2);
|
||||
xstrndup(arg->logmsg, reftable_be_write_options(arg->refs)->opts.block_size / 2);
|
||||
memcpy(logs[logs_nr].value.update.new_hash, old_ref.value.val1, GIT_MAX_RAWSZ);
|
||||
logs_nr++;
|
||||
|
||||
|
|
@ -1961,6 +2003,7 @@ static int reftable_be_rename_ref(struct ref_store *ref_store,
|
|||
if (ret)
|
||||
goto done;
|
||||
ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg,
|
||||
&reftable_be_write_options(refs)->opts,
|
||||
REFTABLE_STACK_NEW_ADDITION_RELOAD);
|
||||
|
||||
done:
|
||||
|
|
@ -1991,6 +2034,7 @@ static int reftable_be_copy_ref(struct ref_store *ref_store,
|
|||
if (ret)
|
||||
goto done;
|
||||
ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg,
|
||||
&reftable_be_write_options(refs)->opts,
|
||||
REFTABLE_STACK_NEW_ADDITION_RELOAD);
|
||||
|
||||
done:
|
||||
|
|
@ -2356,6 +2400,7 @@ static int reftable_be_create_reflog(struct ref_store *ref_store,
|
|||
arg.stack = be->stack;
|
||||
|
||||
ret = reftable_stack_add(be->stack, &write_reflog_existence_table, &arg,
|
||||
&reftable_be_write_options(refs)->opts,
|
||||
REFTABLE_STACK_NEW_ADDITION_RELOAD);
|
||||
|
||||
done:
|
||||
|
|
@ -2428,6 +2473,7 @@ static int reftable_be_delete_reflog(struct ref_store *ref_store,
|
|||
arg.stack = be->stack;
|
||||
|
||||
ret = reftable_stack_add(be->stack, &write_reflog_delete_table, &arg,
|
||||
&reftable_be_write_options(refs)->opts,
|
||||
REFTABLE_STACK_NEW_ADDITION_RELOAD);
|
||||
|
||||
assert(ret != REFTABLE_API_ERROR);
|
||||
|
|
@ -2550,6 +2596,7 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
|
|||
goto done;
|
||||
|
||||
ret = reftable_stack_new_addition(&add, be->stack,
|
||||
&reftable_be_write_options(refs)->opts,
|
||||
REFTABLE_STACK_NEW_ADDITION_RELOAD);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -26,11 +26,29 @@
|
|||
*/
|
||||
struct reftable_stack;
|
||||
|
||||
/* Options related to opening a stack. */
|
||||
struct reftable_stack_options {
|
||||
/*
|
||||
* 4-byte identifier ("sha1", "s256") of the hash. Defaults to SHA1 if
|
||||
* unset.
|
||||
*/
|
||||
enum reftable_hash hash_id;
|
||||
|
||||
/*
|
||||
* Callback function to execute whenever the stack is being reloaded.
|
||||
* This can be used e.g. to discard cached information that relies on
|
||||
* the old stack's data. The payload data will be passed as argument to
|
||||
* the callback.
|
||||
*/
|
||||
void (*on_reload)(void *payload);
|
||||
void *on_reload_payload;
|
||||
};
|
||||
|
||||
/* open a new reftable stack. The tables along with the table list will be
|
||||
* stored in 'dir'. Typically, this should be .git/reftables.
|
||||
*/
|
||||
int reftable_new_stack(struct reftable_stack **dest, const char *dir,
|
||||
const struct reftable_write_options *opts);
|
||||
const struct reftable_stack_options *opts);
|
||||
|
||||
/* returns the update_index at which a next table should be written. */
|
||||
uint64_t reftable_stack_next_update_index(struct reftable_stack *st);
|
||||
|
|
@ -52,6 +70,7 @@ enum {
|
|||
*/
|
||||
int reftable_stack_new_addition(struct reftable_addition **dest,
|
||||
struct reftable_stack *st,
|
||||
const struct reftable_write_options *opts,
|
||||
unsigned int flags);
|
||||
|
||||
/* Adds a reftable to transaction. */
|
||||
|
|
@ -77,7 +96,9 @@ void reftable_addition_destroy(struct reftable_addition *add);
|
|||
int reftable_stack_add(struct reftable_stack *st,
|
||||
int (*write_table)(struct reftable_writer *wr,
|
||||
void *write_arg),
|
||||
void *write_arg, unsigned flags);
|
||||
void *write_arg,
|
||||
const struct reftable_write_options *opts,
|
||||
unsigned flags);
|
||||
|
||||
struct reftable_iterator;
|
||||
|
||||
|
|
@ -122,6 +143,7 @@ struct reftable_log_expiry_config {
|
|||
/* compacts all reftables into a giant table. Expire reflog entries if config is
|
||||
* non-NULL */
|
||||
int reftable_stack_compact_all(struct reftable_stack *st,
|
||||
const struct reftable_write_options *opts,
|
||||
struct reftable_log_expiry_config *config);
|
||||
|
||||
/*
|
||||
|
|
@ -132,11 +154,13 @@ int reftable_stack_compact_all(struct reftable_stack *st,
|
|||
* compacted to maintain geometric progression.
|
||||
*/
|
||||
int reftable_stack_compaction_required(struct reftable_stack *st,
|
||||
const struct reftable_write_options *opts,
|
||||
bool use_heuristics,
|
||||
bool *required);
|
||||
|
||||
/* heuristically compact unbalanced table stack. */
|
||||
int reftable_stack_auto_compact(struct reftable_stack *st);
|
||||
int reftable_stack_auto_compact(struct reftable_stack *st,
|
||||
const struct reftable_write_options *opts);
|
||||
|
||||
/* delete stale .ref tables. */
|
||||
int reftable_stack_clean(struct reftable_stack *st);
|
||||
|
|
|
|||
|
|
@ -28,11 +28,6 @@ struct reftable_write_options {
|
|||
/* how often to write complete keys in each block. */
|
||||
uint16_t restart_interval;
|
||||
|
||||
/* 4-byte identifier ("sha1", "s256") of the hash.
|
||||
* Defaults to SHA1 if unset
|
||||
*/
|
||||
enum reftable_hash hash_id;
|
||||
|
||||
/* Default mode for creating files. If unset, use 0666 (+umask) */
|
||||
unsigned int default_permissions;
|
||||
|
||||
|
|
@ -60,15 +55,6 @@ struct reftable_write_options {
|
|||
* negative value will cause us to block indefinitely.
|
||||
*/
|
||||
long lock_timeout_ms;
|
||||
|
||||
/*
|
||||
* Callback function to execute whenever the stack is being reloaded.
|
||||
* This can be used e.g. to discard cached information that relies on
|
||||
* the old stack's data. The payload data will be passed as argument to
|
||||
* the callback.
|
||||
*/
|
||||
void (*on_reload)(void *payload);
|
||||
void *on_reload_payload;
|
||||
};
|
||||
|
||||
/* reftable_block_stats holds statistics for a single block type */
|
||||
|
|
@ -114,7 +100,8 @@ struct reftable_writer;
|
|||
int reftable_writer_new(struct reftable_writer **out,
|
||||
ssize_t (*writer_func)(void *, const void *, size_t),
|
||||
int (*flush_func)(void *),
|
||||
void *writer_arg, const struct reftable_write_options *opts);
|
||||
void *writer_arg, enum reftable_hash hash_id,
|
||||
const struct reftable_write_options *opts);
|
||||
|
||||
/*
|
||||
* Set the range of update indices for the records we will add. When writing a
|
||||
|
|
|
|||
100
reftable/stack.c
100
reftable/stack.c
|
|
@ -501,10 +501,10 @@ out:
|
|||
}
|
||||
|
||||
int reftable_new_stack(struct reftable_stack **dest, const char *dir,
|
||||
const struct reftable_write_options *_opts)
|
||||
const struct reftable_stack_options *_opts)
|
||||
{
|
||||
struct reftable_buf list_file_name = REFTABLE_BUF_INIT;
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack_options opts = { 0 };
|
||||
struct reftable_stack *p;
|
||||
int err;
|
||||
|
||||
|
|
@ -629,6 +629,7 @@ int reftable_stack_reload(struct reftable_stack *st)
|
|||
struct reftable_addition {
|
||||
struct reftable_flock tables_list_lock;
|
||||
struct reftable_stack *stack;
|
||||
struct reftable_write_options opts;
|
||||
|
||||
char **new_tables;
|
||||
size_t new_tables_len, new_tables_cap;
|
||||
|
|
@ -657,6 +658,7 @@ static void reftable_addition_close(struct reftable_addition *add)
|
|||
|
||||
static int reftable_stack_init_addition(struct reftable_addition *add,
|
||||
struct reftable_stack *st,
|
||||
const struct reftable_write_options *opts,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct reftable_buf lock_file_name = REFTABLE_BUF_INIT;
|
||||
|
|
@ -664,15 +666,17 @@ static int reftable_stack_init_addition(struct reftable_addition *add,
|
|||
|
||||
memset(add, 0, sizeof(*add));
|
||||
add->stack = st;
|
||||
if (opts)
|
||||
add->opts = *opts;
|
||||
|
||||
err = flock_acquire(&add->tables_list_lock, st->list_file,
|
||||
st->opts.lock_timeout_ms);
|
||||
add->opts.lock_timeout_ms);
|
||||
if (err < 0)
|
||||
goto done;
|
||||
|
||||
if (st->opts.default_permissions) {
|
||||
if (add->opts.default_permissions) {
|
||||
if (chmod(add->tables_list_lock.path,
|
||||
st->opts.default_permissions) < 0) {
|
||||
add->opts.default_permissions) < 0) {
|
||||
err = REFTABLE_IO_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -702,12 +706,14 @@ done:
|
|||
static int stack_try_add(struct reftable_stack *st,
|
||||
int (*write_table)(struct reftable_writer *wr,
|
||||
void *arg),
|
||||
void *arg, unsigned flags)
|
||||
void *arg,
|
||||
const struct reftable_write_options *opts,
|
||||
unsigned flags)
|
||||
{
|
||||
struct reftable_addition add;
|
||||
int err;
|
||||
|
||||
err = reftable_stack_init_addition(&add, st, flags);
|
||||
err = reftable_stack_init_addition(&add, st, opts, flags);
|
||||
if (err < 0)
|
||||
goto done;
|
||||
|
||||
|
|
@ -723,9 +729,11 @@ done:
|
|||
|
||||
int reftable_stack_add(struct reftable_stack *st,
|
||||
int (*write)(struct reftable_writer *wr, void *arg),
|
||||
void *arg, unsigned flags)
|
||||
void *arg,
|
||||
const struct reftable_write_options *opts,
|
||||
unsigned flags)
|
||||
{
|
||||
int err = stack_try_add(st, write, arg, flags);
|
||||
int err = stack_try_add(st, write, arg, opts, flags);
|
||||
if (err < 0) {
|
||||
if (err == REFTABLE_OUTDATED_ERROR) {
|
||||
/* Ignore error return, we want to propagate
|
||||
|
|
@ -810,7 +818,7 @@ int reftable_addition_commit(struct reftable_addition *add)
|
|||
if (err)
|
||||
goto done;
|
||||
|
||||
if (!add->stack->opts.disable_auto_compact) {
|
||||
if (!add->opts.disable_auto_compact) {
|
||||
/*
|
||||
* Auto-compact the stack to keep the number of tables in
|
||||
* control. It is possible that a concurrent writer is already
|
||||
|
|
@ -820,7 +828,7 @@ int reftable_addition_commit(struct reftable_addition *add)
|
|||
* concurrent writer, which causes `REFTABLE_OUTDATED_ERROR`.
|
||||
* Both of these errors are benign, so we simply ignore them.
|
||||
*/
|
||||
err = reftable_stack_auto_compact(add->stack);
|
||||
err = reftable_stack_auto_compact(add->stack, &add->opts);
|
||||
if (err < 0 && err != REFTABLE_LOCK_ERROR &&
|
||||
err != REFTABLE_OUTDATED_ERROR)
|
||||
goto done;
|
||||
|
|
@ -834,6 +842,7 @@ done:
|
|||
|
||||
int reftable_stack_new_addition(struct reftable_addition **dest,
|
||||
struct reftable_stack *st,
|
||||
const struct reftable_write_options *opts,
|
||||
unsigned int flags)
|
||||
{
|
||||
int err;
|
||||
|
|
@ -842,7 +851,7 @@ int reftable_stack_new_addition(struct reftable_addition **dest,
|
|||
if (!*dest)
|
||||
return REFTABLE_OUT_OF_MEMORY_ERROR;
|
||||
|
||||
err = reftable_stack_init_addition(*dest, st, flags);
|
||||
err = reftable_stack_init_addition(*dest, st, opts, flags);
|
||||
if (err) {
|
||||
reftable_free(*dest);
|
||||
*dest = NULL;
|
||||
|
|
@ -862,7 +871,7 @@ int reftable_addition_add(struct reftable_addition *add,
|
|||
struct reftable_writer *wr = NULL;
|
||||
struct reftable_tmpfile tab_file = REFTABLE_TMPFILE_INIT;
|
||||
struct fd_writer writer = {
|
||||
.opts = &add->stack->opts,
|
||||
.opts = &add->opts,
|
||||
};
|
||||
int err = 0;
|
||||
|
||||
|
|
@ -883,9 +892,9 @@ int reftable_addition_add(struct reftable_addition *add,
|
|||
err = tmpfile_from_pattern(&tab_file, temp_tab_file_name.buf);
|
||||
if (err < 0)
|
||||
goto done;
|
||||
if (add->stack->opts.default_permissions) {
|
||||
if (add->opts.default_permissions) {
|
||||
if (chmod(tab_file.path,
|
||||
add->stack->opts.default_permissions)) {
|
||||
add->opts.default_permissions)) {
|
||||
err = REFTABLE_IO_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -893,7 +902,7 @@ int reftable_addition_add(struct reftable_addition *add,
|
|||
|
||||
writer.fd = tab_file.fd;
|
||||
err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush,
|
||||
&writer, &add->stack->opts);
|
||||
&writer, add->stack->opts.hash_id, &add->opts);
|
||||
if (err < 0)
|
||||
goto done;
|
||||
|
||||
|
|
@ -1066,13 +1075,14 @@ done:
|
|||
static int stack_compact_locked(struct reftable_stack *st,
|
||||
size_t first, size_t last,
|
||||
struct reftable_log_expiry_config *config,
|
||||
const struct reftable_write_options *opts,
|
||||
struct reftable_tmpfile *tab_file_out)
|
||||
{
|
||||
struct reftable_buf next_name = REFTABLE_BUF_INIT;
|
||||
struct reftable_buf tab_file_path = REFTABLE_BUF_INIT;
|
||||
struct reftable_writer *wr = NULL;
|
||||
struct fd_writer writer= {
|
||||
.opts = &st->opts,
|
||||
.opts = opts,
|
||||
};
|
||||
struct reftable_tmpfile tab_file = REFTABLE_TMPFILE_INIT;
|
||||
int err = 0;
|
||||
|
|
@ -1094,15 +1104,15 @@ static int stack_compact_locked(struct reftable_stack *st,
|
|||
if (err < 0)
|
||||
goto done;
|
||||
|
||||
if (st->opts.default_permissions &&
|
||||
chmod(tab_file.path, st->opts.default_permissions) < 0) {
|
||||
if (opts->default_permissions &&
|
||||
chmod(tab_file.path, opts->default_permissions) < 0) {
|
||||
err = REFTABLE_IO_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
writer.fd = tab_file.fd;
|
||||
err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush,
|
||||
&writer, &st->opts);
|
||||
&writer, st->opts.hash_id, opts);
|
||||
if (err < 0)
|
||||
goto done;
|
||||
|
||||
|
|
@ -1150,6 +1160,7 @@ enum stack_compact_range_flags {
|
|||
static int stack_compact_range(struct reftable_stack *st,
|
||||
size_t first, size_t last,
|
||||
struct reftable_log_expiry_config *expiry,
|
||||
const struct reftable_write_options *opts,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct reftable_buf tables_list_buf = REFTABLE_BUF_INIT;
|
||||
|
|
@ -1175,7 +1186,7 @@ static int stack_compact_range(struct reftable_stack *st,
|
|||
* Hold the lock so that we can read "tables.list" and lock all tables
|
||||
* which are part of the user-specified range.
|
||||
*/
|
||||
err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms);
|
||||
err = flock_acquire(&tables_list_lock, st->list_file, opts->lock_timeout_ms);
|
||||
if (err < 0)
|
||||
goto done;
|
||||
|
||||
|
|
@ -1274,7 +1285,7 @@ static int stack_compact_range(struct reftable_stack *st,
|
|||
* these tables may end up with an empty new table in case tombstones
|
||||
* end up cancelling out all refs in that range.
|
||||
*/
|
||||
err = stack_compact_locked(st, first, last, expiry, &new_table);
|
||||
err = stack_compact_locked(st, first, last, expiry, opts, &new_table);
|
||||
if (err < 0) {
|
||||
if (err != REFTABLE_EMPTY_TABLE_ERROR)
|
||||
goto done;
|
||||
|
|
@ -1286,13 +1297,13 @@ static int stack_compact_range(struct reftable_stack *st,
|
|||
* "tables.list". We'll then replace the compacted range of tables with
|
||||
* the new table.
|
||||
*/
|
||||
err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms);
|
||||
err = flock_acquire(&tables_list_lock, st->list_file, opts->lock_timeout_ms);
|
||||
if (err < 0)
|
||||
goto done;
|
||||
|
||||
if (st->opts.default_permissions) {
|
||||
if (opts->default_permissions) {
|
||||
if (chmod(tables_list_lock.path,
|
||||
st->opts.default_permissions) < 0) {
|
||||
opts->default_permissions) < 0) {
|
||||
err = REFTABLE_IO_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -1513,10 +1524,16 @@ done:
|
|||
}
|
||||
|
||||
int reftable_stack_compact_all(struct reftable_stack *st,
|
||||
const struct reftable_write_options *opts,
|
||||
struct reftable_log_expiry_config *config)
|
||||
{
|
||||
struct reftable_write_options opts_default = { 0 };
|
||||
size_t last = st->merged->tables_len ? st->merged->tables_len - 1 : 0;
|
||||
return stack_compact_range(st, 0, last, config, 0);
|
||||
|
||||
if (!opts)
|
||||
opts = &opts_default;
|
||||
|
||||
return stack_compact_range(st, 0, last, config, opts, 0);
|
||||
}
|
||||
|
||||
static int segment_size(struct segment *s)
|
||||
|
|
@ -1601,6 +1618,7 @@ struct segment suggest_compaction_segment(uint64_t *sizes, size_t n,
|
|||
}
|
||||
|
||||
static int stack_segments_for_compaction(struct reftable_stack *st,
|
||||
const struct reftable_write_options *opts,
|
||||
struct segment *seg)
|
||||
{
|
||||
int version = (st->opts.hash_id == REFTABLE_HASH_SHA1) ? 1 : 2;
|
||||
|
|
@ -1615,13 +1633,14 @@ static int stack_segments_for_compaction(struct reftable_stack *st,
|
|||
sizes[i] = st->tables[i]->size - overhead;
|
||||
|
||||
*seg = suggest_compaction_segment(sizes, st->merged->tables_len,
|
||||
st->opts.auto_compaction_factor);
|
||||
opts->auto_compaction_factor);
|
||||
reftable_free(sizes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int update_segment_if_compaction_required(struct reftable_stack *st,
|
||||
const struct reftable_write_options *opts,
|
||||
struct segment *seg,
|
||||
bool use_geometric,
|
||||
bool *required)
|
||||
|
|
@ -1638,7 +1657,7 @@ static int update_segment_if_compaction_required(struct reftable_stack *st,
|
|||
return 0;
|
||||
}
|
||||
|
||||
err = stack_segments_for_compaction(st, seg);
|
||||
err = stack_segments_for_compaction(st, opts, seg);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -1647,27 +1666,40 @@ static int update_segment_if_compaction_required(struct reftable_stack *st,
|
|||
}
|
||||
|
||||
int reftable_stack_compaction_required(struct reftable_stack *st,
|
||||
const struct reftable_write_options *opts,
|
||||
bool use_heuristics,
|
||||
bool *required)
|
||||
{
|
||||
struct reftable_write_options opts_default = { 0 };
|
||||
struct segment seg;
|
||||
return update_segment_if_compaction_required(st, &seg, use_heuristics,
|
||||
required);
|
||||
|
||||
if (!opts)
|
||||
opts = &opts_default;
|
||||
|
||||
return update_segment_if_compaction_required(st, opts, &seg,
|
||||
use_heuristics, required);
|
||||
}
|
||||
|
||||
int reftable_stack_auto_compact(struct reftable_stack *st)
|
||||
int reftable_stack_auto_compact(struct reftable_stack *st,
|
||||
const struct reftable_write_options *opts)
|
||||
{
|
||||
struct reftable_write_options opts_default = { 0 };
|
||||
struct segment seg;
|
||||
bool required;
|
||||
int err;
|
||||
|
||||
err = update_segment_if_compaction_required(st, &seg, true, &required);
|
||||
if (!opts)
|
||||
opts = &opts_default;
|
||||
|
||||
err = update_segment_if_compaction_required(st, opts, &seg, true,
|
||||
&required);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (required)
|
||||
return stack_compact_range(st, seg.start, seg.end - 1,
|
||||
NULL, STACK_COMPACT_RANGE_BEST_EFFORT);
|
||||
NULL, opts,
|
||||
STACK_COMPACT_RANGE_BEST_EFFORT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1807,7 +1839,7 @@ static int reftable_stack_clean_locked(struct reftable_stack *st)
|
|||
int reftable_stack_clean(struct reftable_stack *st)
|
||||
{
|
||||
struct reftable_addition *add = NULL;
|
||||
int err = reftable_stack_new_addition(&add, st, 0);
|
||||
int err = reftable_stack_new_addition(&add, st, NULL, 0);
|
||||
if (err < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ struct reftable_stack {
|
|||
|
||||
char *reftable_dir;
|
||||
|
||||
struct reftable_write_options opts;
|
||||
struct reftable_stack_options opts;
|
||||
|
||||
struct reftable_table **tables;
|
||||
size_t tables_len;
|
||||
|
|
|
|||
|
|
@ -80,9 +80,6 @@ static void options_set_defaults(struct reftable_write_options *opts)
|
|||
opts->restart_interval = 16;
|
||||
}
|
||||
|
||||
if (opts->hash_id == 0) {
|
||||
opts->hash_id = REFTABLE_HASH_SHA1;
|
||||
}
|
||||
if (opts->block_size == 0) {
|
||||
opts->block_size = DEFAULT_BLOCK_SIZE;
|
||||
}
|
||||
|
|
@ -90,7 +87,7 @@ static void options_set_defaults(struct reftable_write_options *opts)
|
|||
|
||||
static int writer_version(struct reftable_writer *w)
|
||||
{
|
||||
return (w->opts.hash_id == 0 || w->opts.hash_id == REFTABLE_HASH_SHA1) ?
|
||||
return (w->hash_id == 0 || w->hash_id == REFTABLE_HASH_SHA1) ?
|
||||
1 :
|
||||
2;
|
||||
}
|
||||
|
|
@ -107,7 +104,7 @@ static int writer_write_header(struct reftable_writer *w, uint8_t *dest)
|
|||
if (writer_version(w) == 2) {
|
||||
uint32_t hash_id;
|
||||
|
||||
switch (w->opts.hash_id) {
|
||||
switch (w->hash_id) {
|
||||
case REFTABLE_HASH_SHA1:
|
||||
hash_id = REFTABLE_FORMAT_ID_SHA1;
|
||||
break;
|
||||
|
|
@ -134,7 +131,7 @@ static int writer_reinit_block_writer(struct reftable_writer *w, uint8_t typ)
|
|||
reftable_buf_reset(&w->last_key);
|
||||
ret = block_writer_init(&w->block_writer_data, typ, w->block,
|
||||
w->opts.block_size, block_start,
|
||||
hash_size(w->opts.hash_id));
|
||||
hash_size(w->hash_id));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
@ -147,7 +144,9 @@ static int writer_reinit_block_writer(struct reftable_writer *w, uint8_t typ)
|
|||
int reftable_writer_new(struct reftable_writer **out,
|
||||
ssize_t (*writer_func)(void *, const void *, size_t),
|
||||
int (*flush_func)(void *),
|
||||
void *writer_arg, const struct reftable_write_options *_opts)
|
||||
void *writer_arg,
|
||||
enum reftable_hash hash_id,
|
||||
const struct reftable_write_options *_opts)
|
||||
{
|
||||
struct reftable_write_options opts = {0};
|
||||
struct reftable_writer *wp;
|
||||
|
|
@ -162,6 +161,9 @@ int reftable_writer_new(struct reftable_writer **out,
|
|||
if (opts.block_size >= (1 << 24))
|
||||
return REFTABLE_API_ERROR;
|
||||
|
||||
if (!hash_id)
|
||||
hash_id = REFTABLE_HASH_SHA1;
|
||||
|
||||
reftable_buf_init(&wp->block_writer_data.last_key);
|
||||
reftable_buf_init(&wp->last_key);
|
||||
reftable_buf_init(&wp->scratch);
|
||||
|
|
@ -173,6 +175,7 @@ int reftable_writer_new(struct reftable_writer **out,
|
|||
wp->write = writer_func;
|
||||
wp->write_arg = writer_arg;
|
||||
wp->opts = opts;
|
||||
wp->hash_id = hash_id;
|
||||
wp->flush = flush_func;
|
||||
writer_reinit_block_writer(wp, REFTABLE_BLOCK_TYPE_REF);
|
||||
|
||||
|
|
@ -367,7 +370,7 @@ int reftable_writer_add_ref(struct reftable_writer *w,
|
|||
if (!w->opts.skip_index_objects && reftable_ref_record_val1(ref)) {
|
||||
reftable_buf_reset(&w->scratch);
|
||||
err = reftable_buf_add(&w->scratch, (char *)reftable_ref_record_val1(ref),
|
||||
hash_size(w->opts.hash_id));
|
||||
hash_size(w->hash_id));
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
|
|
@ -379,7 +382,7 @@ int reftable_writer_add_ref(struct reftable_writer *w,
|
|||
if (!w->opts.skip_index_objects && reftable_ref_record_val2(ref)) {
|
||||
reftable_buf_reset(&w->scratch);
|
||||
err = reftable_buf_add(&w->scratch, reftable_ref_record_val2(ref),
|
||||
hash_size(w->opts.hash_id));
|
||||
hash_size(w->hash_id));
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ struct reftable_writer {
|
|||
uint64_t next;
|
||||
uint64_t min_update_index, max_update_index;
|
||||
struct reftable_write_options opts;
|
||||
enum reftable_hash hash_id;
|
||||
|
||||
/* memory buffer for writing */
|
||||
uint8_t *block;
|
||||
|
|
|
|||
|
|
@ -177,22 +177,6 @@ void repo_settings_set_big_file_threshold(struct repository *repo, unsigned long
|
|||
repo->settings.big_file_threshold = value;
|
||||
}
|
||||
|
||||
enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo)
|
||||
{
|
||||
const char *value;
|
||||
|
||||
if (!repo_config_get_string_tmp(repo, "core.logallrefupdates", &value)) {
|
||||
if (value && !strcasecmp(value, "always"))
|
||||
return LOG_REFS_ALWAYS;
|
||||
else if (git_config_bool("core.logallrefupdates", value))
|
||||
return LOG_REFS_NORMAL;
|
||||
else
|
||||
return LOG_REFS_NONE;
|
||||
}
|
||||
|
||||
return LOG_REFS_UNSET;
|
||||
}
|
||||
|
||||
int repo_settings_get_warn_ambiguous_refs(struct repository *repo)
|
||||
{
|
||||
prepare_repo_settings(repo);
|
||||
|
|
|
|||
|
|
@ -16,13 +16,6 @@ enum fetch_negotiation_setting {
|
|||
FETCH_NEGOTIATION_NOOP,
|
||||
};
|
||||
|
||||
enum log_refs_config {
|
||||
LOG_REFS_UNSET = -1,
|
||||
LOG_REFS_NONE = 0,
|
||||
LOG_REFS_NORMAL,
|
||||
LOG_REFS_ALWAYS
|
||||
};
|
||||
|
||||
struct repo_settings {
|
||||
int initialized;
|
||||
|
||||
|
|
@ -86,8 +79,6 @@ struct repo_settings {
|
|||
void prepare_repo_settings(struct repository *r);
|
||||
void repo_settings_clear(struct repository *r);
|
||||
|
||||
/* Read the value for "core.logAllRefUpdates". */
|
||||
enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo);
|
||||
/* Read the value for "core.warnAmbiguousRefs". */
|
||||
int repo_settings_get_warn_ambiguous_refs(struct repository *repo);
|
||||
/* Read the value for "core.hooksPath". */
|
||||
|
|
|
|||
|
|
@ -422,6 +422,11 @@ void repo_clear(struct repository *repo)
|
|||
FREE_AND_NULL(repo->remote_state);
|
||||
}
|
||||
|
||||
if (repo->refs_private) {
|
||||
ref_store_release(repo->refs_private);
|
||||
FREE_AND_NULL(repo->refs_private);
|
||||
}
|
||||
|
||||
strmap_for_each_entry(&repo->submodule_ref_stores, &iter, e)
|
||||
ref_store_release(e->value);
|
||||
strmap_clear(&repo->submodule_ref_stores, 1);
|
||||
|
|
|
|||
101
setup.c
101
setup.c
|
|
@ -1798,32 +1798,6 @@ int apply_repository_format(struct repository *repo,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the repository format version in the path found in repo_get_git_dir(repo),
|
||||
* and die if it is a version we don't understand. Generally one would
|
||||
* set_git_dir() before calling this, and use it only for "are we in a valid
|
||||
* repo?".
|
||||
*
|
||||
* If successful and fmt is not NULL, fill fmt with data.
|
||||
*/
|
||||
static void check_and_apply_repository_format(struct repository *repo,
|
||||
struct repository_format *fmt,
|
||||
enum apply_repository_format_flags flags)
|
||||
{
|
||||
struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
|
||||
if (!fmt)
|
||||
fmt = &repo_fmt;
|
||||
|
||||
check_repository_format_gently(repo_get_git_dir(repo), fmt, NULL);
|
||||
if (apply_repository_format(repo, fmt, flags, &err) < 0)
|
||||
die("%s", err.buf);
|
||||
startup_info->have_repository = 1;
|
||||
|
||||
clear_repository_format(&repo_fmt);
|
||||
}
|
||||
|
||||
const char *enter_repo(struct repository *repo, const char *path, unsigned flags)
|
||||
{
|
||||
static struct strbuf validated_path = STRBUF_INIT;
|
||||
|
|
@ -1897,9 +1871,17 @@ const char *enter_repo(struct repository *repo, const char *path, unsigned flags
|
|||
}
|
||||
|
||||
if (is_git_directory(".")) {
|
||||
struct repository_format fmt = REPOSITORY_FORMAT_INIT;
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
|
||||
set_git_dir(repo, ".", 0);
|
||||
check_and_apply_repository_format(repo, NULL,
|
||||
APPLY_REPOSITORY_FORMAT_HONOR_ENV);
|
||||
check_repository_format_gently(".", &fmt, NULL);
|
||||
if (apply_repository_format(repo, &fmt, APPLY_REPOSITORY_FORMAT_HONOR_ENV, &err) < 0)
|
||||
die("%s", err.buf);
|
||||
startup_info->have_repository = 1;
|
||||
|
||||
clear_repository_format(&fmt);
|
||||
strbuf_release(&err);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
|
@ -1934,7 +1916,6 @@ const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)
|
|||
static struct strbuf cwd = STRBUF_INIT;
|
||||
struct strbuf dir = STRBUF_INIT, gitdir = STRBUF_INIT, report = STRBUF_INIT;
|
||||
const char *prefix = NULL;
|
||||
const char *ref_backend_uri;
|
||||
struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
|
||||
|
||||
/*
|
||||
|
|
@ -2060,6 +2041,25 @@ const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)
|
|||
|
||||
if (startup_info->have_repository) {
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
const char *ref_backend_uri;
|
||||
|
||||
/*
|
||||
* The env variable should override the repository config
|
||||
* for 'extensions.refStorage'.
|
||||
*/
|
||||
ref_backend_uri = getenv(GIT_REFERENCE_BACKEND_ENVIRONMENT);
|
||||
if (ref_backend_uri) {
|
||||
char *format;
|
||||
|
||||
free(repo_fmt.ref_storage_payload);
|
||||
|
||||
parse_reference_uri(ref_backend_uri, &format, &repo_fmt.ref_storage_payload);
|
||||
repo_fmt.ref_storage_format = ref_storage_format_by_name(format);
|
||||
if (repo_fmt.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
|
||||
die(_("unknown ref storage format: '%s'"), format);
|
||||
|
||||
free(format);
|
||||
}
|
||||
|
||||
if (apply_repository_format(repo, &repo_fmt,
|
||||
APPLY_REPOSITORY_FORMAT_HONOR_ENV, &err) < 0)
|
||||
|
|
@ -2085,25 +2085,6 @@ const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)
|
|||
setenv(GIT_PREFIX_ENVIRONMENT, "", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* The env variable should override the repository config
|
||||
* for 'extensions.refStorage'.
|
||||
*/
|
||||
ref_backend_uri = getenv(GIT_REFERENCE_BACKEND_ENVIRONMENT);
|
||||
if (ref_backend_uri) {
|
||||
char *backend, *payload;
|
||||
enum ref_storage_format format;
|
||||
|
||||
parse_reference_uri(ref_backend_uri, &backend, &payload);
|
||||
format = ref_storage_format_by_name(backend);
|
||||
if (format == REF_STORAGE_FORMAT_UNKNOWN)
|
||||
die(_("unknown ref storage format: '%s'"), backend);
|
||||
repo_set_ref_storage_format(repo, format, payload);
|
||||
|
||||
free(backend);
|
||||
free(payload);
|
||||
}
|
||||
|
||||
setup_original_cwd(repo);
|
||||
|
||||
strbuf_release(&dir);
|
||||
|
|
@ -2613,10 +2594,14 @@ static int create_default_files(struct repository *repo,
|
|||
if (is_bare_repository(repo))
|
||||
repo_config_set(repo, "core.bare", "true");
|
||||
else {
|
||||
const char *value;
|
||||
|
||||
repo_config_set(repo, "core.bare", "false");
|
||||
|
||||
/* allow template config file to override the default */
|
||||
if (repo_settings_get_log_all_ref_updates(repo) == LOG_REFS_UNSET)
|
||||
if (repo_config_get_string_tmp(repo, "core.logallrefupdates", &value))
|
||||
repo_config_set(repo, "core.logallrefupdates", "true");
|
||||
|
||||
if (needs_work_tree_config(original_git_dir, work_tree))
|
||||
repo_config_set(repo, "core.worktree", work_tree);
|
||||
}
|
||||
|
|
@ -2738,8 +2723,7 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void repository_format_configure(struct repository *repo,
|
||||
struct repository_format *repo_fmt,
|
||||
static void repository_format_configure(struct repository_format *repo_fmt,
|
||||
int hash, enum ref_storage_format ref_format)
|
||||
{
|
||||
struct default_format_config cfg = {
|
||||
|
|
@ -2776,7 +2760,6 @@ static void repository_format_configure(struct repository *repo,
|
|||
} else if (cfg.hash != GIT_HASH_UNKNOWN) {
|
||||
repo_fmt->hash_algo = cfg.hash;
|
||||
}
|
||||
repo_set_hash_algo(repo, repo_fmt->hash_algo);
|
||||
|
||||
env = getenv("GIT_DEFAULT_REF_FORMAT");
|
||||
if (repo_fmt->version >= 0 &&
|
||||
|
|
@ -2814,9 +2797,6 @@ static void repository_format_configure(struct repository *repo,
|
|||
|
||||
free(backend);
|
||||
}
|
||||
|
||||
repo_set_ref_storage_format(repo, repo_fmt->ref_storage_format,
|
||||
repo_fmt->ref_storage_payload);
|
||||
}
|
||||
|
||||
int init_db(struct repository *repo,
|
||||
|
|
@ -2830,6 +2810,7 @@ int init_db(struct repository *repo,
|
|||
int exist_ok = flags & INIT_DB_EXIST_OK;
|
||||
char *original_git_dir = real_pathdup(git_dir, 1);
|
||||
struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
|
||||
if (real_git_dir) {
|
||||
struct stat st;
|
||||
|
|
@ -2856,10 +2837,11 @@ int init_db(struct repository *repo,
|
|||
* config file, so this will not fail. What we are catching
|
||||
* is an attempt to reinitialize new repository with an old tool.
|
||||
*/
|
||||
check_and_apply_repository_format(repo, &repo_fmt,
|
||||
APPLY_REPOSITORY_FORMAT_HONOR_ENV);
|
||||
|
||||
repository_format_configure(repo, &repo_fmt, hash, ref_storage_format);
|
||||
check_repository_format_gently(repo_get_git_dir(repo), &repo_fmt, NULL);
|
||||
repository_format_configure(&repo_fmt, hash, ref_storage_format);
|
||||
if (apply_repository_format(repo, &repo_fmt, APPLY_REPOSITORY_FORMAT_HONOR_ENV, &err) < 0)
|
||||
die("%s", err.buf);
|
||||
startup_info->have_repository = 1;
|
||||
|
||||
/*
|
||||
* Ensure `core.hidedotfiles` is processed. This must happen after we
|
||||
|
|
@ -2914,6 +2896,7 @@ int init_db(struct repository *repo,
|
|||
}
|
||||
|
||||
clear_repository_format(&repo_fmt);
|
||||
strbuf_release(&err);
|
||||
free(original_git_dir);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ static int dump_table(struct reftable_merged_table *mt)
|
|||
static int dump_stack(const char *stackdir, uint32_t hash_id)
|
||||
{
|
||||
struct reftable_stack *stack = NULL;
|
||||
struct reftable_write_options opts = { .hash_id = hash_id };
|
||||
struct reftable_stack_options opts = { .hash_id = hash_id };
|
||||
struct reftable_merged_table *merged = NULL;
|
||||
|
||||
int err = reftable_new_stack(&stack, stackdir, &opts);
|
||||
|
|
|
|||
|
|
@ -519,4 +519,25 @@ test_expect_success 'symref transaction supports false symlink config' '
|
|||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success SYMLINKS,!MINGW,!WITH_BREAKING_CHANGES 'core.preferSymlinkRefs can be set up via onbranch condition' '
|
||||
test_when_finished "git symbolic-ref -d TEST_SYMREF_HEAD" &&
|
||||
test_when_finished "rm -f .git/include" &&
|
||||
git update-ref refs/heads/new @ &&
|
||||
cat >.git/include <<-\EOF &&
|
||||
[core]
|
||||
preferSymlinkRefs = true
|
||||
EOF
|
||||
test_config includeIf.onbranch:"$(git branch --show-current)".path \
|
||||
"$(pwd)/.git/include" &&
|
||||
cat >stdin <<-EOF &&
|
||||
start
|
||||
symref-create TEST_SYMREF_HEAD refs/heads/new
|
||||
prepare
|
||||
commit
|
||||
EOF
|
||||
git update-ref --no-deref --stdin <stdin &&
|
||||
test_path_is_symlink .git/TEST_SYMREF_HEAD &&
|
||||
test "$(test_readlink .git/TEST_SYMREF_HEAD)" = refs/heads/new
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
|
|||
|
|
@ -278,4 +278,23 @@ test_expect_success 'object index can be disabled' '
|
|||
)
|
||||
'
|
||||
|
||||
test_expect_success 'write options can be set up via onbranch condition' '
|
||||
test_config_global core.logAllRefUpdates false &&
|
||||
test_when_finished "rm -rf repo" &&
|
||||
init_repo &&
|
||||
(
|
||||
cd repo &&
|
||||
test_commit A &&
|
||||
test_commit B &&
|
||||
cat >.git/include <<-\EOF &&
|
||||
[reftable]
|
||||
blockSize = 123
|
||||
EOF
|
||||
git config includeIf.onbranch:master.path "$(pwd)/.git/include" &&
|
||||
git refs optimize &&
|
||||
test-tool dump-reftable -b .git/reftable/*.ref >stats &&
|
||||
test_grep "block_size: 123" stats
|
||||
)
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
|
|||
|
|
@ -178,6 +178,18 @@ test_expect_success '--no-create-reflog overrides core.logAllRefUpdates=always'
|
|||
test_must_fail git reflog exists $outside
|
||||
'
|
||||
|
||||
test_expect_success 'core.logAllRefUpdates can be set up via onbranch condition' '
|
||||
test_when_finished "git update-ref -d $outside" &&
|
||||
test_when_finished "rm -f .git/include" &&
|
||||
cat >.git/include <<-\EOF &&
|
||||
[core]
|
||||
logAllRefUpdates = always
|
||||
EOF
|
||||
test_config includeIf.onbranch:main.path "$(pwd)/.git/include" &&
|
||||
git update-ref $outside $A &&
|
||||
git reflog exists $outside
|
||||
'
|
||||
|
||||
test_expect_success "create $m (by HEAD)" '
|
||||
git update-ref HEAD $A &&
|
||||
test $A = $(git show-ref -s --verify $m)
|
||||
|
|
|
|||
|
|
@ -25,11 +25,12 @@ static int strbuf_writer_flush(void *arg UNUSED)
|
|||
}
|
||||
|
||||
struct reftable_writer *cl_reftable_strbuf_writer(struct reftable_buf *buf,
|
||||
enum reftable_hash hash_id,
|
||||
struct reftable_write_options *opts)
|
||||
{
|
||||
struct reftable_writer *writer;
|
||||
int ret = reftable_writer_new(&writer, &strbuf_writer_write, &strbuf_writer_flush,
|
||||
buf, opts);
|
||||
buf, hash_id, opts);
|
||||
cl_assert(!ret);
|
||||
return writer;
|
||||
}
|
||||
|
|
@ -39,6 +40,7 @@ void cl_reftable_write_to_buf(struct reftable_buf *buf,
|
|||
size_t nrefs,
|
||||
struct reftable_log_record *logs,
|
||||
size_t nlogs,
|
||||
enum reftable_hash hash_id,
|
||||
struct reftable_write_options *_opts)
|
||||
{
|
||||
struct reftable_write_options opts = { 0 };
|
||||
|
|
@ -66,7 +68,7 @@ void cl_reftable_write_to_buf(struct reftable_buf *buf,
|
|||
min = ui;
|
||||
}
|
||||
|
||||
writer = cl_reftable_strbuf_writer(buf, &opts);
|
||||
writer = cl_reftable_strbuf_writer(buf, hash_id, &opts);
|
||||
ret = reftable_writer_set_limits(writer, min, max);
|
||||
cl_assert(!ret);
|
||||
|
||||
|
|
@ -88,7 +90,7 @@ void cl_reftable_write_to_buf(struct reftable_buf *buf,
|
|||
size_t off = i * (opts.block_size ? opts.block_size
|
||||
: DEFAULT_BLOCK_SIZE);
|
||||
if (!off)
|
||||
off = header_size(opts.hash_id == REFTABLE_HASH_SHA256 ? 2 : 1);
|
||||
off = header_size(hash_id == REFTABLE_HASH_SHA256 ? 2 : 1);
|
||||
cl_assert(buf->buf[off] == 'r');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ struct reftable_buf;
|
|||
void cl_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id);
|
||||
|
||||
struct reftable_writer *cl_reftable_strbuf_writer(struct reftable_buf *buf,
|
||||
enum reftable_hash hash_id,
|
||||
struct reftable_write_options *opts);
|
||||
|
||||
void cl_reftable_write_to_buf(struct reftable_buf *buf,
|
||||
|
|
@ -17,4 +18,5 @@ void cl_reftable_write_to_buf(struct reftable_buf *buf,
|
|||
size_t nrecords,
|
||||
struct reftable_log_record *logs,
|
||||
size_t nlogs,
|
||||
enum reftable_hash hash_id,
|
||||
struct reftable_write_options *opts);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ merged_table_from_records(struct reftable_ref_record **refs,
|
|||
cl_assert(*source != NULL);
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
cl_reftable_write_to_buf(&buf[i], refs[i], sizes[i], NULL, 0, &opts);
|
||||
cl_reftable_write_to_buf(&buf[i], refs[i], sizes[i], NULL, 0,
|
||||
REFTABLE_HASH_SHA1, &opts);
|
||||
block_source_from_buf(&(*source)[i], &buf[i]);
|
||||
|
||||
err = reftable_table_new(&(*tables)[i], &(*source)[i],
|
||||
|
|
@ -357,7 +358,8 @@ merged_table_from_log_records(struct reftable_log_record **logs,
|
|||
cl_assert(*source != NULL);
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
cl_reftable_write_to_buf(&buf[i], NULL, 0, logs[i], sizes[i], &opts);
|
||||
cl_reftable_write_to_buf(&buf[i], NULL, 0, logs[i], sizes[i],
|
||||
REFTABLE_HASH_SHA1, &opts);
|
||||
block_source_from_buf(&(*source)[i], &buf[i]);
|
||||
|
||||
err = reftable_table_new(&(*tables)[i], &(*source)[i],
|
||||
|
|
@ -487,7 +489,8 @@ void test_reftable_merged__default_write_opts(void)
|
|||
{
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_buf buf = REFTABLE_BUF_INIT;
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
|
||||
REFTABLE_HASH_SHA1, &opts);
|
||||
struct reftable_ref_record rec = {
|
||||
.refname = (char *) "master",
|
||||
.update_index = 1,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ static void write_table(char ***names, struct reftable_buf *buf, int N,
|
|||
{
|
||||
struct reftable_write_options opts = {
|
||||
.block_size = block_size,
|
||||
.hash_id = hash_id,
|
||||
};
|
||||
struct reftable_ref_record *refs;
|
||||
struct reftable_log_record *logs;
|
||||
|
|
@ -78,7 +77,7 @@ static void write_table(char ***names, struct reftable_buf *buf, int N,
|
|||
logs[i].value.update.message = (char *) "message";
|
||||
}
|
||||
|
||||
cl_reftable_write_to_buf(buf, refs, N, logs, N, &opts);
|
||||
cl_reftable_write_to_buf(buf, refs, N, logs, N, hash_id, &opts);
|
||||
|
||||
reftable_free(refs);
|
||||
reftable_free(logs);
|
||||
|
|
@ -103,6 +102,7 @@ void test_reftable_readwrite__log_buffer_size(void)
|
|||
.message = (char *) "commit: 9\n",
|
||||
} } };
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
|
||||
REFTABLE_HASH_SHA1,
|
||||
&opts);
|
||||
|
||||
/* This tests buffer extension for log compression. Must use a random
|
||||
|
|
@ -143,6 +143,7 @@ void test_reftable_readwrite__log_overflow(void)
|
|||
},
|
||||
};
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
|
||||
REFTABLE_HASH_SHA1,
|
||||
&opts);
|
||||
|
||||
memset(msg, 'x', sizeof(msg) - 1);
|
||||
|
|
@ -157,6 +158,7 @@ void test_reftable_readwrite__log_write_limits(void)
|
|||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_buf buf = REFTABLE_BUF_INIT;
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
|
||||
REFTABLE_HASH_SHA1,
|
||||
&opts);
|
||||
struct reftable_log_record log = {
|
||||
.refname = (char *)"refs/head/master",
|
||||
|
|
@ -202,7 +204,9 @@ void test_reftable_readwrite__log_write_read(void)
|
|||
struct reftable_table *table;
|
||||
struct reftable_block_source source = { 0 };
|
||||
struct reftable_buf buf = REFTABLE_BUF_INIT;
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
|
||||
REFTABLE_HASH_SHA1,
|
||||
&opts);
|
||||
const struct reftable_stats *stats = NULL;
|
||||
int N = 2, i;
|
||||
char **names;
|
||||
|
|
@ -299,6 +303,7 @@ void test_reftable_readwrite__log_zlib_corruption(void)
|
|||
struct reftable_block_source source = { 0 };
|
||||
struct reftable_buf buf = REFTABLE_BUF_INIT;
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
|
||||
REFTABLE_HASH_SHA1,
|
||||
&opts);
|
||||
const struct reftable_stats *stats = NULL;
|
||||
char message[100] = { 0 };
|
||||
|
|
@ -531,6 +536,7 @@ static void t_table_refs_for(int indexed)
|
|||
struct reftable_block_source source = { 0 };
|
||||
struct reftable_buf buf = REFTABLE_BUF_INIT;
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
|
||||
REFTABLE_HASH_SHA1,
|
||||
&opts);
|
||||
struct reftable_iterator it = { 0 };
|
||||
int N = 50, j, i;
|
||||
|
|
@ -622,7 +628,9 @@ void test_reftable_readwrite__write_empty_table(void)
|
|||
{
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_buf buf = REFTABLE_BUF_INIT;
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
|
||||
REFTABLE_HASH_SHA1,
|
||||
&opts);
|
||||
struct reftable_block_source source = { 0 };
|
||||
struct reftable_table *table = NULL;
|
||||
struct reftable_ref_record rec = { 0 };
|
||||
|
|
@ -660,7 +668,9 @@ void test_reftable_readwrite__write_object_id_min_length(void)
|
|||
.block_size = 75,
|
||||
};
|
||||
struct reftable_buf buf = REFTABLE_BUF_INIT;
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
|
||||
REFTABLE_HASH_SHA1,
|
||||
&opts);
|
||||
struct reftable_ref_record ref = {
|
||||
.update_index = 1,
|
||||
.value_type = REFTABLE_REF_VAL1,
|
||||
|
|
@ -691,7 +701,9 @@ void test_reftable_readwrite__write_object_id_length(void)
|
|||
.block_size = 75,
|
||||
};
|
||||
struct reftable_buf buf = REFTABLE_BUF_INIT;
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
|
||||
REFTABLE_HASH_SHA1,
|
||||
&opts);
|
||||
struct reftable_ref_record ref = {
|
||||
.update_index = 1,
|
||||
.value_type = REFTABLE_REF_VAL1,
|
||||
|
|
@ -721,7 +733,9 @@ void test_reftable_readwrite__write_empty_key(void)
|
|||
{
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_buf buf = REFTABLE_BUF_INIT;
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
|
||||
REFTABLE_HASH_SHA1,
|
||||
&opts);
|
||||
struct reftable_ref_record ref = {
|
||||
.refname = (char *) "",
|
||||
.update_index = 1,
|
||||
|
|
@ -740,7 +754,9 @@ void test_reftable_readwrite__write_key_order(void)
|
|||
{
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_buf buf = REFTABLE_BUF_INIT;
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
|
||||
struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
|
||||
REFTABLE_HASH_SHA1,
|
||||
&opts);
|
||||
struct reftable_ref_record refs[2] = {
|
||||
{
|
||||
.refname = (char *) "b",
|
||||
|
|
@ -787,7 +803,8 @@ void test_reftable_readwrite__write_multiple_indices(void)
|
|||
int i;
|
||||
int err;
|
||||
|
||||
writer = cl_reftable_strbuf_writer(&writer_buf, &opts);
|
||||
writer = cl_reftable_strbuf_writer(&writer_buf, REFTABLE_HASH_SHA1,
|
||||
&opts);
|
||||
reftable_writer_set_limits(writer, 1, 1);
|
||||
for (i = 0; i < 100; i++) {
|
||||
struct reftable_ref_record ref = {
|
||||
|
|
@ -861,7 +878,8 @@ void test_reftable_readwrite__write_multi_level_index(void)
|
|||
struct reftable_table *table;
|
||||
int err;
|
||||
|
||||
writer = cl_reftable_strbuf_writer(&writer_buf, &opts);
|
||||
writer = cl_reftable_strbuf_writer(&writer_buf, REFTABLE_HASH_SHA1,
|
||||
&opts);
|
||||
reftable_writer_set_limits(writer, 1, 1);
|
||||
for (size_t i = 0; i < 200; i++) {
|
||||
struct reftable_ref_record ref = {
|
||||
|
|
|
|||
|
|
@ -111,10 +111,9 @@ static int write_test_ref(struct reftable_writer *wr, void *arg)
|
|||
static void write_n_ref_tables(struct reftable_stack *st,
|
||||
size_t n)
|
||||
{
|
||||
int disable_auto_compact;
|
||||
|
||||
disable_auto_compact = st->opts.disable_auto_compact;
|
||||
st->opts.disable_auto_compact = 1;
|
||||
struct reftable_write_options opts = {
|
||||
.disable_auto_compact = 1,
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
struct reftable_ref_record ref = {
|
||||
|
|
@ -128,10 +127,8 @@ static void write_n_ref_tables(struct reftable_stack *st,
|
|||
cl_reftable_set_hash(ref.value.val1, i, REFTABLE_HASH_SHA1);
|
||||
|
||||
cl_assert_equal_i(reftable_stack_add(st,
|
||||
&write_test_ref, &ref, 0), 0);
|
||||
&write_test_ref, &ref, &opts, 0), 0);
|
||||
}
|
||||
|
||||
st->opts.disable_auto_compact = disable_auto_compact;
|
||||
}
|
||||
|
||||
struct write_log_arg {
|
||||
|
|
@ -168,10 +165,10 @@ void test_reftable_stack__add_one(void)
|
|||
struct stat stat_result = { 0 };
|
||||
int err;
|
||||
|
||||
err = reftable_new_stack(&st, dir, &opts);
|
||||
err = reftable_new_stack(&st, dir, NULL);
|
||||
cl_assert(!err);
|
||||
|
||||
err = reftable_stack_add(st, write_test_ref, &ref, 0);
|
||||
err = reftable_stack_add(st, write_test_ref, &ref, &opts, 0);
|
||||
cl_assert(!err);
|
||||
|
||||
err = reftable_stack_read_ref(st, ref.refname, &dest);
|
||||
|
|
@ -210,7 +207,6 @@ void test_reftable_stack__add_one(void)
|
|||
|
||||
void test_reftable_stack__uptodate(void)
|
||||
{
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st1 = NULL;
|
||||
struct reftable_stack *st2 = NULL;
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
|
|
@ -232,15 +228,15 @@ void test_reftable_stack__uptodate(void)
|
|||
/* simulate multi-process access to the same stack
|
||||
by creating two stacks for the same directory.
|
||||
*/
|
||||
cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st1, dir, NULL), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st2, dir, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_add(st1, write_test_ref,
|
||||
&ref1, 0), 0);
|
||||
&ref1, NULL, 0), 0);
|
||||
cl_assert_equal_i(reftable_stack_add(st2, write_test_ref,
|
||||
&ref2, 0), REFTABLE_OUTDATED_ERROR);
|
||||
&ref2, NULL, 0), REFTABLE_OUTDATED_ERROR);
|
||||
cl_assert_equal_i(reftable_stack_reload(st2), 0);
|
||||
cl_assert_equal_i(reftable_stack_add(st2, write_test_ref,
|
||||
&ref2, 0), 0);
|
||||
&ref2, NULL, 0), 0);
|
||||
reftable_stack_destroy(st1);
|
||||
reftable_stack_destroy(st2);
|
||||
clear_dir(dir);
|
||||
|
|
@ -249,7 +245,6 @@ void test_reftable_stack__uptodate(void)
|
|||
void test_reftable_stack__transaction_api(void)
|
||||
{
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st = NULL;
|
||||
struct reftable_addition *add = NULL;
|
||||
|
||||
|
|
@ -261,11 +256,11 @@ void test_reftable_stack__transaction_api(void)
|
|||
};
|
||||
struct reftable_ref_record dest = { 0 };
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
|
||||
reftable_addition_destroy(add);
|
||||
|
||||
cl_assert_equal_i(reftable_stack_new_addition(&add, st, 0), 0);
|
||||
cl_assert_equal_i(reftable_stack_new_addition(&add, st, NULL, 0), 0);
|
||||
cl_assert_equal_i(reftable_addition_add(add, write_test_ref,
|
||||
&ref), 0);
|
||||
cl_assert_equal_i(reftable_addition_commit(add), 0);
|
||||
|
|
@ -306,7 +301,7 @@ void test_reftable_stack__transaction_with_reload(void)
|
|||
|
||||
cl_assert_equal_i(reftable_new_stack(&st1, dir, NULL), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st2, dir, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_new_addition(&add, st1, 0), 0);
|
||||
cl_assert_equal_i(reftable_stack_new_addition(&add, st1, NULL, 0), 0);
|
||||
cl_assert_equal_i(reftable_addition_add(add, write_test_ref,
|
||||
&refs[0]), 0);
|
||||
cl_assert_equal_i(reftable_addition_commit(add), 0);
|
||||
|
|
@ -317,9 +312,9 @@ void test_reftable_stack__transaction_with_reload(void)
|
|||
* create the addition and lock the stack by default, but allow the
|
||||
* reload to happen when REFTABLE_STACK_NEW_ADDITION_RELOAD is set.
|
||||
*/
|
||||
cl_assert_equal_i(reftable_stack_new_addition(&add, st2, 0),
|
||||
cl_assert_equal_i(reftable_stack_new_addition(&add, st2, NULL, 0),
|
||||
REFTABLE_OUTDATED_ERROR);
|
||||
cl_assert_equal_i(reftable_stack_new_addition(&add, st2,
|
||||
cl_assert_equal_i(reftable_stack_new_addition(&add, st2, NULL,
|
||||
REFTABLE_STACK_NEW_ADDITION_RELOAD), 0);
|
||||
cl_assert_equal_i(reftable_addition_add(add, write_test_ref,
|
||||
&refs[1]), 0);
|
||||
|
|
@ -342,12 +337,11 @@ void test_reftable_stack__transaction_with_reload(void)
|
|||
void test_reftable_stack__transaction_api_performs_auto_compaction(void)
|
||||
{
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
struct reftable_write_options opts = {0};
|
||||
struct reftable_addition *add = NULL;
|
||||
struct reftable_stack *st = NULL;
|
||||
size_t n = 20;
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
|
||||
for (size_t i = 0; i <= n; i++) {
|
||||
struct reftable_ref_record ref = {
|
||||
|
|
@ -356,6 +350,9 @@ void test_reftable_stack__transaction_api_performs_auto_compaction(void)
|
|||
.value.symref = (char *) "master",
|
||||
};
|
||||
char name[100];
|
||||
struct reftable_write_options write_opts = {
|
||||
.disable_auto_compact = (i != n),
|
||||
};
|
||||
|
||||
snprintf(name, sizeof(name), "branch%04"PRIuMAX, (uintmax_t)i);
|
||||
ref.refname = name;
|
||||
|
|
@ -365,10 +362,8 @@ void test_reftable_stack__transaction_api_performs_auto_compaction(void)
|
|||
* we can ensure that we indeed honor this setting and have
|
||||
* better control over when exactly auto compaction runs.
|
||||
*/
|
||||
st->opts.disable_auto_compact = i != n;
|
||||
|
||||
cl_assert_equal_i(reftable_stack_new_addition(&add,
|
||||
st, 0), 0);
|
||||
st, &write_opts, 0), 0);
|
||||
cl_assert_equal_i(reftable_addition_add(add,
|
||||
write_test_ref, &ref), 0);
|
||||
cl_assert_equal_i(reftable_addition_commit(add), 0);
|
||||
|
|
@ -398,15 +393,14 @@ void test_reftable_stack__auto_compaction_fails_gracefully(void)
|
|||
.value_type = REFTABLE_REF_VAL1,
|
||||
.value.val1 = {0x01},
|
||||
};
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st;
|
||||
struct reftable_buf table_path = REFTABLE_BUF_INIT;
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
int err;
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
|
||||
&ref, 0), 0);
|
||||
&ref, NULL, 0), 0);
|
||||
cl_assert_equal_i(st->merged->tables_len, 1);
|
||||
cl_assert_equal_i(st->stats.attempts, 0);
|
||||
cl_assert_equal_i(st->stats.failures, 0);
|
||||
|
|
@ -424,7 +418,7 @@ void test_reftable_stack__auto_compaction_fails_gracefully(void)
|
|||
write_file_buf(table_path.buf, "", 0);
|
||||
|
||||
ref.update_index = 2;
|
||||
err = reftable_stack_add(st, write_test_ref, &ref, 0);
|
||||
err = reftable_stack_add(st, write_test_ref, &ref, NULL, 0);
|
||||
cl_assert(!err);
|
||||
cl_assert_equal_i(st->merged->tables_len, 2);
|
||||
cl_assert_equal_i(st->stats.attempts, 1);
|
||||
|
|
@ -443,7 +437,6 @@ static int write_error(struct reftable_writer *wr UNUSED, void *arg)
|
|||
void test_reftable_stack__update_index_check(void)
|
||||
{
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st = NULL;
|
||||
struct reftable_ref_record ref1 = {
|
||||
.refname = (char *) "name1",
|
||||
|
|
@ -458,11 +451,11 @@ void test_reftable_stack__update_index_check(void)
|
|||
.value.symref = (char *) "master",
|
||||
};
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
|
||||
&ref1, 0), 0);
|
||||
&ref1, NULL, 0), 0);
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
|
||||
&ref2, 0), REFTABLE_API_ERROR);
|
||||
&ref2, NULL, 0), REFTABLE_API_ERROR);
|
||||
reftable_stack_destroy(st);
|
||||
clear_dir(dir);
|
||||
}
|
||||
|
|
@ -470,14 +463,13 @@ void test_reftable_stack__update_index_check(void)
|
|||
void test_reftable_stack__lock_failure(void)
|
||||
{
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st = NULL;
|
||||
int i;
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
for (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--)
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_error,
|
||||
&i, 0), i);
|
||||
&i, NULL, 0), i);
|
||||
|
||||
reftable_stack_destroy(st);
|
||||
clear_dir(dir);
|
||||
|
|
@ -499,7 +491,7 @@ void test_reftable_stack__add(void)
|
|||
size_t i, N = ARRAY_SIZE(refs);
|
||||
int err = 0;
|
||||
|
||||
err = reftable_new_stack(&st, dir, &opts);
|
||||
err = reftable_new_stack(&st, dir, NULL);
|
||||
cl_assert(!err);
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
|
|
@ -521,7 +513,7 @@ void test_reftable_stack__add(void)
|
|||
|
||||
for (i = 0; i < N; i++)
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
|
||||
&refs[i], 0), 0);
|
||||
&refs[i], &opts, 0), 0);
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
struct write_log_arg arg = {
|
||||
|
|
@ -529,10 +521,10 @@ void test_reftable_stack__add(void)
|
|||
.update_index = reftable_stack_next_update_index(st),
|
||||
};
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
|
||||
&arg, 0), 0);
|
||||
&arg, &opts, 0), 0);
|
||||
}
|
||||
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st, &opts, NULL), 0);
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
struct reftable_ref_record dest = { 0 };
|
||||
|
|
@ -584,7 +576,6 @@ void test_reftable_stack__add(void)
|
|||
|
||||
void test_reftable_stack__iterator(void)
|
||||
{
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st = NULL;
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
struct reftable_ref_record refs[10] = { 0 };
|
||||
|
|
@ -593,7 +584,7 @@ void test_reftable_stack__iterator(void)
|
|||
size_t N = ARRAY_SIZE(refs), i;
|
||||
int err;
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
refs[i].refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i);
|
||||
|
|
@ -613,7 +604,7 @@ void test_reftable_stack__iterator(void)
|
|||
|
||||
for (i = 0; i < N; i++)
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
|
||||
&refs[i], 0), 0);
|
||||
&refs[i], NULL, 0), 0);
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
struct write_log_arg arg = {
|
||||
|
|
@ -622,7 +613,7 @@ void test_reftable_stack__iterator(void)
|
|||
};
|
||||
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
|
||||
&arg, 0), 0);
|
||||
&arg, NULL, 0), 0);
|
||||
}
|
||||
|
||||
reftable_stack_init_ref_iterator(st, &it);
|
||||
|
|
@ -669,9 +660,6 @@ void test_reftable_stack__iterator(void)
|
|||
|
||||
void test_reftable_stack__log_normalize(void)
|
||||
{
|
||||
struct reftable_write_options opts = {
|
||||
0,
|
||||
};
|
||||
struct reftable_stack *st = NULL;
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
struct reftable_log_record input = {
|
||||
|
|
@ -693,15 +681,15 @@ void test_reftable_stack__log_normalize(void)
|
|||
.update_index = 1,
|
||||
};
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
|
||||
input.value.update.message = (char *) "one\ntwo";
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
|
||||
&arg, 0), REFTABLE_API_ERROR);
|
||||
&arg, NULL, 0), REFTABLE_API_ERROR);
|
||||
|
||||
input.value.update.message = (char *) "one";
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
|
||||
&arg, 0), 0);
|
||||
&arg, NULL, 0), 0);
|
||||
cl_assert_equal_i(reftable_stack_read_log(st, input.refname,
|
||||
&dest), 0);
|
||||
cl_assert_equal_s(dest.value.update.message, "one\n");
|
||||
|
|
@ -709,7 +697,7 @@ void test_reftable_stack__log_normalize(void)
|
|||
input.value.update.message = (char *) "two\n";
|
||||
arg.update_index = 2;
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
|
||||
&arg, 0), 0);
|
||||
&arg, NULL, 0), 0);
|
||||
cl_assert_equal_i(reftable_stack_read_log(st, input.refname,
|
||||
&dest), 0);
|
||||
cl_assert_equal_s(dest.value.update.message, "two\n");
|
||||
|
|
@ -723,7 +711,6 @@ void test_reftable_stack__log_normalize(void)
|
|||
void test_reftable_stack__tombstone(void)
|
||||
{
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st = NULL;
|
||||
struct reftable_ref_record refs[2] = { 0 };
|
||||
struct reftable_log_record logs[2] = { 0 };
|
||||
|
|
@ -731,7 +718,7 @@ void test_reftable_stack__tombstone(void)
|
|||
struct reftable_ref_record dest = { 0 };
|
||||
struct reftable_log_record log_dest = { 0 };
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
|
||||
/* even entries add the refs, odd entries delete them. */
|
||||
for (i = 0; i < N; i++) {
|
||||
|
|
@ -760,7 +747,7 @@ void test_reftable_stack__tombstone(void)
|
|||
}
|
||||
for (i = 0; i < N; i++)
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
|
||||
&refs[i], 0), 0);
|
||||
&refs[i], NULL, 0), 0);
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
struct write_log_arg arg = {
|
||||
|
|
@ -768,7 +755,7 @@ void test_reftable_stack__tombstone(void)
|
|||
.update_index = reftable_stack_next_update_index(st),
|
||||
};
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
|
||||
&arg, 0), 0);
|
||||
&arg, NULL, 0), 0);
|
||||
}
|
||||
|
||||
cl_assert_equal_i(reftable_stack_read_ref(st, "branch",
|
||||
|
|
@ -779,7 +766,7 @@ void test_reftable_stack__tombstone(void)
|
|||
&log_dest), 1);
|
||||
reftable_log_record_release(&log_dest);
|
||||
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st, NULL, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_read_ref(st, "branch",
|
||||
&dest), 1);
|
||||
cl_assert_equal_i(reftable_stack_read_log(st, "branch",
|
||||
|
|
@ -799,7 +786,6 @@ void test_reftable_stack__tombstone(void)
|
|||
void test_reftable_stack__hash_id(void)
|
||||
{
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st = NULL;
|
||||
|
||||
struct reftable_ref_record ref = {
|
||||
|
|
@ -808,15 +794,14 @@ void test_reftable_stack__hash_id(void)
|
|||
.value.symref = (char *) "target",
|
||||
.update_index = 1,
|
||||
};
|
||||
struct reftable_write_options opts32 = { .hash_id = REFTABLE_HASH_SHA256 };
|
||||
struct reftable_stack_options opts32 = { .hash_id = REFTABLE_HASH_SHA256 };
|
||||
struct reftable_stack *st32 = NULL;
|
||||
struct reftable_write_options opts_default = { 0 };
|
||||
struct reftable_stack *st_default = NULL;
|
||||
struct reftable_ref_record dest = { 0 };
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
|
||||
&ref, 0), 0);
|
||||
&ref, NULL, 0), 0);
|
||||
|
||||
/* can't read it with the wrong hash ID. */
|
||||
cl_assert_equal_i(reftable_new_stack(&st32, dir,
|
||||
|
|
@ -824,7 +809,7 @@ void test_reftable_stack__hash_id(void)
|
|||
|
||||
/* check that we can read it back with default opts too. */
|
||||
cl_assert_equal_i(reftable_new_stack(&st_default, dir,
|
||||
&opts_default), 0);
|
||||
NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_read_ref(st_default, "master",
|
||||
&dest), 0);
|
||||
cl_assert(reftable_ref_record_equal(&ref, &dest,
|
||||
|
|
@ -855,7 +840,6 @@ void test_reftable_stack__suggest_compaction_segment_nothing(void)
|
|||
void test_reftable_stack__reflog_expire(void)
|
||||
{
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st = NULL;
|
||||
struct reftable_log_record logs[20] = { 0 };
|
||||
size_t i, N = ARRAY_SIZE(logs) - 1;
|
||||
|
|
@ -864,7 +848,7 @@ void test_reftable_stack__reflog_expire(void)
|
|||
};
|
||||
struct reftable_log_record log = { 0 };
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
|
||||
for (i = 1; i <= N; i++) {
|
||||
char buf[256];
|
||||
|
|
@ -885,18 +869,18 @@ void test_reftable_stack__reflog_expire(void)
|
|||
.update_index = reftable_stack_next_update_index(st),
|
||||
};
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
|
||||
&arg, 0), 0);
|
||||
&arg, NULL, 0), 0);
|
||||
}
|
||||
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st, &expiry), 0);
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st, NULL, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st, NULL, &expiry), 0);
|
||||
cl_assert_equal_i(reftable_stack_read_log(st, logs[9].refname,
|
||||
&log), 1);
|
||||
cl_assert_equal_i(reftable_stack_read_log(st, logs[11].refname,
|
||||
&log), 0);
|
||||
|
||||
expiry.min_update_index = 15;
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st, &expiry), 0);
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st, NULL, &expiry), 0);
|
||||
cl_assert_equal_i(reftable_stack_read_log(st, logs[14].refname,
|
||||
&log), 1);
|
||||
cl_assert_equal_i(reftable_stack_read_log(st, logs[16].refname,
|
||||
|
|
@ -918,15 +902,14 @@ static int write_nothing(struct reftable_writer *wr, void *arg UNUSED)
|
|||
|
||||
void test_reftable_stack__empty_add(void)
|
||||
{
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st = NULL;
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
struct reftable_stack *st2 = NULL;
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_nothing,
|
||||
NULL, 0), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0);
|
||||
NULL, NULL, 0), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st2, dir, NULL), 0);
|
||||
clear_dir(dir);
|
||||
reftable_stack_destroy(st);
|
||||
reftable_stack_destroy(st2);
|
||||
|
|
@ -952,7 +935,7 @@ void test_reftable_stack__auto_compaction(void)
|
|||
size_t i, N = 100;
|
||||
int err;
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
char name[100];
|
||||
|
|
@ -964,10 +947,10 @@ void test_reftable_stack__auto_compaction(void)
|
|||
};
|
||||
snprintf(name, sizeof(name), "branch%04"PRIuMAX, (uintmax_t)i);
|
||||
|
||||
err = reftable_stack_add(st, write_test_ref, &ref, 0);
|
||||
err = reftable_stack_add(st, write_test_ref, &ref, &opts, 0);
|
||||
cl_assert(!err);
|
||||
|
||||
err = reftable_stack_auto_compact(st);
|
||||
err = reftable_stack_auto_compact(st, &opts);
|
||||
cl_assert(!err);
|
||||
cl_assert(i < 2 || st->merged->tables_len < 2 * fastlogN(i, 2));
|
||||
}
|
||||
|
|
@ -989,7 +972,7 @@ void test_reftable_stack__auto_compaction_factor(void)
|
|||
size_t N = 100;
|
||||
int err;
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
char name[20];
|
||||
|
|
@ -1000,7 +983,7 @@ void test_reftable_stack__auto_compaction_factor(void)
|
|||
};
|
||||
xsnprintf(name, sizeof(name), "branch%04"PRIuMAX, (uintmax_t)i);
|
||||
|
||||
err = reftable_stack_add(st, &write_test_ref, &ref, 0);
|
||||
err = reftable_stack_add(st, &write_test_ref, &ref, &opts, 0);
|
||||
cl_assert(!err);
|
||||
|
||||
cl_assert(i < 5 || st->merged->tables_len < 5 * fastlogN(i, 5));
|
||||
|
|
@ -1020,7 +1003,7 @@ void test_reftable_stack__auto_compaction_with_locked_tables(void)
|
|||
char *dir = get_tmp_dir(__LINE__);
|
||||
int err;
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
|
||||
write_n_ref_tables(st, 5);
|
||||
cl_assert_equal_i(st->merged->tables_len, 5);
|
||||
|
|
@ -1042,7 +1025,7 @@ void test_reftable_stack__auto_compaction_with_locked_tables(void)
|
|||
* would in theory compact all tables, due to the preexisting lock we
|
||||
* only compact the newest two tables.
|
||||
*/
|
||||
err = reftable_stack_auto_compact(st);
|
||||
err = reftable_stack_auto_compact(st, &opts);
|
||||
cl_assert(!err);
|
||||
cl_assert_equal_i(st->stats.failures, 0);
|
||||
cl_assert_equal_i(st->merged->tables_len, 4);
|
||||
|
|
@ -1054,12 +1037,11 @@ void test_reftable_stack__auto_compaction_with_locked_tables(void)
|
|||
|
||||
void test_reftable_stack__add_performs_auto_compaction(void)
|
||||
{
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st = NULL;
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
size_t i, n = 20;
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
|
||||
for (i = 0; i <= n; i++) {
|
||||
struct reftable_ref_record ref = {
|
||||
|
|
@ -1067,6 +1049,9 @@ void test_reftable_stack__add_performs_auto_compaction(void)
|
|||
.value_type = REFTABLE_REF_SYMREF,
|
||||
.value.symref = (char *) "master",
|
||||
};
|
||||
struct reftable_write_options write_opts = {
|
||||
.disable_auto_compact = (i != n),
|
||||
};
|
||||
bool required = false;
|
||||
char buf[128];
|
||||
|
||||
|
|
@ -1075,20 +1060,18 @@ void test_reftable_stack__add_performs_auto_compaction(void)
|
|||
* we can ensure that we indeed honor this setting and have
|
||||
* better control over when exactly auto compaction runs.
|
||||
*/
|
||||
st->opts.disable_auto_compact = i != n;
|
||||
|
||||
snprintf(buf, sizeof(buf), "branch-%04"PRIuMAX, (uintmax_t)i);
|
||||
ref.refname = buf;
|
||||
|
||||
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
|
||||
&ref, 0), 0);
|
||||
&ref, &write_opts, 0), 0);
|
||||
|
||||
/*
|
||||
* The stack length should grow continuously for all runs where
|
||||
* auto compaction is disabled. When enabled, we should merge
|
||||
* all tables in the stack.
|
||||
*/
|
||||
cl_assert_equal_i(reftable_stack_compaction_required(st, true, &required), 0);
|
||||
cl_assert_equal_i(reftable_stack_compaction_required(st, NULL, true, &required), 0);
|
||||
if (i != n) {
|
||||
cl_assert_equal_i(st->merged->tables_len, i + 1);
|
||||
if (i < 1)
|
||||
|
|
@ -1115,7 +1098,7 @@ void test_reftable_stack__compaction_with_locked_tables(void)
|
|||
char *dir = get_tmp_dir(__LINE__);
|
||||
int err;
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
|
||||
write_n_ref_tables(st, 3);
|
||||
cl_assert_equal_i(st->merged->tables_len, 3);
|
||||
|
|
@ -1131,7 +1114,7 @@ void test_reftable_stack__compaction_with_locked_tables(void)
|
|||
* Compaction is expected to fail given that we were not able to
|
||||
* compact all tables.
|
||||
*/
|
||||
err = reftable_stack_compact_all(st, NULL);
|
||||
err = reftable_stack_compact_all(st, &opts, NULL);
|
||||
cl_assert_equal_i(err, REFTABLE_LOCK_ERROR);
|
||||
cl_assert_equal_i(st->stats.failures, 1);
|
||||
cl_assert_equal_i(st->merged->tables_len, 3);
|
||||
|
|
@ -1143,15 +1126,14 @@ void test_reftable_stack__compaction_with_locked_tables(void)
|
|||
|
||||
void test_reftable_stack__compaction_concurrent(void)
|
||||
{
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st1 = NULL, *st2 = NULL;
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st1, dir, NULL), 0);
|
||||
write_n_ref_tables(st1, 3);
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st1, NULL), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st2, dir, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st1, NULL, NULL), 0);
|
||||
|
||||
reftable_stack_destroy(st1);
|
||||
reftable_stack_destroy(st2);
|
||||
|
|
@ -1171,20 +1153,19 @@ static void unclean_stack_close(struct reftable_stack *st)
|
|||
|
||||
void test_reftable_stack__compaction_concurrent_clean(void)
|
||||
{
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st1 = NULL, *st2 = NULL, *st3 = NULL;
|
||||
char *dir = get_tmp_dir(__LINE__);
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st1, dir, NULL), 0);
|
||||
write_n_ref_tables(st1, 3);
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st1, NULL), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st2, dir, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_compact_all(st1, NULL, NULL), 0);
|
||||
|
||||
unclean_stack_close(st1);
|
||||
unclean_stack_close(st2);
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st3, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st3, dir, NULL), 0);
|
||||
cl_assert_equal_i(reftable_stack_clean(st3), 0);
|
||||
cl_assert_equal_i(count_dir_entries(dir), 2);
|
||||
|
||||
|
|
@ -1197,7 +1178,6 @@ void test_reftable_stack__compaction_concurrent_clean(void)
|
|||
|
||||
void test_reftable_stack__read_across_reload(void)
|
||||
{
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st1 = NULL, *st2 = NULL;
|
||||
struct reftable_ref_record rec = { 0 };
|
||||
struct reftable_iterator it = { 0 };
|
||||
|
|
@ -1205,17 +1185,17 @@ void test_reftable_stack__read_across_reload(void)
|
|||
int err;
|
||||
|
||||
/* Create a first stack and set up an iterator for it. */
|
||||
cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st1, dir, NULL), 0);
|
||||
write_n_ref_tables(st1, 2);
|
||||
cl_assert_equal_i(st1->merged->tables_len, 2);
|
||||
reftable_stack_init_ref_iterator(st1, &it);
|
||||
cl_assert_equal_i(reftable_iterator_seek_ref(&it, ""), 0);
|
||||
|
||||
/* Set up a second stack for the same directory and compact it. */
|
||||
err = reftable_new_stack(&st2, dir, &opts);
|
||||
err = reftable_new_stack(&st2, dir, NULL);
|
||||
cl_assert(!err);
|
||||
cl_assert_equal_i(st2->merged->tables_len, 2);
|
||||
err = reftable_stack_compact_all(st2, NULL);
|
||||
err = reftable_stack_compact_all(st2, NULL, NULL);
|
||||
cl_assert(!err);
|
||||
cl_assert_equal_i(st2->merged->tables_len, 1);
|
||||
|
||||
|
|
@ -1244,7 +1224,6 @@ void test_reftable_stack__read_across_reload(void)
|
|||
|
||||
void test_reftable_stack__reload_with_missing_table(void)
|
||||
{
|
||||
struct reftable_write_options opts = { 0 };
|
||||
struct reftable_stack *st = NULL;
|
||||
struct reftable_ref_record rec = { 0 };
|
||||
struct reftable_iterator it = { 0 };
|
||||
|
|
@ -1253,7 +1232,7 @@ void test_reftable_stack__reload_with_missing_table(void)
|
|||
int err;
|
||||
|
||||
/* Create a first stack and set up an iterator for it. */
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
write_n_ref_tables(st, 2);
|
||||
cl_assert_equal_i(st->merged->tables_len, 2);
|
||||
reftable_stack_init_ref_iterator(st, &it);
|
||||
|
|
@ -1320,11 +1299,11 @@ void test_reftable_stack__invalid_limit_updates(void)
|
|||
char *dir = get_tmp_dir(__LINE__);
|
||||
struct reftable_stack *st = NULL;
|
||||
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
|
||||
cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
|
||||
|
||||
reftable_addition_destroy(add);
|
||||
|
||||
cl_assert_equal_i(reftable_stack_new_addition(&add, st, 0), 0);
|
||||
cl_assert_equal_i(reftable_stack_new_addition(&add, st, &opts, 0), 0);
|
||||
|
||||
/*
|
||||
* write_limits_after_ref also updates the update indexes after adding
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ void test_reftable_table__seek_once(void)
|
|||
struct reftable_buf buf = REFTABLE_BUF_INIT;
|
||||
int ret;
|
||||
|
||||
cl_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL);
|
||||
cl_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0,
|
||||
REFTABLE_HASH_SHA1, NULL);
|
||||
block_source_from_buf(&source, &buf);
|
||||
|
||||
ret = reftable_table_new(&table, &source, "name");
|
||||
|
|
@ -64,7 +65,7 @@ void test_reftable_table__reseek(void)
|
|||
int ret;
|
||||
|
||||
cl_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records),
|
||||
NULL, 0, NULL);
|
||||
NULL, 0, REFTABLE_HASH_SHA1, NULL);
|
||||
block_source_from_buf(&source, &buf);
|
||||
|
||||
ret = reftable_table_new(&table, &source, "name");
|
||||
|
|
@ -147,7 +148,8 @@ void test_reftable_table__block_iterator(void)
|
|||
(uintmax_t) i);
|
||||
}
|
||||
|
||||
cl_reftable_write_to_buf(&buf, records, nrecords, NULL, 0, NULL);
|
||||
cl_reftable_write_to_buf(&buf, records, nrecords, NULL, 0,
|
||||
REFTABLE_HASH_SHA1, NULL);
|
||||
block_source_from_buf(&source, &buf);
|
||||
|
||||
ret = reftable_table_new(&table, &source, "name");
|
||||
|
|
|
|||
Loading…
Reference in New Issue