mirror of
https://github.com/git/git.git
synced 2026-08-08 17:11:48 +00:00
Merge branch 'kj/repo-info-more-path-keys' into seen
The 'git repo info' command has been taught more keys to output paths of various repository components (such as the working tree root, superproject working tree, object database, etc.), supporting both absolute and relative path formats. * kj/repo-info-more-path-keys: repo: remove unused setup.h include repo: add path.git-prefix repo: add path.grafts with absolute and relative suffixes repo: add path.index with absolute and relative suffixes repo: add path.hooks with absolute and relative suffixes repo: add path.superproject-root with absolute and relative suffixes repo: add path.toplevel with absolute and relative suffix formatting
This commit is contained in:
@@ -113,12 +113,69 @@ values that they return:
|
||||
The path to the Git repository's common directory relative to
|
||||
the current working directory.
|
||||
|
||||
`path.git-prefix`::
|
||||
The path from the root of the working tree to the current working
|
||||
directory. Returns the empty string when the current working directory
|
||||
is the root of the working tree.
|
||||
|
||||
`path.gitdir.absolute`::
|
||||
The canonical absolute path to the Git repository directory (the `.git` directory).
|
||||
|
||||
`path.gitdir.relative`::
|
||||
The path to the Git repository directory relative to the current working directory.
|
||||
|
||||
`path.grafts.absolute`::
|
||||
The canonical absolute path to the repository's graft file.
|
||||
Respects the `GIT_GRAFT_FILE` environment override. The path is
|
||||
returned regardless of whether the file currently exists on disk.
|
||||
|
||||
`path.grafts.relative`::
|
||||
The path to the repository's graft file relative to the current
|
||||
working directory. Respects the `GIT_GRAFT_FILE` environment
|
||||
override. The path is returned regardless of whether the file
|
||||
currently exists on disk.
|
||||
|
||||
`path.hooks.absolute`::
|
||||
The canonical absolute path to the repository's hooks directory.
|
||||
Respects the `core.hooksPath` configuration. If `core.hooksPath` is
|
||||
set to `/dev/null`, that value is returned unchanged.
|
||||
|
||||
`path.hooks.relative`::
|
||||
The path to the repository's hooks directory relative to the current
|
||||
working directory. Respects the `core.hooksPath` configuration.
|
||||
|
||||
`path.index.absolute`::
|
||||
The canonical absolute path to the repository's current index file.
|
||||
Respects the `GIT_INDEX_FILE` environment override. Returns the
|
||||
configured index path even if the repository is bare or the file does
|
||||
not exist.
|
||||
|
||||
`path.index.relative`::
|
||||
The path to the repository's current index file relative to the current
|
||||
working directory. Respects the `GIT_INDEX_FILE` environment override.
|
||||
Returns the configured index path even if the repository is bare or the
|
||||
file does not exist.
|
||||
|
||||
`path.superproject-root.absolute`::
|
||||
The canonical absolute path to the working tree root of the superproject
|
||||
if the current repository is an initialized submodule. Outputs an empty
|
||||
string if not in a submodule.
|
||||
|
||||
`path.superproject-root.relative`::
|
||||
The path to the working tree root of the superproject relative to the
|
||||
current working directory if the current repository is an initialized
|
||||
submodule. Outputs an empty string if not in a submodule.
|
||||
|
||||
`path.toplevel.absolute`::
|
||||
The canonical absolute path to the top-level directory of the
|
||||
repository's working tree. Outputs an empty string if the repository
|
||||
is bare.
|
||||
|
||||
`path.toplevel.relative`::
|
||||
The path to the top-level directory of the repository's working
|
||||
tree relative to the current working directory. Outputs an empty
|
||||
string if the repository is bare.
|
||||
|
||||
`references.format`::
|
||||
The reference storage format. The valid values are:
|
||||
+
|
||||
|
||||
137
builtin/repo.c
137
builtin/repo.c
@@ -14,10 +14,10 @@
|
||||
#include "ref-filter.h"
|
||||
#include "refs.h"
|
||||
#include "revision.h"
|
||||
#include "setup.h"
|
||||
#include "strbuf.h"
|
||||
#include "string-list.h"
|
||||
#include "shallow.h"
|
||||
#include "submodule.h"
|
||||
#include "tree.h"
|
||||
#include "tree-walk.h"
|
||||
#include "utf8.h"
|
||||
@@ -99,6 +99,16 @@ static int get_path_commondir_relative(struct repository *repo, struct strbuf *b
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path_git_prefix(struct repository *repo, struct strbuf *buf)
|
||||
{
|
||||
/*
|
||||
* repo->prefix is NULL when the current working directory is
|
||||
* the worktree root.
|
||||
*/
|
||||
strbuf_addstr(buf, repo->prefix ? repo->prefix : "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path_gitdir_absolute(struct repository *repo, struct strbuf *buf)
|
||||
{
|
||||
const char *git_dir = repo_get_git_dir(repo);
|
||||
@@ -121,6 +131,120 @@ static int get_path_gitdir_relative(struct repository *repo, struct strbuf *buf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path_grafts_absolute(struct repository *repo, struct strbuf *buf)
|
||||
{
|
||||
const char *graft_file = repo_get_graft_file(repo);
|
||||
|
||||
if (!graft_file)
|
||||
return error(_("unable to get graft file"));
|
||||
|
||||
format_path(buf, graft_file, "", PATH_FORMAT_CANONICAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path_grafts_relative(struct repository *repo, struct strbuf *buf)
|
||||
{
|
||||
const char *graft_file = repo_get_graft_file(repo);
|
||||
|
||||
if (!graft_file)
|
||||
return error(_("unable to get graft file"));
|
||||
|
||||
format_path(buf, graft_file, repo->prefix, PATH_FORMAT_RELATIVE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path_hooks_absolute(struct repository *repo, struct strbuf *buf)
|
||||
{
|
||||
struct strbuf hooks_path = STRBUF_INIT;
|
||||
|
||||
repo_git_path_replace(repo, &hooks_path, "hooks");
|
||||
format_path(buf, hooks_path.buf, "", PATH_FORMAT_CANONICAL);
|
||||
strbuf_release(&hooks_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path_hooks_relative(struct repository *repo, struct strbuf *buf)
|
||||
{
|
||||
struct strbuf hooks_path = STRBUF_INIT;
|
||||
|
||||
repo_git_path_replace(repo, &hooks_path, "hooks");
|
||||
format_path(buf, hooks_path.buf, repo->prefix, PATH_FORMAT_RELATIVE);
|
||||
strbuf_release(&hooks_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path_index_absolute(struct repository *repo, struct strbuf *buf)
|
||||
{
|
||||
const char *index_file = repo_get_index_file(repo);
|
||||
|
||||
if (!index_file)
|
||||
return error(_("unable to get index file"));
|
||||
|
||||
format_path(buf, index_file, "", PATH_FORMAT_CANONICAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path_index_relative(struct repository *repo, struct strbuf *buf)
|
||||
{
|
||||
const char *index_file = repo_get_index_file(repo);
|
||||
|
||||
if (!index_file)
|
||||
return error(_("unable to get index file"));
|
||||
|
||||
format_path(buf, index_file, repo->prefix, PATH_FORMAT_RELATIVE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path_superproject_absolute(struct repository *repo UNUSED, struct strbuf *buf)
|
||||
{
|
||||
struct strbuf superproject = STRBUF_INIT;
|
||||
|
||||
if (!get_superproject_working_tree(&superproject)) {
|
||||
strbuf_release(&superproject);
|
||||
return 0;
|
||||
}
|
||||
|
||||
format_path(buf, superproject.buf, "", PATH_FORMAT_CANONICAL);
|
||||
strbuf_release(&superproject);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path_superproject_relative(struct repository *repo, struct strbuf *buf)
|
||||
{
|
||||
struct strbuf superproject = STRBUF_INIT;
|
||||
|
||||
if (!get_superproject_working_tree(&superproject)) {
|
||||
strbuf_release(&superproject);
|
||||
return 0;
|
||||
}
|
||||
|
||||
format_path(buf, superproject.buf, repo->prefix, PATH_FORMAT_RELATIVE);
|
||||
strbuf_release(&superproject);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path_toplevel_absolute(struct repository *repo, struct strbuf *buf)
|
||||
{
|
||||
const char *work_tree = repo_get_work_tree(repo);
|
||||
|
||||
if (!work_tree)
|
||||
return 0;
|
||||
|
||||
format_path(buf, work_tree, "", PATH_FORMAT_CANONICAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path_toplevel_relative(struct repository *repo, struct strbuf *buf)
|
||||
{
|
||||
const char *work_tree = repo_get_work_tree(repo);
|
||||
|
||||
if (!work_tree)
|
||||
return 0;
|
||||
|
||||
format_path(buf, work_tree, repo->prefix, PATH_FORMAT_RELATIVE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_references_format(struct repository *repo, struct strbuf *buf)
|
||||
{
|
||||
strbuf_addstr(buf,
|
||||
@@ -135,8 +259,19 @@ static const struct repo_info_field repo_info_field[] = {
|
||||
{ "object.format", get_object_format },
|
||||
{ "path.commondir.absolute", get_path_commondir_absolute },
|
||||
{ "path.commondir.relative", get_path_commondir_relative },
|
||||
{ "path.git-prefix", get_path_git_prefix },
|
||||
{ "path.gitdir.absolute", get_path_gitdir_absolute },
|
||||
{ "path.gitdir.relative", get_path_gitdir_relative },
|
||||
{ "path.grafts.absolute", get_path_grafts_absolute },
|
||||
{ "path.grafts.relative", get_path_grafts_relative },
|
||||
{ "path.hooks.absolute", get_path_hooks_absolute },
|
||||
{ "path.hooks.relative", get_path_hooks_relative },
|
||||
{ "path.index.absolute", get_path_index_absolute },
|
||||
{ "path.index.relative", get_path_index_relative },
|
||||
{ "path.superproject-root.absolute", get_path_superproject_absolute },
|
||||
{ "path.superproject-root.relative", get_path_superproject_relative },
|
||||
{ "path.toplevel.absolute", get_path_toplevel_absolute },
|
||||
{ "path.toplevel.relative", get_path_toplevel_relative },
|
||||
{ "references.format", get_references_format },
|
||||
};
|
||||
|
||||
|
||||
@@ -174,7 +174,11 @@ test_repo_info_path () {
|
||||
cd repo/sub &&
|
||||
ROOT="$(test-tool path-utils real_path ..)" && export ROOT &&
|
||||
eval "$init_command" &&
|
||||
echo "path.$field_name.absolute=$ROOT/$expected_dir" >expect &&
|
||||
case "$expected_dir" in
|
||||
/*) EXPECT_ABS="$expected_dir" ;;
|
||||
*) EXPECT_ABS="$ROOT/$expected_dir" ;;
|
||||
esac &&
|
||||
echo "path.$field_name.absolute=$EXPECT_ABS" >expect &&
|
||||
git repo info "path.$field_name.absolute" >actual &&
|
||||
test_cmp expect actual
|
||||
)
|
||||
@@ -188,7 +192,11 @@ test_repo_info_path () {
|
||||
cd repo/sub &&
|
||||
ROOT="$(test-tool path-utils real_path ..)" && export ROOT &&
|
||||
eval "$init_command" &&
|
||||
echo "path.$field_name.relative=../$expected_dir" >expect &&
|
||||
case "$expected_dir" in
|
||||
/*) EXPECT_REL="$(test-tool path-utils relative_path "$expected_dir" "$PWD")" ;;
|
||||
*) EXPECT_REL="../$expected_dir" ;;
|
||||
esac &&
|
||||
echo "path.$field_name.relative=$EXPECT_REL" >expect &&
|
||||
git repo info "path.$field_name.relative" >actual &&
|
||||
test_cmp expect actual
|
||||
)
|
||||
@@ -207,10 +215,152 @@ test_repo_info_path 'commondir with only GIT_DIR' 'commondir' \
|
||||
'.git' \
|
||||
'GIT_DIR="../.git" && export GIT_DIR'
|
||||
|
||||
test_expect_success 'path.git-prefix at repository root' '
|
||||
test_when_finished "rm -rf repo" &&
|
||||
git init repo &&
|
||||
(
|
||||
cd repo &&
|
||||
echo "path.git-prefix=" >expect &&
|
||||
git repo info path.git-prefix >actual &&
|
||||
test_cmp expect actual
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'path.git-prefix in subdirectory' '
|
||||
test_when_finished "rm -rf repo" &&
|
||||
git init repo &&
|
||||
mkdir -p repo/sub/dir &&
|
||||
(
|
||||
cd repo/sub/dir &&
|
||||
echo "path.git-prefix=sub/dir/" >expect &&
|
||||
git repo info path.git-prefix >actual &&
|
||||
test_cmp expect actual
|
||||
)
|
||||
'
|
||||
|
||||
test_repo_info_path 'gitdir standard' 'gitdir' '.git'
|
||||
|
||||
test_repo_info_path 'gitdir with explicit GIT_DIR' 'gitdir' \
|
||||
'.git' \
|
||||
'GIT_DIR="../.git" && export GIT_DIR'
|
||||
|
||||
test_repo_info_path 'grafts standard' 'grafts' '.git/info/grafts'
|
||||
|
||||
test_repo_info_path 'grafts with GIT_GRAFT_FILE override' 'grafts' \
|
||||
'custom-graft-file' \
|
||||
'GIT_GRAFT_FILE="$ROOT/custom-graft-file" && export GIT_GRAFT_FILE'
|
||||
|
||||
test_repo_info_path 'hooks standard' 'hooks' '.git/hooks'
|
||||
|
||||
test_repo_info_path 'hooks with core.hooksPath override' 'hooks' \
|
||||
'custom-hooks' \
|
||||
'git config core.hooksPath "$ROOT/custom-hooks" && mkdir -p "$ROOT/custom-hooks"'
|
||||
|
||||
# /dev/null is not a real, canonicalizable filesystem path on Windows,
|
||||
# so path resolution for core.hooksPath=/dev/null cannot be expected to
|
||||
# produce a literal "/dev/null" the way it does on POSIX systems.
|
||||
if ! test_have_prereq MINGW
|
||||
then
|
||||
test_repo_info_path 'hooks with core.hooksPath=/dev/null' 'hooks' \
|
||||
'/dev/null' \
|
||||
'git config core.hooksPath /dev/null'
|
||||
fi
|
||||
|
||||
test_repo_info_path 'index standard' 'index' '.git/index'
|
||||
|
||||
test_repo_info_path 'index with GIT_INDEX_FILE override' 'index' \
|
||||
'custom-index-file' \
|
||||
'GIT_INDEX_FILE="$ROOT/custom-index-file" && export GIT_INDEX_FILE'
|
||||
|
||||
test_expect_success 'path.index in a bare repository returns default index location' '
|
||||
test_when_finished "rm -rf bare.git" &&
|
||||
git init --bare bare.git &&
|
||||
(
|
||||
cd bare.git &&
|
||||
ROOT="$(test-tool path-utils real_path .)" &&
|
||||
|
||||
echo "path.index.absolute=$ROOT/index" >expect.abs &&
|
||||
git repo info path.index.absolute >actual.abs &&
|
||||
test_cmp expect.abs actual.abs &&
|
||||
|
||||
echo "path.index.relative=index" >expect.rel &&
|
||||
git repo info path.index.relative >actual.rel &&
|
||||
test_cmp expect.rel actual.rel
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'path.superproject-root absolute and relative' '
|
||||
test_when_finished "rm -rf sub super" &&
|
||||
git init sub &&
|
||||
test_commit -C sub initial &&
|
||||
git init super &&
|
||||
(
|
||||
cd super &&
|
||||
git -c protocol.file.allow=always submodule add "../sub" sub &&
|
||||
git commit -m "add submodule" &&
|
||||
|
||||
cd sub &&
|
||||
ROOT="$(test-tool path-utils real_path ..)" &&
|
||||
|
||||
echo "path.superproject-root.absolute=$ROOT" >expect.abs &&
|
||||
git repo info path.superproject-root.absolute >actual.abs &&
|
||||
test_cmp expect.abs actual.abs &&
|
||||
|
||||
echo "path.superproject-root.relative=../" >expect.rel &&
|
||||
git repo info path.superproject-root.relative >actual.rel &&
|
||||
test_cmp expect.rel actual.rel
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'path.superproject-root returns empty when not in a submodule' '
|
||||
test_when_finished "rm -rf repo" &&
|
||||
git init repo &&
|
||||
(
|
||||
cd repo &&
|
||||
|
||||
echo "path.superproject-root.absolute=" >expect.abs &&
|
||||
git repo info path.superproject-root.absolute >actual.abs &&
|
||||
test_cmp expect.abs actual.abs &&
|
||||
|
||||
echo "path.superproject-root.relative=" >expect.rel &&
|
||||
git repo info path.superproject-root.relative >actual.rel &&
|
||||
test_cmp expect.rel actual.rel
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'path.toplevel absolute and relative' '
|
||||
test_when_finished "rm -rf repo" &&
|
||||
git init repo &&
|
||||
(
|
||||
mkdir -p repo/sub &&
|
||||
cd repo/sub &&
|
||||
|
||||
ROOT="$(test-tool path-utils real_path ..)" &&
|
||||
|
||||
echo "path.toplevel.absolute=$ROOT" >expect.abs &&
|
||||
git repo info path.toplevel.absolute >actual.abs &&
|
||||
test_cmp expect.abs actual.abs &&
|
||||
|
||||
echo "path.toplevel.relative=../" >expect.rel &&
|
||||
git repo info path.toplevel.relative >actual.rel &&
|
||||
test_cmp expect.rel actual.rel
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'path.toplevel absolute and relative in a bare repository' '
|
||||
test_when_finished "rm -rf bare.git" &&
|
||||
git init --bare bare.git &&
|
||||
(
|
||||
cd bare.git &&
|
||||
|
||||
echo "path.toplevel.absolute=" >expect.abs &&
|
||||
git repo info path.toplevel.absolute >actual.abs &&
|
||||
test_cmp expect.abs actual.abs &&
|
||||
|
||||
echo "path.toplevel.relative=" >expect.rel &&
|
||||
git repo info path.toplevel.relative >actual.rel &&
|
||||
test_cmp expect.rel actual.rel
|
||||
)
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
Reference in New Issue
Block a user