Skip to content

Commit 4dc4e14

Browse files
pcloudsgitster
authored andcommitted
setup.c: detect $GIT_COMMON_DIR in is_git_directory()
If the file "$GIT_DIR/commondir" exists, it contains the value of $GIT_COMMON_DIR. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 1d186b6 commit 4dc4e14

2 files changed

Lines changed: 44 additions & 6 deletions

File tree

Documentation/gitrepository-layout.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,13 @@ shallow::
240240
file is ignored if $GIT_COMMON_DIR is set and
241241
"$GIT_COMMON_DIR/shallow" will be used instead.
242242

243+
commondir::
244+
If this file exists, $GIT_COMMON_DIR (see linkgit:git[1]) will
245+
be set to the path specified in this file if it is not
246+
explicitly set. If the specified path is relative, it is
247+
relative to $GIT_DIR. The repository with commondir is
248+
incomplete without the repository pointed by "commondir".
249+
243250
modules::
244251
Contains the git-repositories of the submodules. This
245252
directory is ignored if $GIT_COMMON_DIR is set and

setup.c

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,33 @@ void verify_non_filename(const char *prefix, const char *arg)
224224
"'git <command> [<revision>...] -- [<file>...]'", arg);
225225
}
226226

227+
static void get_common_dir(struct strbuf *sb, const char *gitdir)
228+
{
229+
struct strbuf data = STRBUF_INIT;
230+
struct strbuf path = STRBUF_INIT;
231+
const char *git_common_dir = getenv(GIT_COMMON_DIR_ENVIRONMENT);
232+
if (git_common_dir) {
233+
strbuf_addstr(sb, git_common_dir);
234+
return;
235+
}
236+
strbuf_addf(&path, "%s/commondir", gitdir);
237+
if (file_exists(path.buf)) {
238+
if (strbuf_read_file(&data, path.buf, 0) <= 0)
239+
die_errno(_("failed to read %s"), path.buf);
240+
while (data.len && (data.buf[data.len - 1] == '\n' ||
241+
data.buf[data.len - 1] == '\r'))
242+
data.len--;
243+
data.buf[data.len] = '\0';
244+
strbuf_reset(&path);
245+
if (!is_absolute_path(data.buf))
246+
strbuf_addf(&path, "%s/", gitdir);
247+
strbuf_addbuf(&path, &data);
248+
strbuf_addstr(sb, real_path(path.buf));
249+
} else
250+
strbuf_addstr(sb, gitdir);
251+
strbuf_release(&data);
252+
strbuf_release(&path);
253+
}
227254

228255
/*
229256
* Test if it looks like we're at a git directory.
@@ -242,13 +269,22 @@ int is_git_directory(const char *suspect)
242269
int ret = 0;
243270
size_t len;
244271

245-
strbuf_addstr(&path, suspect);
272+
/* Check worktree-related signatures */
273+
strbuf_addf(&path, "%s/HEAD", suspect);
274+
if (validate_headref(path.buf))
275+
goto done;
276+
277+
strbuf_reset(&path);
278+
get_common_dir(&path, suspect);
246279
len = path.len;
280+
281+
/* Check non-worktree-related signatures */
247282
if (getenv(DB_ENVIRONMENT)) {
248283
if (access(getenv(DB_ENVIRONMENT), X_OK))
249284
goto done;
250285
}
251286
else {
287+
strbuf_setlen(&path, len);
252288
strbuf_addstr(&path, "/objects");
253289
if (access(path.buf, X_OK))
254290
goto done;
@@ -259,11 +295,6 @@ int is_git_directory(const char *suspect)
259295
if (access(path.buf, X_OK))
260296
goto done;
261297

262-
strbuf_setlen(&path, len);
263-
strbuf_addstr(&path, "/HEAD");
264-
if (validate_headref(path.buf))
265-
goto done;
266-
267298
ret = 1;
268299
done:
269300
strbuf_release(&path);

0 commit comments

Comments
 (0)