public inbox for git@vger.kernel.org
 help / color / mirror / Atom feed
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)


  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