Merge branch 'ps/ref-storage-format' into jch

The terminology regarding reference storage formats has been unified
across command-line options, environment variables, configuration
variables, and source code, standardizing on the phrase "ref storage
format" (e.g., `--ref-storage-format`, `'GIT_REF_STORAGE_FORMAT'`).
Additionally, the `--ref-storage-format` option has been updated to
accept payloads in the form `<format>://<payload>`.

* ps/ref-storage-format:
  setup: allow "--ref-storage-format=" to specify a payload
  setup: rename "init.defaultRefFormat" to "init.defaultRefStorageFormat"
  t: rename GIT_TEST_DEFAULT_REF_FORMAT
  setup: rename ref storage format environment variables
  setup: refactor how we configure the ref storage format
  refs: expose function to parse reference URIs
  help: rename "default-ref-format" to "default-ref-storage-format"
  builtin/rev-parse: rename "--show-ref-format" to "--show-ref-storage-format"
  builtin/submodule: rename "--ref-format=" to "--ref-storage-format="
  builtin/refs: rename "--ref-format=" to "--ref-storage-format="
  builtin/clone: rename "--ref-format=" to "--ref-storage-format="
  builtin/init: rename "--ref-format=" to "--ref-storage-format="
  parse-options: allow for hidden aliases
Junio C Hamano 2026-09-17 12:54:15 -07:00
commit fdb8395264
50 changed files with 464 additions and 339 deletions

View File

@ -156,7 +156,7 @@ Cf. <2f5de416-04ba-c23d-1e0b-83bb655829a7@zombino.com>,
"packed-refs" file.
+
Users that get immediate benefit from the "reftable" backend could continue to
opt-in to the "reftable" format manually by setting the "init.defaultRefFormat"
opt-in to the "reftable" format manually by setting the "init.defaultRefStorageFormat"
config. But defaults matter, and we think that overall users will have a better
experience with less platform-specific quirks when they use the new backend by
default.

View File

@ -25,7 +25,7 @@ reusing objects from multiple packs instead of just one.
significantly smaller in the presence of certain filename collisions with Git's
default name-hash.
+
* `init.defaultRefFormat=reftable` causes newly initialized repositories to use
* `init.defaultRefStorageFormat=reftable` causes newly initialized repositories to use
the reftable format for storing references. This new format solves issues with
case-insensitive filesystems, compresses better and performs significantly
better with many use cases. Refer to Documentation/technical/reftable.adoc for

View File

@ -13,11 +13,13 @@ endif::[]
`--object-format=` in linkgit:git-init[1]. Both the command line option
and the `GIT_DEFAULT_HASH` environment variable take precedence over
this config.
`init.defaultRefFormat`::
`init.defaultRefStorageFormat`::
Allows overriding the default ref storage format for new repositories.
See `--ref-format=` in linkgit:git-init[1]. Both the command line
option and the `GIT_DEFAULT_REF_FORMAT` environment variable take
See `--ref-storage-format=` in linkgit:git-init[1]. Both the command line
option and the `GIT_DEFAULT_REF_STORAGE_FORMAT` environment variable take
precedence over this config.
`init.defaultRefFormat`::
Deprecated alias of `init.defaultRefStorageFormat`.

init.defaultSubmodulePathConfig::
A boolean that specifies if `git init` and `git clone` should

View File

@ -348,12 +348,18 @@ or `--mirror` is given)
The result is Git repository can be separated from working
tree.

`--ref-format=<ref-format>`::
`--ref-storage-format=<format>`::

Specify the given ref storage format for the repository. The valid values are:
Specify the given ref storage _<format>_ for the repository. Backends that
require additional configuration accept a payload in the form
`<format>://<payload>`, for example a connection string identifying the
database that shall store the references. The valid values are:
+
include::ref-storage-format.adoc[]

`--ref-format=<format>`::
Deprecated alias of `--ref-storage-format=<format>`.

`-j<n>`::
`--jobs=<n>`::
The number of submodules fetched at the same time.

View File

@ -11,7 +11,7 @@ SYNOPSIS
[synopsis]
git init [-q | --quiet] [--bare] [--template=<template-directory>]
[--separate-git-dir <git-dir>] [--object-format=<format>]
[--ref-format=<format>]
[--ref-storage-format=<format>]
[-b <branch-name> | --initial-branch=<branch-name>]
[--shared[=<permissions>]] [<directory>]

@ -57,11 +57,17 @@ values are `sha1` and (if enabled) `sha256`. `sha1` is the default.
+
include::object-format-disclaimer.adoc[]

`--ref-format=<format>`::
Specify the given ref storage _<format>_ for the repository. The valid values are:
`--ref-storage-format=<format>`::
Specify the given ref storage _<format>_ for the repository. Backends that
require additional configuration accept a payload in the form
`<format>://<payload>`, for example a connection string identifying the
database that shall store the references. The valid values are:
+
include::ref-storage-format.adoc[]

`--ref-format=<format>`::
Deprecated alias of `--ref-storage-format=<format>`.

`--template=<template-directory>`::
Specify the directory from which templates will be used. (See the "TEMPLATE
DIRECTORY" section below.)

View File

@ -9,7 +9,7 @@ git-refs - Low-level access to refs
SYNOPSIS
--------
[synopsis]
git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]
git refs migrate --ref-storage-format=<format> [--no-reflog] [--dry-run]
git refs verify [--strict] [--verbose]
git refs list [--count=<count>] [--shell|--perl|--python|--tcl]
[(--sort=<key>)...] [--format=<format>]
@ -97,11 +97,14 @@ OPTIONS

The following options are specific to `git refs migrate`:

`--ref-format=<format>`::
The ref format to migrate the ref store to. Can be one of:
`--ref-storage-format=<format>`::
The ref storage format to migrate the ref store to. Can be one of:
+
include::ref-storage-format.adoc[]

`--ref-format=<format>`::
Deprecated alias of `--ref-storage-format=<format>`.

`--dry-run`::
Perform the migration, but do not modify the repository. The migrated
refs will be written into a separate directory that can be inspected

View File

@ -331,9 +331,12 @@ The following options are unaffected by `--path-format`:
requested and no compatibility algorithm is enabled, prints an empty line. If
not specified, the default is "storage".

--show-ref-format::
--show-ref-storage-format::
Show the reference storage format used for the repository.

--show-ref-format::
Deprecated alias of `--show-ref-storage-format`.


Other Options
~~~~~~~~~~~~~

View File

@ -34,7 +34,7 @@ COMMANDS
With no arguments, shows the status of existing submodules. Several
subcommands are available to perform operations on the submodules.

`add [-b <branch>] [-f | --force] [--name <name>] [--reference <repository>] [--ref-format <format>] [--depth <depth>] [--] <repository> [<path>]`::
`add [-b <branch>] [-f | --force] [--name <name>] [--reference <repository>] [--ref-storage-format <format>] [--depth <depth>] [--] <repository> [<path>]`::
Add the given repository as a submodule at the given path
to the changeset to be committed next to the current
project: the current project is termed the "superproject".
@ -72,8 +72,9 @@ location, and only the superproject's URL needs to be provided.
git-submodule will correctly locate the submodule using the relative
URL in `.gitmodules`.
+
If `--ref-format <format>` is specified, the ref storage format of newly
cloned submodules will be set accordingly.
If `--ref-storage-format <format>` or its deprecated alias `--ref-format
<format>` is specified, the ref storage format of the newly cloned submodules
will be set accordingly.

`status [--cached] [--recursive] [--] [<path>...]`::
Show the status of the submodules. This will print the SHA-1 of the
@ -139,7 +140,7 @@ If you really want to remove a submodule from the repository and commit
that use linkgit:git-rm[1] instead. See linkgit:gitsubmodules[7] for removal
options.

`update [--init] [--remote] [-N | --no-fetch] [--[no-]recommend-shallow] [-f | --force] [--checkout | --rebase | --merge] [--reference=<repository>] [--ref-format=<format>] [--depth=<depth>] [--recursive] [--jobs <n>] [--[no-]single-branch] [--filter=<filter-spec>] [--] [<path>...]`::
`update [--init] [--remote] [-N | --no-fetch] [--[no-]recommend-shallow] [-f | --force] [--checkout | --rebase | --merge] [--reference=<repository>] [--ref-storage-format=<format>] [--depth=<depth>] [--recursive] [--jobs <n>] [--[no-]single-branch] [--filter=<filter-spec>] [--] [<path>...]`::
+
--
Update the registered submodules to match what the superproject
@ -188,8 +189,9 @@ submodule with the `--init` option.
If `--recursive` is specified, this command will recurse into the
registered submodules, and update any nested submodules within.

If `--ref-format <format>` is specified, the ref storage format of newly
cloned submodules will be set accordingly.
If `--ref-storage-format <format>` or its deprecated alias `--ref-format
<format>` is specified, the ref storage format of the newly cloned submodules
will be set accordingly.

If `--filter <filter-spec>` is specified, the given partial clone filter will be
applied to the submodule. See linkgit:git-rev-list[1] for details on filter

View File

@ -593,15 +593,21 @@ double-quotes and respecting backslash escapes. E.g., the value
is always used. The default is "sha1".
See `--object-format` in linkgit:git-init[1].

`GIT_DEFAULT_REF_FORMAT`::
If this variable is set, the default reference backend format for new
`GIT_DEFAULT_REF_STORAGE_FORMAT`::
If this variable is set, the default ref storage format for new
repositories will be set to this value. The default is "files".
See `--ref-format` in linkgit:git-init[1].
See `--ref-storage-format` in linkgit:git-init[1].

`GIT_DEFAULT_REF_FORMAT`::
Deprecated alias of `GIT_DEFAULT_REF_STORAGE_FORMAT`.

`GIT_REF_STORAGE_FORMAT`::
Specify which ref storage format to use along with its URI.
See `extensions.refStorage` option in linkgit:git-config[1] for more
details. Overrides the config variable when used.

`GIT_REFERENCE_BACKEND`::
Specify which reference backend to be used along with its URI.
See `extensions.refStorage` option in linkgit:git-config[1] for more
details. Overrides the config variable when used.
Deprecated alias of `GIT_REF_STORAGE_FORMAT`.

Git Commits
~~~~~~~~~~~

View File

@ -750,7 +750,7 @@ static int checkout(int submodule_progress,
}

if (ref_storage_format != REF_STORAGE_FORMAT_UNKNOWN)
strvec_pushf(&cmd.args, "--ref-format=%s",
strvec_pushf(&cmd.args, "--ref-storage-format=%s",
ref_storage_format_to_name(ref_storage_format));

if (filter_submodules && filter_options->choice)
@ -926,7 +926,7 @@ int cmd_clone(int argc,
char *option_origin = NULL;
struct string_list option_not = STRING_LIST_INIT_NODUP;
const char *real_git_dir = NULL;
const char *ref_format = NULL;
const char *ref_storage_format_uri = NULL;
const char *option_upload_pack = "git-upload-pack";
int option_progress = -1;
int option_sparse_checkout = 0;
@ -1006,8 +1006,9 @@ int cmd_clone(int argc,
N_("any cloned submodules will be shallow")),
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
N_("separate git dir from working tree")),
OPT_STRING(0, "ref-format", &ref_format, N_("format"),
N_("specify the reference format to use")),
OPT_STRING(0, "ref-storage-format", &ref_storage_format_uri, N_("format"),
N_("specify the reference storage format to use")),
OPT_ALIAS_F(0, "ref-format", "ref-storage-format", PARSE_OPT_HIDDEN),
OPT_STRING_LIST('c', "config", &option_config, N_("key=value"),
N_("set config inside the new repository")),
OPT_STRING_LIST(0, "server-option", &server_options,
@ -1053,10 +1054,10 @@ int cmd_clone(int argc,
if (option_single_branch == -1)
option_single_branch = deepen ? 1 : 0;

if (ref_format) {
ref_storage_format = ref_storage_format_by_name(ref_format);
if (ref_storage_format_uri) {
ref_storage_format = ref_storage_format_by_uri(ref_storage_format_uri, NULL);
if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
die(_("unknown ref storage format '%s'"), ref_format);
die(_("unknown ref storage format '%s'"), ref_storage_format_uri);
}

if (option_mirror) {
@ -1212,7 +1213,7 @@ int cmd_clone(int argc,
* their on-disk data structures.
*/
create_repository(the_repository, git_dir, real_git_dir, work_tree,
option_template, GIT_HASH_UNKNOWN, ref_storage_format,
option_template, GIT_HASH_UNKNOWN, ref_storage_format_uri,
do_not_override_repo_unix_permissions, NULL);

if (real_git_dir) {

View File

@ -1848,7 +1848,7 @@ static void ref_transaction_rejection_handler(const char *refname,
"can either accept this as-is, in which case you won't be able to\n"
"store all remote references on disk. Or you can alternatively\n"
"migrate your repository to use the 'reftable' backend with the\n"
"following command:\n\n git refs migrate --ref-format=reftable\n\n"
"following command:\n\n git refs migrate --ref-storage-format=reftable\n\n"
"Please keep in mind that not all implementations of Git support this\n"
"new format yet. So if you use tools other than Git to access this\n"
"repository it may not be an option to migrate to reftables.\n"));

View File

@ -57,7 +57,7 @@ static int shared_callback(const struct option *opt, const char *arg, int unset)
static const char *const init_db_usage[] = {
N_("git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
" [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
" [--ref-format=<format>]\n"
" [--ref-storage-format=<format>]\n"
" [-b <branch-name> | --initial-branch=<branch-name>]\n"
" [--shared[=<permissions>]] [<directory>]"),
NULL
@ -83,10 +83,9 @@ int cmd_init_db(int argc,
int quiet = 0;
int bare = startup_info->force_bare_repository ? 1 : -1;
const char *object_format = NULL;
const char *ref_format = NULL;
const char *ref_storage_format_uri = NULL;
const char *initial_branch = NULL;
int hash_algo = GIT_HASH_UNKNOWN;
enum ref_storage_format ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN;
int init_shared_repository = -1;
const struct option init_db_options[] = {
OPT_STRING(0, "template", &template_dir, N_("template-directory"),
@ -109,8 +108,9 @@ int cmd_init_db(int argc,
N_("override the name of the initial branch")),
OPT_STRING(0, "object-format", &object_format, N_("hash"),
N_("specify the hash algorithm to use")),
OPT_STRING(0, "ref-format", &ref_format, N_("format"),
N_("specify the reference format to use")),
OPT_STRING(0, "ref-storage-format", &ref_storage_format_uri, N_("format"),
N_("specify the reference storage format to use")),
OPT_ALIAS_F(0, "ref-format", "ref-storage-format", PARSE_OPT_HIDDEN),
OPT_END()
};
int reinit;
@ -173,12 +173,6 @@ int cmd_init_db(int argc,
die(_("unknown hash algorithm '%s'"), object_format);
}

if (ref_format) {
ref_storage_format = ref_storage_format_by_name(ref_format);
if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
die(_("unknown ref storage format '%s'"), ref_format);
}

if (init_shared_repository != -1)
repo_settings_set_shared_repository(the_repository, init_shared_repository);

@ -248,7 +242,7 @@ int cmd_init_db(int argc,
}

create_repository(the_repository, git_dir, real_git_dir, work_tree,
template_dir, hash_algo, ref_storage_format,
template_dir, hash_algo, ref_storage_format_uri,
init_shared_repository, &reinit);
create_reference_database(the_repository, initial_branch, quiet);
create_object_database(the_repository, NULL);

View File

@ -10,7 +10,7 @@
#include "refs/refs-internal.h"

#define REFS_MIGRATE_USAGE \
N_("git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]")
N_("git refs migrate --ref-storage-format=<format> [--no-reflog] [--dry-run]")

#define REFS_VERIFY_USAGE \
N_("git refs verify [--strict] [--verbose]")
@ -44,9 +44,10 @@ static int cmd_refs_migrate(int argc, const char **argv, const char *prefix,
enum ref_storage_format format;
unsigned int flags = 0;
struct option options[] = {
OPT_STRING_F(0, "ref-format", &format_str, N_("format"),
N_("specify the reference format to convert to"),
OPT_STRING_F(0, "ref-storage-format", &format_str, N_("format"),
N_("specify the reference storage format to convert to"),
PARSE_OPT_NONEG),
OPT_ALIAS_F(0, "ref-format", "ref-storage-format", PARSE_OPT_HIDDEN),
OPT_BIT(0, "dry-run", &flags,
N_("perform a non-destructive dry-run"),
REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN),
@ -62,7 +63,7 @@ static int cmd_refs_migrate(int argc, const char **argv, const char *prefix,
if (argc)
usage(_("too many arguments"));
if (!format_str)
usage(_("missing --ref-format=<format>"));
usage(_("missing --ref-storage-format=<format>"));

format = ref_storage_format_by_name(format_str);
if (format == REF_STORAGE_FORMAT_UNKNOWN) {

View File

@ -1134,7 +1134,7 @@ int cmd_rev_parse(int argc,
}
continue;
}
if (!strcmp(arg, "--show-ref-format")) {
if (!strcmp(arg, "--show-ref-format") || !strcmp(arg, "--show-ref-storage-format")) {
puts(ref_storage_format_to_name(the_repository->ref_storage_format));
continue;
}

View File

@ -1945,7 +1945,7 @@ static int clone_submodule(const struct module_clone_data *clone_data,
item->string, NULL);
}
if (clone_data->ref_storage_format != REF_STORAGE_FORMAT_UNKNOWN)
strvec_pushf(&cp.args, "--ref-format=%s",
strvec_pushf(&cp.args, "--ref-storage-format=%s",
ref_storage_format_to_name(clone_data->ref_storage_format));
if (clone_data->dissociate)
strvec_push(&cp.args, "--dissociate");
@ -2061,8 +2061,9 @@ static int module_clone(int argc, const char **argv, const char *prefix,
OPT_STRING_LIST(0, "reference", &reference,
N_("repo"),
N_("reference repository")),
OPT_STRING(0, "ref-format", &ref_storage_format, N_("format"),
N_("specify the reference format to use")),
OPT_STRING(0, "ref-storage-format", &ref_storage_format, N_("format"),
N_("specify the reference storage format to use")),
OPT_ALIAS_F(0, "ref-format", "ref-storage-format", PARSE_OPT_HIDDEN),
OPT_BOOL(0, "dissociate", &dissociate,
N_("use --reference only while cloning")),
OPT_INTEGER(0, "depth", &clone_data.depth,
@ -2361,7 +2362,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
if (suc->update_data->require_init)
strvec_push(&child->args, "--require-init");
if (suc->update_data->ref_storage_format != REF_STORAGE_FORMAT_UNKNOWN)
strvec_pushf(&child->args, "--ref-format=%s",
strvec_pushf(&child->args, "--ref-storage-format=%s",
ref_storage_format_to_name(suc->update_data->ref_storage_format));
strvec_pushl(&child->args, "--path", sub->path, NULL);
strvec_pushl(&child->args, "--name", sub->name, NULL);
@ -2805,7 +2806,7 @@ static void update_data_to_args(const struct update_data *update_data,
strvec_pushl(args, "--reference", item->string, NULL);
}
if (update_data->ref_storage_format != REF_STORAGE_FORMAT_UNKNOWN)
strvec_pushf(args, "--ref-format=%s",
strvec_pushf(args, "--ref-storage-format=%s",
ref_storage_format_to_name(update_data->ref_storage_format));
if (update_data->filter_options && update_data->filter_options->choice)
strvec_pushf(args, "--filter=%s",
@ -3014,8 +3015,9 @@ static int module_update(int argc, const char **argv, const char *prefix,
SM_UPDATE_REBASE),
OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"),
N_("reference repository")),
OPT_STRING(0, "ref-format", &ref_storage_format, N_("format"),
N_("specify the reference format to use")),
OPT_STRING(0, "ref-storage-format", &ref_storage_format, N_("format"),
N_("specify the reference storage format to use")),
OPT_ALIAS_F(0, "ref-format", "ref-storage-format", PARSE_OPT_HIDDEN),
OPT_BOOL(0, "dissociate", &opt.dissociate,
N_("use --reference only while cloning")),
OPT_INTEGER(0, "depth", &opt.depth,
@ -3663,8 +3665,9 @@ static int module_add(int argc, const char **argv, const char *prefix,
OPT_BOOL(0, "progress", &progress, N_("force cloning progress")),
OPT_STRING(0, "reference", &add_data.reference_path, N_("repository"),
N_("reference repository")),
OPT_STRING(0, "ref-format", &ref_storage_format, N_("format"),
N_("specify the reference format to use")),
OPT_STRING(0, "ref-storage-format", &ref_storage_format, N_("format"),
N_("specify the reference storage format to use")),
OPT_ALIAS_F(0, "ref-format", "ref-storage-format", PARSE_OPT_HIDDEN),
OPT_BOOL(0, "dissociate", &dissociate, N_("borrow the objects from reference repositories")),
OPT_STRING(0, "name", &add_data.sm_name, N_("name"),
N_("sets the submodule's name to the given string "

View File

@ -45,7 +45,7 @@ linux-sha256)
export GIT_TEST_DEFAULT_HASH=sha256
;;
linux-reftable|linux-reftable-leaks|osx-reftable)
export GIT_TEST_DEFAULT_REF_FORMAT=reftable
export GIT_TEST_DEFAULT_REF_STORAGE_FORMAT=reftable
;;

esac

View File

@ -466,7 +466,7 @@ __git_ps1 ()

local repo_info rev_parse_exit_code
repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
--is-bare-repository --is-inside-work-tree --show-ref-format \
--is-bare-repository --is-inside-work-tree --show-ref-storage-format \
--short HEAD 2>/dev/null)"
rev_parse_exit_code="$?"


View File

@ -44,6 +44,7 @@
#define GIT_TEXT_DOMAIN_DIR_ENVIRONMENT "GIT_TEXTDOMAINDIR"
#define GIT_ATTR_SOURCE_ENVIRONMENT "GIT_ATTR_SOURCE"
#define GIT_REFERENCE_BACKEND_ENVIRONMENT "GIT_REFERENCE_BACKEND"
#define GIT_REF_STORAGE_FORMAT_ENVIRONMENT "GIT_REF_STORAGE_FORMAT"

/*
* Environment variable used to propagate the --no-advice global option to the

View File

@ -95,13 +95,13 @@ cmd_add()
--reference=*)
reference="$1"
;;
--ref-format)
--ref-format|--ref-storage-format)
case "$2" in '') usage ;; esac
ref_format="--ref-format=$2"
ref_storage_format="--ref-storage-format=$2"
shift
;;
--ref-format=*)
ref_format="$1"
--ref-format=*|--ref-storage-format=*)
ref_storage_format="$1"
;;
--dissociate)
dissociate=$1
@ -147,7 +147,7 @@ cmd_add()
$progress \
${branch:+"$branch"} \
${reference:+"$reference"} \
${ref_format:+"$ref_format"} \
${ref_storage_format:+"$ref_storage_format"} \
$dissociate \
${name:+"$name"} \
${depth:+"$depth"} \
@ -302,13 +302,13 @@ cmd_update()
-r|--rebase)
rebase=$1
;;
--ref-format)
--ref-format|--ref-storage-format)
case "$2" in '') usage ;; esac
ref_format="--ref-format=$2"
ref_storage_format="--ref-storage-format=$2"
shift
;;
--ref-format=*)
ref_format="$1"
--ref-format=*|--ref-storage-format=*)
ref_storage_format="$1"
;;
--reference)
case "$2" in '') usage ;; esac
@ -385,7 +385,7 @@ cmd_update()
$rebase \
$merge \
$checkout \
${ref_format:+"$ref_format"} \
${ref_storage_format:+"$ref_storage_format"} \
${reference:+"$reference"} \
$dissociate \
${depth:+"$depth"} \

2
help.c
View File

@ -824,7 +824,7 @@ void get_version_info(struct strbuf *buf, int show_build_options)
SHA1_UNSAFE_BACKEND);
#endif
strbuf_addf(buf, "SHA-256: %s\n", SHA256_BACKEND);
strbuf_addf(buf, "default-ref-format: %s\n",
strbuf_addf(buf, "default-ref-storage-format: %s\n",
ref_storage_format_to_name(REF_STORAGE_FORMAT_DEFAULT));
strbuf_addf(buf, "default-hash: %s\n", hash_algos[GIT_HASH_DEFAULT].name);
}

View File

@ -925,6 +925,7 @@ static struct option *preprocess_options(struct parse_opt_ctx_t *ctx,
const char *long_name;
const char *source;
struct strbuf help = STRBUF_INIT;
enum parse_opt_option_flags flags;
int j;

if (newopt[i].type != OPTION_ALIAS)
@ -933,6 +934,7 @@ static struct option *preprocess_options(struct parse_opt_ctx_t *ctx,
short_name = newopt[i].short_name;
long_name = newopt[i].long_name;
source = newopt[i].value;
flags = newopt[i].flags;

if (!long_name)
BUG("An alias must have long option name");
@ -951,7 +953,7 @@ static struct option *preprocess_options(struct parse_opt_ctx_t *ctx,
newopt[i].short_name = short_name;
newopt[i].long_name = long_name;
newopt[i].help = strbuf_detach(&help, NULL);
newopt[i].flags |= PARSE_OPT_FROM_ALIAS;
newopt[i].flags |= flags | PARSE_OPT_FROM_ALIAS;
break;
}


View File

@ -386,13 +386,16 @@ static char *parse_options_noop_ignored_value MAYBE_UNUSED;
.callback = parse_opt_noop_cb, \
}

#define OPT_ALIAS(s, l, source_long_name) { \
#define OPT_ALIAS_F(s, l, source_long_name, f) { \
.type = OPTION_ALIAS, \
.short_name = (s), \
.long_name = (l), \
.value = (char *)(source_long_name), \
.flags = (f), \
}

#define OPT_ALIAS(s, l, source_long_name) OPT_ALIAS_F(s, l, source_long_name, 0)

#define OPT_SUBCOMMAND_F(l, v, fn, f) { \
.type = OPTION_SUBCOMMAND, \
.long_name = (l), \

23
refs.c
View File

@ -54,6 +54,29 @@ enum ref_storage_format ref_storage_format_by_name(const char *name)
return REF_STORAGE_FORMAT_UNKNOWN;
}

enum ref_storage_format ref_storage_format_by_uri(const char *uri,
char **payload)
{
enum ref_storage_format format;
const char *schema_end;
char *name;

schema_end = strstr(uri, "://");
if (!schema_end) {
name = xstrdup(uri);
if (payload)
*payload = NULL;
} else {
name = xstrndup(uri, schema_end - uri);
if (payload)
*payload = xstrdup(schema_end + 3);
}

format = ref_storage_format_by_name(name);
free(name);
return format;
}

const char *ref_storage_format_to_name(enum ref_storage_format ref_storage_format)
{
const struct ref_storage_be *be = find_ref_storage_backend(ref_storage_format);

4
refs.h
View File

@ -17,6 +17,10 @@ struct worktree;
enum ref_storage_format ref_storage_format_by_name(const char *name);
const char *ref_storage_format_to_name(enum ref_storage_format ref_storage_format);

/* Parse a reference storage URI in the format "<format>[://<payload>]". */
enum ref_storage_format ref_storage_format_by_uri(const char *uri,
char **payload);

enum ref_transaction_error {
/* Default error code */
REF_TRANSACTION_ERROR_GENERIC = -1,

175
setup.c
View File

@ -632,21 +632,6 @@ static enum extension_result handle_extension_v0(const char *var,
return EXTENSION_UNKNOWN;
}

static void parse_reference_uri(const char *value, char **format,
char **payload)
{
const char *schema_end;

schema_end = strstr(value, "://");
if (!schema_end) {
*format = xstrdup(value);
*payload = NULL;
} else {
*format = xstrndup(value, schema_end - value);
*payload = xstrdup_or_null(schema_end + 3);
}
}

/*
* Record any new extensions in this function.
*/
@ -689,16 +674,13 @@ static enum extension_result handle_extension(const char *var,
return EXTENSION_OK;
} else if (!strcmp(ext, "refstorage")) {
unsigned int format;
char *format_str;

if (!value)
return config_error_nonbool(var);

parse_reference_uri(value, &format_str,
&data->ref_storage_payload);

format = ref_storage_format_by_name(format_str);
free(format_str);
FREE_AND_NULL(data->ref_storage_payload);
format = ref_storage_format_by_uri(value,
&data->ref_storage_payload);

if (format == REF_STORAGE_FORMAT_UNKNOWN)
return error(_("invalid value for '%s': '%s'"),
@ -2084,18 +2066,16 @@ const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)
* The env variable should override the repository config
* for 'extensions.refStorage'.
*/
ref_backend_uri = getenv(GIT_REFERENCE_BACKEND_ENVIRONMENT);
ref_backend_uri = getenv(GIT_REF_STORAGE_FORMAT_ENVIRONMENT);
if (!ref_backend_uri)
ref_backend_uri = getenv(GIT_REFERENCE_BACKEND_ENVIRONMENT);
if (ref_backend_uri) {
char *format;

free(discovery.format.ref_storage_payload);

parse_reference_uri(ref_backend_uri, &format, &discovery.format.ref_storage_payload);
discovery.format.ref_storage_format = ref_storage_format_by_name(format);
FREE_AND_NULL(discovery.format.ref_storage_payload);
discovery.format.ref_storage_format =
ref_storage_format_by_uri(ref_backend_uri,
&discovery.format.ref_storage_payload);
if (discovery.format.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
die(_("unknown ref storage format: '%s'"), format);

free(format);
die(_("unknown ref storage format: '%s'"), ref_backend_uri);
}

if (apply_repository_format(repo, &discovery.format,
@ -2718,7 +2698,7 @@ static void separate_git_dir(struct repository *repo,

struct default_format_config {
int hash;
enum ref_storage_format ref_format;
enum ref_storage_format ref_storage_format;
};

static int read_default_format_config(const char *key, const char *value,
@ -2739,24 +2719,25 @@ static int read_default_format_config(const char *key, const char *value,
goto out;
}

if (!strcmp(key, "init.defaultrefformat")) {
if (!strcmp(key, "init.defaultrefstorageformat") ||
!strcmp(key, "init.defaultrefformat")) {
ret = git_config_string(&str, key, value);
if (ret)
goto out;
cfg->ref_format = ref_storage_format_by_name(str);
if (cfg->ref_format == REF_STORAGE_FORMAT_UNKNOWN)
cfg->ref_storage_format = ref_storage_format_by_name(str);
if (cfg->ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
warning(_("unknown ref storage format '%s'"), str);
goto out;
}

/*
* Enable the reftable format when "features.experimental" is enabled.
* "init.defaultRefFormat" takes precedence over this setting.
* "init.defaultRefStorageFormat" takes precedence over this setting.
*/
if (!strcmp(key, "feature.experimental") &&
cfg->ref_format == REF_STORAGE_FORMAT_UNKNOWN &&
cfg->ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN &&
git_config_bool(key, value)) {
cfg->ref_format = REF_STORAGE_FORMAT_REFTABLE;
cfg->ref_storage_format = REF_STORAGE_FORMAT_REFTABLE;
ret = 0;
goto out;
}
@ -2768,18 +2749,20 @@ out:
}

static void repository_format_configure(struct repository_format *repo_fmt,
int hash, enum ref_storage_format ref_format)
int hash,
const char *ref_storage_format_uri)
{
struct default_format_config cfg = {
.hash = GIT_HASH_UNKNOWN,
.ref_format = REF_STORAGE_FORMAT_UNKNOWN,
.ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN,
};
struct config_options opts = {
.respect_includes = 1,
.ignore_repo = 1,
.ignore_worktree = 1,
};
const char *ref_backend_uri;
enum ref_storage_format ref_storage_format;
char *ref_storage_payload = NULL;
const char *env;

config_with_options(read_default_format_config, &cfg, NULL, NULL, &opts);
@ -2805,42 +2788,84 @@ static void repository_format_configure(struct repository_format *repo_fmt,
repo_fmt->hash_algo = cfg.hash;
}

env = getenv("GIT_DEFAULT_REF_FORMAT");
if (repo_fmt->version >= 0 &&
ref_format != REF_STORAGE_FORMAT_UNKNOWN &&
ref_format != repo_fmt->ref_storage_format) {
die(_("attempt to reinitialize repository with different reference storage format"));
} else if (ref_format != REF_STORAGE_FORMAT_UNKNOWN) {
repo_fmt->ref_storage_format = ref_format;
} else if (env) {
ref_format = ref_storage_format_by_name(env);
if (ref_format == REF_STORAGE_FORMAT_UNKNOWN)
die(_("unknown ref storage format '%s'"), env);
if (repo_fmt->version < 0 ||
repo_fmt->ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
repo_fmt->ref_storage_format = ref_format;
} else if (cfg.ref_format != REF_STORAGE_FORMAT_UNKNOWN) {
repo_fmt->ref_storage_format = cfg.ref_format;
/*
* We have the following order of preference when configuring the ref
* storage format:
*
* 1. Explicit override via the command line, like in `git init
* --ref-storage-format=`.
*
* 2. Explicit override via the environment with
* "GIT_REF_STORAGE_FORMAT".
*
* 3. Its deprecated equivalent "GIT_REFERENCE_BACKEND".
*
* 4. Existing repository format. All the subsequent sources only
* kick in when there is no repository yet.
*
* 4. The default ref storage format for new repositories as
* configured via "GIT_DEFAULT_REF_STORAGE_FORMAT".
*
* 5. Its deprecated equivalent "GIT_DEFAULT_REF_FORMAT".
*
* 6. The default ref storage format for new repositories as
* configured via "init.defaultRefStorageFormat" or its deprecated
* equivalent "init.defaultRefFormat".
*
* 7. Otherwise, we fall back to the default ref storage format
* compiled into Git.
*/
if (ref_storage_format_uri) {
ref_storage_format = ref_storage_format_by_uri(ref_storage_format_uri,
&ref_storage_payload);
if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
die(_("unknown ref storage format specified via command line: '%s'"),
ref_storage_format_uri);
} else if ((env = getenv(GIT_REF_STORAGE_FORMAT_ENVIRONMENT))) {
ref_storage_format = ref_storage_format_by_uri(env, &ref_storage_payload);
if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
die(_("unknown ref storage format specified via %s: '%s'"),
GIT_REF_STORAGE_FORMAT_ENVIRONMENT, env);
} else if ((env = getenv(GIT_REFERENCE_BACKEND_ENVIRONMENT))) {
ref_storage_format = ref_storage_format_by_uri(env, &ref_storage_payload);
if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
die(_("unknown ref storage format specified via %s: '%s'"),
GIT_REFERENCE_BACKEND_ENVIRONMENT, env);
} else if (repo_fmt->version >= 0) {
ref_storage_format = repo_fmt->ref_storage_format;
ref_storage_payload = xstrdup_or_null(repo_fmt->ref_storage_payload);
} else if ((env = getenv("GIT_DEFAULT_REF_STORAGE_FORMAT"))) {
ref_storage_format = ref_storage_format_by_name(env);
if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
die(_("unknown ref storage format specified via %s: '%s'"),
"GIT_DEFAULT_REF_STORAGE_FORMAT", env);
} else if ((env = getenv("GIT_DEFAULT_REF_FORMAT"))) {
ref_storage_format = ref_storage_format_by_name(env);
if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
die(_("unknown ref storage format specified via %s: '%s'"),
"GIT_DEFAULT_REF_FORMAT", env);
} else if (cfg.ref_storage_format != REF_STORAGE_FORMAT_UNKNOWN) {
ref_storage_format = cfg.ref_storage_format;
} else {
repo_fmt->ref_storage_format = REF_STORAGE_FORMAT_DEFAULT;
ref_storage_format = REF_STORAGE_FORMAT_DEFAULT;
}


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_fmt->ref_storage_format = format;
repo_fmt->ref_storage_payload = payload;

free(backend);
/*
* If we have a preexisting repository we need to verify that its
* current ref storage format does not change.
*/
if (repo_fmt->version >= 0) {
if (ref_storage_format != repo_fmt->ref_storage_format)
die(_("attempt to reinitialize repository with different reference storage format"));
if ((ref_storage_payload || repo_fmt->ref_storage_payload) &&
strcmp(ref_storage_payload ? ref_storage_payload : "",
repo_fmt->ref_storage_payload ? repo_fmt->ref_storage_payload : ""))
die(_("attempt to reinitialize repository with different reference storage payload"));
}

free(repo_fmt->ref_storage_payload);
repo_fmt->ref_storage_format = ref_storage_format;
repo_fmt->ref_storage_payload = ref_storage_payload;
}

void create_repository(struct repository *repo,
@ -2849,7 +2874,7 @@ void create_repository(struct repository *repo,
const char *worktree,
const char *template_dir,
int hash,
enum ref_storage_format ref_storage_format,
const char *ref_storage_format_uri,
int init_shared_repository,
int *reinit_ok)
{
@ -2885,7 +2910,7 @@ void create_repository(struct repository *repo,
* is an attempt to reinitialize new repository with an old tool.
*/
read_and_verify_repository_format(&repo_fmt, repo_get_git_dir(repo), NULL);
repository_format_configure(&repo_fmt, hash, ref_storage_format);
repository_format_configure(&repo_fmt, hash, ref_storage_format_uri);
if (apply_repository_format(repo, &repo_fmt, APPLY_REPOSITORY_FORMAT_HONOR_ENV, &err) < 0)
die("%s", err.buf);


View File

@ -273,7 +273,7 @@ void create_repository(struct repository *repo,
const char *worktree,
const char *template_dir,
int hash_algo,
enum ref_storage_format ref_storage_format,
const char *ref_storage_format_uri,
int init_shared_repository,
int *reinit_ok);


View File

@ -448,8 +448,8 @@ GIT_TEST_DEFAULT_HASH=<hash-algo> specifies which hash algorithm to
use in the test scripts. Recognized values for <hash-algo> are "sha1"
and "sha256".

GIT_TEST_DEFAULT_REF_FORMAT=<format> specifies which ref storage format to use
in the test scripts. Recognized values for <format> are "files" and
GIT_TEST_DEFAULT_REF_STORAGE_FORMAT=<format> specifies which ref storage format
to use in the test scripts. Recognized values for <format> are "files" and
"reftable".

GIT_TEST_NO_WRITE_REV_INDEX=<boolean>, when true disables the

View File

@ -5,7 +5,7 @@ test_description="Tests performance of ref operations with many tombstones"
. ./perf-lib.sh

test_expect_success "setup" '
git init --ref-format=reftable repo &&
git init --ref-storage-format=reftable repo &&
blob=$(echo foo | git -C repo hash-object -w --stdin) &&
for i in $(test_seq 8000)
do
@ -24,7 +24,7 @@ test_perf "recreate refs after mass delete" '
'

test_expect_success "setup asymmetric" '
git init --ref-format=reftable repo2 &&
git init --ref-storage-format=reftable repo2 &&
blob=$(echo foo | git -C repo2 hash-object -w --stdin) &&
for i in $(test_seq 8000)
do

View File

@ -135,7 +135,7 @@ test_perf_create_repo_from () {
source_git="$("$MODERN_GIT" -C "$source" rev-parse --git-dir)"
objects_dir="$("$MODERN_GIT" -C "$source" rev-parse --git-path objects)"
common_dir="$("$MODERN_GIT" -C "$source" rev-parse --git-common-dir)"
refformat="$("$MODERN_GIT" -C "$source" rev-parse --show-ref-format)"
ref_storage_format="$("$MODERN_GIT" -C "$source" rev-parse --show-ref-storage-format)"
objectformat="$("$MODERN_GIT" -C "$source" rev-parse --show-object-format)"
mkdir -p "$repo/.git"
(
@ -153,7 +153,7 @@ test_perf_create_repo_from () {
) &&
(
cd "$repo" &&
"$MODERN_GIT" init -q --ref-format="$refformat" --object-format="$objectformat" &&
"$MODERN_GIT" init -q --ref-storage-format="$ref_storage_format" --object-format="$objectformat" &&
test_perf_do_repo_symlink_config_ &&
mv .git/hooks .git/hooks-disabled 2>/dev/null &&
if test -f .git/index.lock

View File

@ -640,45 +640,55 @@ test_expect_success DEFAULT_REPO_FORMAT 'extensions.refStorage with unknown back
test_grep "invalid value for ${SQ}extensions.refstorage${SQ}: ${SQ}garbage${SQ}" err
'

test_expect_success 'init with GIT_DEFAULT_REF_FORMAT=garbage' '
test_expect_success 'init with GIT_DEFAULT_REF_STORAGE_FORMAT=garbage' '
test_when_finished "rm -rf refformat" &&
cat >expect <<-EOF &&
fatal: unknown ref storage format ${SQ}garbage${SQ}
fatal: unknown ref storage format specified via GIT_DEFAULT_REF_STORAGE_FORMAT: ${SQ}garbage${SQ}
EOF
test_must_fail env GIT_DEFAULT_REF_FORMAT=garbage git init refformat 2>err &&
test_must_fail env GIT_DEFAULT_REF_STORAGE_FORMAT=garbage git init refformat 2>err &&
test_cmp expect err
'

test_expect_success 'init warns about invalid init.defaultRefFormat' '
test_expect_success 'GIT_REF_STORAGE_FORMAT refuses to reinitialize with different storage format' '
test_when_finished "rm -rf refbackend" &&
git init --ref-storage-format=files refbackend &&
cat >expect <<-EOF &&
fatal: attempt to reinitialize repository with different reference storage format
EOF
test_must_fail env GIT_REF_STORAGE_FORMAT=reftable git init refbackend 2>err &&
test_cmp expect err
'

test_expect_success 'init warns about invalid init.defaultRefStorageFormat' '
test_when_finished "rm -rf repo" &&
test_config_global init.defaultRefFormat garbage &&
test_config_global init.defaultRefStorageFormat garbage &&

echo "warning: unknown ref storage format ${SQ}garbage${SQ}" >expect &&
git init repo 2>err &&
test_cmp expect err &&

git -C repo rev-parse --show-ref-format >actual &&
echo $GIT_DEFAULT_REF_FORMAT >expected &&
git -C repo rev-parse --show-ref-storage-format >actual &&
echo $GIT_DEFAULT_REF_STORAGE_FORMAT >expected &&
test_cmp expected actual
'

test_expect_success 'default ref format' '
test_when_finished "rm -rf refformat" &&
(
sane_unset GIT_DEFAULT_REF_FORMAT &&
sane_unset GIT_DEFAULT_REF_STORAGE_FORMAT &&
git init refformat
) &&
git version --build-options | sed -ne "s/^default-ref-format: //p" >expect &&
git -C refformat rev-parse --show-ref-format >actual &&
git version --build-options | sed -ne "s/^default-ref-storage-format: //p" >expect &&
git -C refformat rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

backends="files reftable"
for format in $backends
do
test_expect_success DEFAULT_REPO_FORMAT "init with GIT_DEFAULT_REF_FORMAT=$format" '
test_expect_success DEFAULT_REPO_FORMAT "init with GIT_DEFAULT_REF_STORAGE_FORMAT=$format" '
test_when_finished "rm -rf refformat" &&
GIT_DEFAULT_REF_FORMAT=$format git init refformat &&
GIT_DEFAULT_REF_STORAGE_FORMAT=$format git init refformat &&

if test $format = files
then
@ -692,64 +702,64 @@ do
test_cmp expect actual &&

echo $format >expect &&
git -C refformat rev-parse --show-ref-format >actual &&
git -C refformat rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

test_expect_success "init with --ref-format=$format" '
test_expect_success "init with --ref-storage-format=$format" '
test_when_finished "rm -rf refformat" &&
git init --ref-format=$format refformat &&
git init --ref-storage-format=$format refformat &&
echo $format >expect &&
git -C refformat rev-parse --show-ref-format >actual &&
git -C refformat rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

test_expect_success "init with init.defaultRefFormat=$format" '
test_expect_success "init with init.defaultRefStorageFormat=$format" '
test_when_finished "rm -rf refformat" &&
test_config_global init.defaultRefFormat $format &&
test_config_global init.defaultRefStorageFormat $format &&
(
sane_unset GIT_DEFAULT_REF_FORMAT &&
sane_unset GIT_DEFAULT_REF_STORAGE_FORMAT &&
git init refformat
) &&

echo $format >expect &&
git -C refformat rev-parse --show-ref-format >actual &&
git -C refformat rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

test_expect_success "--ref-format=$format overrides GIT_DEFAULT_REF_FORMAT" '
test_expect_success "--ref-storage-format=$format overrides GIT_DEFAULT_REF_STORAGE_FORMAT" '
test_when_finished "rm -rf refformat" &&
GIT_DEFAULT_REF_FORMAT=garbage git init --ref-format=$format refformat &&
GIT_DEFAULT_REF_STORAGE_FORMAT=garbage git init --ref-storage-format=$format refformat &&
echo $format >expect &&
git -C refformat rev-parse --show-ref-format >actual &&
git -C refformat rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

test_expect_success "reinit repository with GIT_DEFAULT_REF_FORMAT=$format does not change format" '
test_expect_success "reinit repository with GIT_DEFAULT_REF_STORAGE_FORMAT=$format does not change format" '
test_when_finished "rm -rf refformat" &&
git init refformat &&
git -C refformat rev-parse --show-ref-format >expect &&
GIT_DEFAULT_REF_FORMAT=$format git init refformat &&
git -C refformat rev-parse --show-ref-format >actual &&
git -C refformat rev-parse --show-ref-storage-format >expect &&
GIT_DEFAULT_REF_STORAGE_FORMAT=$format git init refformat &&
git -C refformat rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'
done

test_expect_success "--ref-format= overrides GIT_DEFAULT_REF_FORMAT" '
test_expect_success "--ref-storage-format= overrides GIT_DEFAULT_REF_STORAGE_FOMAT" '
test_when_finished "rm -rf refformat" &&
GIT_DEFAULT_REF_FORMAT=files git init --ref-format=reftable refformat &&
GIT_DEFAULT_REF_STORAGE_FORMAT=files git init --ref-storage-format=reftable refformat &&
echo reftable >expect &&
git -C refformat rev-parse --show-ref-format >actual &&
git -C refformat rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

test_expect_success "GIT_DEFAULT_REF_FORMAT= overrides init.defaultRefFormat" '
test_expect_success "GIT_DEFAULT_REF_STORAGE_FORMAT= overrides init.defaultRefStorageFormat" '
test_when_finished "rm -rf refformat" &&
test_config_global init.defaultRefFormat files &&
test_config_global init.defaultRefStorageFormat files &&

GIT_DEFAULT_REF_FORMAT=reftable git init refformat &&
GIT_DEFAULT_REF_STORAGE_FORMAT=reftable git init refformat &&
echo reftable >expect &&
git -C refformat rev-parse --show-ref-format >actual &&
git -C refformat rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

@ -757,33 +767,33 @@ test_expect_success "init with feature.experimental=true" '
test_when_finished "rm -rf refformat" &&
test_config_global feature.experimental true &&
(
sane_unset GIT_DEFAULT_REF_FORMAT &&
sane_unset GIT_DEFAULT_REF_STORAGE_FORMAT &&
git init refformat
) &&
echo reftable >expect &&
git -C refformat rev-parse --show-ref-format >actual &&
git -C refformat rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

test_expect_success "init.defaultRefFormat overrides feature.experimental=true" '
test_expect_success "init.defaultRefStorageFormat overrides feature.experimental=true" '
test_when_finished "rm -rf refformat" &&
test_config_global feature.experimental true &&
test_config_global init.defaultRefFormat files &&
test_config_global init.defaultRefStorageFormat files &&
(
sane_unset GIT_DEFAULT_REF_FORMAT &&
sane_unset GIT_DEFAULT_REF_STORAGE_FORMAT &&
git init refformat
) &&
echo files >expect &&
git -C refformat rev-parse --show-ref-format >actual &&
git -C refformat rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

test_expect_success "GIT_DEFAULT_REF_FORMAT= overrides feature.experimental=true" '
test_expect_success "GIT_DEFAULT_REF_STORAGE_FORMAT= overrides feature.experimental=true" '
test_when_finished "rm -rf refformat" &&
test_config_global feature.experimental true &&
GIT_DEFAULT_REF_FORMAT=files git init refformat &&
GIT_DEFAULT_REF_STORAGE_FORMAT=files git init refformat &&
echo files >expect &&
git -C refformat rev-parse --show-ref-format >actual &&
git -C refformat rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

@ -791,10 +801,10 @@ for from_format in $backends
do
test_expect_success "re-init with same format ($from_format)" '
test_when_finished "rm -rf refformat" &&
git init --ref-format=$from_format refformat &&
git init --ref-format=$from_format refformat &&
git init --ref-storage-format=$from_format refformat &&
git init --ref-storage-format=$from_format refformat &&
echo $from_format >expect &&
git -C refformat rev-parse --show-ref-format >actual &&
git -C refformat rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

@ -807,25 +817,25 @@ do

test_expect_success "re-init with different format fails ($from_format -> $to_format)" '
test_when_finished "rm -rf refformat" &&
git init --ref-format=$from_format refformat &&
git init --ref-storage-format=$from_format refformat &&
cat >expect <<-EOF &&
fatal: attempt to reinitialize repository with different reference storage format
EOF
test_must_fail git init --ref-format=$to_format refformat 2>err &&
test_must_fail git init --ref-storage-format=$to_format refformat 2>err &&
test_cmp expect err &&
echo $from_format >expect &&
git -C refformat rev-parse --show-ref-format >actual &&
git -C refformat rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'
done
done

test_expect_success 'init with --ref-format=garbage' '
test_expect_success 'init with --ref-storage-format=garbage' '
test_when_finished "rm -rf refformat" &&
cat >expect <<-EOF &&
fatal: unknown ref storage format ${SQ}garbage${SQ}
fatal: unknown ref storage format specified via command line: ${SQ}garbage${SQ}
EOF
test_must_fail git init --ref-format=garbage refformat 2>err &&
test_must_fail git init --ref-storage-format=garbage refformat 2>err &&
test_cmp expect err
'

@ -932,8 +942,8 @@ test_expect_success 'branch -m with the initial branch' '
test_expect_success 'init with includeIf.onbranch condition' '
test_when_finished "rm -rf repo" &&
git -c includeIf.onbranch:main.path=nonexistent init repo &&
echo $GIT_DEFAULT_REF_FORMAT >expect &&
git -C repo rev-parse --show-ref-format >actual &&
echo $GIT_DEFAULT_REF_STORAGE_FORMAT >expect &&
git -C repo rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

@ -941,8 +951,8 @@ test_expect_success 'init with includeIf.onbranch condition with existing direct
test_when_finished "rm -rf repo" &&
mkdir repo &&
git -c includeIf.onbranch:nonexistent.path=/does/not/exist init repo &&
echo $GIT_DEFAULT_REF_FORMAT >expect &&
git -C repo rev-parse --show-ref-format >actual &&
echo $GIT_DEFAULT_REF_STORAGE_FORMAT >expect &&
git -C repo rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

@ -950,8 +960,8 @@ test_expect_success 're-init with includeIf.onbranch condition' '
test_when_finished "rm -rf repo" &&
git init repo &&
git -c includeIf.onbranch:nonexistent.path=/does/not/exist init repo &&
echo $GIT_DEFAULT_REF_FORMAT >expect &&
git -C repo rev-parse --show-ref-format >actual &&
echo $GIT_DEFAULT_REF_STORAGE_FORMAT >expect &&
git -C repo rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'


View File

@ -4,8 +4,8 @@ test_description='Test reffiles backend'

GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
GIT_TEST_DEFAULT_REF_FORMAT=files
export GIT_TEST_DEFAULT_REF_FORMAT
GIT_TEST_DEFAULT_REF_STORAGE_FORMAT=files
export GIT_TEST_DEFAULT_REF_STORAGE_FORMAT

. ./test-lib.sh


View File

@ -12,8 +12,8 @@ semantic is still the same.

GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
GIT_TEST_DEFAULT_REF_FORMAT=files
export GIT_TEST_DEFAULT_REF_FORMAT
GIT_TEST_DEFAULT_REF_STORAGE_FORMAT=files
export GIT_TEST_DEFAULT_REF_STORAGE_FORMAT

. ./test-lib.sh


View File

@ -4,8 +4,8 @@ test_description='Test reffiles backend consistency check'

GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
GIT_TEST_DEFAULT_REF_FORMAT=files
export GIT_TEST_DEFAULT_REF_FORMAT
GIT_TEST_DEFAULT_REF_STORAGE_FORMAT=files
export GIT_TEST_DEFAULT_REF_STORAGE_FORMAT

. ./test-lib.sh


View File

@ -7,8 +7,8 @@ test_description='reftable basics'

GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
GIT_TEST_DEFAULT_REF_FORMAT=reftable
export GIT_TEST_DEFAULT_REF_FORMAT
GIT_TEST_DEFAULT_REF_STORAGE_FORMAT=reftable
export GIT_TEST_DEFAULT_REF_STORAGE_FORMAT

. ./test-lib.sh

@ -27,7 +27,7 @@ test_expect_success 'init: creates basic reftable structures' '
test_path_is_dir repo/.git/reftable &&
test_path_is_file repo/.git/reftable/tables.list &&
echo reftable >expect &&
git -C repo rev-parse --show-ref-format >actual &&
git -C repo rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

@ -38,7 +38,7 @@ test_expect_success 'init: sha256 object format via environment variable' '
sha256
reftable
EOF
git -C repo rev-parse --show-object-format --show-ref-format >actual &&
git -C repo rev-parse --show-object-format --show-ref-storage-format >actual &&
test_cmp expect actual
'

@ -49,7 +49,7 @@ test_expect_success 'init: sha256 object format via option' '
sha256
reftable
EOF
git -C repo rev-parse --show-object-format --show-ref-format >actual &&
git -C repo rev-parse --show-object-format --show-ref-storage-format >actual &&
test_cmp expect actual
'

@ -59,28 +59,28 @@ test_expect_success 'init: reinitializing reftable backend succeeds' '
test_commit -C repo A &&

git -C repo for-each-ref >expect &&
git init --ref-format=reftable repo &&
git init --ref-storage-format=reftable repo &&
git -C repo for-each-ref >actual &&
test_cmp expect actual
'

test_expect_success 'init: reinitializing files with reftable backend fails' '
test_when_finished "rm -rf repo" &&
git init --ref-format=files repo &&
git init --ref-storage-format=files repo &&
test_commit -C repo file &&

cp repo/.git/HEAD expect &&
test_must_fail git init --ref-format=reftable repo &&
test_must_fail git init --ref-storage-format=reftable repo &&
test_cmp expect repo/.git/HEAD
'

test_expect_success 'init: reinitializing reftable with files backend fails' '
test_when_finished "rm -rf repo" &&
git init --ref-format=reftable repo &&
git init --ref-storage-format=reftable repo &&
test_commit -C repo file &&

cp repo/.git/HEAD expect &&
test_must_fail git init --ref-format=files repo &&
test_must_fail git init --ref-storage-format=files repo &&
test_cmp expect repo/.git/HEAD
'

@ -156,45 +156,45 @@ test_expect_success 'clone: can clone reftable repository' '

git clone repo cloned &&
echo reftable >expect &&
git -C cloned rev-parse --show-ref-format >actual &&
git -C cloned rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual &&
test_path_is_file cloned/file1
'

test_expect_success 'clone: can clone reffiles into reftable repository' '
test_when_finished "rm -rf reffiles reftable" &&
git init --ref-format=files reffiles &&
git init --ref-storage-format=files reffiles &&
test_commit -C reffiles A &&
git clone --ref-format=reftable ./reffiles reftable &&
git clone --ref-storage-format=reftable ./reffiles reftable &&

git -C reffiles rev-parse HEAD >expect &&
git -C reftable rev-parse HEAD >actual &&
test_cmp expect actual &&

git -C reftable rev-parse --show-ref-format >actual &&
git -C reftable rev-parse --show-ref-storage-format >actual &&
echo reftable >expect &&
test_cmp expect actual &&

git -C reffiles rev-parse --show-ref-format >actual &&
git -C reffiles rev-parse --show-ref-storage-format >actual &&
echo files >expect &&
test_cmp expect actual
'

test_expect_success 'clone: can clone reftable into reffiles repository' '
test_when_finished "rm -rf reffiles reftable" &&
git init --ref-format=reftable reftable &&
git init --ref-storage-format=reftable reftable &&
test_commit -C reftable A &&
git clone --ref-format=files ./reftable reffiles &&
git clone --ref-storage-format=files ./reftable reffiles &&

git -C reftable rev-parse HEAD >expect &&
git -C reffiles rev-parse HEAD >actual &&
test_cmp expect actual &&

git -C reftable rev-parse --show-ref-format >actual &&
git -C reftable rev-parse --show-ref-storage-format >actual &&
echo reftable >expect &&
test_cmp expect actual &&

git -C reffiles rev-parse --show-ref-format >actual &&
git -C reffiles rev-parse --show-ref-storage-format >actual &&
echo files >expect &&
test_cmp expect actual
'

View File

@ -10,7 +10,7 @@ start_httpd
REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo"

test_expect_success 'serving ls-remote' '
git init --ref-format=reftable -b main "$REPO" &&
git init --ref-storage-format=reftable -b main "$REPO" &&
cd "$REPO" &&
test_commit m1 &&
>.git/git-daemon-export-ok &&

View File

@ -4,8 +4,8 @@ test_description='reftables are compatible with JGit'

GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
GIT_TEST_DEFAULT_REF_FORMAT=reftable
export GIT_TEST_DEFAULT_REF_FORMAT
GIT_TEST_DEFAULT_REF_STORAGE_FORMAT=reftable
export GIT_TEST_DEFAULT_REF_STORAGE_FORMAT

# JGit does not support the 'link' DIRC extension.
GIT_TEST_SPLIT_INDEX=0

View File

@ -2,8 +2,8 @@

test_description='reftable write options'

GIT_TEST_DEFAULT_REF_FORMAT=reftable
export GIT_TEST_DEFAULT_REF_FORMAT
GIT_TEST_DEFAULT_REF_STORAGE_FORMAT=reftable
export GIT_TEST_DEFAULT_REF_STORAGE_FORMAT
# Disable auto-compaction for all tests as we explicitly control repacking of
# refs.
GIT_TEST_REFTABLE_AUTOCOMPACTION=false

View File

@ -2,8 +2,8 @@

test_description='Test reftable backend consistency check'

GIT_TEST_DEFAULT_REF_FORMAT=reftable
export GIT_TEST_DEFAULT_REF_FORMAT
GIT_TEST_DEFAULT_REF_STORAGE_FORMAT=reftable
export GIT_TEST_DEFAULT_REF_STORAGE_FORMAT

. ./test-lib.sh


View File

@ -2361,7 +2361,7 @@ do
'

test_expect_success CASE_INSENSITIVE_FS "stdin $type batch-updates existing reference" '
git init --ref-format=reftable repo &&
git init --ref-storage-format=reftable repo &&
test_when_finished "rm -fr repo" &&
(
cd repo &&

View File

@ -21,13 +21,13 @@ assert_jumps () {
local nr="$1"
local trace="$2"

case "$GIT_DEFAULT_REF_FORMAT" in
case "$GIT_DEFAULT_REF_STORAGE_FORMAT" in
files)
grep -q "name:jumps_made value:$nr$" $trace;;
reftable)
grep -q "name:reseeks_made value:$nr$" $trace;;
*)
BUG "unhandled ref format $GIT_DEFAULT_REF_FORMAT";;
BUG "unhandled ref storage format $GIT_DEFAULT_REF_STORAGE_FORMAT";;
esac
}

@ -93,13 +93,13 @@ test_expect_success 'adjacent, non-overlapping excluded regions' '
for_each_ref refs/heads/foo refs/heads/quux >expect &&

test_cmp expect actual &&
case "$GIT_DEFAULT_REF_FORMAT" in
case "$GIT_DEFAULT_REF_STORAGE_FORMAT" in
files)
assert_jumps 1 perf;;
reftable)
assert_jumps 2 perf;;
*)
BUG "unhandled ref format $GIT_DEFAULT_REF_FORMAT";;
BUG "unhandled ref storage format $GIT_DEFAULT_REF_STORAGE_FORMAT";;
esac
'

@ -125,13 +125,13 @@ test_expect_success 'several overlapping excluded regions' '
for_each_ref refs/heads/quux >expect &&

test_cmp expect actual &&
case "$GIT_DEFAULT_REF_FORMAT" in
case "$GIT_DEFAULT_REF_STORAGE_FORMAT" in
files)
assert_jumps 1 perf;;
reftable)
assert_jumps 3 perf;;
*)
BUG "unhandled ref format $GIT_DEFAULT_REF_FORMAT";;
BUG "unhandled ref storage format $GIT_DEFAULT_REF_STORAGE_FORMAT";;
esac
'

@ -141,13 +141,13 @@ test_expect_success 'unordered excludes' '
for_each_ref refs/heads/bar refs/heads/quux >expect &&

test_cmp expect actual &&
case "$GIT_DEFAULT_REF_FORMAT" in
case "$GIT_DEFAULT_REF_STORAGE_FORMAT" in
files)
assert_jumps 1 perf;;
reftable)
assert_jumps 2 perf;;
*)
BUG "unhandled ref format $GIT_DEFAULT_REF_FORMAT";;
BUG "unhandled ref storage format $GIT_DEFAULT_REF_STORAGE_FORMAT";;
esac
'


View File

@ -12,7 +12,7 @@ test_description='Test reference backend URIs'
# <uri> is the new URI to be set for the ref storage.
# <cmd> is the git subcommand to be run in the repository.
# <via> if 'config', set the backend via the 'extensions.refStorage' config.
# if 'env', set the backend via the 'GIT_REFERENCE_BACKEND' env.
# if 'env', set the backend via the 'GIT_REF_STORAGE_FORMAT' env.
run_with_uri () {
repo=$1 &&
backend=$2 &&
@ -23,7 +23,7 @@ run_with_uri () {
git -C "$repo" config set core.repositoryformatversion 1 &&
if test "$via" = "env"
then
test_env GIT_REFERENCE_BACKEND="$uri" git -C "$repo" $cmd
test_env GIT_REF_STORAGE_FORMAT="$uri" git -C "$repo" $cmd
elif test "$via" = "config"
then
git -C "$repo" config set extensions.refStorage "$uri" &&
@ -40,7 +40,7 @@ run_with_uri () {
# <backend> is the original ref storage of the repo.
# <uri> is the new URI to be set for the ref storage.
# <via> if 'config', set the backend via the 'extensions.refStorage' config.
# if 'env', set the backend via the 'GIT_REFERENCE_BACKEND' env.
# if 'env', set the backend via the 'GIT_REF_STORAGE_FORMAT' env.
# <err_msg> (optional) if set, check if 'git-refs(1)' failed with the provided msg.
test_refs_backend () {
repo=$1 &&
@ -54,7 +54,7 @@ test_refs_backend () {
then
if test "$via" = "env"
then
test_env GIT_REFERENCE_BACKEND="$uri" test_must_fail git -C "$repo" refs list 2>err
test_env GIT_REF_STORAGE_FORMAT="$uri" test_must_fail git -C "$repo" refs list 2>err
elif test "$via" = "config"
then
git -C "$repo" config set extensions.refStorage "$uri" &&
@ -83,7 +83,7 @@ verify_files_exist () {
test_cmp expect $gitdir/HEAD

# verify that backend specific files exist.
case "$GIT_DEFAULT_REF_FORMAT" in
case "$GIT_DEFAULT_REF_STORAGE_FORMAT" in
files)
test_path_is_dir $refdir/refs/heads &&
test_path_is_file $refdir/HEAD;;
@ -91,7 +91,7 @@ verify_files_exist () {
test_path_is_dir $refdir/reftable &&
test_path_is_file $refdir/reftable/tables.list;;
*)
BUG "unhandled ref format $GIT_DEFAULT_REF_FORMAT";;
BUG "unhandled ref storage format $GIT_DEFAULT_REF_STORAGE_FORMAT";;
esac
}

@ -137,14 +137,14 @@ do

test_expect_success "$method: read from $to_format backend, $dir dir" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
(
cd repo &&
test_commit 1 &&
test_commit 2 &&
test_commit 3 &&

git refs migrate --dry-run --ref-format=$to_format >out &&
git refs migrate --dry-run --ref-storage-format=$to_format >out &&
BACKEND_PATH="$dir/$(sed "s/.* ${SQ}.git\/\(.*\)${SQ}/\1/" out)" &&
test_refs_backend . $from_format "$to_format://$BACKEND_PATH" "$method"
)
@ -152,14 +152,14 @@ do

test_expect_success "$method: write to $to_format backend, $dir dir" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
(
cd repo &&
test_commit 1 &&
test_commit 2 &&
test_commit 3 &&

git refs migrate --dry-run --ref-format=$to_format >out &&
git refs migrate --dry-run --ref-storage-format=$to_format >out &&
BACKEND_PATH="$dir/$(sed "s/.* ${SQ}.git\/\(.*\)${SQ}/\1/" out)" &&

test_refs_backend . $from_format "$to_format://$BACKEND_PATH" "$method" &&
@ -179,14 +179,14 @@ do

test_expect_success "$method: with worktree and $to_format backend, $dir dir" '
test_when_finished "rm -rf repo wt" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
(
cd repo &&
test_commit 1 &&
test_commit 2 &&
test_commit 3 &&

git refs migrate --dry-run --ref-format=$to_format >out &&
git refs migrate --dry-run --ref-storage-format=$to_format >out &&
BACKEND_PATH="$dir/$(sed "s/.* ${SQ}.git\/\(.*\)${SQ}/\1/" out)" &&

run_with_uri . "$from_format" "$to_format://$BACKEND_PATH" \
@ -210,7 +210,7 @@ do
test_expect_success "migrating repository to $to_format with alternate refs directory" '
test_when_finished "rm -rf repo refdir" &&
mkdir refdir &&
GIT_REFERENCE_BACKEND="${from_format}://$(pwd)/refdir" git init repo &&
GIT_REF_STORAGE_FORMAT="${from_format}://$(pwd)/refdir" git init repo &&
(
cd repo &&

@ -218,7 +218,7 @@ do
test_commit 2 &&
test_commit 3 &&

git refs migrate --ref-format=$to_format &&
git refs migrate --ref-storage-format=$to_format &&
git refs list >out &&
test_grep "refs/tags/1" out &&
test_grep "refs/tags/2" out &&
@ -235,7 +235,7 @@ test_expect_success 'initializing repository with alt ref directory' '
test_when_finished "rm -rf repo refdir" &&
mkdir refdir &&
BACKEND="$(test_detect_ref_format)://$(pwd)/refdir" &&
GIT_REFERENCE_BACKEND=$BACKEND git init repo &&
GIT_REF_STORAGE_FORMAT=$BACKEND git init repo &&
verify_files_exist repo/.git refdir &&
(
cd repo &&
@ -254,6 +254,36 @@ test_expect_success 'initializing repository with alt ref directory' '
)
'

test_expect_success 'initializing repository with --ref-storage-format and payload' '
test_when_finished "rm -rf repo refdir" &&
mkdir refdir &&
BACKEND="$(test_detect_ref_format)://$(pwd)/refdir" &&
git init --ref-storage-format="$BACKEND" repo &&
verify_files_exist repo/.git refdir &&

git -C repo config get extensions.refstorage >actual &&
echo $BACKEND >expect &&
test_cmp expect actual &&

test_commit -C repo 1 &&
git -C repo refs list >out &&
test_grep "refs/tags/1" out &&

# Reinitializing the repository is fine when not specifying any format.
git -C repo init &&
# Reinitializing with the same backend is fine, too.
git -C repo init --ref-storage-format="$BACKEND" &&
# Reinitializing without a payload should fail.
test_must_fail git -C repo init --ref-storage-format="$(test_detect_ref_format)" 2>err &&
test_grep "attempt to reinitialize repository with different reference storage payload" err &&
# Reinitializing with a different payload should fail, too.
test_must_fail git -C repo init --ref-storage-format="$(test_detect_ref_format)://$(pwd)/other" 2>err &&
test_grep "attempt to reinitialize repository with different reference storage payload" err &&

git -C repo config get extensions.refstorage >actual &&
test_cmp expect actual
'

test_expect_success 'cloning repository with alt ref directory' '
test_when_finished "rm -rf source repo refdir" &&
mkdir refdir &&
@ -264,7 +294,7 @@ test_expect_success 'cloning repository with alt ref directory' '
test_commit -C source 3 &&

BACKEND="$(test_detect_ref_format)://$(pwd)/refdir" &&
GIT_REFERENCE_BACKEND=$BACKEND git clone source repo &&
GIT_REF_STORAGE_FORMAT=$BACKEND git clone source repo &&

git -C repo config get extensions.refstorage >actual &&
echo $BACKEND >expect &&

View File

@ -42,7 +42,7 @@ test_migration () {
print_all_reflog_entries "$repo" >expect_logs
fi &&

git -C "$repo" refs migrate --ref-format="$format" "$@" &&
git -C "$repo" refs migrate --ref-storage-format="$format" "$@" &&

git -C "$repo" for-each-ref --include-root-refs \
--format='%(refname) %(objectname) %(symref)' >actual &&
@ -53,7 +53,7 @@ test_migration () {
test_cmp expect_logs actual_logs
fi &&

git -C "$repo" rev-parse --show-ref-format >actual &&
git -C "$repo" rev-parse --show-ref-storage-format >actual &&
echo "$format" >expect &&
test_cmp expect actual
}
@ -77,7 +77,7 @@ test_expect_success "missing ref storage format" '
git init repo &&
test_must_fail git -C repo refs migrate 2>err &&
cat >expect <<-EOF &&
usage: missing --ref-format=<format>
usage: missing --ref-storage-format=<format>
EOF
test_cmp expect err
'
@ -86,7 +86,7 @@ test_expect_success "unknown ref storage format" '
test_when_finished "rm -rf repo" &&
git init repo &&
test_must_fail git -C repo refs migrate \
--ref-format=unknown 2>err &&
--ref-storage-format=unknown 2>err &&
cat >expect <<-EOF &&
error: unknown ref storage format ${SQ}unknown${SQ}
EOF
@ -105,9 +105,9 @@ do

test_expect_success "$from_format: migration to same format fails" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
test_must_fail git -C repo refs migrate \
--ref-format=$from_format 2>err &&
--ref-storage-format=$from_format 2>err &&
cat >expect <<-EOF &&
error: repository already uses ${SQ}$from_format${SQ} format
EOF
@ -116,10 +116,10 @@ do

test_expect_success "$from_format -> $to_format: migration with worktree fails" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
git -C repo worktree add wt &&
test_must_fail git -C repo refs migrate \
--ref-format=$to_format 2>err &&
--ref-storage-format=$to_format 2>err &&
cat >expect <<-EOF &&
error: migrating repositories with worktrees is not supported yet
EOF
@ -128,28 +128,28 @@ do

test_expect_success "$from_format -> $to_format: unborn HEAD" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
test_migration repo "$to_format"
'

test_expect_success "$from_format -> $to_format: single ref" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
test_commit -C repo initial &&
test_migration repo "$to_format"
'

test_expect_success "$from_format -> $to_format: bare repository" '
test_when_finished "rm -rf repo repo.git" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
test_commit -C repo initial &&
git clone --ref-format=$from_format --mirror repo repo.git &&
git clone --ref-storage-format=$from_format --mirror repo repo.git &&
test_migration repo.git "$to_format"
'

test_expect_success "$from_format -> $to_format: dangling symref" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
test_commit -C repo initial &&
git -C repo symbolic-ref BROKEN_HEAD refs/heads/nonexistent &&
test_migration repo "$to_format" &&
@ -160,7 +160,7 @@ do

test_expect_success "$from_format -> $to_format: broken ref" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
test_commit -C repo initial &&
test-tool -C repo ref-store main update-ref "" refs/heads/broken \
"$(test_oid 001)" "$ZERO_OID" REF_SKIP_CREATE_REFLOG,REF_SKIP_OID_VERIFICATION &&
@ -172,7 +172,7 @@ do

test_expect_success "$from_format -> $to_format: pseudo-refs" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
test_commit -C repo initial &&
git -C repo update-ref FOO_HEAD HEAD &&
test_migration repo "$to_format"
@ -180,7 +180,7 @@ do

test_expect_success "$from_format -> $to_format: special refs are left alone" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
test_commit -C repo initial &&
git -C repo rev-parse HEAD >repo/.git/MERGE_HEAD &&
git -C repo rev-parse MERGE_HEAD &&
@ -190,7 +190,7 @@ do

test_expect_success "$from_format -> $to_format: a bunch of refs" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&

test_commit -C repo initial &&
cat >input <<-EOF &&
@ -208,20 +208,20 @@ do

test_expect_success "$from_format -> $to_format: dry-run migration does not modify repository" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
test_commit -C repo initial &&
git -C repo refs migrate --dry-run \
--ref-format=$to_format >output &&
--ref-storage-format=$to_format >output &&
test_grep "Finished dry-run migration of refs" output &&
test_path_is_dir repo/.git/ref_migration.* &&
echo $from_format >expect &&
git -C repo rev-parse --show-ref-format >actual &&
git -C repo rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

test_expect_success "$from_format -> $to_format: reflogs of symrefs with target deleted" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
test_commit -C repo initial &&
git -C repo branch branch-1 HEAD &&
git -C repo symbolic-ref refs/heads/symref refs/heads/branch-1 &&
@ -234,7 +234,7 @@ do

test_expect_success "$from_format -> $to_format: reflogs order is retained" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
test_commit --date "100005000 +0700" --no-tag -C repo initial &&
test_commit --date "100003000 +0700" --no-tag -C repo second &&
test_migration repo "$to_format"
@ -242,7 +242,7 @@ do

test_expect_success "$from_format -> $to_format: stash is retained" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
(
cd repo &&
test_commit initial A &&
@ -259,7 +259,7 @@ do

test_expect_success "$from_format -> $to_format: skip reflog with --skip-reflog" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
git init --ref-storage-format=$from_format repo &&
test_commit -C repo initial &&
# we see that the repository contains reflogs.
git -C repo reflog --all >reflogs &&
@ -274,7 +274,7 @@ done

test_expect_success 'multiple reftable blocks with multiple entries' '
test_when_finished "rm -rf repo" &&
git init --ref-format=files repo &&
git init --ref-storage-format=files repo &&
test_commit -C repo first &&
test_seq -f "create refs/heads/ref-%d HEAD" 5000 |
git -C repo update-ref --stdin &&
@ -286,7 +286,7 @@ test_expect_success 'multiple reftable blocks with multiple entries' '

test_expect_success 'migrating from files format deletes backend files' '
test_when_finished "rm -rf repo" &&
git init --ref-format=files repo &&
git init --ref-storage-format=files repo &&
test_commit -C repo first &&
git -C repo pack-refs --all &&
test_commit -C repo second &&
@ -313,7 +313,7 @@ test_expect_success 'migrating from files format deletes backend files' '

test_expect_success 'migrating from reftable format deletes backend files' '
test_when_finished "rm -rf repo" &&
git init --ref-format=reftable repo &&
git init --ref-storage-format=reftable repo &&
test_commit -C repo first &&

test_path_is_dir repo/.git/reftable &&

View File

@ -8,8 +8,8 @@ semantic is still the same.

GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
GIT_TEST_DEFAULT_REF_FORMAT=files
export GIT_TEST_DEFAULT_REF_FORMAT
GIT_TEST_DEFAULT_REF_STORAGE_FORMAT=files
export GIT_TEST_DEFAULT_REF_STORAGE_FORMAT

. ./test-lib.sh


View File

@ -241,19 +241,19 @@ test_expect_success RUST 'rev-parse --show-object-format in repo with compat mod
)
'

test_expect_success 'rev-parse --show-ref-format' '
test_expect_success 'rev-parse --show-ref-storage-format' '
test_detect_ref_format >expect &&
git rev-parse --show-ref-format >actual &&
git rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

test_expect_success 'rev-parse --show-ref-format with invalid storage' '
test_expect_success 'rev-parse --show-ref-storage-format with invalid storage' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
git config extensions.refstorage broken &&
test_must_fail git rev-parse --show-ref-format 2>err &&
test_must_fail git rev-parse --show-ref-storage-format 2>err &&
test_grep "error: invalid value for ${SQ}extensions.refstorage${SQ}: ${SQ}broken${SQ}" err
)
'

View File

@ -39,10 +39,10 @@ test_repo_info () {
}

test_repo_info 'ref format files is retrieved correctly' \
'git init --ref-format=files' 'format-files' 'references.format' 'files'
'git init --ref-storage-format=files' 'format-files' 'references.format' 'files'

test_repo_info 'ref format reftable is retrieved correctly' \
'git init --ref-format=reftable' 'format-reftable' 'references.format' 'reftable'
'git init --ref-storage-format=reftable' 'format-reftable' 'references.format' 'reftable'

test_repo_info 'bare repository = false is retrieved correctly' \
'git init' 'nonbare' 'layout.bare' 'false'
@ -75,7 +75,7 @@ test_expect_success 'values returned in order requested' '
references.format=files
layout.bare=false
EOF
git init --ref-format=files ordered &&
git init --ref-storage-format=files ordered &&
git -C ordered repo info layout.bare references.format layout.bare >actual &&
test_cmp expect actual
'

View File

@ -46,19 +46,19 @@ test_expect_success "clone and setup child repos" '
) &&
git clone . bundle &&
git clone . seven &&
git clone --ref-format=reftable . case_sensitive &&
git clone --ref-storage-format=reftable . case_sensitive &&
(
cd case_sensitive &&
git branch branch1 &&
git branch bRanch1
) &&
git clone --ref-format=reftable . case_sensitive_fd &&
git clone --ref-storage-format=reftable . case_sensitive_fd &&
(
cd case_sensitive_fd &&
git branch foo/bar &&
git branch Foo
) &&
git clone --ref-format=reftable . case_sensitive_df &&
git clone --ref-storage-format=reftable . case_sensitive_df &&
(
cd case_sensitive_df &&
git branch Foo/bar &&
@ -1803,7 +1803,7 @@ test_expect_success CASE_INSENSITIVE_FS,REFFILES 'existing references in a case
test_expect_success REFFILES 'existing reference lock in repo' '
test_when_finished rm -rf base repo &&
(
git init --ref-format=reftable base &&
git init --ref-storage-format=reftable base &&
cd base &&
echo >file update &&
git add . &&
@ -1814,7 +1814,7 @@ test_expect_success REFFILES 'existing reference lock in repo' '
git update-ref refs/heads/branch @ &&
cd .. &&

git init --ref-format=files --bare repo &&
git init --ref-storage-format=files --bare repo &&
cd repo &&
git remote add origin ../base &&
touch refs/heads/foo.lock &&
@ -1857,7 +1857,7 @@ test_expect_success CASE_INSENSITIVE_FS,REFFILES 'D/F conflict on case insensiti
test_expect_success REFFILES 'D/F conflict on case sensitive filesystem with lock' '
test_when_finished rm -rf base repo &&
(
git init --ref-format=reftable base &&
git init --ref-storage-format=reftable base &&
cd base &&
echo >file update &&
git add . &&
@ -1868,7 +1868,7 @@ test_expect_success REFFILES 'D/F conflict on case sensitive filesystem with loc
git update-ref refs/heads/branch @ &&
cd .. &&

git init --ref-format=files --bare repo &&
git init --ref-storage-format=files --bare repo &&
cd repo &&
git remote add origin ../base &&
mkdir refs/heads/foo &&

View File

@ -166,9 +166,9 @@ test_expect_success 'clone --mirror does not repeat tags' '

test_expect_success 'clone with files ref format' '
test_when_finished "rm -rf ref-storage" &&
git clone --ref-format=files --mirror src ref-storage &&
git clone --ref-storage-format=files --mirror src ref-storage &&
echo files >expect &&
git -C ref-storage rev-parse --show-ref-format >actual &&
git -C ref-storage rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
'

@ -176,7 +176,7 @@ test_expect_success 'clone with garbage ref format' '
cat >expect <<-EOF &&
fatal: unknown ref storage format ${SQ}garbage${SQ}
EOF
test_must_fail git clone --ref-format=garbage --mirror src ref-storage 2>err &&
test_must_fail git clone --ref-storage-format=garbage --mirror src ref-storage 2>err &&
test_cmp expect err &&
test_path_is_missing ref-storage
'

View File

@ -6,13 +6,13 @@ test_description='submodules handle mixed ref storage formats'

test_ref_format () {
echo "$2" >expect &&
git -C "$1" rev-parse --show-ref-format >actual &&
git -C "$1" rev-parse --show-ref-storage-format >actual &&
test_cmp expect actual
}

for OTHER_FORMAT in files reftable
do
if test "$OTHER_FORMAT" = "$GIT_DEFAULT_REF_FORMAT"
if test "$OTHER_FORMAT" = "$GIT_DEFAULT_REF_STORAGE_FORMAT"
then
continue
fi
@ -31,7 +31,7 @@ test_expect_success 'add existing repository with different ref storage format'
(
cd parent &&
test_commit parent &&
git init --ref-format=$OTHER_FORMAT submodule &&
git init --ref-storage-format=$OTHER_FORMAT submodule &&
test_commit -C submodule submodule &&
git submodule add ./submodule
)
@ -43,8 +43,8 @@ test_expect_success 'add submodules with different ref storage format' '
git init submodule &&
test_commit -C submodule submodule-initial &&
git init upstream &&
test_ref_format upstream "$GIT_DEFAULT_REF_FORMAT" &&
git -C upstream submodule add --ref-format="$OTHER_FORMAT" "file://$(pwd)/submodule" &&
test_ref_format upstream "$GIT_DEFAULT_REF_STORAGE_FORMAT" &&
git -C upstream submodule add --ref-storage-format="$OTHER_FORMAT" "file://$(pwd)/submodule" &&
test_ref_format upstream/submodule "$OTHER_FORMAT"
'

@ -59,13 +59,13 @@ test_expect_success 'recursive clone propagates ref storage format' '

# The upstream repository and its submodule should be using the default
# ref format.
test_ref_format upstream "$GIT_DEFAULT_REF_FORMAT" &&
test_ref_format upstream/submodule "$GIT_DEFAULT_REF_FORMAT" &&
test_ref_format upstream "$GIT_DEFAULT_REF_STORAGE_FORMAT" &&
test_ref_format upstream/submodule "$GIT_DEFAULT_REF_STORAGE_FORMAT" &&

# The cloned repositories should use the other ref format that we have
# specified via `--ref-format`. The option should propagate to cloned
# specified via `--ref-storage-format`. The option should propagate to cloned
# submodules.
git clone --ref-format=$OTHER_FORMAT --recurse-submodules \
git clone --ref-storage-format=$OTHER_FORMAT --recurse-submodules \
upstream downstream &&
test_ref_format downstream "$OTHER_FORMAT" &&
test_ref_format downstream/submodule "$OTHER_FORMAT"
@ -81,8 +81,8 @@ test_expect_success 'clone submodules with different ref storage format' '
git -C upstream commit -m "upstream submodule" &&

git clone --no-recurse-submodules "file://$(pwd)/upstream" downstream &&
test_ref_format downstream "$GIT_DEFAULT_REF_FORMAT" &&
git -C downstream submodule update --init --ref-format=$OTHER_FORMAT &&
test_ref_format downstream "$GIT_DEFAULT_REF_STORAGE_FORMAT" &&
git -C downstream submodule update --init --ref-storage-format=$OTHER_FORMAT &&
test_ref_format downstream/submodule "$OTHER_FORMAT"
'

@ -94,11 +94,11 @@ test_expect_success 'status with mixed submodule ref storages' '
git init main &&
git -C main submodule add "file://$(pwd)/submodule" &&
git -C main commit -m "add submodule" &&
git -C main/submodule refs migrate --ref-format=$OTHER_FORMAT &&
git -C main/submodule refs migrate --ref-storage-format=$OTHER_FORMAT &&

# The main repository should use the default ref format now, whereas
# the submodule should use the other format.
test_ref_format main "$GIT_DEFAULT_REF_FORMAT" &&
test_ref_format main "$GIT_DEFAULT_REF_STORAGE_FORMAT" &&
test_ref_format main/submodule "$OTHER_FORMAT" &&

cat >expect <<-EOF &&
@ -122,8 +122,8 @@ test_expect_success 'recursive pull with mixed formats' '
# Clone the upstream repository such that the main repo and its
# submodules have different formats.
git clone --no-recurse-submodules "file://$(pwd)/upstream" downstream &&
git -C downstream submodule update --init --ref-format=$OTHER_FORMAT &&
test_ref_format downstream "$GIT_DEFAULT_REF_FORMAT" &&
git -C downstream submodule update --init --ref-storage-format=$OTHER_FORMAT &&
test_ref_format downstream "$GIT_DEFAULT_REF_STORAGE_FORMAT" &&
test_ref_format downstream/submodule "$OTHER_FORMAT" &&

# Update the upstream submodule as well as the owning repository such

View File

@ -1737,7 +1737,7 @@ test_detect_hash () {

# Detect the ref format in use.
test_detect_ref_format () {
echo "${GIT_TEST_DEFAULT_REF_FORMAT:-files}"
echo "${GIT_TEST_DEFAULT_REF_STORAGE_FORMAT:-files}"
}

# Load common hash metadata and common placeholder object IDs for use with

View File

@ -575,8 +575,8 @@ export EDITOR
GIT_TEST_BUILTIN_HASH=$("$GIT_BINARY" version --build-options | sed -ne 's/^default-hash: //p')
GIT_DEFAULT_HASH="${GIT_TEST_DEFAULT_HASH:-$GIT_TEST_BUILTIN_HASH}"
export GIT_DEFAULT_HASH
GIT_DEFAULT_REF_FORMAT="${GIT_TEST_DEFAULT_REF_FORMAT:-files}"
export GIT_DEFAULT_REF_FORMAT
GIT_DEFAULT_REF_STORAGE_FORMAT="${GIT_TEST_DEFAULT_REF_STORAGE_FORMAT:-files}"
export GIT_DEFAULT_REF_STORAGE_FORMAT

# Tests using GIT_TRACE typically don't want <timestamp> <file>:<line> output
GIT_TRACE_BARE=1
@ -1752,13 +1752,13 @@ parisc* | hppa*)
;;
esac

case "$GIT_DEFAULT_REF_FORMAT" in
case "$GIT_DEFAULT_REF_STORAGE_FORMAT" in
files)
test_set_prereq REFFILES;;
reftable)
test_set_prereq REFTABLE;;
*)
echo 2>&1 "error: unknown ref format $GIT_DEFAULT_REF_FORMAT"
echo 2>&1 "error: unknown ref storage format $GIT_DEFAULT_REF_STORAGE_FORMAT"
exit 1
;;
esac