Re: [PATCH v3 1/7] repo: add path.toplevel with absolute and relative suffix formatting
Justin Tobler <[email protected]> Tue, 28 Jul 2026 11:36:04 -0500
| Newsgroups | org.kernel.vger.git |
|---|---|
| Message-ID | <amjUPEgenletgbp5@denethor> |
On 26/07/26 04:13PM, K Jayatheerth wrote: > Scripts frequently need to find the root directory of a repository's > working tree. Currently, this requires using `git rev-parse --show-toplevel` > or inferring it from other path components. > > Introduce `path.toplevel.absolute` and `path.toplevel.relative` keys > to `git repo info`. This allows scripts to retrieve the top-level > working tree path in a predictable, strictly formatted manner without > relying on `rev-parse`. Ok, this seems like suitable information to also look up under git-repo-info. > If requested in a bare repository where no working tree exists, the > command returns an empty string. This matches the existing behavior in git-rev-parse(1). Makes sense. > Mentored-by: Justin Tobler <[email protected]> > Mentored-by: Lucas Seiki Oshiro <[email protected]> > Signed-off-by: K Jayatheerth <[email protected]> > --- > Documentation/git-repo.adoc | 10 ++++++++++ > builtin/repo.c | 28 ++++++++++++++++++++++++++++ > t/t1900-repo-info.sh | 30 ++++++++++++++++++++++++++++++ > 3 files changed, 68 insertions(+) > > diff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc > index ed7d80c690..e34abe5fea 100644 > --- a/Documentation/git-repo.adoc > +++ b/Documentation/git-repo.adoc > @@ -119,6 +119,16 @@ values that they return: > `path.gitdir.relative`:: > The path to the Git repository directory relative to the current working directory. > > +`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: > + > diff --git a/builtin/repo.c b/builtin/repo.c > index 042d6de558..194757eb18 100644 > --- a/builtin/repo.c > +++ b/builtin/repo.c > @@ -121,6 +121,32 @@ static int get_path_gitdir_relative(struct repository *repo, struct strbuf *buf) > 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) { > + strbuf_addstr(buf, ""); The strbuf here is already NULL-terminated when its initialized. I don't think this should be necessary. > + return 0; > + } > + > + format_path(buf, work_tree, startup_info->prefix, 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) { > + strbuf_addstr(buf, ""); Same here. > + return 0; > + } > + > + format_path(buf, work_tree, startup_info->prefix, PATH_FORMAT_RELATIVE); > + return 0; > +} > + > static int get_references_format(struct repository *repo, struct strbuf *buf) > { > strbuf_addstr(buf, > @@ -137,6 +163,8 @@ static const struct repo_info_field repo_info_field[] = { > { "path.commondir.relative", get_path_commondir_relative }, > { "path.gitdir.absolute", get_path_gitdir_absolute }, > { "path.gitdir.relative", get_path_gitdir_relative }, > + { "path.toplevel.absolute", get_path_toplevel_absolute }, > + { "path.toplevel.relative", get_path_toplevel_relative }, > { "references.format", get_references_format }, > }; > > diff --git a/t/t1900-repo-info.sh b/t/t1900-repo-info.sh > index ae8c22c817..fbb9063ee5 100755 > --- a/t/t1900-repo-info.sh > +++ b/t/t1900-repo-info.sh > @@ -213,4 +213,34 @@ test_repo_info_path 'gitdir with explicit GIT_DIR' 'gitdir' \ > '.git' \ > 'GIT_DIR="../.git" && export GIT_DIR' > > +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 returns empty in a bare repository' ' > + test_when_finished "rm -rf bare.git" && > + git init --bare bare.git && > + ( > + cd bare.git && > + echo "path.toplevel.absolute=" >expect && > + git repo info path.toplevel.absolute >actual && > + test_cmp expect actual In this test we are only checking the absolute path. It probably wouldn't hurt to also check the relative path too. -Justin