Skip to content

Commit b9cf3f6

Browse files
jayatheerthkulkarnigitster
authored andcommitted
repo: add path.commondir with absolute and relative suffix formatting
Scripts working with worktree setups need a reliable way to discover the common directory, which diverges from the git directory when multiple worktrees are in use. There is no way to retrieve this path from git repo info today. Introduce path.commondir.absolute and path.commondir.relative keys. Exposing explicit format variants rather than a single key with a default avoids ambiguity for scripts that require predictable output. Add a test helper test_repo_info_path that creates isolated repositories per test case to prevent state leaks, captures the repo root before changing directories to avoid eval, and accepts an optional init_command to cover environment variable overrides such as GIT_COMMON_DIR and GIT_DIR. Mentored-by: Justin Tobler <jltobler@gmail.com> Mentored-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com> Signed-off-by: K Jayatheerth <jayatheerthkulkarni2005@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent fe19dc3 commit b9cf3f6

3 files changed

Lines changed: 96 additions & 0 deletions

File tree

Documentation/git-repo.adoc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ values that they return:
104104
`object.format`::
105105
The object format (hash algorithm) used in the repository.
106106

107+
`path.commondir.absolute`::
108+
The canonical absolute path to the Git repository's common
109+
directory (the shared `.git` directory containing objects,
110+
refs, and global configuration).
111+
112+
`path.commondir.relative`::
113+
The path to the Git repository's common directory relative to
114+
the current working directory.
115+
107116
`references.format`::
108117
The reference storage format. The valid values are:
109118
+

builtin/repo.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
#include "hex.h"
88
#include "odb.h"
99
#include "parse-options.h"
10+
#include "path.h"
1011
#include "path-walk.h"
1112
#include "progress.h"
1213
#include "quote.h"
1314
#include "ref-filter.h"
1415
#include "refs.h"
1516
#include "revision.h"
17+
#include "setup.h"
1618
#include "strbuf.h"
1719
#include "string-list.h"
1820
#include "shallow.h"
@@ -75,6 +77,28 @@ static int get_object_format(struct repository *repo, struct strbuf *buf)
7577
return 0;
7678
}
7779

80+
static int get_path_commondir_absolute(struct repository *repo, struct strbuf *buf)
81+
{
82+
const char *common_dir = repo_get_common_dir(repo);
83+
84+
if (!common_dir)
85+
return error(_("unable to get common directory"));
86+
87+
append_formatted_path(buf, common_dir, startup_info->prefix, PATH_FORMAT_CANONICAL);
88+
return 0;
89+
}
90+
91+
static int get_path_commondir_relative(struct repository *repo, struct strbuf *buf)
92+
{
93+
const char *common_dir = repo_get_common_dir(repo);
94+
95+
if (!common_dir)
96+
return error(_("unable to get common directory"));
97+
98+
append_formatted_path(buf, common_dir, startup_info->prefix, PATH_FORMAT_RELATIVE);
99+
return 0;
100+
}
101+
78102
static int get_references_format(struct repository *repo, struct strbuf *buf)
79103
{
80104
strbuf_addstr(buf,
@@ -87,6 +111,8 @@ static const struct repo_info_field repo_info_field[] = {
87111
{ "layout.bare", get_layout_bare },
88112
{ "layout.shallow", get_layout_shallow },
89113
{ "object.format", get_object_format },
114+
{ "path.commondir.absolute", get_path_commondir_absolute },
115+
{ "path.commondir.relative", get_path_commondir_relative },
90116
{ "references.format", get_references_format },
91117
};
92118

t/t1900-repo-info.sh

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,65 @@ test_expect_success 'git repo info -h shows only repo info usage' '
155155
test_grep ! "git repo structure" actual
156156
'
157157

158+
# Helper function to test path keys in both absolute and relative formats.
159+
# $1: label for the test
160+
# $2: field_name (e.g., commondir)
161+
# $3: unique repo name for isolation
162+
# $4: expect_absolute (suffix appended to repo root)
163+
# $5: expect_relative (the relative path string expected)
164+
# $6: init_command (extra setup like exporting env vars)
165+
test_repo_info_path () {
166+
label=$1
167+
field_name=$2
168+
repo_name=$3
169+
expect_absolute_suffix=$4
170+
expect_relative=$5
171+
init_command=$6
172+
173+
absolute_root="$repo_name-absolute"
174+
relative_root="$repo_name-relative"
175+
176+
test_expect_success "setup: $label" '
177+
git init "$absolute_root" &&
178+
git init "$relative_root" &&
179+
mkdir -p "$absolute_root/sub" "$relative_root/sub"
180+
'
181+
182+
test_expect_success "absolute: $label" '
183+
(
184+
cd "$absolute_root/sub" &&
185+
ROOT="$(test-tool path-utils real_path "..")" && export ROOT &&
186+
eval "$init_command" &&
187+
expect_path="$ROOT${expect_absolute_suffix:+/$expect_absolute_suffix}" &&
188+
echo "path.$field_name.absolute=$expect_path" >expect &&
189+
git repo info "path.$field_name.absolute" >actual &&
190+
test_cmp expect actual
191+
)
192+
'
193+
194+
test_expect_success "relative: $label" '
195+
(
196+
cd "$relative_root/sub" &&
197+
ROOT="$(test-tool path-utils real_path "..")" && export ROOT &&
198+
eval "$init_command" &&
199+
echo "path.$field_name.relative=$expect_relative" >expect &&
200+
git repo info "path.$field_name.relative" >actual &&
201+
test_cmp expect actual
202+
)
203+
'
204+
}
205+
206+
test_repo_info_path 'commondir standard' 'commondir' 'commondir-std' \
207+
'.git' '../.git'
208+
209+
test_repo_info_path 'commondir with GIT_COMMON_DIR and GIT_DIR' 'commondir' \
210+
'commondir-envs' 'custom-common' '../custom-common' \
211+
'GIT_COMMON_DIR="$ROOT/custom-common" && export GIT_COMMON_DIR &&
212+
GIT_DIR="../.git" && export GIT_DIR &&
213+
git init --bare "$ROOT/custom-common"'
214+
215+
test_repo_info_path 'commondir with only GIT_DIR' 'commondir' \
216+
'commondir-only-gitdir' '.git' '../.git' \
217+
'GIT_DIR="../.git" && export GIT_DIR'
218+
158219
test_done

0 commit comments

Comments
 (0)