{"thread":{"id":"6610","subject":"working directory with GIT_DIR","startedAt":"2007-02-01T17:47:15Z","lastAt":"2007-02-01T17:47:15Z","messageCount":1,"participants":["Matthias Lederhofer"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"33263","messageId":"20070201174715.GA29440@moooo.ath.cx","threadId":"6610","inReplyTo":null,"subject":"working directory with GIT_DIR","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-02-01T17:47:15Z","receivedAt":"2007-02-01T17:47:15Z","isPatch":false,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Today on IRC someone asked if it is possible to use GIT_DIR with a\nworking directory.  At the moment cwd is used as working directory (no\nsubdirectory support).  I've been thinking for a while about adding an\nenvironment variable to specify the working directory in addition to\nGIT_DIR to allow the .git directory to be somewhere else than the\nworking directory.\n\nI've hacked up a patch to do this using either an environment variable\nor take the directory from $GIT_DIR/topdir/ (supposed to be a\nsymlink).\n\nAny comments?  Is there any interest to add this feature to git?\n\nHere is the patch if anyone is interested, definetly needs some\ncleanup.  I'm just asking before I put any further effort into this.\n---\nallow to specify a working directory with GIT_DIR\n\nset the environment variable GIT_TOP_DIR to the working directory\nor $GIT_DIR/topdir/ is tried (e.g. a symlink)\n---\n cache.h       |    1 +\n environment.c |    4 ++++\n setup.c       |   54 ++++++++++++++++++++++++++++++++++++++++++++++++------\n 3 files changed, 53 insertions(+), 6 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 9873ee9..4975cf1 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -118,6 +118,7 @@ extern struct cache_tree *active_cache_tree;\n extern int cache_errno;\n \n #define GIT_DIR_ENVIRONMENT \"GIT_DIR\"\n+#define GIT_WORKING_DIR_ENVIRONMENT \"GIT_TOP_DIR\"\n #define DEFAULT_GIT_DIR_ENVIRONMENT \".git\"\n #define DB_ENVIRONMENT \"GIT_OBJECT_DIRECTORY\"\n #define INDEX_ENVIRONMENT \"GIT_INDEX_FILE\"\ndiff --git a/environment.c b/environment.c\nindex 54c22f8..d6974f8 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -59,7 +59,11 @@ int is_bare_repository(void)\n \tconst char *dir, *s;\n \tif (0 <= is_bare_repository_cfg)\n \t\treturn is_bare_repository_cfg;\n+\t/* FIXME */\n+\treturn 0;\n \n+\tif (getenv(GIT_WORKING_DIR_ENVIRONMENT))\n+\t\treturn 0;\n \tdir = get_git_dir();\n \tif (!strcmp(dir, DEFAULT_GIT_DIR_ENVIRONMENT))\n \t\treturn 0;\ndiff --git a/setup.c b/setup.c\nindex e9d3f5a..b20fb33 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -205,15 +205,57 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t */\n \tgitdirenv = getenv(GIT_DIR_ENVIRONMENT);\n \tif (gitdirenv) {\n+\t\tstruct stat st;\n+\t\tstruct stat stcwd;\n+\n \t\tif (PATH_MAX - 40 < strlen(gitdirenv))\n \t\t\tdie(\"'$%s' too big\", GIT_DIR_ENVIRONMENT);\n-\t\tif (is_git_directory(gitdirenv))\n-\t\t\treturn NULL;\n-\t\tif (nongit_ok) {\n-\t\t\t*nongit_ok = 1;\n-\t\t\treturn NULL;\n+\t\tif (!is_git_directory(gitdirenv)) {\n+\t\t\tif (nongit_ok) {\n+\t\t\t\t*nongit_ok = 1;\n+\t\t\t\treturn NULL;\n+\t\t\t}\n+\t\t\tdie(\"Not a git repository: '%s'\", gitdirenv);\n+\t\t}\n+\t\tif (getenv(GIT_WORKING_DIR_ENVIRONMENT)) {\n+\t\t\tif (stat(getenv(GIT_WORKING_DIR_ENVIRONMENT), &st))\n+\t\t\t\tdie(\"Unable to stat specified working \"\n+\t\t\t\t\t\"directory '%s'\",\n+\t\t\t\t\tgetenv(GIT_WORKING_DIR_ENVIRONMENT));\n+\t\t} else {\n+\t\t\tstrcpy(cwd, gitdirenv);\n+\t\t\tstrcat(cwd, \"/topdir/\");\n+\t\t\tif (stat(cwd, &st))\n+\t\t\t\treturn NULL;\n \t\t}\n-\t\tdie(\"Not a git repository: '%s'\", gitdirenv);\n+\t\tif (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')\n+\t\t\tdie(\"Unable to read current working directory\");\n+\n+\t\toffset = len = strlen(cwd);\n+\t\tfor (;;) {\n+\t\t\tif (offset)\n+\t\t\t\tcwd[offset] = '\\0';\n+\t\t\tif (stat(cwd, &stcwd))\n+\t\t\t\tdie(\"Unable to stat '%s'\", cwd);\n+\t\t\tcwd[offset] = '/';\n+\t\t\tif (st.st_dev == stcwd.st_dev && st.st_ino == stcwd.st_ino)\n+\t\t\t\tbreak;\n+\t\t\tchdir(\"..\");\n+\t\t\tdo {\n+\t\t\t\tif (!offset)\n+\t\t\t\t\tdie(\"Not below specified working directory\");\n+\t\t\t} while(cwd[--offset] != '/');\n+\t\t}\n+\n+\t\t/* FIXME */\n+\t\tinside_git_dir = 0;\n+\n+\t\tif (offset == len)\n+\t\t\treturn NULL;\n+\t\toffset++;\n+\t\tcwd[len++] = '/';\n+\t\tcwd[len] = '\\0';\n+\t\treturn cwd+offset;\n \t}\n \n \tif (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')\n-- \n1.5.0.rc3.1.gbc850-dirty\n"}]}