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 <pclo...@gmail.com>
---
 Documentation/gitrepository-layout.txt |  4 ++++
 setup.c                                | 38 ++++++++++++++++++++++++++++------
 strbuf.c                               |  8 +++++++
 strbuf.h                               |  1 +
 4 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/Documentation/gitrepository-layout.txt 
b/Documentation/gitrepository-layout.txt
index aa03882..9bfe0f1 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -211,6 +211,10 @@ shallow::
        and maintained by shallow clone mechanism.  See `--depth`
        option to linkgit:git-clone[1] and linkgit:git-fetch[1].
 
+commondir::
+       If this file exists, $GIT_COMMON_DIR will be set to the path
+       specified in this file if it is not set.
+
 modules::
        Contains the git-repositories of the submodules.
 
diff --git a/setup.c b/setup.c
index 999225b..4e5711c 100644
--- a/setup.c
+++ b/setup.c
@@ -170,6 +170,30 @@ void verify_non_filename(const char *prefix, const char 
*arg)
            "'git <command> [<revision>...] -- [<file>...]'", arg);
 }
 
+static void get_common_dir(struct strbuf *sb, const char *gitdir)
+{
+       struct strbuf data = STRBUF_INIT;
+       struct strbuf path = STRBUF_INIT;
+       const char *git_common_dir = getenv(GIT_COMMON_DIR_ENVIRONMENT);
+       if (git_common_dir) {
+               strbuf_addstr(sb, git_common_dir);
+               return;
+       }
+       strbuf_addf(&path, "%s/commondir", gitdir);
+       if (file_exists(path.buf)) {
+               if (strbuf_read_file(&data, path.buf, 0) <= 0)
+                       die_errno(_("failed to read %s"), path.buf);
+               strbuf_chomp(&data);
+               strbuf_reset(&path);
+               if (!is_absolute_path(data.buf))
+                       strbuf_addf(&path, "%s/", gitdir);
+               strbuf_addbuf(&path, &data);
+               strbuf_addstr(sb, real_path(path.buf));
+       } else
+               strbuf_addstr(sb, gitdir);
+       strbuf_release(&data);
+       strbuf_release(&path);
+}
 
 /*
  * Test if it looks like we're at a git directory.
@@ -188,14 +212,20 @@ int is_git_directory(const char *suspect)
        int ret = 0;
        size_t len;
 
-       strbuf_addstr(&path, suspect);
+       strbuf_addf(&path, "%s/HEAD", suspect);
+       if (validate_headref(path.buf))
+               goto done;
+
+       strbuf_reset(&path);
+       get_common_dir(&path, suspect);
        len = path.len;
+
        if (getenv(DB_ENVIRONMENT)) {
                if (access(getenv(DB_ENVIRONMENT), X_OK))
                        goto done;
        }
        else {
-               strbuf_addstr(&path, "/objects");
+               strbuf_addstr_at(&path, len, "/objects");
                if (access(path.buf, X_OK))
                        goto done;
        }
@@ -204,10 +234,6 @@ int is_git_directory(const char *suspect)
        if (access(path.buf, X_OK))
                goto done;
 
-       strbuf_addstr_at(&path, len, "/HEAD");
-       if (validate_headref(path.buf))
-               goto done;
-
        ret = 1;
 done:
        strbuf_release(&path);
diff --git a/strbuf.c b/strbuf.c
index 83caf4a..e17c358 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -588,3 +588,11 @@ int fprintf_ln(FILE *fp, const char *fmt, ...)
                return -1;
        return ret + 1;
 }
+
+void strbuf_chomp(struct strbuf *sb)
+{
+       while (sb->len && (sb->buf[sb->len - 1] == '\n' ||
+                          sb->buf[sb->len - 1] == '\r'))
+               sb->len--;
+       sb->buf[sb->len] = '\0';
+}
diff --git a/strbuf.h b/strbuf.h
index aec9fdb..cd9578f 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -109,6 +109,7 @@ extern void strbuf_remove(struct strbuf *, size_t pos, 
size_t len);
 /* splice pos..pos+len with given data */
 extern void strbuf_splice(struct strbuf *, size_t pos, size_t len,
                           const void *, size_t);
+extern void strbuf_chomp(struct strbuf *sb);
 
 extern void strbuf_add_commented_lines(struct strbuf *out, const char *buf, 
size_t size);
 
-- 
1.8.5.2.240.g8478abd

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to