mirror of
https://github.com/git/git
synced 2024-10-01 06:05:20 +00:00
repository: wire ref extensions to ref backends
The previous change introduced the extensions.refFormat config option. It is a multi-valued config option that currently understands "files" and "packed", with both values assumed by default. If any value is provided explicitly, this default is ignored and the provided settings are used instead. The multi-valued nature of this extension presents a way to allow a user to specify that they never want a packed-refs file (only use "files") or that they never want loose reference files (only use "packed"). However, that functionality is not currently connected. Before actually modifying the files backend to understand these extension settings, do the basic wiring that connects the extensions.refFormat parsing to the creation of the ref backend. A future change will actually change the ref backend initialization based on these settings, but this communication of the extension is sufficiently complicated to be worth an isolated change. For now, also forbid the setting of only "packed". This is done by redirecting the choice of backend to the packed backend when that selection is made. A later change will make the "files"-only extension value ignore the packed backend. Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>
This commit is contained in:
parent
b62ddf44aa
commit
51d24fadb5
2
cache.h
2
cache.h
|
@ -1155,6 +1155,8 @@ struct repository_format {
|
|||
int hash_algo;
|
||||
int sparse_index;
|
||||
char *work_tree;
|
||||
int ref_format_count;
|
||||
enum ref_format_flags ref_format;
|
||||
struct string_list unknown_extensions;
|
||||
struct string_list v1_only_extensions;
|
||||
};
|
||||
|
|
22
refs.c
22
refs.c
|
@ -1982,6 +1982,15 @@ static struct ref_store *lookup_ref_store_map(struct hashmap *map,
|
|||
return entry ? entry->refs : NULL;
|
||||
}
|
||||
|
||||
static int add_ref_format_flags(enum ref_format_flags flags, int caps) {
|
||||
if (flags & REF_FORMAT_FILES)
|
||||
caps |= REF_STORE_FORMAT_FILES;
|
||||
if (flags & REF_FORMAT_PACKED)
|
||||
caps |= REF_STORE_FORMAT_PACKED;
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create, record, and return a ref_store instance for the specified
|
||||
* gitdir.
|
||||
|
@ -1991,9 +2000,17 @@ static struct ref_store *ref_store_init(struct repository *repo,
|
|||
unsigned int flags)
|
||||
{
|
||||
const char *be_name = "files";
|
||||
struct ref_storage_be *be = find_ref_storage_backend(be_name);
|
||||
struct ref_storage_be *be;
|
||||
struct ref_store *refs;
|
||||
|
||||
flags = add_ref_format_flags(repo->ref_format, flags);
|
||||
|
||||
if (!(flags & REF_STORE_FORMAT_FILES) &&
|
||||
(flags & REF_STORE_FORMAT_PACKED))
|
||||
be_name = "packed";
|
||||
|
||||
be = find_ref_storage_backend(be_name);
|
||||
|
||||
if (!be)
|
||||
BUG("reference backend %s is unknown", be_name);
|
||||
|
||||
|
@ -2009,7 +2026,8 @@ struct ref_store *get_main_ref_store(struct repository *r)
|
|||
if (!r->gitdir)
|
||||
BUG("attempting to get main_ref_store outside of repository");
|
||||
|
||||
r->refs_private = ref_store_init(r, r->gitdir, REF_STORE_ALL_CAPS);
|
||||
r->refs_private = ref_store_init(r, r->gitdir,
|
||||
REF_STORE_ALL_CAPS);
|
||||
r->refs_private = maybe_debug_wrap_ref_store(r->gitdir, r->refs_private);
|
||||
return r->refs_private;
|
||||
}
|
||||
|
|
|
@ -3274,7 +3274,7 @@ static int files_init_db(struct ref_store *ref_store, struct strbuf *err UNUSED)
|
|||
}
|
||||
|
||||
struct ref_storage_be refs_be_files = {
|
||||
.next = NULL,
|
||||
.next = &refs_be_packed,
|
||||
.name = "files",
|
||||
.init = files_ref_store_create,
|
||||
.init_db = files_init_db,
|
||||
|
|
|
@ -521,6 +521,9 @@ struct ref_store;
|
|||
REF_STORE_ODB | \
|
||||
REF_STORE_MAIN)
|
||||
|
||||
#define REF_STORE_FORMAT_FILES (1 << 8) /* can use loose ref files */
|
||||
#define REF_STORE_FORMAT_PACKED (1 << 9) /* can use packed-refs file */
|
||||
|
||||
/*
|
||||
* Initialize the ref_store for the specified gitdir. These functions
|
||||
* should call base_ref_store_init() to initialize the shared part of
|
||||
|
|
|
@ -182,6 +182,8 @@ int repo_init(struct repository *repo,
|
|||
repo->repository_format_partial_clone = format.partial_clone;
|
||||
format.partial_clone = NULL;
|
||||
|
||||
repo->ref_format = format.ref_format;
|
||||
|
||||
if (worktree)
|
||||
repo_set_worktree(repo, worktree);
|
||||
|
||||
|
|
|
@ -61,6 +61,11 @@ struct repo_path_cache {
|
|||
char *shallow;
|
||||
};
|
||||
|
||||
enum ref_format_flags {
|
||||
REF_FORMAT_FILES = (1 << 0),
|
||||
REF_FORMAT_PACKED = (1 << 1),
|
||||
};
|
||||
|
||||
struct repository {
|
||||
/* Environment */
|
||||
/*
|
||||
|
@ -95,6 +100,7 @@ struct repository {
|
|||
* the ref object.
|
||||
*/
|
||||
struct ref_store *refs_private;
|
||||
enum ref_format_flags ref_format;
|
||||
|
||||
/*
|
||||
* Contains path to often used file names.
|
||||
|
|
18
setup.c
18
setup.c
|
@ -578,9 +578,14 @@ static enum extension_result handle_extension(const char *var,
|
|||
data->hash_algo = format;
|
||||
return EXTENSION_OK;
|
||||
} else if (!strcmp(ext, "refformat")) {
|
||||
if (strcmp(value, "files") && strcmp(value, "packed"))
|
||||
if (!strcmp(value, "files"))
|
||||
data->ref_format |= REF_FORMAT_FILES;
|
||||
else if (!strcmp(value, "packed"))
|
||||
data->ref_format |= REF_FORMAT_PACKED;
|
||||
else
|
||||
return error(_("invalid value for '%s': '%s'"),
|
||||
"extensions.refFormat", value);
|
||||
data->ref_format_count++;
|
||||
return EXTENSION_OK;
|
||||
}
|
||||
return EXTENSION_UNKNOWN;
|
||||
|
@ -723,6 +728,11 @@ int read_repository_format(struct repository_format *format, const char *path)
|
|||
git_config_from_file(check_repo_format, path, format);
|
||||
if (format->version == -1)
|
||||
clear_repository_format(format);
|
||||
|
||||
/* Set default ref_format if no extensions.refFormat exists. */
|
||||
if (!format->ref_format_count)
|
||||
format->ref_format = REF_FORMAT_FILES | REF_FORMAT_PACKED;
|
||||
|
||||
return format->version;
|
||||
}
|
||||
|
||||
|
@ -1425,6 +1435,9 @@ int discover_git_directory(struct strbuf *commondir,
|
|||
candidate.partial_clone;
|
||||
candidate.partial_clone = NULL;
|
||||
|
||||
/* take ownership of candidate.ref_format */
|
||||
the_repository->ref_format = candidate.ref_format;
|
||||
|
||||
clear_repository_format(&candidate);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1561,6 +1574,8 @@ const char *setup_git_directory_gently(int *nongit_ok)
|
|||
the_repository->repository_format_partial_clone =
|
||||
repo_fmt.partial_clone;
|
||||
repo_fmt.partial_clone = NULL;
|
||||
|
||||
the_repository->ref_format = repo_fmt.ref_format;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
@ -1650,6 +1665,7 @@ void check_repository_format(struct repository_format *fmt)
|
|||
repo_set_hash_algo(the_repository, fmt->hash_algo);
|
||||
the_repository->repository_format_partial_clone =
|
||||
xstrdup_or_null(fmt->partial_clone);
|
||||
the_repository->ref_format = fmt->ref_format;
|
||||
clear_repository_format(&repo_fmt);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,4 +24,16 @@ test_expect_success 'invalid extensions.refFormat' '
|
|||
grep "invalid value for '\''extensions.refFormat'\'': '\''bogus'\''" err
|
||||
'
|
||||
|
||||
test_expect_success 'extensions.refFormat=packed only' '
|
||||
git init only-packed &&
|
||||
(
|
||||
cd only-packed &&
|
||||
git config core.repositoryFormatVersion 1 &&
|
||||
git config extensions.refFormat packed &&
|
||||
test_commit A &&
|
||||
test_path_exists .git/packed-refs &&
|
||||
test_path_is_missing .git/refs/tags/A
|
||||
)
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
Loading…
Reference in a new issue