{"thread":{"id":"7191","subject":"[RFC] introduce GIT_WORK_DIR environment variable","startedAt":"2007-03-11T04:32:50Z","lastAt":"2007-04-01T07:42:50Z","messageCount":39,"participants":["Matthias Lederhofer","Junio C Hamano","Andy Parkins","Nguyen Thai Ngoc Duy","Linus Torvalds","Johannes Schindelin","A.J. Rossini","Joshua N Pritikin","Shawn O. Pearce"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"36781","messageId":"20070311043250.GA21331@moooo.ath.cx","threadId":"7191","inReplyTo":null,"subject":"[RFC] introduce GIT_WORK_DIR environment variable","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-11T04:32:50Z","receivedAt":"2007-03-11T04:32:50Z","isPatch":false,"sender":{"key":"matled@gmx.net","avatar":null},"body":"This environment variable can be used with GIT_DIR to\nspecify the toplevel working directory.  When GIT_DIR is not\nset this variable is ignored.  As for GIT_DIR there is also\nthe option git --work-dir which overrides the environment\nvariable.\n---\nMissing:\nDocumentation update but if this feature should not get accepted..\ntherefore I'll wait for feedback first.\n\nIdea:\nAdd some way to configure tho working directory for one repository\nand set GIT_WORK_DIR automatically when GIT_DIR is used.  I think of:\n * a subdirectory in the repository directory\n   e.g. .git/work_dir which is supposed to be a symlink (or a textfile\n   containing the path for windows compatibility?)\nor\n * a configuration variable\n\nConsiderations:\nWithout running setup_git_directory_gently is_bare_repository and\nis_inside_git_dir may return wrong values.  Except for cmd_init_db I\nfound no place calling on of the functions without calling\nsetup_git_directory_gently before.\n\nTo do:\ngit init should probably set bare = false when GIT_WORK_DIR is\nexported.  And if the idea about configurable working directories gets\nimplemented it could also set this option accordingly.\n\n---\n cache.h       |    2 +\n environment.c |    2 +\n git.c         |   12 +++++++++-\n setup.c       |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++++----\n 4 files changed, 80 insertions(+), 6 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex ae25759..042734c 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -144,6 +144,7 @@ enum object_type {\n };\n \n #define GIT_DIR_ENVIRONMENT \"GIT_DIR\"\n+#define GIT_WORKING_DIR_ENVIRONMENT \"GIT_WORK_DIR\"\n #define DEFAULT_GIT_DIR_ENVIRONMENT \".git\"\n #define DB_ENVIRONMENT \"GIT_OBJECT_DIRECTORY\"\n #define INDEX_ENVIRONMENT \"GIT_INDEX_FILE\"\n@@ -164,6 +165,7 @@ extern char *get_graft_file(void);\n \n #define ALTERNATE_DB_ENVIRONMENT \"GIT_ALTERNATE_OBJECT_DIRECTORIES\"\n \n+extern int has_working_directory;\n extern const char **get_pathspec(const char *prefix, const char **pathspec);\n extern const char *setup_git_directory_gently(int *);\n extern const char *setup_git_directory(void);\ndiff --git a/environment.c b/environment.c\nindex 0151ad0..5c30c9b 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -61,6 +61,8 @@ 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+\tif (0 <= has_working_directory)\n+\t\treturn !has_working_directory;\n \n \tdir = get_git_dir();\n \tif (!strcmp(dir, DEFAULT_GIT_DIR_ENVIRONMENT))\ndiff --git a/git.c b/git.c\nindex 04fc99a..3cf7ce2 100644\n--- a/git.c\n+++ b/git.c\n@@ -4,7 +4,7 @@\n #include \"quote.h\"\n \n const char git_usage_string[] =\n-\t\"git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]\";\n+\t\"git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--work-dir=GIT_WORK_DIR] [--help] COMMAND [ARGS]\";\n \n static void prepend_to_path(const char *dir, int len)\n {\n@@ -68,6 +68,16 @@ static int handle_options(const char*** argv, int* argc)\n \t\t\t(*argc)--;\n \t\t} else if (!prefixcmp(cmd, \"--git-dir=\")) {\n \t\t\tsetenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);\n+\t\t} else if (!strcmp(cmd, \"--work-dir\")) {\n+\t\t\tif (*argc < 2) {\n+\t\t\t\tfprintf(stderr, \"No directory given for --work-dir.\\n\" );\n+\t\t\t\tusage(git_usage_string);\n+\t\t\t}\n+\t\t\tsetenv(GIT_WORKING_DIR_ENVIRONMENT, (*argv)[1], 1);\n+\t\t\t(*argv)++;\n+\t\t\t(*argc)--;\n+\t\t} else if (!prefixcmp(cmd, \"--work-dir=\")) {\n+\t\t\tsetenv(GIT_WORKING_DIR_ENVIRONMENT, cmd + 11, 1);\n \t\t} else if (!strcmp(cmd, \"--bare\")) {\n \t\t\tstatic char git_dir[PATH_MAX+1];\n \t\t\tsetenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 1);\ndiff --git a/setup.c b/setup.c\nindex dda67d2..7f5d73b 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -192,6 +192,8 @@ int is_inside_git_dir(void)\n \treturn inside_git_dir;\n }\n \n+int has_working_directory = -1;\n+\n const char *setup_git_directory_gently(int *nongit_ok)\n {\n \tstatic char cwd[PATH_MAX+1];\n@@ -205,15 +207,73 @@ 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, st_work, st_git;\n+\t\tconst char *gitwd;\n+\t\tchar *prefix;\n+\t\tchar c;\n+\t\tint len;\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\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+\n+\t\tgitwd = getenv(GIT_WORKING_DIR_ENVIRONMENT);\n+\t\tif (!gitwd || stat(gitwd, &st_work))\n \t\t\treturn NULL;\n+\t\tif (inside_git_dir == -1 && stat(gitdirenv, &st_git))\n+\t\t\tdie(\"Unable to stat git directory\");\n+\t\tif (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')\n+\t\t\tdie(\"Unable to read current working directory\");\n+\t\tlen = strlen(cwd);\n+\n+\t\tprefix = cwd+len;\n+\t\tfor (;;) {\n+\t\t\tc = *prefix;\n+\t\t\t*prefix = '\\0';\n+\t\t\tif (stat(cwd, &st))\n+\t\t\t\tdie(\"Unable to stat '%s'\", cwd);\n+\t\t\tif (st_work.st_dev == st.st_dev &&\n+\t\t\t    st_work.st_ino == st.st_ino)\n+\t\t\t\tbreak;\n+\t\t\tif (inside_git_dir == -1 &&\n+\t\t\t    st_git.st_dev == st.st_dev &&\n+\t\t\t    st_git.st_ino == st.st_ino)\n+\t\t\t\tinside_git_dir = 1;\n+\t\t\t*prefix = c;\n+\n+\t\t\tif (prefix == cwd+1) {\n+\t\t\t\thas_working_directory = 0;\n+\t\t\t\treturn NULL;\n+\t\t\t}\n+\t\t\twhile (*(--prefix) != '/')\n+\t\t\t\t; /* do nothing */\n+\t\t\tif (prefix == cwd)\n+\t\t\t\tprefix++;\n+\t\t}\n+\n+\t\tif (chdir(cwd))\n+\t\t\tdie(\"Cannot change directory to '%s'\", cwd);\n+\n+\t\tif (c) {\n+\t\t\t*prefix = c;\n+\t\t\tprefix++;\n+\t\t\tcwd[len] = '/';\n+\t\t\tcwd[len+1] = '\\0';\n+\t\t} else {\n+\t\t\tprefix = NULL;\n \t\t}\n-\t\tdie(\"Not a git repository: '%s'\", gitdirenv);\n+\n+\t\thas_working_directory = 1;\n+\t\tif (inside_git_dir == -1)\n+\t\t\tinside_git_dir = 0;\n+\n+\t\treturn prefix;\n \t}\n \n \tif (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')\n-- \n1.5.0.3\n"},{"id":"36791","messageId":"7vabykxs15.fsf@assigned-by-dhcp.cox.net","threadId":"7191","inReplyTo":"20070311043250.GA21331@moooo.ath.cx","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-11T05:34:14Z","receivedAt":"2007-03-11T05:34:14Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthias Lederhofer <matled@gmx.net> writes:\n\n> Missing:\n> Documentation update but if this feature should not get accepted..\n> therefore I'll wait for feedback first.\n\nDid I say something about a comment like this in the past?  But\nI'll let this pass this time...\n\n> Idea:\n> Add some way to configure tho working directory for one repository\n> and set GIT_WORK_DIR automatically when GIT_DIR is used.  I think of:\n>  * a subdirectory in the repository directory\n>    e.g. .git/work_dir which is supposed to be a symlink (or a textfile\n>    containing the path for windows compatibility?)\n> or\n>  * a configuration variable\n\nI am not sure why you bother.  Obviously I am missing a few\nuseful use cases you and Nguyen have in mind.\n\nOne very typical use of GIT_DIR to have the repository somewhere\nother than the usual $GIT_TOP_DIR/.git is to do an initial\nimport from an extracted tarball into a bare repository (and\nthen wipe away the temporary directory that contains extracted\ntarball), and that use case I understand well.\n\nBut either .git/work_dir or a configuration means you are\nlinking a repository with a _single_ working tree, permanently.\nIf you are permanently linking one repository with a _single_\nworking tree, is it too much bother to have that repository at\nthe usual $GIT_TOP_DIR/.git like everybody else?\n\nIf storage space is the issue, then doing\n\n\t$ln -s $else_where/.git .git\n\nwould be sufficient.\n\nWhat's the real motivation behind all this?  \n\nI've heard read-only working tree in the past, but that cannot\nbe it.  If the working tree is read-only and if you are telling\ngit to always use that read-only working tree when using that\nparticular repository, what useful git operations are you doing\nwhile in that working tree?\n"},{"id":"36794","messageId":"200703110826.39283.andyparkins@gmail.com","threadId":"7191","inReplyTo":"7vabykxs15.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Andy Parkins","fromEmail":"andyparkins@gmail.com","sentAt":"2007-03-11T08:26:30Z","receivedAt":"2007-03-11T08:26:30Z","isPatch":false,"sender":{"key":"andyparkins@gmail.com","avatar":null},"body":"On Sunday 2007, March 11, Junio C Hamano wrote:\n\n> What's the real motivation behind all this?\n\nCoincidentally, I found I was needing this feature just yesterday.\n\nI wanted to keep random configuration files in a repository.  I didn't \nwant the directory structure though.  The config files are, of course, \nin my home directory, however I didn't want the danger of putting \na .git that low in my hierarchy.  Having a .git that is findable from \nany location in my tree seems a bad idea.\n\nSo; I put the repository somewhere else and set GIT_DIR.  However that \nscuppered my plans.  Trying to add a config file results in \"not in a \nworking directory\" (of course), because even though git can find the \nrepository, it has no way of knowing which directory to consider as the \nroot of the working tree.\n\nLet me put this in command form for you:\n\n $ cd $HOME\n $ export GIT_DIR=$HOME/gitrepos\n $ git init\n $ git add .bashrc\n fatal: add must be run in a work tree\n\nBeing able to set GIT_WORKING_DIR would have let me do this.\n\n\n\nAndy\n-- \nDr Andy Parkins, M Eng (hons), MIET\nandyparkins@gmail.com\n"},{"id":"36799","messageId":"fcaeb9bf0703110542t49bb3e77kb164ba7bfee1a6ed@mail.gmail.com","threadId":"7191","inReplyTo":"20070311043250.GA21331@moooo.ath.cx","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2007-03-11T12:42:02Z","receivedAt":"2007-03-11T12:42:02Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On 3/11/07, Matthias Lederhofer <matled@gmx.net> wrote:\n> +               gitwd = getenv(GIT_WORKING_DIR_ENVIRONMENT);\n> +               if (!gitwd || stat(gitwd, &st_work))\n>                         return NULL;\n\nI propose the following instead of the last two lines:\n\n                if (!gitwd)\n                        return NULL;\n                if (stat(gitwd, &st_work))\n                        die(\"Unable to stat git working directory %s\",gitwd);\n\n> +               if (inside_git_dir == -1 && stat(gitdirenv, &st_git))\n> +                       die(\"Unable to stat git directory\");\n> +               if (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')\n> +                       die(\"Unable to read current working directory\");\n> +               len = strlen(cwd);\n> +\n> +               prefix = cwd+len;\n> +               for (;;) {\n> +                       c = *prefix;\n> +                       *prefix = '\\0';\n> +                       if (stat(cwd, &st))\n> +                               die(\"Unable to stat '%s'\", cwd);\n> +                       if (st_work.st_dev == st.st_dev &&\n> +                           st_work.st_ino == st.st_ino)\n> +                               break;\n> +                       if (inside_git_dir == -1 &&\n> +                           st_git.st_dev == st.st_dev &&\n> +                           st_git.st_ino == st.st_ino)\n> +                               inside_git_dir = 1;\n> +                       *prefix = c;\n> +\n> +                       if (prefix == cwd+1) {\n> +                               has_working_directory = 0;\n> +                               return NULL;\n\nMy case seems a bit complicated than usual. The working directory\n(/home/pclouds/blog/data) was not a prefix of cwd (/home/pclouds/blog)\nso the code failed silently at this line. If I replace\n\"has_working_directory = 0; return NULL;\" with \"strcpy(cwd,gitwd);c =\n0;break;\", it may work but see below\n\n> +                       }\n> +                       while (*(--prefix) != '/')\n> +                               ; /* do nothing */\n> +                       if (prefix == cwd)\n> +                               prefix++;\n> +               }\n> +\n> +               if (chdir(cwd))\n> +                       die(\"Cannot change directory to '%s'\", cwd);\n> +\n\nIf cwd changed and GIT_DIR is a relative path, git can no longer\naccess GIT_DIR properly.\n-- \nDuy\n"},{"id":"36801","messageId":"fcaeb9bf0703110627r6500d621rf6710c58e9e8d65b@mail.gmail.com","threadId":"7191","inReplyTo":"20070311043250.GA21331@moooo.ath.cx","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2007-03-11T13:27:02Z","receivedAt":"2007-03-11T13:27:02Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On 3/11/07, Matthias Lederhofer <matled@gmx.net> wrote:\n> diff --git a/environment.c b/environment.c\n> index 0151ad0..5c30c9b 100644\n> --- a/environment.c\n> +++ b/environment.c\n> @@ -61,6 +61,8 @@ int is_bare_repository(void)\n>         const char *dir, *s;\n>         if (0 <= is_bare_repository_cfg)\n>                 return is_bare_repository_cfg;\n> +       if (0 <= has_working_directory)\n> +               return !has_working_directory;\n>\n>         dir = get_git_dir();\n>         if (!strcmp(dir, DEFAULT_GIT_DIR_ENVIRONMENT))\n\nUm.. git-sh-setup.sh may need special treatment because its\nis_bare_directory doesn't call this function.\n-- \nDuy\n"},{"id":"36802","messageId":"20070311133350.GA12553@moooo.ath.cx","threadId":"7191","inReplyTo":"fcaeb9bf0703110542t49bb3e77kb164ba7bfee1a6ed@mail.gmail.com","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-11T13:33:51Z","receivedAt":"2007-03-11T13:33:51Z","isPatch":false,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:\n> My case seems a bit complicated than usual. The working directory\n> (/home/pclouds/blog/data) was not a prefix of cwd (/home/pclouds/blog)\n> so the code failed silently at this line. If I replace\n> \"has_working_directory = 0; return NULL;\" with \"strcpy(cwd,gitwd);c =\n> 0;break;\", it may work but see below\n\nIf you're outside the specifed working directory the\nis_bare_repository will return true, just as if you don't have a\nworking directory.  Do you expect anything else or doesn't this work?\n"},{"id":"36803","messageId":"fcaeb9bf0703110646p5417048bx27f119679c01e988@mail.gmail.com","threadId":"7191","inReplyTo":"20070311133350.GA12553@moooo.ath.cx","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2007-03-11T13:46:24Z","receivedAt":"2007-03-11T13:46:24Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On 3/11/07, Matthias Lederhofer <matled@gmx.net> wrote:\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:\n> > My case seems a bit complicated than usual. The working directory\n> > (/home/pclouds/blog/data) was not a prefix of cwd (/home/pclouds/blog)\n> > so the code failed silently at this line. If I replace\n> > \"has_working_directory = 0; return NULL;\" with \"strcpy(cwd,gitwd);c =\n> > 0;break;\", it may work but see below\n>\n> If you're outside the specifed working directory the\n> is_bare_repository will return true, just as if you don't have a\n> working directory.  Do you expect anything else or doesn't this work?\n\nYes I expected it to move the specified working directory as described\nin the previous mail (copied/pasted below). However the patch requires\nme to be in workdir somewhere already (which is fine if that is your\nexpectation). If that's the case, maybe you should tell users\nsomething about GIT_WORK_DIR not applicable.\n\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:\n> > By the way, is it plausible to add --git-workdir option to specify\n> > working directory? With that option, I won't need to _chdir_ to the\n> > working directory, run git commands and _chdir back_.\n>\n> http://article.gmane.org/gmane.comp.version-control.git/38382\n> Since I did not need this feature that much and no one replied that\n> there is any interest I did not look any further into it.\n\n-- \nDuy\n"},{"id":"36804","messageId":"20070311140553.GA18947@moooo.ath.cx","threadId":"7191","inReplyTo":"fcaeb9bf0703110646p5417048bx27f119679c01e988@mail.gmail.com","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-11T14:05:53Z","receivedAt":"2007-03-11T14:05:53Z","isPatch":false,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:\n> Yes I expected it to move the specified working directory as described\n> in the previous mail (copied/pasted below). However the patch requires\n> me to be in workdir somewhere already (which is fine if that is your\n> expectation). If that's the case, maybe you should tell users\n> something about GIT_WORK_DIR not applicable.\n\nLet's say we have GIT_DIR=/tmp/git GIT_WORK_DIR=/tmp/foo and are in\n/tmp.  You want `git add bar` to chdir to /tmp/foo and add the file\nbar from /tmp/foo?\n\n> >Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:\n> >> By the way, is it plausible to add --git-workdir option to specify\n> >> working directory? With that option, I won't need to _chdir_ to the\n> >> working directory, run git commands and _chdir back_.\nI thought you meant the chdir to the toplevel directory when you're in\na subdirectory.  For this case I'd rather suggest\nmygit() {\n    old=$(pwd)\n    cd \"$MYTOPDIR\"\n    git \"$@\"\n    ret=$?\n    cd \"$old\"\n    return $ret\n}\n"},{"id":"36806","messageId":"fcaeb9bf0703110718i70742b8frca4d0df78bff214d@mail.gmail.com","threadId":"7191","inReplyTo":"20070311140553.GA18947@moooo.ath.cx","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2007-03-11T14:18:49Z","receivedAt":"2007-03-11T14:18:49Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On 3/11/07, Matthias Lederhofer <matled@gmx.net> wrote:\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:\n> > Yes I expected it to move the specified working directory as described\n> > in the previous mail (copied/pasted below). However the patch requires\n> > me to be in workdir somewhere already (which is fine if that is your\n> > expectation). If that's the case, maybe you should tell users\n> > something about GIT_WORK_DIR not applicable.\n>\n> Let's say we have GIT_DIR=/tmp/git GIT_WORK_DIR=/tmp/foo and are in\n> /tmp.  You want `git add bar` to chdir to /tmp/foo and add the file\n> bar from /tmp/foo?\n\nYes. I wanted it for easy scripting but it's not very intuitive from\ncommand line. I'd take it back.\n\n>\n> > >Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:\n> > >> By the way, is it plausible to add --git-workdir option to specify\n> > >> working directory? With that option, I won't need to _chdir_ to the\n> > >> working directory, run git commands and _chdir back_.\n> I thought you meant the chdir to the toplevel directory when you're in\n> a subdirectory.  For this case I'd rather suggest\n> mygit() {\n>     old=$(pwd)\n>     cd \"$MYTOPDIR\"\n>     git \"$@\"\n>     ret=$?\n>     cd \"$old\"\n>     return $ret\n> }\n>\nThanks, will try\n\n-- \nDuy\n"},{"id":"36809","messageId":"20070311150527.GA23224@moooo.ath.cx","threadId":"7191","inReplyTo":"fcaeb9bf0703110627r6500d621rf6710c58e9e8d65b@mail.gmail.com","subject":"[PATCH] rev-parse: --is-bare-repository option","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-11T15:05:27Z","receivedAt":"2007-03-11T15:05:27Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Signed-off-by: Matthias Lederhofer <matled@gmx.net>\n---\nNguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:\n> Um.. git-sh-setup.sh may need special treatment because its\n> is_bare_directory doesn't call this function.\nHere is rev-parse --is-bare-repository to fix this.\n\nI'm not sure if git-sh-setup.sh:is_bare_repository should do other\nchecks if git-rev-parse --is-bare-repository fails.\n---\n Documentation/git-rev-parse.txt |    7 +++++++\n builtin-rev-parse.c             |    5 +++++\n git-sh-setup.sh                 |    6 +-----\n git-svn.perl                    |    2 +-\n 4 files changed, 14 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt\nindex ccc66aa..d024d93 100644\n--- a/Documentation/git-rev-parse.txt\n+++ b/Documentation/git-rev-parse.txt\n@@ -89,6 +89,13 @@ OPTIONS\n --git-dir::\n \tShow `$GIT_DIR` if defined else show the path to the .git directory.\n \n+--is-inside-git-dir::\n+\tWhen the current working directory is below the repository\n+\tdirectory print \"true\", otherwise \"false\".\n+\n+--is-bare-repository::\n+\tWhen the repository is bare print \"true\", otherwise \"false\".\n+\n --short, --short=number::\n \tInstead of outputting the full SHA1 values of object names try to\n \tabbreviate them to a shorter unique name. When no length is specified\ndiff --git a/builtin-rev-parse.c b/builtin-rev-parse.c\nindex 37addb2..71d5162 100644\n--- a/builtin-rev-parse.c\n+++ b/builtin-rev-parse.c\n@@ -352,6 +352,11 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t\t: \"false\");\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!strcmp(arg, \"--is-bare-repository\")) {\n+\t\t\t\tprintf(\"%s\\n\", is_bare_repository() ? \"true\"\n+\t\t\t\t\t\t: \"false\");\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!prefixcmp(arg, \"--since=\")) {\n \t\t\t\tshow_datestring(\"--max-age=\", arg+8);\n \t\t\t\tcontinue;\ndiff --git a/git-sh-setup.sh b/git-sh-setup.sh\nindex f24c7f2..9ac657a 100755\n--- a/git-sh-setup.sh\n+++ b/git-sh-setup.sh\n@@ -29,11 +29,7 @@ set_reflog_action() {\n }\n \n is_bare_repository () {\n-\tgit-config --bool --get core.bare ||\n-\tcase \"$GIT_DIR\" in\n-\t.git | */.git) echo false ;;\n-\t*) echo true ;;\n-\tesac\n+\tgit-rev-parse --is-bare-repository\n }\n \n cd_to_toplevel () {\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 326e89f..ea5da95 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -559,7 +559,7 @@ sub post_fetch_checkout {\n \tmy $index = $ENV{GIT_INDEX_FILE} || \"$ENV{GIT_DIR}/index\";\n \treturn if -f $index;\n \n-\tchomp(my $bare = `git config --bool --get core.bare`);\n+\tchomp(my $bare = `git rev-parse --is-bare-repository`);\n \treturn if $bare eq 'true';\n \treturn if command_oneline(qw/rev-parse --is-inside-git-dir/) eq 'true';\n \tcommand_noisy(qw/read-tree -m -u -v HEAD HEAD/);\n-- \n1.5.0.3.355.g8488f-dirty\n"},{"id":"36813","messageId":"20070311155649.GA29663@moooo.ath.cx","threadId":"7191","inReplyTo":"fcaeb9bf0703110542t49bb3e77kb164ba7bfee1a6ed@mail.gmail.com","subject":"[PATCH(amend)] introduce GIT_WORK_DIR environment variable","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-11T15:56:49Z","receivedAt":"2007-03-11T15:56:49Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"This environment variable can be used with GIT_DIR to\nspecify the toplevel working directory.  When GIT_DIR is not\nset this variable is ignored.  As for GIT_DIR there is also\nthe option git --work-dir which overrides the environment\nvariable.\n\nSigned-off-by: Matthias Lederhofer <matled@gmx.net>\n---\nNew patch, this should go with the 'rev-parse --is-bare-repository\noption' patch.\n\nDocumentation added, is_bare_repository check fixed, relative GIT_DIR\nfix.  Becaus GIT_DIR is expanded to a full path setup_git_env should\nbe called after setup_git_directory_gently.  I searched for the\ncallers of setup_git_directory_gently and think this is fulfilled.\n\nNguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:\n> I propose the following instead of the last two lines:\n> \n>                if (!gitwd)\n>                        return NULL;\n>                if (stat(gitwd, &st_work))\n>                        die(\"Unable to stat git working directory %s\",gitwd);\nIt's in this new patch.\n\n> If cwd changed and GIT_DIR is a relative path, git can no longer\n> access GIT_DIR properly.\nThis too.\n---\n Documentation/git.txt |   16 ++++++++-\n cache.h               |    2 +\n environment.c         |   11 +++++-\n git.c                 |   12 ++++++-\n setup.c               |   92 +++++++++++++++++++++++++++++++++++++++++++-----\n 5 files changed, 119 insertions(+), 14 deletions(-)\n\ndiff --git a/Documentation/git.txt b/Documentation/git.txt\nindex e875e83..d2f5d27 100644\n--- a/Documentation/git.txt\n+++ b/Documentation/git.txt\n@@ -10,7 +10,8 @@ SYNOPSIS\n --------\n [verse]\n 'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate]\n-    [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]\n+    [--bare] [--git-dir=GIT_DIR] [--work-dir=GIT_WORK_DIR]\n+    [--help] COMMAND [ARGS]\n \n DESCRIPTION\n -----------\n@@ -81,6 +82,13 @@ OPTIONS\n \tSet the path to the repository. This can also be controlled by\n \tsetting the GIT_DIR environment variable.\n \n+--work-dir=<path>::\n+\tSet the path to the toplevel working directory.  The value will\n+\tbe used only in combination with $GIT_DIR or '--git-dir'.\n+\tWithout this option git will assume that the current directory\n+\tis also the toplevel directory.  This can also be controlled by\n+\tsetting the GIT_WORK_DIR environment variable.\n+\n --bare::\n \tSame as --git-dir=`pwd`.\n \n@@ -325,6 +333,12 @@ git so take care if using Cogito etc.\n \tspecifies a path to use instead of the default `.git`\n \tfor the base of the repository.\n \n+'GIT_WORK_DIR'::\n+\tSet the path to the toplevel working directory.  The value will\n+\tbe used only in combination with $GIT_DIR or '--git-dir'.\n+\tWithout this environment variable git will assume that the\n+\tcurrent directory is also the toplevel directory.\n+\n git Commits\n ~~~~~~~~~~~\n 'GIT_AUTHOR_NAME'::\ndiff --git a/cache.h b/cache.h\nindex f172d02..e3ca087 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -144,6 +144,7 @@ enum object_type {\n };\n \n #define GIT_DIR_ENVIRONMENT \"GIT_DIR\"\n+#define GIT_WORKING_DIR_ENVIRONMENT \"GIT_WORK_DIR\"\n #define DEFAULT_GIT_DIR_ENVIRONMENT \".git\"\n #define DB_ENVIRONMENT \"GIT_OBJECT_DIRECTORY\"\n #define INDEX_ENVIRONMENT \"GIT_INDEX_FILE\"\n@@ -164,6 +165,7 @@ extern char *get_graft_file(void);\n \n #define ALTERNATE_DB_ENVIRONMENT \"GIT_ALTERNATE_OBJECT_DIRECTORIES\"\n \n+extern int has_working_directory;\n extern const char **get_pathspec(const char *prefix, const char **pathspec);\n extern const char *setup_git_directory_gently(int *);\n extern const char *setup_git_directory(void);\ndiff --git a/environment.c b/environment.c\nindex 0151ad0..7bf6a87 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -59,8 +59,15 @@ static void setup_git_env(void)\n int is_bare_repository(void)\n {\n \tconst char *dir, *s;\n-\tif (0 <= is_bare_repository_cfg)\n-\t\treturn is_bare_repository_cfg;\n+\t/* definitely bare */\n+\tif (is_bare_repository_cfg == 1)\n+\t\treturn 1;\n+\t/* GIT_WORK_DIR is set, bare if cwd is outside */\n+\tif (has_working_directory >= 0)\n+\t\treturn !has_working_directory;\n+\t/* configuration says it is not bare */\n+\tif (is_bare_repository_cfg == 0)\n+\t\treturn 0;\n \n \tdir = get_git_dir();\n \tif (!strcmp(dir, DEFAULT_GIT_DIR_ENVIRONMENT))\ndiff --git a/git.c b/git.c\nindex fe2b74a..8a73648 100644\n--- a/git.c\n+++ b/git.c\n@@ -4,7 +4,7 @@\n #include \"quote.h\"\n \n const char git_usage_string[] =\n-\t\"git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]\";\n+\t\"git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--work-dir=GIT_WORK_DIR] [--help] COMMAND [ARGS]\";\n \n static void prepend_to_path(const char *dir, int len)\n {\n@@ -68,6 +68,16 @@ static int handle_options(const char*** argv, int* argc)\n \t\t\t(*argc)--;\n \t\t} else if (!prefixcmp(cmd, \"--git-dir=\")) {\n \t\t\tsetenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);\n+\t\t} else if (!strcmp(cmd, \"--work-dir\")) {\n+\t\t\tif (*argc < 2) {\n+\t\t\t\tfprintf(stderr, \"No directory given for --work-dir.\\n\" );\n+\t\t\t\tusage(git_usage_string);\n+\t\t\t}\n+\t\t\tsetenv(GIT_WORKING_DIR_ENVIRONMENT, (*argv)[1], 1);\n+\t\t\t(*argv)++;\n+\t\t\t(*argc)--;\n+\t\t} else if (!prefixcmp(cmd, \"--work-dir=\")) {\n+\t\t\tsetenv(GIT_WORKING_DIR_ENVIRONMENT, cmd + 11, 1);\n \t\t} else if (!strcmp(cmd, \"--bare\")) {\n \t\t\tstatic char git_dir[PATH_MAX+1];\n \t\t\tsetenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 1);\ndiff --git a/setup.c b/setup.c\nindex a45ea83..ebf628e 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -192,28 +192,100 @@ int is_inside_git_dir(void)\n \treturn inside_git_dir;\n }\n \n+int has_working_directory = -1;\n+\n const char *setup_git_directory_gently(int *nongit_ok)\n {\n \tstatic char cwd[PATH_MAX+1];\n \tconst char *gitdirenv;\n \tint len, offset;\n \n-\t/*\n-\t * If GIT_DIR is set explicitly, we're not going\n-\t * to do any discovery, but we still do repository\n-\t * validation.\n-\t */\n \tgitdirenv = getenv(GIT_DIR_ENVIRONMENT);\n \tif (gitdirenv) {\n+\t\tstruct stat st, st_work, st_git;\n+\t\tconst char *gitwd;\n+\t\tchar *prefix;\n+\t\tchar c;\n+\t\tint len;\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\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+\n+\t\t/* check for working directory */\n+\t\tgitwd = getenv(GIT_WORKING_DIR_ENVIRONMENT);\n+\t\tif (!gitwd)\n \t\t\treturn NULL;\n+\t\tif (stat(gitwd, &st_work))\n+\t\t\tdie(\"Unable to stat git working directory '%s'\", gitwd);\n+\t\tif (inside_git_dir == -1 && stat(gitdirenv, &st_git))\n+\t\t\tdie(\"Unable to stat git directory\");\n+\t\tif (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')\n+\t\t\tdie(\"Unable to read current working directory\");\n+\t\tlen = strlen(cwd);\n+\n+\t\tprefix = cwd+len;\n+\t\tfor (;;) {\n+\t\t\tc = *prefix;\n+\t\t\t*prefix = '\\0';\n+\t\t\tif (stat(cwd, &st))\n+\t\t\t\tdie(\"Unable to stat '%s'\", cwd);\n+\t\t\tif (st_work.st_dev == st.st_dev &&\n+\t\t\t    st_work.st_ino == st.st_ino)\n+\t\t\t\tbreak;\n+\t\t\tif (inside_git_dir == -1 &&\n+\t\t\t    st_git.st_dev == st.st_dev &&\n+\t\t\t    st_git.st_ino == st.st_ino)\n+\t\t\t\tinside_git_dir = 1;\n+\t\t\t*prefix = c;\n+\n+\t\t\tif (prefix == cwd+1) {\n+\t\t\t\thas_working_directory = 0;\n+\t\t\t\treturn NULL;\n+\t\t\t}\n+\t\t\twhile (*(--prefix) != '/')\n+\t\t\t\t; /* do nothing */\n+\t\t\tif (prefix == cwd)\n+\t\t\t\tprefix++;\n+\t\t}\n+\n+\t\t/*\n+\t\t * if GIT_DIR is no absolute path it wont work anymore after\n+\t\t * changing the directory, therefore expand it to an absolute\n+\t\t * path\n+\t\t */\n+\t\tif (gitdirenv[0] != '/') {\n+\t\t\tchar buf[PATH_MAX];\n+\t\t\tif (chdir(gitdirenv))\n+\t\t\t\tdie(\"Cannot change directory to '%s'\",\n+\t\t\t\t    gitdirenv);\n+\t\t\tif (!getcwd(buf, sizeof(buf)) || buf[0] != '/')\n+\t\t\t\tdie(\"Unable to read current working directory\");\n+\t\t\tsetenv(GIT_DIR_ENVIRONMENT, buf, 1);\n+\t\t}\n+\t\tif (chdir(cwd))\n+\t\t\tdie(\"Cannot change directory to '%s'\", cwd);\n+\n+\t\tif (c) {\n+\t\t\t*prefix = c;\n+\t\t\tprefix++;\n+\t\t\tcwd[len] = '/';\n+\t\t\tcwd[len+1] = '\\0';\n+\t\t} else {\n+\t\t\tprefix = NULL;\n \t\t}\n-\t\tdie(\"Not a git repository: '%s'\", gitdirenv);\n+\n+\t\thas_working_directory = 1;\n+\t\tif (inside_git_dir == -1)\n+\t\t\tinside_git_dir = 0;\n+\n+\t\treturn prefix;\n \t}\n \n \tif (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')\n-- \n1.5.0.3.356.gafc9e-dirty\n"},{"id":"36817","messageId":"20070311162201.GA26983@moooo.ath.cx","threadId":"7191","inReplyTo":"7vabykxs15.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-11T16:22:01Z","receivedAt":"2007-03-11T16:22:01Z","isPatch":false,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> Matthias Lederhofer <matled@gmx.net> writes:\n> > Idea:\n> > Add some way to configure tho working directory for one repository\n> > and set GIT_WORK_DIR automatically when GIT_DIR is used.  I think of:\n> >  * a subdirectory in the repository directory\n> >    e.g. .git/work_dir which is supposed to be a symlink (or a textfile\n> >    containing the path for windows compatibility?)\n> > or\n> >  * a configuration variable\n> \n> I am not sure why you bother.  Obviously I am missing a few\n> useful use cases you and Nguyen have in mind.\n\nFor example have the checkout of a git repository publicly available\n(e.g. on a webserver).  The .git directory containing all the history\nshould probably not go there (especially if it tracks scripts).  Sure,\nsetting strict permissions solves this too in most cases but anyway\nit's nice to have the option to move the repository away.\n\nAdditionally when reading the man page about GIT_DIR it says 'the\ndefault value is .git', which sounds a bit like \"hey, if you don't\nlike the name you're free to change it\", but as soon as you change it\nyou run into problems because git behaves strange in subdirectories :)\n\n> But either .git/work_dir or a configuration means you are\n> linking a repository with a _single_ working tree, permanently.\n\nWell, this would only be the default value for convenience with\nGIT_WORK_DIR/--work-dir still overriding this value.  You'd only have\nto set GIT_DIR=~/src/website and work on the website without setting\nthe second environment variable too.\n\n> I've heard read-only working tree in the past, but that cannot\n> be it.  If the working tree is read-only and if you are telling\n> git to always use that read-only working tree when using that\n> particular repository, what useful git operations are you doing\n> while in that working tree?\n\nThe tools to inspect (git diff, ..) and track (git add, ..) work fine.\nSo one could easily (without copying stuff around) track changes of a\nread-only directory.\n"},{"id":"36818","messageId":"fcaeb9bf0703110925j6518a52ex68fad8f23a55e5c@mail.gmail.com","threadId":"7191","inReplyTo":"20070311155649.GA29663@moooo.ath.cx","subject":"Re: [PATCH(amend)] introduce GIT_WORK_DIR environment variable","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2007-03-11T16:25:03Z","receivedAt":"2007-03-11T16:25:03Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On 3/11/07, Matthias Lederhofer <matled@gmx.net> wrote:\n> This environment variable can be used with GIT_DIR to\n> specify the toplevel working directory.  When GIT_DIR is not\n> set this variable is ignored.  As for GIT_DIR there is also\n> the option git --work-dir which overrides the environment\n> variable.\n>\n> Signed-off-by: Matthias Lederhofer <matled@gmx.net>\n\nWorks for me.\n\n-- \nDuy\n"},{"id":"36848","messageId":"7vlki3wngv.fsf@assigned-by-dhcp.cox.net","threadId":"7191","inReplyTo":"20070311162201.GA26983@moooo.ath.cx","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-11T20:10:24Z","receivedAt":"2007-03-11T20:10:24Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthias Lederhofer <matled@gmx.net> writes:\n\n> For example have the checkout of a git repository publicly available\n> (e.g. on a webserver).  The .git directory containing all the history\n> should probably not go there (especially if it tracks scripts).  Sure,\n> setting strict permissions solves this too in most cases but anyway\n> it's nice to have the option to move the repository away.\n\nThat's fine.  Will you constantly work inside that webserver exposed\nworking tree, though?  I suspect the operation you would do\nthere would only be \"GIT_DIR=/some/where/else git checkout -f\"\nto refresh the published copy, so I do not think even GIT_WORK_DIR\nis needed for that use case (just to make sure, I am not opposed\nto having GIT_WORK_DIR -- my \"why bother\" is about having the\nequivalent in .git/work_dir or .git/config).\n\n> Additionally when reading the man page about GIT_DIR it says 'the\n> default value is .git', which sounds a bit like \"hey, if you don't\n> like the name you're free to change it\", but as soon as you change it\n> you run into problems because git behaves strange in subdirectories :)\n\nThat is really a historical mention.  The current Porcelain-ish\ndepend on that \"default\" layout (I know you know that after\nseeing what setup_git_directory does), and I think GIT_DIR\nshould not be taught to new people as such.\n\n> The tools to inspect (git diff, ..) and track (git add, ..) work fine.\n> So one could easily (without copying stuff around) track changes of a\n> read-only directory.\n\nWhy does read-only directory have changes to begin with???\n"},{"id":"36857","messageId":"Pine.LNX.4.64.0703111326170.9690@woody.linux-foundation.org","threadId":"7191","inReplyTo":"7vabykxs15.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-11T20:37:23Z","receivedAt":"2007-03-11T20:37:23Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sat, 10 Mar 2007, Junio C Hamano wrote:\n> Matthias Lederhofer <matled@gmx.net> writes:\n> > Idea:\n> > Add some way to configure tho working directory for one repository\n> > and set GIT_WORK_DIR automatically when GIT_DIR is used.  I think of:\n> >  * a subdirectory in the repository directory\n> >    e.g. .git/work_dir which is supposed to be a symlink (or a textfile\n> >    containing the path for windows compatibility?)\n> > or\n> >  * a configuration variable\n> \n> I am not sure why you bother.  Obviously I am missing a few\n> useful use cases you and Nguyen have in mind.\n\nI actually like this feature. Let me explain why I think it's a great \nfeature:\n\n> But either .git/work_dir or a configuration means you are\n> linking a repository with a _single_ working tree, permanently.\n> If you are permanently linking one repository with a _single_\n> working tree, is it too much bother to have that repository at\n> the usual $GIT_TOP_DIR/.git like everybody else?\n\nI'll tell you why: it makes tons of sense to have the git repository \nlinked to exactly one working tree, *but the reverse is not necessarily \nalways true*!\n\nIn other words, it can be a 1:n relationship.\n\nYou can have one working tree that is related to *multiple* git \nrepositories.\n\nThat sounds insane, but I actually think it works, and makes tons of \nsense. Think something as simple as your own home directory.\n\nIt's possible that you want to track your music collection with git, but \nsay that your music collection is a few different subdirectories or files \nin your home directory: maybe you track your \"Music\" directory (which \ncontains the actual mp3 files or whatever), but maybe you'd like the same \nrepository to *also* track things like your configuration file for \nwhatever mp3-player you're using (\".xmms\"? Whatever).\n\nSo let's say that you have a git repository for tracking all that. The \n\"working tree\" for that git repository would be your home directory.\n\nNow, imagine that you *also* want to track something else in git, that you \n*also* have in your home directory. Say your \".bashrc\" files etc. They \nhave nothing to do with your music tracking setup, so you don't want to \ntrack it in the same git repository, and you want to have a totally \ndifferent .git/index file for those. But again, the *working*tree* is \nactually your home directory.\n\nSo allowing you to set the working tree associated with a particular git \nrepository actually solves that problem. They can both share the same \nworking tree (you'd want to track disjunct parts of the working tree, of \ncourse), which means that the working tree obviously does *not* want to \nhave a .git/ directory in it. And to track your music changes, you'd just \ndo\n\n\tcd music-repository\n\tgit add music/\n\tgit commit\n\nto add any new files, and you'd be all set (or something like this).\n\nThere are other cases than just your home directory where you might want \nto track disjoint filesets in different git repositories. Things like /etc \nfall under the same \"many unrelated things in the same working tree\" \nsetup.\n\nSo I actually think it makes tons of sense to allow a way to set the \nworking tree for a git repository, and go the other way.\n\n\t\tLinus\n"},{"id":"36861","messageId":"7vodmzv6dq.fsf@assigned-by-dhcp.cox.net","threadId":"7191","inReplyTo":"Pine.LNX.4.64.0703111326170.9690@woody.linux-foundation.org","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-11T21:04:49Z","receivedAt":"2007-03-11T21:04:49Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> So let's say that you have a git repository for tracking all that. The \n> \"working tree\" for that git repository would be your home directory.\n>\n> Now, imagine that you *also* want to track something else in git, that you \n> *also* have in your home directory. Say your \".bashrc\" files etc. They \n> have nothing to do with your music tracking setup, so you don't want to \n> track it in the same git repository, and you want to have a totally \n> different .git/index file for those. But again, the *working*tree* is \n> actually your home directory.\n\nThat is a good example usage schenario; we would need to think\nabout what to do with .gitignore (and .gitattributes if we will\nhave that in-tree), though.\n"},{"id":"36863","messageId":"Pine.LNX.4.64.0703111410520.9690@woody.linux-foundation.org","threadId":"7191","inReplyTo":"7vodmzv6dq.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-11T21:13:09Z","receivedAt":"2007-03-11T21:13:09Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 11 Mar 2007, Junio C Hamano wrote:\n> \n> That is a good example usage schenario; we would need to think\n> about what to do with .gitignore (and .gitattributes if we will\n> have that in-tree), though.\n\nGood point. That's a real problem.\n\nI guess you could say that for this kind of usage scenario you only want \nto use the per-repository .git/ignore file, or maybe have some way of \nspecifying the name of the .gitignore file per repository.\n\nHmm. I'm not sure it was a great idea. I still like the concept, but \nyou're right, it's not without its problems.\n\n\t\tLinus\n"},{"id":"36864","messageId":"20070311212906.GA18208@moooo.ath.cx","threadId":"7191","inReplyTo":"20070311155649.GA29663@moooo.ath.cx","subject":"[PATCH] use $GIT_DIR/workdir as working directory with $GIT_DIR","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-11T21:29:06Z","receivedAt":"2007-03-11T21:29:06Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"$GIT_DIR/workdir will be used as fallback if $GIT_WORK_DIR is not set\n\nSigned-off-by: Matthias Lederhofer <matled@gmx.net>\n---\n Documentation/repository-layout.txt |    4 ++\n setup.c                             |   64 ++++++++++++++++++++++++++++++++---\n 2 files changed, 63 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/repository-layout.txt b/Documentation/repository-layout.txt\nindex 0459bd9..8a88080 100644\n--- a/Documentation/repository-layout.txt\n+++ b/Documentation/repository-layout.txt\n@@ -179,3 +179,7 @@ shallow::\n \tand maintained by shallow clone mechanism.  See `--depth`\n \toption to gitlink:git-clone[1] and gitlink:git-fetch[1].\n \n+workdir::\n+\tDirectory to be used as toplevel working directory when GIT_DIR\n+\tis set.  If this is a file the first line will be used as the\n+\tname of the directory.  This can be overriden by GIT_WORK_DIR.\ndiff --git a/setup.c b/setup.c\nindex ebf628e..a8b9fae 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -192,6 +192,64 @@ int is_inside_git_dir(void)\n \treturn inside_git_dir;\n }\n \n+static int stat_git_work_dir(struct stat *st)\n+{\n+\tchar workdir[PATH_MAX], cwd[PATH_MAX];\n+\tconst char *gitdir = getenv(GIT_DIR_ENVIRONMENT);\n+\tconst char *gitwd = getenv(GIT_WORKING_DIR_ENVIRONMENT);\n+\tint offset;\n+\tFILE *fp;\n+\n+\tif (gitwd) {\n+\t\tif (!stat(gitwd, st))\n+\t\t\treturn 1;\n+\t\tdie(\"Unable to stat git working directory '%s'\", gitwd);\n+\t}\n+\n+\t/* setup_git_directory_gently: PATH_MAX - 40 >= strlen(gitdirenv) */\n+\tstrcpy(workdir, gitdir);\n+\tstrcat(workdir, \"/workdir\");\n+\n+\tif (stat(workdir, st))\n+\t\treturn 0;\n+\tif (st->st_mode & S_IFDIR)\n+\t\treturn 1;\n+\tif (!(st->st_mode & S_IFREG))\n+\t\tdie(\"GIT_DIR/workdir is neither a file nor a directory\");\n+\n+\t/* GIT_DIR/workdir is a file */\n+\tfp = fopen(workdir, \"r\");\n+\tif (!fp)\n+\t\tdie(\"Unable to open '%s'\", workdir);\n+\tif (!fgets(workdir, sizeof(workdir), fp))\n+\t\tdie(\"Reading working directory from '%s' failed\", workdir);\n+\tfclose(fp);\n+\t/* remove newline character(s) */\n+\toffset = strlen(workdir)-1;\n+\twhile (offset >= 0 && (workdir[offset] == '\\r' ||\n+\t\t\tworkdir[offset] == '\\n'))\n+\t\t--offset;\n+\tworkdir[offset+1] = '\\0';\n+\n+\t/* relative path: change to gitdir for stat */\n+\tif (workdir[0] != '/') {\n+\t\tif (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')\n+\t\t\tdie(\"Unable to read current working directory\");\n+\t\tif (chdir(gitdir))\n+\t\t\tdie(\"Cannot change directory to '%s'\", gitdir);\n+\t}\n+\n+\tif (stat(workdir, st))\n+\t\tdie(\"Unable to stat directory from GIT_DIR/workdir\");\n+\tif (!(st->st_mode & S_IFDIR))\n+\t\tdie(\"GIT_DIR/workdir does not point to a directory\");\n+\n+\tif (workdir[0] != '/' && chdir(cwd))\n+\t\tdie(\"Cannot come back to cwd\");\n+\n+\treturn 1;\n+}\n+\n int has_working_directory = -1;\n \n const char *setup_git_directory_gently(int *nongit_ok)\n@@ -203,7 +261,6 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \tgitdirenv = getenv(GIT_DIR_ENVIRONMENT);\n \tif (gitdirenv) {\n \t\tstruct stat st, st_work, st_git;\n-\t\tconst char *gitwd;\n \t\tchar *prefix;\n \t\tchar c;\n \t\tint len;\n@@ -219,11 +276,8 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\t}\n \n \t\t/* check for working directory */\n-\t\tgitwd = getenv(GIT_WORKING_DIR_ENVIRONMENT);\n-\t\tif (!gitwd)\n+\t\tif (!stat_git_work_dir(&st_work))\n \t\t\treturn NULL;\n-\t\tif (stat(gitwd, &st_work))\n-\t\t\tdie(\"Unable to stat git working directory '%s'\", gitwd);\n \t\tif (inside_git_dir == -1 && stat(gitdirenv, &st_git))\n \t\t\tdie(\"Unable to stat git directory\");\n \t\tif (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')\n-- \n1.5.0.3.357.g0b2cd\n"},{"id":"36869","messageId":"Pine.LNX.4.63.0703112241540.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7191","inReplyTo":"7vlki3wngv.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-11T21:43:08Z","receivedAt":"2007-03-11T21:43:08Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 11 Mar 2007, Junio C Hamano wrote:\n\n> Why does read-only directory have changes to begin with???\n\nTracking (parts of) /etc/, I change as root, but commit as another user \n(to prevent accidental corruption).\n\nCiao,\nDscho\n"},{"id":"36892","messageId":"1abe3fa90703120108x3fbc5b49k17ee6d00ff5fb79@mail.gmail.com","threadId":"7191","inReplyTo":"7vodmzv6dq.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"A.J. Rossini","fromEmail":"blindglobe@gmail.com","sentAt":"2007-03-12T08:08:46Z","receivedAt":"2007-03-12T08:08:46Z","isPatch":false,"sender":{"key":"blindglobe@gmail.com","avatar":"https://gravatar.com/avatar/d9ce41197180da6d03ab12a6c3e9ff8a030b1677bca88ad65458c2f5566d8550?d=mp&s=160"},"body":"On 3/11/07, Junio C Hamano <junkio@cox.net> wrote:\n> Linus Torvalds <torvalds@linux-foundation.org> writes:\n>\n> > So let's say that you have a git repository for tracking all that. The\n> > \"working tree\" for that git repository would be your home directory.\n> >\n> > Now, imagine that you *also* want to track something else in git, that you\n> > *also* have in your home directory. Say your \".bashrc\" files etc. They\n> > have nothing to do with your music tracking setup, so you don't want to\n> > track it in the same git repository, and you want to have a totally\n> > different .git/index file for those. But again, the *working*tree* is\n> > actually your home directory.\n>\n> That is a good example usage schenario; we would need to think\n> about what to do with .gitignore (and .gitattributes if we will\n> have that in-tree), though.\n\nModulo problems like above, isn't this just a solid solution to the\nmodules problem?   (not only directory-level modules, but intertwined\n(in the sense of repositories) files within a directory).\n\nAnd wouldn't the cheap hack just to be to have a pecking order for\ndetermining attributes?  (i.e. a master file with metadata which is\nowned by the working directory, not the repository, to decide which\nrepository to look at for which files).\n\nOuch, but Junio's right, it's still painful, ugly and problematic.\n\nbest,\n-tony\n\nblindglobe@gmail.com\nMuttenz, Switzerland.\n\"Commit early,commit often, and commit in a repository from which we\ncan easily roll-back your mistakes\" (AJR, 4Jan05).\n"},{"id":"36899","messageId":"20070312115350.GA15179@moooo.ath.cx","threadId":"7191","inReplyTo":"20070311043250.GA21331@moooo.ath.cx","subject":"[PATCH] git-init: set up GIT_DIR/workdir if GIT_WORK_DIR is set","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-12T11:53:50Z","receivedAt":"2007-03-12T11:53:50Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"git-init will always put an absolute path in\nGIT_DIR/workdir, relative paths are resolved from the\ndirectory git-init was called from.\n\nSigned-off-by: Matthias Lederhofer <matled@gmx.net>\n---\nI found this static char path[PATH_MAX] even though path is neither\nreused nor returned.  If there is any reason to have this as a static\nbuffer please change this back to 'static char'\n---\n builtin-init-db.c |   40 ++++++++++++++++++++++++++++++++++++++--\n 1 files changed, 38 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin-init-db.c b/builtin-init-db.c\nindex 4df9fd0..f0b4444 100644\n--- a/builtin-init-db.c\n+++ b/builtin-init-db.c\n@@ -176,12 +176,13 @@ static void copy_templates(const char *git_dir, int len, const char *template_di\n static int create_default_files(const char *git_dir, const char *template_path)\n {\n \tunsigned len = strlen(git_dir);\n-\tstatic char path[PATH_MAX];\n+\tchar path[PATH_MAX], workdir[PATH_MAX];\n \tunsigned char sha1[20];\n \tstruct stat st1;\n \tchar repo_version_string[10];\n \tint reinit;\n \tint filemode;\n+\tconst char *gitwd = getenv(GIT_WORKING_DIR_ENVIRONMENT);\n \n \tif (len > sizeof(path)-50)\n \t\tdie(\"insane git directory %s\", git_dir);\n@@ -252,7 +253,42 @@ static int create_default_files(const char *git_dir, const char *template_path)\n \t}\n \tgit_config_set(\"core.filemode\", filemode ? \"true\" : \"false\");\n \n-\tif (is_bare_repository()) {\n+\t/* make gitwd an absolute path */\n+\tif (gitwd && gitwd[0] != '/') {\n+\t\tchar cwd[PATH_MAX];\n+\n+\t\tif (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')\n+\t\t\tdie(\"Unable to read current working directory\");\n+\t\tif (chdir(gitwd)) {\n+\t\t\tfprintf(stderr, \"warning: chdir to specified relative \"\n+\t\t\t\t\"working directory failed, ignoring\\n\");\n+\t\t\tgitwd = NULL;\n+\t\t}\n+\t\telse if (!getcwd(workdir, sizeof(workdir)) || workdir[0] != '/')\n+\t\t\tdie(\"Unable to read current working directory\");\n+\t\telse {\n+\t\t\tgitwd = workdir;\n+\t\t\tif (chdir(cwd))\n+\t\t\t\tdie(\"Cannot come back to cwd\");\n+\t\t}\n+\t}\n+\n+\tif (gitwd) {\n+\t\tFILE *fp = NULL;\n+\n+\t\tpath[len] = 0;\n+\t\tstrcpy(path + len, \"workdir\");\n+\t\tif (!(fp = fopen(path, \"w\")))\n+\t\t\tdie(\"Cannot open GIT_DIR/workdir\");\n+\t\tfprintf(fp, \"%s\\n\", gitwd);\n+\t\tfclose(fp);\n+\n+\t\tgit_config_set(\"core.bare\", \"false\");\n+\t\t/* allow template config file to override the default */\n+\t\tif (log_all_ref_updates == -1)\n+\t\t    git_config_set(\"core.logallrefupdates\", \"true\");\n+\t}\n+\telse if (is_bare_repository()) {\n \t\tgit_config_set(\"core.bare\", \"true\");\n \t}\n \telse {\n-- \n1.5.0.3.1006.gd633\n"},{"id":"36901","messageId":"20070312121226.GB2268@always.joy.eth.net","threadId":"7191","inReplyTo":"20070312115350.GA15179@moooo.ath.cx","subject":"Re: [PATCH] git-init: set up GIT_DIR/workdir if GIT_WORK_DIR is set","fromName":"Joshua N Pritikin","fromEmail":"jpritikin@pobox.com","sentAt":"2007-03-12T12:12:26Z","receivedAt":"2007-03-12T12:12:26Z","isPatch":true,"sender":{"key":"jpritikin@pobox.com","avatar":"https://gravatar.com/avatar/3f2561fdd7efac4e127dc65ac7e06f044069c115dcc94d0ac540f4126d47759d?d=mp&s=160"},"body":"On Mon, Mar 12, 2007 at 12:53:50PM +0100, Matthias Lederhofer wrote:\n> git-init will always put an absolute path in\n> GIT_DIR/workdir, relative paths are resolved from the\n> directory git-init was called from.\n\nDoes that mean I can't move my GIT trees around without changing a \nconfig entry? What is that an improvement?\n"},{"id":"36903","messageId":"20070312125207.GA16335@moooo.ath.cx","threadId":"7191","inReplyTo":"20070312121226.GB2268@always.joy.eth.net","subject":"Re: [PATCH] git-init: set up GIT_DIR/workdir if GIT_WORK_DIR is set","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-12T12:52:07Z","receivedAt":"2007-03-12T12:52:07Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Joshua N Pritikin <jpritikin@pobox.com> wrote:\n> On Mon, Mar 12, 2007 at 12:53:50PM +0100, Matthias Lederhofer wrote:\n> > git-init will always put an absolute path in\n> > GIT_DIR/workdir, relative paths are resolved from the\n> > directory git-init was called from.\n> \n> Does that mean I can't move my GIT trees around without changing a \n> config entry? What is that an improvement?\nOnly when using $GIT_DIR.  $GIT_DIR/workdir is only the default value\nfor $GIT_WORK_DIR.\n"},{"id":"36904","messageId":"20070312131253.GA16452@moooo.ath.cx","threadId":"7191","inReplyTo":"20070312121226.GB2268@always.joy.eth.net","subject":"Re: [PATCH] git-init: set up GIT_DIR/workdir if GIT_WORK_DIR is set","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-12T13:12:53Z","receivedAt":"2007-03-12T13:12:53Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Joshua N Pritikin <jpritikin@pobox.com> wrote:\n> On Mon, Mar 12, 2007 at 12:53:50PM +0100, Matthias Lederhofer wrote:\n> > git-init will always put an absolute path in\n> > GIT_DIR/workdir, relative paths are resolved from the\n> > directory git-init was called from.\n> \n> Does that mean I can't move my GIT trees around without changing a \n> config entry? What is that an improvement?\n\nAnd for the decision to put an absolute path there by default:\n\nPutting $GIT_WORK_DIR as is into $GIT_DIR/workdir is probably not what\nthe user expects because the content of $GIT_DIR/workdir is\ninterpreted relative to $GIT_DIR, not the current working directory.\nExample:\n\n    /tmp$ mkdir repository working_directory\n    /tmp$ git --git-dir=repository --work-dir=working_directory init\n\nIf git init puts 'working_directory' into $GIT_DIR/workdir it would\nmake the associated working directory $GIT_DIR/working_directory =\n/tmp/repository/working_directory and not /tmp/working_directory.\n\nThe alternative to use\n\n    /tmp$ git --git-dir=repository --work-dir=../working_directory init\n\nseems quite confusing to me.\n\nIf you've any other idea to solve this please tell me.\n"},{"id":"36907","messageId":"fcaeb9bf0703120636r7038a7fat24e571e7c087d13d@mail.gmail.com","threadId":"7191","inReplyTo":"20070312131253.GA16452@moooo.ath.cx","subject":"Re: [PATCH] git-init: set up GIT_DIR/workdir if GIT_WORK_DIR is set","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2007-03-12T13:36:42Z","receivedAt":"2007-03-12T13:36:42Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On 3/12/07, Matthias Lederhofer <matled@gmx.net> wrote:\n> Putting $GIT_WORK_DIR as is into $GIT_DIR/workdir is probably not what\n> the user expects because the content of $GIT_DIR/workdir is\n> interpreted relative to $GIT_DIR, not the current working directory.\n> Example:\n>\n>     /tmp$ mkdir repository working_directory\n>     /tmp$ git --git-dir=repository --work-dir=working_directory init\n>\n> If git init puts 'working_directory' into $GIT_DIR/workdir it would\n> make the associated working directory $GIT_DIR/working_directory =\n> /tmp/repository/working_directory and not /tmp/working_directory.\n>\n> The alternative to use\n>\n>     /tmp$ git --git-dir=repository --work-dir=../working_directory init\n>\n> seems quite confusing to me.\n>\n> If you've any other idea to solve this please tell me.\n\nLet users create $GIT_DIR/workdir themselves. Your way may be less\nconfusing to you but might be more confusing to me because I _might_\nexpect a relative workdir setting (for example I move the repository\nand the working directory together to another place).\n\n-- \nDuy\n"},{"id":"36909","messageId":"20070312140808.GA17450@moooo.ath.cx","threadId":"7191","inReplyTo":"fcaeb9bf0703120636r7038a7fat24e571e7c087d13d@mail.gmail.com","subject":"Re: [PATCH] git-init: set up GIT_DIR/workdir if GIT_WORK_DIR is set","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-12T14:08:08Z","receivedAt":"2007-03-12T14:08:08Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:\n> Let users create $GIT_DIR/workdir themselves. Your way may be less\n> confusing to you but might be more confusing to me because I _might_\n> expect a relative workdir setting (for example I move the repository\n> and the working directory together to another place).\n\nWell, without this patch you havo to do one of these:\n\n    /tmp$ mkdir repository working_directory\n    /tmp$ git --git-dir=repository init\n    /tmp$ git --git-dir=repository config core.bare false\n    /tmp$ echo ../working_directory > repository/workdir\n\nor\n\n    /tmp$ mkdir repository working_directory\n    /tmp/repository$ cd repository\n    /tmp$ git init\n    /tmp/repository$ mv .git/* .\n    /tmp/repository$ rmdir .git\n    /tmp$ echo ../working_directory > repository/workdir\n\nWhere the second example is probably better because git init creates a\nbare repository in the first case which might have more settings\ndifferent from a 'normal' repository (it actually sets also\ncore.logallrefupdates = true which probably should be added to the\nfirst example).\n\nWith this patch you'd have to do\n\n    /tmp$ mkdir repository working_directory\n    /tmp$ git --git-dir=repository --work-dir=working_directory init\n    /tmp$ echo ../working_directory > repository/workdir\n\nin case you really want a relative path.\n\nBecause the first two ways are so long I think git init should have\nsome way to handle this case.\n\nI don't want to put $GIT_WORK_DIR 'as is' to $GIT_DIR/workdir because\n$GIT_WORK_DIR is normally interpreted as relative path to the current\nworking directory and not relative to $GIT_DIR.\n\nPerhaps we could add another flag to git init which will be used 'as is'\nfor $GIT_DIR/workdir:\n    git --git-dir=repository init --work-dir=../working_directory\n\nOther things I can think of:\n\n    Add a --not-bare flag to git init:\n    $ git --git-dir=repository init --not-bare\n    $ echo ../working_directory > repository/workdir\n\n    Tell the user what to do in case the path should be relative:\n    $ git --git-dir=repository --work-dir=working_directory init\n    You specified a relative working directory and git has\n    automatically expanded this to /tmp/working_directory.  If you\n    prefer a relative path you can do:\n        echo relative_path > repository/workdir\n"},{"id":"36923","messageId":"7vabyitlld.fsf@assigned-by-dhcp.cox.net","threadId":"7191","inReplyTo":"20070312140808.GA17450@moooo.ath.cx","subject":"Re: [PATCH] git-init: set up GIT_DIR/workdir if GIT_WORK_DIR is set","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-12T17:31:26Z","receivedAt":"2007-03-12T17:31:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthias Lederhofer <matled@gmx.net> writes:\n\n> ... because\n> $GIT_WORK_DIR is normally interpreted as relative path to the current\n> working directory and not relative to $GIT_DIR.\n\nWell, it could be that _that_ handling of the environment\nvariable is what needs to be fixed.\n\nIf you are using $GIT_DIR, you are working in a subdirectory,\nsay, Documentation/, and you are using a relative path to\nspecify GIT_WORK_DIR, then you would need to do this, right?\n\n\t$ GIT_DIR=/src/git/git.git ;# top of repository\n        $ export GIT_DIR\n        $ cd /work/git/git.git ;# go to top of working tree\n\t$ cd Documentation ;# I want to work in here...\n\n        $ GIT_WORK_DIR=.. ;# toplevel is .. relative to here\n        $ export GIT_WORK_DIR\n        $ hack hack ; git commit\n\n        $ cd .. ;# Now I want to update the toplevel\n        $ GIT_WORK_DIR=. ;# oops I need to update this env\n\t$ hack hack ; git commit\n\n        $ cd t ;# Now to testcase\n        $ GIT_WORK_DIR=.. ;# oops again\n\nIf $GIT_WORK_DIR is given absolute you do not have to worry\nabout this problem, but if you allow giving relative path, it\nseems to me that it would be more useful to make it relative to\nGIT_DIR.  Then you would need to set it just once, at the same\ntime when you set and export GIT_DIR, and keep working in that\nworking tree.\n\nThe same goes for $GIT_DIR/workdir.\n"},{"id":"36930","messageId":"20070312180837.GA22701@moooo.ath.cx","threadId":"7191","inReplyTo":"7vabyitlld.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-init: set up GIT_DIR/workdir if GIT_WORK_DIR is set","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-12T18:08:37Z","receivedAt":"2007-03-12T18:08:37Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> Matthias Lederhofer <matled@gmx.net> writes:\n> \n> > ... because\n> > $GIT_WORK_DIR is normally interpreted as relative path to the current\n> > working directory and not relative to $GIT_DIR.\n> \n> Well, it could be that _that_ handling of the environment\n> variable is what needs to be fixed.\n\nYou're right,  this seems to be much better.\n\nI just thought that GIT_WORK_DIR should be relative to the current\nworking directory because it's more intuitive, e.g.\n\n    $ git --git-dir=/path/to/repo.git --work-dir=../.. add a\n\nwhere ../.. matches the path to the toplevel working directory from\ncwd.  But this definitely is annoying when changing directories.\n\nI'll go and fix this.  Do you prefer an amended patch or just a patch\non top?\n"},{"id":"36942","messageId":"20070312191812.GA29327@moooo.ath.cx","threadId":"7191","inReplyTo":"20070312180837.GA22701@moooo.ath.cx","subject":"[PATCH] always interpret GIT_WORK_DIR relative to $GIT_DIR","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-12T19:18:12Z","receivedAt":"2007-03-12T19:18:12Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Signed-off-by: Matthias Lederhofer <matled@gmx.net>\n---\n setup.c |   39 +++++++++++++++++++++++----------------\n 1 files changed, 23 insertions(+), 16 deletions(-)\n\ndiff --git a/setup.c b/setup.c\nindex a8b9fae..f8c020e 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -192,16 +192,36 @@ int is_inside_git_dir(void)\n \treturn inside_git_dir;\n }\n \n+static int stat_relative(const char *base, const char *path, struct stat *st)\n+{\n+\tchar cwd[PATH_MAX];\n+\tint ret;\n+\n+\tif (path[0] != '/') {\n+\t\tif (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')\n+\t\t\tdie(\"Unable to read current working directory\");\n+\t\tif (chdir(base))\n+\t\t\tdie(\"Cannot change directory to '%s'\", base);\n+\t}\n+\n+\tret = stat(path, st);\n+\n+\tif (path[0] != '/' && chdir(cwd))\n+\t\tdie(\"Cannot come back to cwd\");\n+\n+\treturn ret;\n+}\n+\n static int stat_git_work_dir(struct stat *st)\n {\n-\tchar workdir[PATH_MAX], cwd[PATH_MAX];\n+\tchar workdir[PATH_MAX];\n \tconst char *gitdir = getenv(GIT_DIR_ENVIRONMENT);\n \tconst char *gitwd = getenv(GIT_WORKING_DIR_ENVIRONMENT);\n \tint offset;\n \tFILE *fp;\n \n \tif (gitwd) {\n-\t\tif (!stat(gitwd, st))\n+\t\tif (!stat_relative(gitdir, gitwd, st))\n \t\t\treturn 1;\n \t\tdie(\"Unable to stat git working directory '%s'\", gitwd);\n \t}\n@@ -231,21 +251,8 @@ static int stat_git_work_dir(struct stat *st)\n \t\t--offset;\n \tworkdir[offset+1] = '\\0';\n \n-\t/* relative path: change to gitdir for stat */\n-\tif (workdir[0] != '/') {\n-\t\tif (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')\n-\t\t\tdie(\"Unable to read current working directory\");\n-\t\tif (chdir(gitdir))\n-\t\t\tdie(\"Cannot change directory to '%s'\", gitdir);\n-\t}\n-\n-\tif (stat(workdir, st))\n+\tif (stat_relative(gitdir, workdir, st))\n \t\tdie(\"Unable to stat directory from GIT_DIR/workdir\");\n-\tif (!(st->st_mode & S_IFDIR))\n-\t\tdie(\"GIT_DIR/workdir does not point to a directory\");\n-\n-\tif (workdir[0] != '/' && chdir(cwd))\n-\t\tdie(\"Cannot come back to cwd\");\n \n \treturn 1;\n }\n-- \n1.5.0.3.1007.g7ff7\n"},{"id":"36943","messageId":"20070312192301.GB29327@moooo.ath.cx","threadId":"7191","inReplyTo":"20070312115350.GA15179@moooo.ath.cx","subject":"[PATCH(amend)] git-init: set up GIT_DIR/workdir if GIT_WORK_DIR is set","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-12T19:23:01Z","receivedAt":"2007-03-12T19:23:01Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Signed-off-by: Matthias Lederhofer <matled@gmx.net>\n---\nIt's much easier when $GIT_WORK_DIR is always interpreted relative to\n$GIT_DIR.\n---\n builtin-init-db.c |   14 +++++++++++++-\n 1 files changed, 13 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-init-db.c b/builtin-init-db.c\nindex 4df9fd0..8d0065c 100644\n--- a/builtin-init-db.c\n+++ b/builtin-init-db.c\n@@ -182,6 +182,7 @@ static int create_default_files(const char *git_dir, const char *template_path)\n \tchar repo_version_string[10];\n \tint reinit;\n \tint filemode;\n+\tconst char *gitwd = getenv(GIT_WORKING_DIR_ENVIRONMENT);\n \n \tif (len > sizeof(path)-50)\n \t\tdie(\"insane git directory %s\", git_dir);\n@@ -252,10 +253,21 @@ static int create_default_files(const char *git_dir, const char *template_path)\n \t}\n \tgit_config_set(\"core.filemode\", filemode ? \"true\" : \"false\");\n \n-\tif (is_bare_repository()) {\n+\tif (is_bare_repository() && !gitwd) {\n \t\tgit_config_set(\"core.bare\", \"true\");\n \t}\n \telse {\n+\t\tif (gitwd) {\n+\t\t\tFILE *fp = NULL;\n+\n+\t\t\tpath[len] = 0;\n+\t\t\tstrcpy(path + len, \"workdir\");\n+\t\t\tif (!(fp = fopen(path, \"w\")))\n+\t\t\t\tdie(\"Cannot open GIT_DIR/workdir\");\n+\t\t\tfprintf(fp, \"%s\\n\", gitwd);\n+\t\t\tfclose(fp);\n+\t\t}\n+\n \t\tgit_config_set(\"core.bare\", \"false\");\n \t\t/* allow template config file to override the default */\n \t\tif (log_all_ref_updates == -1)\n-- \n1.5.0.3.1007.g7ff7\n"},{"id":"36955","messageId":"20070312195348.GA30520@moooo.ath.cx","threadId":"7191","inReplyTo":"20070312191812.GA29327@moooo.ath.cx","subject":"[PATCH] GIT_WORK_DIR: documentation for relative path","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-12T19:53:48Z","receivedAt":"2007-03-12T19:53:48Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Signed-off-by: Matthias Lederhofer <matled@gmx.net>\n---\n Documentation/git.txt |   22 +++++++++++++---------\n 1 files changed, 13 insertions(+), 9 deletions(-)\n\ndiff --git a/Documentation/git.txt b/Documentation/git.txt\nindex d2f5d27..177adf5 100644\n--- a/Documentation/git.txt\n+++ b/Documentation/git.txt\n@@ -83,11 +83,13 @@ OPTIONS\n \tsetting the GIT_DIR environment variable.\n \n --work-dir=<path>::\n-\tSet the path to the toplevel working directory.  The value will\n-\tbe used only in combination with $GIT_DIR or '--git-dir'.\n-\tWithout this option git will assume that the current directory\n-\tis also the toplevel directory.  This can also be controlled by\n-\tsetting the GIT_WORK_DIR environment variable.\n+\tSet the path to the toplevel working directory.  If the path is\n+\trelative it is interpreted from $GIT_DIR, not the current\n+\tworking directory.  The value will be used only in combination\n+\twith $GIT_DIR or '--git-dir'.  Without this option git will\n+\tassume that the current working directory is also the toplevel\n+\tdirectory.  This can also be controlled by setting the\n+\tGIT_WORK_DIR environment variable.\n \n --bare::\n \tSame as --git-dir=`pwd`.\n@@ -334,10 +336,12 @@ git so take care if using Cogito etc.\n \tfor the base of the repository.\n \n 'GIT_WORK_DIR'::\n-\tSet the path to the toplevel working directory.  The value will\n-\tbe used only in combination with $GIT_DIR or '--git-dir'.\n-\tWithout this environment variable git will assume that the\n-\tcurrent directory is also the toplevel directory.\n+\tSet the path to the toplevel working directory.  If the path is\n+\trelative it is interpreted from $GIT_DIR, not the current\n+\tworking directory.  The value will be used only in combination\n+\twith $GIT_DIR or '--git-dir'.  Without this environment variable\n+\tgit will assume that the current working directory is also the\n+\ttoplevel directory.\n \n git Commits\n ~~~~~~~~~~~\n-- \n1.5.0.3.1007.g7ff7\n"},{"id":"36957","messageId":"7vird6qlbn.fsf@assigned-by-dhcp.cox.net","threadId":"7191","inReplyTo":"20070312180837.GA22701@moooo.ath.cx","subject":"Re: [PATCH] git-init: set up GIT_DIR/workdir if GIT_WORK_DIR is set","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-12T20:05:32Z","receivedAt":"2007-03-12T20:05:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthias Lederhofer <matled@gmx.net> writes:\n\n> I just thought that GIT_WORK_DIR should be relative to the current\n> working directory because it's more intuitive, e.g.\n>\n>     $ git --git-dir=/path/to/repo.git --work-dir=../.. add a\n>\n> where ../.. matches the path to the toplevel working directory from\n> cwd.  But this definitely is annoying when changing directories.\n\nNot so fast.  That was a trick suggestion, only meant to see if\nyou have thought through the issues, and you did not have to\nagree with me so quickly ;-).  What I was pointing out was\nmerely that specifying the top as a path relative to the cwd in\npermanent basis was not useful if you are going to cd around,\nwhich is a tautology.\n\nFor a one-shot thing, I would agree that being able to say \"I am\nin Documentation/howto directory of the whole thing, so I can\nname the top of my working tree as ../..\" is far more useful and\nnatural than having to say \"ehhhh, what is the top of the\nworking tree relative to my repository???\".  If it is not a\none-shot thing and the user expects to cd around, then:\n\n\t$ GIT_WORK_DIR=$(pwd)/../..; export GIT_WORK_DIR\n\t$ git foo ...; git bar ...;\n\nwould be more natural, so I do not expect the semantics of\nrelative path would be a big issue in reality, as long as we\nmake it clear that it is relative to cwd.\n\nBy the way, I do not find your command line example intuitive at\nall, whether the --work-dir= parameter is relative or absolute.\nDo you honestry expect that loooong command line is something\npeople would use in real life?\n\nWith $GIT_DIR/workdir support, I would expect that people would\ndo (if what is done is only to add one file and nothing else):\n\n\t$ GIT_DIR=/path/to/repo.git git add a\n\nAnd without $GIT_DIR/workdir support:\n\n\t$ GIT_DIR=/path/to/repo.git GIT_WORK_DIR=../.. git add a\n\nIf the user is going to work in the working tree for extended\nperiod of time, cd'ing around and running multiple git commands:\n\n\t$ GIT_DIR=/path/to/repo.git; export GIT_DIR\n        $ git foo ; git bar ; cd subdir ; git baz ; ...\n\nAnd without $GIT_DIR/workdir support, perhaps the user would do:\n\n\t$ GIT_DIR=/path/to/repo.git; export GIT_DIR\n\t$ GIT_WORK_DIR=$(pwd)/../..; export GIT_WORK_DIR\n        $ git foo ; git bar ; cd subdir ; git baz ; ...\n\nWhat I am getting at is that I personally feel that --git-dir=\noption is already an unnecessary redundancy that is there only\nto confuse new people by having more than one way to do the same\nthing, and --work-dir= option seems to be only adding to the\nsame confusion.  Do we really want that as an option?\n"},{"id":"36959","messageId":"20070312204041.GA31018@moooo.ath.cx","threadId":"7191","inReplyTo":"7vird6qlbn.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-init: set up GIT_DIR/workdir if GIT_WORK_DIR is set","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-12T20:40:41Z","receivedAt":"2007-03-12T20:40:41Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> Matthias Lederhofer <matled@gmx.net> writes:\n> \n> > I just thought that GIT_WORK_DIR should be relative to the current\n> > working directory because it's more intuitive, e.g.\n> >\n> >     $ git --git-dir=/path/to/repo.git --work-dir=../.. add a\n> >\n> > where ../.. matches the path to the toplevel working directory from\n> > cwd.  But this definitely is annoying when changing directories.\n> \n> Not so fast.  That was a trick suggestion, only meant to see if\n> you have thought through the issues, and you did not have to\n> agree with me so quickly ;-).\n\nWell, I have no strong feelings for either handling because I'll\nprobably always use `pwd`/relative/path anyway.\n\nIs there anything more to this decision than this?\n\nGIT_WORK_DIR relative to cwd:\n    git --work-dir <path> [..] is more intuitive\n\nGIT_WORK_DIR relative to $GIT_DIR:\n    $GIT_DIR/workdir and $GIT_WORK_DIR are interpreted exactly the\n    same way, which primarily makes it easier to implement git init\n    with --work-dir :-)\n\n> By the way, I do not find your command line example intuitive at\n> all, whether the --work-dir= parameter is relative or absolute.\n> Do you honestry expect that loooong command line is something\n> people would use in real life?\n\nFor one-shot things I prefer --git-dir and --work-dir over\nGIT_DIR and GIT_WORK_DIR because they are lowercase and for\nGIT_WORK_DIR it's even shorter; and all the examples were one-shot\nthings (well, one used the same --git-dir twice).\n"},{"id":"37034","messageId":"20070313231004.GA15058@moooo.ath.cx","threadId":"7191","inReplyTo":"20070311212906.GA18208@moooo.ath.cx","subject":"[PATCH] core.workdir config variable","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-13T23:10:04Z","receivedAt":"2007-03-13T23:10:04Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"core.workdir is used as default value for $GIT_WORK_DIR\n\nSigned-off-by: Matthias Lederhofer <matled@gmx.net>\n---\nThis one replaces the 'use $GIT_DIR/workdir as working directory with\n$GIT_DIR' patch and uses core.workdir instead.  This patch gets\ncore.workdir only for setup.c from the configuration file.  Perhaps\nthis should be handled in git_default_config like most other core.*\nvariables.\n\nI just noticed that dying if the specified workdir is invalid can\ncause trouble too:\n\n    $ export GIT_DIR=/path/to/repository\n    $ git config core.workdir /non-existent\n    $ git config core.workdir ../workdir\n    fatal: Unable to stat git working directory '/non-existent'\n\nWorkaround is either to edit the file manually or do:\n\n    $ git --work-dir=. config core.workdir ../workdir\n\n---\n Documentation/config.txt |    4 +++\n setup.c                  |   53 +++++++++++++++++++++++++++++++++++++++++----\n 2 files changed, 52 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 5408dd6..663d82d 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -162,6 +162,10 @@ repository that ends in \"/.git\" is assumed to be not bare (bare =\n false), while all other repositories are assumed to be bare (bare\n = true).\n \n+core.workdir::\n+\tDirectory to be used as toplevel working directory when GIT_DIR\n+\tis set.  This can be overriden by GIT_WORK_DIR.\n+\n core.logAllRefUpdates::\n \tUpdates to a ref <ref> is logged to the file\n \t\"$GIT_DIR/logs/<ref>\", by appending the new and old\ndiff --git a/setup.c b/setup.c\nindex ebf628e..913c4b4 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -192,6 +192,53 @@ int is_inside_git_dir(void)\n \treturn inside_git_dir;\n }\n \n+static char **git_work_dir;\n+\n+static int git_workdir_config(const char *var, const char *value)\n+{\n+\tif (!strcmp(var, \"core.workdir\")) {\n+\t\tstrlcpy(value, *git_work_dir, PATH_MAX);\n+\t}\n+\treturn 0;\n+}\n+\n+static int stat_git_work_dir(struct stat *st)\n+{\n+\tchar workdir[PATH_MAX], cwd[PATH_MAX];\n+\tconst char *gitdir = getenv(GIT_DIR_ENVIRONMENT);\n+\tconst char *gitwd = getenv(GIT_WORKING_DIR_ENVIRONMENT);\n+\n+\tif (gitwd) {\n+\t\tif (!stat(gitwd, st))\n+\t\t\treturn 1;\n+\t\tdie(\"Unable to stat git working directory '%s'\", gitwd);\n+\t}\n+\n+\t/* get workdir from config */\n+\tworkdir[0] = '\\0';\n+\tgit_work_dir = workdir;\n+\tgit_config(git_workdir_config);\n+\tgit_workdir_config = NULL;\n+\tif (!workdir[0])\n+\t\treturn 0;\n+\n+\t/* relative path: change to gitdir for stat */\n+\tif (workdir[0] != '/') {\n+\t\tif (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')\n+\t\t\tdie(\"Unable to read current working directory\");\n+\t\tif (chdir(gitdir))\n+\t\t\tdie(\"Cannot change directory to '%s'\", gitdir);\n+\t}\n+\n+\tif (stat(workdir, st))\n+\t\tdie(\"Unable to stat git working directory '%s'\", workdir);\n+\n+\tif (workdir[0] != '/' && chdir(cwd))\n+\t\tdie(\"Cannot come back to cwd\");\n+\n+\treturn 1;\n+}\n+\n int has_working_directory = -1;\n \n const char *setup_git_directory_gently(int *nongit_ok)\n@@ -203,7 +250,6 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \tgitdirenv = getenv(GIT_DIR_ENVIRONMENT);\n \tif (gitdirenv) {\n \t\tstruct stat st, st_work, st_git;\n-\t\tconst char *gitwd;\n \t\tchar *prefix;\n \t\tchar c;\n \t\tint len;\n@@ -219,11 +265,8 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\t}\n \n \t\t/* check for working directory */\n-\t\tgitwd = getenv(GIT_WORKING_DIR_ENVIRONMENT);\n-\t\tif (!gitwd)\n+\t\tif (!stat_git_work_dir(&st_work))\n \t\t\treturn NULL;\n-\t\tif (stat(gitwd, &st_work))\n-\t\t\tdie(\"Unable to stat git working directory '%s'\", gitwd);\n \t\tif (inside_git_dir == -1 && stat(gitdirenv, &st_git))\n \t\t\tdie(\"Unable to stat git directory\");\n \t\tif (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')\n-- \n1.5.0.3.970.ge984-dirty\n"},{"id":"37036","messageId":"20070313235755.GA25013@moooo.ath.cx","threadId":"7191","inReplyTo":"20070313231004.GA15058@moooo.ath.cx","subject":"[PATCH(amend)] core.workdir config variable","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2007-03-13T23:57:55Z","receivedAt":"2007-03-13T23:57:55Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"core.workdir is used as default value for $GIT_WORK_DIR\n\nSigned-off-by: Matthias Lederhofer <matled@gmx.net>\n---\nSorry, the last one was totally broken.  Testing without recompiling\nisn't good..\n---\n Documentation/config.txt |    4 +++\n setup.c                  |   53 +++++++++++++++++++++++++++++++++++++++++----\n 2 files changed, 52 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 5408dd6..663d82d 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -162,6 +162,10 @@ repository that ends in \"/.git\" is assumed to be not bare (bare =\n false), while all other repositories are assumed to be bare (bare\n = true).\n \n+core.workdir::\n+\tDirectory to be used as toplevel working directory when GIT_DIR\n+\tis set.  This can be overriden by GIT_WORK_DIR.\n+\n core.logAllRefUpdates::\n \tUpdates to a ref <ref> is logged to the file\n \t\"$GIT_DIR/logs/<ref>\", by appending the new and old\ndiff --git a/setup.c b/setup.c\nindex ebf628e..208124f 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -192,6 +192,53 @@ int is_inside_git_dir(void)\n \treturn inside_git_dir;\n }\n \n+static char *git_work_dir;\n+\n+static int git_workdir_config(const char *var, const char *value)\n+{\n+\tif (!strcmp(var, \"core.workdir\")) {\n+\t\tstrlcpy(git_work_dir, value, PATH_MAX);\n+\t}\n+\treturn 0;\n+}\n+\n+static int stat_git_work_dir(struct stat *st)\n+{\n+\tchar workdir[PATH_MAX], cwd[PATH_MAX];\n+\tconst char *gitdir = getenv(GIT_DIR_ENVIRONMENT);\n+\tconst char *gitwd = getenv(GIT_WORKING_DIR_ENVIRONMENT);\n+\n+\tif (gitwd) {\n+\t\tif (!stat(gitwd, st))\n+\t\t\treturn 1;\n+\t\tdie(\"Unable to stat git working directory '%s'\", gitwd);\n+\t}\n+\n+\t/* get workdir from config */\n+\tworkdir[0] = '\\0';\n+\tgit_work_dir = workdir;\n+\tgit_config(git_workdir_config);\n+\tgit_work_dir = NULL;\n+\tif (!workdir[0])\n+\t\treturn 0;\n+\n+\t/* relative path: change to gitdir for stat */\n+\tif (workdir[0] != '/') {\n+\t\tif (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')\n+\t\t\tdie(\"Unable to read current working directory\");\n+\t\tif (chdir(gitdir))\n+\t\t\tdie(\"Cannot change directory to '%s'\", gitdir);\n+\t}\n+\n+\tif (stat(workdir, st))\n+\t\tdie(\"Unable to stat git working directory '%s'\", workdir);\n+\n+\tif (workdir[0] != '/' && chdir(cwd))\n+\t\tdie(\"Cannot come back to cwd\");\n+\n+\treturn 1;\n+}\n+\n int has_working_directory = -1;\n \n const char *setup_git_directory_gently(int *nongit_ok)\n@@ -203,7 +250,6 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \tgitdirenv = getenv(GIT_DIR_ENVIRONMENT);\n \tif (gitdirenv) {\n \t\tstruct stat st, st_work, st_git;\n-\t\tconst char *gitwd;\n \t\tchar *prefix;\n \t\tchar c;\n \t\tint len;\n@@ -219,11 +265,8 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\t}\n \n \t\t/* check for working directory */\n-\t\tgitwd = getenv(GIT_WORKING_DIR_ENVIRONMENT);\n-\t\tif (!gitwd)\n+\t\tif (!stat_git_work_dir(&st_work))\n \t\t\treturn NULL;\n-\t\tif (stat(gitwd, &st_work))\n-\t\t\tdie(\"Unable to stat git working directory '%s'\", gitwd);\n \t\tif (inside_git_dir == -1 && stat(gitdirenv, &st_git))\n \t\t\tdie(\"Unable to stat git directory\");\n \t\tif (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')\n-- \ngitgui.0.6.3.g4bccd\n"},{"id":"37053","messageId":"20070314060145.GB20978@spearce.org","threadId":"7191","inReplyTo":"20070313235755.GA25013@moooo.ath.cx","subject":"Re: [PATCH(amend)] core.workdir config variable","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-03-14T06:01:45Z","receivedAt":"2007-03-14T06:01:45Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Matthias Lederhofer <matled@gmx.net> wrote:\n> core.workdir is used as default value for $GIT_WORK_DIR\n...\n> -- \n> gitgui.0.6.3.g4bccd\n\nReally?  gitgui generates emails now?  ;-)\n\nMatthias, your git binaries were built with an older (pre 1.5.0)\ngit-describe in the path.  This caused the version number to be\nincorrectly determined, due to an old bug in git-describe.\n\nRecompiling with your \"gitgui.0.6.3\" git-describe should get\nthe correct version number, as that is most definately after the\ngit-describe bug fix.\n\n-- \nShawn.\n"},{"id":"37060","messageId":"7vfy88fepp.fsf@assigned-by-dhcp.cox.net","threadId":"7191","inReplyTo":"20070314060145.GB20978@spearce.org","subject":"Re: [PATCH(amend)] core.workdir config variable","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-14T07:48:18Z","receivedAt":"2007-03-14T07:48:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n> Matthias Lederhofer <matled@gmx.net> wrote:\n>> core.workdir is used as default value for $GIT_WORK_DIR\n> ...\n>> -- \n>> gitgui.0.6.3.g4bccd\n>\n> Really?  gitgui generates emails now?  ;-)\n\nIt might not be a bad idea actually.  You let people make\ncommits.  Why not let them pick commits, run format-patch and\ndrive send-email for them from the UI?\n"},{"id":"37087","messageId":"20070314142002.GC22034@spearce.org","threadId":"7191","inReplyTo":"7vfy88fepp.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH(amend)] core.workdir config variable","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-03-14T14:20:02Z","receivedAt":"2007-03-14T14:20:02Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> \"Shawn O. Pearce\" <spearce@spearce.org> writes:\n> \n> > Matthias Lederhofer <matled@gmx.net> wrote:\n> >> core.workdir is used as default value for $GIT_WORK_DIR\n> > ...\n> >> -- \n> >> gitgui.0.6.3.g4bccd\n> >\n> > Really?  gitgui generates emails now?  ;-)\n> \n> It might not be a bad idea actually.  You let people make\n> commits.  Why not let them pick commits, run format-patch and\n> drive send-email for them from the UI?\n\nNo, its not.  There's a lot of stuff I want to put into there;\nthat just happens to be one of them.  ;-)\n\n-- \nShawn.\n"},{"id":"38462","messageId":"200704010842.53042.andyparkins@gmail.com","threadId":"7191","inReplyTo":"7vodmzv6dq.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC] introduce GIT_WORK_DIR environment variable","fromName":"Andy Parkins","fromEmail":"andyparkins@gmail.com","sentAt":"2007-04-01T07:42:50Z","receivedAt":"2007-04-01T07:42:50Z","isPatch":false,"sender":{"key":"andyparkins@gmail.com","avatar":null},"body":"On Sunday 2007, March 11, Junio C Hamano wrote:\n\n> That is a good example usage schenario; we would need to think\n> about what to do with .gitignore (and .gitattributes if we will\n> have that in-tree), though.\n\nWhile it's not solveable yet; if git gets gitattributes support, then \nit's easy.  As long as there is a way of specifying attributes in the \nconfig (which I'm sure there will be), in the music repository you \nwould have (syntax being made up on the spot)\n\n[attribute \"gitattributesfile\"]\n  path = .gitattribute-music\n[attribute \"gitignorefile\"]\n  path = .gitignore-music\n\nThen in the config repository:\n\n[attribute \"gitattributesfile\"]\n  path = .gitattribute-config\n[attribute \"gitignorefile\"]\n  path = .gitignore-config\n\n\n\nAndy\n-- \nDr Andy Parkins, M Eng (hons), MIET\nandyparkins@gmail.com\n"}]}