mirror of
https://github.com/libgit2/libgit2.git
synced 2026-01-25 02:56:17 +00:00
refdb: initialize on-disk data structures via the backend
The initialization of the on-disk state of refdbs is currently not handled by the actual refdb backend, but it's implemented ad-hoc where needed. This is problematic once we have multiple different refdbs as the filesystem structure is of course not the same. Introduce a new callback function `git_refdb_backend::init()`. If set, this callback can be invoked via `git_refdb_init()` to initialize the on-disk state of a refdb. Like this, each backend can decide for itself how exactly to do this. Note that the initialization of the refdb is a bit intricate. A repository is only recognized as such when it has a "HEAD" file as well as a "refs/" directory. Consequently, regardless of which refdb format we use, those files must always be present. This also proves to be problematic for us, as we cannot access the repository and thus don't have access to the refdb if those files didn't exist. To work around the issue we thus handle the creation of those files outside of the refdb-specific logic. We actually use the same strategy as Git does, and write the invalid reference "ref: refs/heads/.invalid" into "HEAD". This looks almost like a ref, but the name of that ref is not valid and should thus trip up Git clients that try to read that ref in a repository that really uses a different format. So while that invalid "HEAD" reference will of course get rewritten by the "files" backend, other backends should just retain it as-is.
This commit is contained in:
@@ -56,10 +56,48 @@ struct git_reference_iterator {
|
||||
git_reference_iterator *iter);
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
/**
|
||||
* The refdb that is to be initialized is for a worktree.
|
||||
*/
|
||||
GIT_REFDB_BACKEND_INIT_IS_WORKTREE = (1u << 0),
|
||||
|
||||
/*
|
||||
* Force-overwrite HEAD in case the refdb is already (partially)
|
||||
* initialized.
|
||||
*/
|
||||
GIT_REFDB_BACKEND_INIT_FORCE_HEAD = (1u << 1)
|
||||
} git_refdb_backend_init_flag_t;
|
||||
|
||||
/** An instance for a custom backend */
|
||||
struct git_refdb_backend {
|
||||
unsigned int version; /**< The backend API version */
|
||||
|
||||
/**
|
||||
* Create a new refdb and initialize its structures.
|
||||
*
|
||||
* A refdb implementation may provide this function; if it is not
|
||||
* provided, no data structures will be initialized for the refdb when
|
||||
* a new repository is created.
|
||||
*
|
||||
* @param path The path of the Git directory that shall be initialized.
|
||||
* @param initial_head The target that HEAD should point to. This value
|
||||
* should only be applied when there isn't yet a HEAD
|
||||
* reference, or when `GIT_REFDB_BACKEND_INIT_FORCE_HEAD`
|
||||
* is passed. Optional, if unset the backend should not set
|
||||
* up HEAD, either.
|
||||
* @param mode The mode that shall be used to create files and
|
||||
* directories. May be one of `git_repository_init_mode_t`
|
||||
* or normal Unix permission bits.
|
||||
* @param flags A combination of `git_refdb_backend_init_flag_t` flags.
|
||||
* @return `0` on success, a negative error value code.
|
||||
*/
|
||||
int GIT_CALLBACK(init)(
|
||||
git_refdb_backend *backend,
|
||||
const char *head_target,
|
||||
mode_t mode,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* Queries the refdb backend for the existence of a reference.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user