Commit cb3269c9 by Patrick Steinhardt

repository: add function to retrieve paths for repo items

parent c09fd54e
......@@ -371,6 +371,42 @@ GIT_EXTERN(int) git_repository_head_unborn(git_repository *repo);
GIT_EXTERN(int) git_repository_is_empty(git_repository *repo);
/**
* List of items which belong to the git repository layout
*/
typedef enum {
GIT_REPOSITORY_ITEM_GITDIR,
GIT_REPOSITORY_ITEM_WORKDIR,
GIT_REPOSITORY_ITEM_COMMONDIR,
GIT_REPOSITORY_ITEM_INDEX,
GIT_REPOSITORY_ITEM_OBJECTS,
GIT_REPOSITORY_ITEM_REFS,
GIT_REPOSITORY_ITEM_PACKED_REFS,
GIT_REPOSITORY_ITEM_REMOTES,
GIT_REPOSITORY_ITEM_CONFIG,
GIT_REPOSITORY_ITEM_INFO,
GIT_REPOSITORY_ITEM_HOOKS,
GIT_REPOSITORY_ITEM_LOGS,
GIT_REPOSITORY_ITEM_MODULES,
GIT_REPOSITORY_ITEM_WORKTREES
} git_repository_item_t;
/**
* Get the location of a specific repository file or directory
*
* This function will retrieve the path of a specific repository
* item. It will thereby honor things like the repository's
* common directory, gitdir, etc. In case a file path cannot
* exist for a given item (e.g. the working directory of a bare
* repository), an error is returned.
*
* @param out Buffer to store the path at
* @param repo Repository to get path for
* @param item The repository item for which to retrieve the path
* @return 0 on success, otherwise a negative value
*/
GIT_EXTERN(int) git_repository_item_path(git_buf *out, git_repository *repo, git_repository_item_t item);
/**
* Get the path of this repository
*
* This is the path of the `.git` folder for normal repositories,
......
......@@ -36,6 +36,27 @@ GIT__USE_STRMAP
# include "win32/w32_util.h"
#endif
static const struct {
git_repository_item_t parent;
const char *name;
bool directory;
} items[] = {
{ GIT_REPOSITORY_ITEM_GITDIR, NULL, true },
{ GIT_REPOSITORY_ITEM_WORKDIR, NULL, true },
{ GIT_REPOSITORY_ITEM_COMMONDIR, NULL, true },
{ GIT_REPOSITORY_ITEM_GITDIR, "index", false },
{ GIT_REPOSITORY_ITEM_COMMONDIR, "objects", true },
{ GIT_REPOSITORY_ITEM_COMMONDIR, "refs", true },
{ GIT_REPOSITORY_ITEM_COMMONDIR, "packed-refs", false },
{ GIT_REPOSITORY_ITEM_COMMONDIR, "remotes", true },
{ GIT_REPOSITORY_ITEM_COMMONDIR, "config", false },
{ GIT_REPOSITORY_ITEM_COMMONDIR, "info", true },
{ GIT_REPOSITORY_ITEM_COMMONDIR, "hooks", true },
{ GIT_REPOSITORY_ITEM_COMMONDIR, "logs", true },
{ GIT_REPOSITORY_ITEM_GITDIR, "modules", true },
{ GIT_REPOSITORY_ITEM_COMMONDIR, "worktrees", true }
};
static int check_repositoryformatversion(git_config *config);
#define GIT_COMMONDIR_FILE "commondir"
......@@ -2052,6 +2073,46 @@ int git_repository_is_empty(git_repository *repo)
return is_empty;
}
int git_repository_item_path(git_buf *out, git_repository *repo, git_repository_item_t item)
{
const char *parent;
switch (items[item].parent) {
case GIT_REPOSITORY_ITEM_GITDIR:
parent = git_repository_path(repo);
break;
case GIT_REPOSITORY_ITEM_WORKDIR:
parent = git_repository_workdir(repo);
break;
case GIT_REPOSITORY_ITEM_COMMONDIR:
parent = git_repository_commondir(repo);
break;
default:
giterr_set(GITERR_INVALID, "Invalid item directory");
return -1;
}
if (parent == NULL) {
giterr_set(GITERR_INVALID, "Path cannot exist in repository");
return -1;
}
if (git_buf_sets(out, parent) < 0)
return -1;
if (items[item].name) {
if (git_buf_joinpath(out, parent, items[item].name) < 0)
return -1;
}
if (items[item].directory) {
if (git_path_to_dir(out) < 0)
return -1;
}
return 0;
}
const char *git_repository_path(git_repository *repo)
{
assert(repo);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment