Re: [PATCH v7 11/31] $GIT_COMMON_DIR: a new environment variable

From
Eric Sunshine <hidden>
Date
2016-06-15 23:02:00
Reply to
Nguyễn Thái Ngọc Duy, 2016-06-15
On Sun, Jul 13, 2014 at 12:50 AM, Nguyễn Thái Ngọc Duy
[off-list ref] wrote:
quoted hunk ↗ jump to hunk
This variable is intended to support multiple working directories
attached to a repository. Such a repository may have a main working
directory, created by either "git init" or "git clone" and one or more
linked working directories. These working directories and the main
repository share the same repository directory.

Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt
index 17d2ea6..7629e38 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -133,6 +138,11 @@ being a symref to point at the current branch.  Such a state
 is often called 'detached HEAD.'  See linkgit:git-checkout[1]
 for details.

+config::
+       Repository specific configuration file. This file is ignored
s/ignored/ignored if/
quoted hunk ↗ jump to hunk
+       $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/config" will be
+       used instead.
+
 branches::
        A slightly deprecated way to store shorthands to be used
        to specify a URL to 'git fetch', 'git pull' and 'git push'.
diff --git a/environment.c b/environment.c
index fee12a6..6b74f68 100644
--- a/environment.c
+++ b/environment.c
@@ -149,9 +149,18 @@ static void setup_git_env(void)
                git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
        gitfile = read_gitfile(git_dir);
        git_dir = xstrdup(gitfile ? gitfile : git_dir);
-       git_object_dir = git_path_from_env(DB_ENVIRONMENT, "objects", &git_db_env);
-       git_index_file = git_path_from_env(INDEX_ENVIRONMENT, "index", &git_index_env);
-       git_graft_file = git_path_from_env(GRAFT_ENVIRONMENT, "info/grafts", &git_graft_env);
+       git_common_dir = getenv(GIT_COMMON_DIR_ENVIRONMENT);
+       if (git_common_dir) {
+               git_common_dir_env = 1;
+               git_common_dir = xstrdup(git_common_dir);
+       } else
+               git_common_dir = git_dir;
+       git_object_dir = git_path_from_env(DB_ENVIRONMENT, git_common_dir,
+                                          "objects", &git_db_env);
+       git_index_file = git_path_from_env(INDEX_ENVIRONMENT, git_dir,
+                                          "index", &git_index_env);
+       git_graft_file = git_path_from_env(GRAFT_ENVIRONMENT, git_dir,
+                                          "info/grafts", &git_graft_env);
Replacement refs come from git_common_dir, but grafts come from
git_dir. Is the inconsistency intentional?
quoted hunk ↗ jump to hunk
        if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
                check_replace_refs = 0;
        namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT));
diff --git a/path.c b/path.c
index 3deb80c..8a6586c 100644
--- a/path.c
+++ b/path.c
@@ -90,6 +90,38 @@ static void replace_dir(struct strbuf *buf, int len, const char *newdir)
                buf->buf[newlen] = '/';
 }

+static const char *common_list[] = {
+       "/branches", "/hooks", "/info", "/logs", "/lost-found", "/modules",
+       "/objects", "/refs", "/remotes", "/rr-cache", "/svn",
+       "config", "gc.pid", "packed-refs", "shallow",
+       NULL
+};
+
+static void update_common_dir(struct strbuf *buf, int git_dir_len)
+{
+       char *base = buf->buf + git_dir_len;
+       const char **p;
+
+       if (is_dir_file(base, "logs", "HEAD"))
+               return; /* keep this in $GIT_DIR */
+       for (p = common_list; *p; p++) {
+               const char *path = *p;
+               int is_dir = 0;
+               if (*path == '/') {
+                       path++;
+                       is_dir = 1;
+               }
+               if (is_dir && dir_prefix(base, path)) {
+                       replace_dir(buf, git_dir_len, get_git_common_dir());
+                       return;
+               }
+               if (!is_dir && !strcmp(base, path)) {
+                       replace_dir(buf, git_dir_len, get_git_common_dir());
+                       return;
+               }
The bodies of these two conditionals are identical. Would it make
sense to combine them (or does a later patch take advantage of the
distinction)?

    if ((is_dir && dir_prefix(base, path)) ||
       (!is_dir && !strcmp(base, path))) {
        replace_dir(buf, git_dir_len, get_git_common_dir());
        return;
    }
quoted hunk ↗ jump to hunk
+       }
+}
+
 static void adjust_git_path(struct strbuf *buf, int git_dir_len)
 {
        const char *base = buf->buf + git_dir_len;
Thread (78 messages) 78 messages, 5 authors, last reply 2016-06-15
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help