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>

Nguyễn Thái Ngọc Duy committed Nov 30, 2014 at 15:24 UTC 4dc4e1457e17788e8f258a3f18c78bd58ef543af
2 files changed +44 -6
Documentation/gitrepository-layout.txt
+7
@@ -240,6 +240,13 @@ shallow::
240 file is ignored if $GIT_COMMON_DIR is set and
241 "$GIT_COMMON_DIR/shallow" will be used instead.
242
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 +
250 modules::
251 Contains the git-repositories of the submodules. This
252 directory is ignored if $GIT_COMMON_DIR is set and
setup.c
+37 -6
@@ -224,6 +224,33 @@ void verify_non_filename(const char *prefix, const char *arg)
224 "'git <command> [<revision>...] -- [<file>...]'", arg);
225 }
226
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 +}
254
255 /*
256 * Test if it looks like we're at a git directory.
@@ -242,13 +269,22 @@ int is_git_directory(const char *suspect)
269 int ret = 0;
270 size_t len;
271
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);
279 len = path.len;
280 +
281 + /* Check non-worktree-related signatures */
282 if (getenv(DB_ENVIRONMENT)) {
283 if (access(getenv(DB_ENVIRONMENT), X_OK))
284 goto done;
285 }
286 else {
287 + strbuf_setlen(&path, len);
288 strbuf_addstr(&path, "/objects");
289 if (access(path.buf, X_OK))
290 goto done;
@@ -259,11 +295,6 @@ int is_git_directory(const char *suspect)
295 if (access(path.buf, X_OK))
296 goto done;
297
262 - strbuf_setlen(&path, len);
263 - strbuf_addstr(&path, "/HEAD");
264 - if (validate_headref(path.buf))
265 - goto done;
266 -
298 ret = 1;
299 done:
300 strbuf_release(&path);