Thread (94 messages) 94 messages, 5 authors, 2d ago
DORMANTno replies

[GSoC Patch v7 8/8] repo: add path.cdup

From: K Jayatheerth <hidden>
Date: 2026-09-27 11:47:10
Subsystem: documentation, the rest · Maintainers: Jonathan Corbet, Linus Torvalds

Scripts sometimes need the relative path from the current working
directory to the repository's working tree root (cdup). While this
information can be retrieved through `git rev-parse --show-cdup`,
`git repo info` does not currently expose it as a scriptable key.

Introduce the `path.cdup` key to `git repo info`. The key returns the
path from the current working directory to the root of the working tree,
returning the empty string when invoked from the working tree root.

Mentored-by: Justin Tobler [off-list ref]
Mentored-by: Lucas Seiki Oshiro [off-list ref]
Signed-off-by: K Jayatheerth <redacted>
---
 Documentation/git-repo.adoc |  5 +++++
 builtin/repo.c              | 23 +++++++++++++++++++++
 t/t1900-repo-info.sh        | 40 +++++++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+)
diff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc
index fb5aceae8f..7e14aac244 100644
--- a/Documentation/git-repo.adoc
+++ b/Documentation/git-repo.adoc
@@ -104,6 +104,11 @@ values that they return:
 `object.format`::
 	The object format (hash algorithm) used in the repository.
 
+`path.cdup`::
+	When the command is invoked from a subdirectory, show the
+	path of the top-level directory relative to the current
+	directory (typically a sequence of "../", or an empty string).
+
 `path.commondir.absolute`::
 	The canonical absolute path to the Git repository's common
 	directory (the shared `.git` directory containing objects,
diff --git a/builtin/repo.c b/builtin/repo.c
index ce78cdc44e..d4083abedc 100644
--- a/builtin/repo.c
+++ b/builtin/repo.c
@@ -78,6 +78,28 @@ static int get_object_format(struct repository *repo, struct strbuf *buf)
 	return 0;
 }
 
+static int get_path_cdup(struct repository *repo, struct strbuf *buf)
+{
+	const char *pfx = repo->prefix;
+
+	if (!is_inside_work_tree(repo)) {
+		const char *worktree = repo_get_work_tree(repo);
+
+		if (worktree) {
+			strbuf_addstr(buf, worktree);
+		}
+	}
+
+	while (pfx) {
+		pfx = strchr(pfx, '/');
+		if (pfx) {
+			pfx++;
+			strbuf_addstr(buf, "../");
+		}
+	}
+	return 0;
+}
+
 static int get_path_commondir_absolute(struct repository *repo, struct strbuf *buf)
 {
 	const char *common_dir = repo_get_common_dir(repo);
@@ -252,6 +274,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.cdup", get_path_cdup },
 	{ "path.commondir.absolute", get_path_commondir_absolute },
 	{ "path.commondir.relative", get_path_commondir_relative },
 	{ "path.git-prefix", get_path_git_prefix },
diff --git a/t/t1900-repo-info.sh b/t/t1900-repo-info.sh
index b689445b7a..c600074c24 100755
--- a/t/t1900-repo-info.sh
+++ b/t/t1900-repo-info.sh
@@ -215,6 +215,46 @@ test_repo_info_path 'commondir with only GIT_DIR' 'commondir' \
 	'.git' \
 	'GIT_DIR="../.git" && export GIT_DIR'
 
+test_expect_success 'path.cdup at repository root' '
+	test_when_finished "rm -rf repo" &&
+	git init repo &&
+	(
+		cd repo &&
+		echo "path.cdup=" >expect &&
+		git repo info path.cdup >actual &&
+		test_cmp expect actual
+	)
+'
+
+test_expect_success 'path.cdup in subdirectory' '
+	test_when_finished "rm -rf repo" &&
+	git init repo &&
+	mkdir -p repo/sub/dir &&
+	(
+		cd repo/sub/dir &&
+		echo "path.cdup=../../" >expect &&
+		git repo info path.cdup >actual &&
+		test_cmp expect actual
+	)
+'
+
+test_expect_success 'path.cdup cwd outside the working tree' '
+	test_when_finished "rm -rf repo" &&
+	mkdir -p repo/tmp/x &&
+	cd repo &&
+	git init test &&
+	(
+		echo path.cdup=$(pwd)/tmp/x >./test/expect &&
+		cd test &&
+		GIT_WORK_TREE=../tmp/x &&
+		export GIT_WORK_TREE &&
+		GIT_DIR=$(pwd)/.git &&
+		export GIT_DIR &&
+		git repo info path.cdup >actual &&
+		test_cmp expect actual
+	)
+'
+
 test_expect_success 'path.git-prefix at repository root' '
 	test_when_finished "rm -rf repo" &&
 	git init repo &&
-- 
2.56.0-rc2
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help