From: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>
To: git@vger.kernel.org
Cc: sandals@crustytoothpaste.net, kumarayushjha123@gmail.com,
a3205153416@gmail.com, jayatheerthkulkarni2005@gmail.com,
valusoutrik@gmail.com, pushkarkumarsingh1970@gmail.com,
Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>
Subject: [PATCH 4/4] repo: add the field path.toplevel
Date: Sat, 28 Feb 2026 19:05:58 -0300 [thread overview]
Message-ID: <20260228224252.72788-5-lucasseikioshiro@gmail.com> (raw)
In-Reply-To: <20260228224252.72788-1-lucasseikioshiro@gmail.com>
The flag `--show-toplevel` from git-rev-parse is used for retrieving
the top level directory path of the repository. This way, it is used for
querying repository metadata, fitting in the purpose of git-repo-info.
Add a new field `path.toplevel` to the git-repo-info subcommand
containing that information.
Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>
---
builtin/repo.c | 47 +++++++++++++++++++++++++--------
t/t1900-repo-info.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 98 insertions(+), 11 deletions(-)
diff --git a/builtin/repo.c b/builtin/repo.c
index cff4c6db9b..61cd539e05 100644
--- a/builtin/repo.c
+++ b/builtin/repo.c
@@ -22,7 +22,8 @@ static const char *const repo_usage[] = {
NULL
};
-typedef int get_value_fn(struct repository *repo, struct strbuf *buf);
+typedef int get_value_fn(struct repository *repo, struct strbuf *buf,
+ const char *prefix, enum path_format_type format);
enum output_format {
FORMAT_TABLE,
@@ -35,26 +36,46 @@ struct repo_info_field {
get_value_fn *get_value;
};
-static int get_layout_bare(struct repository *repo UNUSED, struct strbuf *buf)
+static int get_layout_bare(struct repository *repo UNUSED, struct strbuf *buf,
+ const char *prefix UNUSED,
+ enum path_format_type format UNUSED)
{
strbuf_addstr(buf, is_bare_repository() ? "true" : "false");
return 0;
}
-static int get_layout_shallow(struct repository *repo, struct strbuf *buf)
+static int get_layout_shallow(struct repository *repo, struct strbuf *buf,
+ const char *prefix UNUSED,
+ enum path_format_type format UNUSED)
{
strbuf_addstr(buf,
is_repository_shallow(repo) ? "true" : "false");
return 0;
}
-static int get_object_format(struct repository *repo, struct strbuf *buf)
+static int get_object_format(struct repository *repo, struct strbuf *buf,
+ const char *prefix UNUSED,
+ enum path_format_type format UNUSED)
{
strbuf_addstr(buf, repo->hash_algo->name);
return 0;
}
-static int get_references_format(struct repository *repo, struct strbuf *buf)
+static int get_path_toplevel(struct repository *repo, struct strbuf *buf,
+ const char *prefix, enum path_format_type format)
+{
+ const char *work_tree = repo_get_work_tree(repo);
+ if (work_tree)
+ strbuf_add_path(buf, work_tree, prefix, format,
+ PATH_DEFAULT_UNMODIFIED);
+ else
+ return error(_("this operation must be run in a work tree"));
+ return 0;
+}
+
+static int get_references_format(struct repository *repo, struct strbuf *buf,
+ const char *prefix UNUSED,
+ enum path_format_type format UNUSED)
{
strbuf_addstr(buf,
ref_storage_format_to_name(repo->ref_storage_format));
@@ -66,6 +87,7 @@ static const struct repo_info_field repo_info_field[] = {
{ "layout.bare", get_layout_bare },
{ "layout.shallow", get_layout_shallow },
{ "object.format", get_object_format },
+ { "path.toplevel", get_path_toplevel },
{ "references.format", get_references_format },
};
@@ -108,8 +130,9 @@ static void print_field(enum output_format format, const char *key,
static int print_fields(int argc, const char **argv,
struct repository *repo,
+ const char *prefix,
enum output_format format,
- enum path_format_type path_format UNUSED)
+ enum path_format_type path_format)
{
int ret = 0;
struct strbuf valbuf = STRBUF_INIT;
@@ -124,7 +147,7 @@ static int print_fields(int argc, const char **argv,
}
strbuf_reset(&valbuf);
- field->get_value(repo, &valbuf);
+ field->get_value(repo, &valbuf, prefix, path_format);
print_field(format, key, valbuf.buf);
}
@@ -133,7 +156,9 @@ static int print_fields(int argc, const char **argv,
}
static int print_all_fields(struct repository *repo,
- enum output_format format)
+ const char *prefix,
+ enum output_format format,
+ enum path_format_type path_format)
{
struct strbuf valbuf = STRBUF_INIT;
@@ -141,7 +166,7 @@ static int print_all_fields(struct repository *repo,
const struct repo_info_field *field = &repo_info_field[i];
strbuf_reset(&valbuf);
- field->get_value(repo, &valbuf);
+ field->get_value(repo, &valbuf, prefix, path_format);
print_field(format, field->key, valbuf.buf);
}
@@ -239,9 +264,9 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,
die(_("--all and <key> cannot be used together"));
if (all_keys)
- return print_all_fields(repo, format);
+ return print_all_fields(repo, prefix, format, path_format);
else
- return print_fields(argc, argv, repo, format, path_format);
+ return print_fields(argc, argv, repo, prefix, format, path_format);
}
struct ref_stats {
diff --git a/t/t1900-repo-info.sh b/t/t1900-repo-info.sh
index f5c76067cb..4985a9cc70 100755
--- a/t/t1900-repo-info.sh
+++ b/t/t1900-repo-info.sh
@@ -38,6 +38,53 @@ test_repo_info () {
'
}
+test_repo_info_path () {
+ label=$1
+ repo_name=$2
+ key=$3
+ relative_path=$4
+ default=$5
+
+ absolute_path=$(cd "$relative_path"; pwd)/"$repo_name"
+
+ case $default in
+ absolute)
+ expected_value="$absolute_path"
+ ;;
+ relative)
+ expected_value="$relative_path"
+ ;;
+ esac
+
+ test_expect_success "setup: $label" '
+ git init "$repo_name"
+ '
+
+ test_expect_success "nul: $label" '
+ printf "%s\n%s\0" "$key" "$expected_value" >expected &&
+ git -C "$repo_name" repo info --format=nul "$key" >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success "default: $label" '
+ echo "$key=$expected_value" > expected &&
+ git -C "$repo_name" repo info "$key" >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success "absolute: $label" '
+ echo "$key=$absolute_path" > expected &&
+ git -C "$repo_name" repo info --path-format=absolute "$key" >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success "relative: $label" '
+ echo "$key=$relative_path" > expected &&
+ git -C "$repo_name" repo info --path-format=relative "$key" >actual &&
+ test_cmp expected actual
+ '
+}
+
test_repo_info 'ref format files is retrieved correctly' \
'git init --ref-format=files' 'format-files' 'references.format' 'files'
@@ -69,6 +116,21 @@ test_repo_info 'object.format = sha1 is retrieved correctly' \
test_repo_info 'object.format = sha256 is retrieved correctly' \
'git init --object-format=sha256' 'sha256' 'object.format' 'sha256'
+test_repo_info_path 'toplevel is retrieved correctly' \
+ 'toplevel' 'path.toplevel' './' 'absolute'
+
+test_expect_success 'git-repo-info fails if an invalid key is requested' '
+ echo "error: key ${SQ}foo${SQ} not found" >expected_err &&
+ test_must_fail git repo info foo 2>actual_err &&
+ test_cmp expected_err actual_err
+'
+
+test_expect_success 'git-repo-info outputs data even if there is an invalid field' '
+ echo "references.format=$(test_detect_ref_format)" >expected &&
+ test_must_fail git repo info foo references.format bar >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'values returned in order requested' '
cat >expect <<-\EOF &&
layout.bare=false
--
2.50.1 (Apple Git-155)
next prev parent reply other threads:[~2026-02-28 22:44 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-28 22:05 [PATCH 0/4] repo: add support for path-related fields Lucas Seiki Oshiro
2026-02-28 22:05 ` [PATCH 1/4] rev-parse: prepend `path_` to path-related enums Lucas Seiki Oshiro
2026-02-28 22:05 ` [PATCH 2/4] path: add new function strbuf_add_path Lucas Seiki Oshiro
2026-02-28 22:05 ` [PATCH 3/4] repo: add the --format-path flag Lucas Seiki Oshiro
2026-02-28 22:05 ` Lucas Seiki Oshiro [this message]
2026-03-01 4:24 ` [PATCH 4/4] repo: add the field path.toplevel Tian Yuchen
2026-03-01 20:21 ` Lucas Seiki Oshiro
2026-03-02 4:54 ` Tian Yuchen
2026-03-01 2:58 ` [PATCH 0/4] repo: add support for path-related fields JAYATHEERTH K
2026-03-01 5:45 ` Ayush Jha
2026-03-01 6:50 ` JAYATHEERTH K
2026-03-01 19:55 ` Lucas Seiki Oshiro
2026-03-03 3:27 ` Ayush Jha
2026-03-01 19:49 ` Lucas Seiki Oshiro
2026-03-01 10:44 ` Phillip Wood
2026-03-01 19:40 ` Lucas Seiki Oshiro
2026-03-01 21:25 ` brian m. carlson
2026-03-02 16:38 ` Junio C Hamano
2026-03-02 18:51 ` Tian Yuchen
2026-03-02 21:34 ` Junio C Hamano
2026-03-03 2:48 ` JAYATHEERTH K
2026-03-03 4:32 ` Tian Yuchen
2026-03-03 7:23 ` JAYATHEERTH K
2026-03-03 9:28 ` Tian Yuchen
2026-03-03 10:31 ` JAYATHEERTH K
2026-03-08 0:29 ` Lucas Seiki Oshiro
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260228224252.72788-5-lucasseikioshiro@gmail.com \
--to=lucasseikioshiro@gmail.com \
--cc=a3205153416@gmail.com \
--cc=git@vger.kernel.org \
--cc=jayatheerthkulkarni2005@gmail.com \
--cc=kumarayushjha123@gmail.com \
--cc=pushkarkumarsingh1970@gmail.com \
--cc=sandals@crustytoothpaste.net \
--cc=valusoutrik@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox