{"thread":{"id":"11912","subject":"[PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","startedAt":"2008-02-06T10:26:08Z","lastAt":"2008-02-08T12:05:08Z","messageCount":13,"participants":["Jeff King","Johannes Sixt","Junio C Hamano","Jay Soffian","Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"67649","messageId":"20080206102608.GA1007@coredump.intra.peff.net","threadId":"11912","inReplyTo":null,"subject":"[PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-02-06T10:26:08Z","receivedAt":"2008-02-06T10:26:08Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"In setup_git_directory_gently, we have a special rule\nthat says \"if GIT_DIR is set but GIT_WORK_TREE is not, then\nuse the current working directory as the work tree.\" This is\nthe intended behavior for the user perspective.\n\nHowever, setup_git_directory_gently sets GIT_DIR itself,\nmeaning that further setups (either because we are executing\na command via alias, or in a subprocess) will see the\nnon-existent GIT_WORK_TREE and assume we fall into the\n\"current working directory is the working tree\" codepath.\n\nInstead, we now use a special value of GIT_WORK_TREE to\nindicate that we have already checked for a worktree and\nthat there isn't one, setting it when we set GIT_DIR and\nchecking for it in the special case path.\n\nThe special value is a blank GIT_WORK_TREE; it could be any\nvalue, but this should not conflict with any user values\n(and as a bonus, you can now tell git \"I don't have a work\ntree\" with \"GIT_WORK_TREE= git\", though I suspect the use\ncase for that is limited).\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nOn Sun, Feb 03, 2008 at 02:59:13AM -0800, Junio C Hamano wrote:\n\n> * \"[alias] st = status\" and \"cd .git && git st\" (Jeff King)\n\nThis turned out to be easier than expected. Note that this patch causes\nt1500 to fail; however, the test is at fault, and is already fixed in\nthe series I just sent out.\n\n environment.c                 |    9 +++++++--\n setup.c                       |    1 +\n t/t1502-worktree-semantics.sh |   20 ++++++++++++++++++++\n 3 files changed, 28 insertions(+), 2 deletions(-)\n create mode 100755 t/t1502-worktree-semantics.sh\n\ndiff --git a/environment.c b/environment.c\nindex 18a1c4e..38e8dff 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -90,8 +90,13 @@ const char *get_git_work_tree(void)\n \t\t\t/* make_absolute_path also normalizes the path */\n \t\t\tif (work_tree && !is_absolute_path(work_tree))\n \t\t\t\twork_tree = xstrdup(make_absolute_path(git_path(work_tree)));\n-\t\t} else if (work_tree)\n-\t\t\twork_tree = xstrdup(make_absolute_path(work_tree));\n+\t\t} else if (work_tree) {\n+\t\t\tif (*work_tree)\n+\t\t\t\twork_tree = xstrdup(\n+\t\t\t\t\t\tmake_absolute_path(work_tree));\n+\t\t\telse\n+\t\t\t\twork_tree = NULL;\n+\t\t}\n \t\tinitialized = 1;\n \t\tif (work_tree)\n \t\t\tis_bare_repository_cfg = 0;\ndiff --git a/setup.c b/setup.c\nindex adede16..85c0b48 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -309,6 +309,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\t\tif (!work_tree_env)\n \t\t\t\tinside_work_tree = 0;\n \t\t\tsetenv(GIT_DIR_ENVIRONMENT, \".\", 1);\n+\t\t\tsetenv(GIT_WORK_TREE_ENVIRONMENT, \"\", 1);\n \t\t\tcheck_repository_format_gently(nongit_ok);\n \t\t\treturn NULL;\n \t\t}\ndiff --git a/t/t1502-worktree-semantics.sh b/t/t1502-worktree-semantics.sh\nnew file mode 100755\nindex 0000000..fbc355b\n--- /dev/null\n+++ b/t/t1502-worktree-semantics.sh\n@@ -0,0 +1,20 @@\n+#!/bin/sh\n+\n+test_description='semantics of GIT_WORK_TREE variable'\n+. ./test-lib.sh\n+\n+test_expect_success 'setup working tree' 'touch file'\n+\n+test_expect_success 'setup alias' 'git config alias.a add'\n+\n+test_expect_success 'blank GIT_WORK_TREE disallows work-tree commands' '\n+\t! GIT_WORK_TREE= git add .\n+'\n+\n+test_expect_success 'alias inside working tree works' 'git a .'\n+\n+test_expect_success 'alias inside .git complains about working tree' '\n+\tcd .git && ! GIT_CONFIG=config git a .\n+'\n+\n+test_done\n-- \n1.5.4.26.g301fb\n"},{"id":"67653","messageId":"47A98F07.4000402@viscovery.net","threadId":"11912","inReplyTo":"20080206102608.GA1007@coredump.intra.peff.net","subject":"Re: [PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-02-06T10:42:15Z","receivedAt":"2008-02-06T10:42:15Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Jeff King schrieb:\n> In setup_git_directory_gently, we have a special rule\n> that says \"if GIT_DIR is set but GIT_WORK_TREE is not, then\n> use the current working directory as the work tree.\" This is\n> the intended behavior for the user perspective.\n> \n> However, setup_git_directory_gently sets GIT_DIR itself,\n> meaning that further setups (either because we are executing\n> a command via alias, or in a subprocess) will see the\n> non-existent GIT_WORK_TREE and assume we fall into the\n> \"current working directory is the working tree\" codepath.\n> \n> Instead, we now use a special value of GIT_WORK_TREE to\n> indicate that we have already checked for a worktree and\n> that there isn't one, setting it when we set GIT_DIR and\n> checking for it in the special case path.\n> \n> The special value is a blank GIT_WORK_TREE; it could be any\n> value, but this should not conflict with any user values\n> (and as a bonus, you can now tell git \"I don't have a work\n> tree\" with \"GIT_WORK_TREE= git\", though I suspect the use\n> case for that is limited).\n\nHrm. Unfortunately, on Windows there is no such thing as an empty\nenvironment string. setenv(x, \"\") *removes* the environment variable.\n\n-- Hannes\n"},{"id":"67655","messageId":"20080206110131.GA4167@coredump.intra.peff.net","threadId":"11912","inReplyTo":"47A98F07.4000402@viscovery.net","subject":"Re: [PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-02-06T11:01:32Z","receivedAt":"2008-02-06T11:01:32Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Feb 06, 2008 at 11:42:15AM +0100, Johannes Sixt wrote:\n\n> > The special value is a blank GIT_WORK_TREE; it could be any\n> > value, but this should not conflict with any user values\n> > (and as a bonus, you can now tell git \"I don't have a work\n> > tree\" with \"GIT_WORK_TREE= git\", though I suspect the use\n> > case for that is limited).\n> \n> Hrm. Unfortunately, on Windows there is no such thing as an empty\n> environment string. setenv(x, \"\") *removes* the environment variable.\n\nBleh. Maybe \"GIT_WORK_TREE=:\"? It doesn't make sense by itself since we\ndon't try to execute the contents of GIT_WORK_TREE, but it's unlikely to\nbe used by a user, and I believe there was recent talk of making\n\"GIT_EDITOR=:\" work.\n\nThe other option is setting\n\n  GIT_MAGICALLY_SET_GIT_DIR_SO_DONT_ACT_LIKE_THE_USER_DID=1\n\nbut I was hoping to avoid that.\n\n-Peff\n"},{"id":"67710","messageId":"7v4pclvmae.fsf@gitster.siamese.dyndns.org","threadId":"11912","inReplyTo":"20080206110131.GA4167@coredump.intra.peff.net","subject":"Re: [PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-02-06T20:54:01Z","receivedAt":"2008-02-06T20:54:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Wed, Feb 06, 2008 at 11:42:15AM +0100, Johannes Sixt wrote:\n>\n>> > The special value is a blank GIT_WORK_TREE; it could be any\n>> > value, but this should not conflict with any user values\n>> > (and as a bonus, you can now tell git \"I don't have a work\n>> > tree\" with \"GIT_WORK_TREE= git\", though I suspect the use\n>> > case for that is limited).\n>> \n>> Hrm. Unfortunately, on Windows there is no such thing as an empty\n>> environment string. setenv(x, \"\") *removes* the environment variable.\n>\n> Bleh. Maybe \"GIT_WORK_TREE=:\"? It doesn't make sense by itself since we\n> don't try to execute the contents of GIT_WORK_TREE, but it's unlikely to\n> be used by a user, and I believe there was recent talk of making\n> \"GIT_EDITOR=:\" work.\n>\n> The other option is setting\n>\n>   GIT_MAGICALLY_SET_GIT_DIR_SO_DONT_ACT_LIKE_THE_USER_DID=1\n>\n> but I was hoping to avoid that.\n\nYuck.  Let's then try your original (slightly redundant) one.\n"},{"id":"67711","messageId":"7vwsphu7gr.fsf@gitster.siamese.dyndns.org","threadId":"11912","inReplyTo":"7v4pclvmae.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-02-06T20:59:32Z","receivedAt":"2008-02-06T20:59:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n>> The other option is setting\n>>\n>>   GIT_MAGICALLY_SET_GIT_DIR_SO_DONT_ACT_LIKE_THE_USER_DID=1\n>>\n>> but I was hoping to avoid that.\n>\n> Yuck.  Let's then try your original (slightly redundant) one.\n\nOops, scratch that.  I was confused.\n\nI do not like the magic GIT_WORK_TREE=: which is simply\nillogical.  GIT_EDITOR=: made perfect sense (\":\" is actually a\ncommand that succeeds without doing anything), but \":\" does not\nhave anything to do with \"there is no such path\".\n\nI was tempted to suggest GIT_WORK_TREE=/dev/null because that is\nwhat \"diff\" uses to mark \"this does not even exist\", but that\nfeels dirty.\n"},{"id":"67750","messageId":"20080207051317.GA32296@sigill.intra.peff.net","threadId":"11912","inReplyTo":"7vwsphu7gr.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-02-07T05:13:18Z","receivedAt":"2008-02-07T05:13:18Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Feb 06, 2008 at 12:59:32PM -0800, Junio C Hamano wrote:\n\n> I do not like the magic GIT_WORK_TREE=: which is simply\n> illogical.  GIT_EDITOR=: made perfect sense (\":\" is actually a\n> command that succeeds without doing anything), but \":\" does not\n> have anything to do with \"there is no such path\".\n\nNo, it doesn't, but they are both no-ops. Sort of. I agree the reasoning\nis stretched, but I think we are just going to have to choose _some_\narbitrary value.\n\nUnless you want to switch it to a \"git set GIT_DIR automatically,\nso don't pretend the user set it\" flag variable.\n\n> I was tempted to suggest GIT_WORK_TREE=/dev/null because that is\n> what \"diff\" uses to mark \"this does not even exist\", but that\n> feels dirty.\n\nIt feels dirty to me, too. I would rather choose something that doesn't\neven look like a path. I think GIT_WORK_TREE=\" \" is too ugly, too.\n\nAlso, having just looked at the '.git-file' code, it does the same thing\n(setting GIT_DIR even though the user didn't explicitly ask for it), so\nit will need a similar fix. Which makes me lean towards just setting a\n\"we set this behind the user's back\" flag, since that code won't even\nhave anything to do with the worktree.\n\nIn fact, the more I think about it, that makes sense. WORK_TREE munging\njust happens to be the only special behavior right now that depends on\nwhether the user manually set GIT_DIR. But what we really want to\ncommunicate to later code is not \"I have corrected this particular\nmunge\" but \"don't run any special behavior as a result of this variable\nbeing set.\"\n\n-Peff\n"},{"id":"67758","messageId":"76718490802062313jdbd0e84xc9f36d703bb86c44@mail.gmail.com","threadId":"11912","inReplyTo":"20080207051317.GA32296@sigill.intra.peff.net","subject":"Re: [PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","fromName":"Jay Soffian","fromEmail":"jaysoffian+git@gmail.com","sentAt":"2008-02-07T07:13:39Z","receivedAt":"2008-02-07T07:13:39Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Feb 7, 2008 12:13 AM, Jeff King <peff@peff.net> wrote:\n>\n> On Wed, Feb 06, 2008 at 12:59:32PM -0800, Junio C Hamano wrote:\n> >\n> > I was tempted to suggest GIT_WORK_TREE=/dev/null because that is\n> > what \"diff\" uses to mark \"this does not even exist\", but that\n> > feels dirty.\n>\n> It feels dirty to me, too. I would rather choose something that doesn't\n> even look like a path. I think GIT_WORK_TREE=\" \" is too ugly, too.\n\nIs using something like \"__GIT_WORK_TREE_NOT_SET__\" that terrible?\n\nj.\n"},{"id":"67771","messageId":"7vmyqdnndh.fsf@gitster.siamese.dyndns.org","threadId":"11912","inReplyTo":"20080207051317.GA32296@sigill.intra.peff.net","subject":"Re: [PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-02-07T09:10:02Z","receivedAt":"2008-02-07T09:10:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> In fact, the more I think about it, that makes sense. WORK_TREE munging\n> just happens to be the only special behavior right now that depends on\n> whether the user manually set GIT_DIR. But what we really want to\n> communicate to later code is not \"I have corrected this particular\n> munge\" but \"don't run any special behavior as a result of this variable\n> being set.\"\n\nYeah, that makes sense.\n"},{"id":"67785","messageId":"alpine.LSU.1.00.0802071231540.8543@racer.site","threadId":"11912","inReplyTo":"76718490802062313jdbd0e84xc9f36d703bb86c44@mail.gmail.com","subject":"Re: [PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-02-07T12:33:16Z","receivedAt":"2008-02-07T12:33:16Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 7 Feb 2008, Jay Soffian wrote:\n\n> On Feb 7, 2008 12:13 AM, Jeff King <peff@peff.net> wrote:\n> >\n> > On Wed, Feb 06, 2008 at 12:59:32PM -0800, Junio C Hamano wrote:\n> > >\n> > > I was tempted to suggest GIT_WORK_TREE=/dev/null because that is\n> > > what \"diff\" uses to mark \"this does not even exist\", but that\n> > > feels dirty.\n> >\n> > It feels dirty to me, too. I would rather choose something that doesn't\n> > even look like a path. I think GIT_WORK_TREE=\" \" is too ugly, too.\n> \n> Is using something like \"__GIT_WORK_TREE_NOT_SET__\" that terrible?\n\nYes.  First: it looks more like a C constant than a proper environment \nvariable.  Second: what to do _sanely_, when both GIT_WORK_TREE and \nGIT_WORK_TREE_NOT_SET are true?\n\nOf course, you could argue that one should override the other.  But the \nconsequence will be user errors that could be prevented, thus it is a \ndesign error.\n\nCiao,\nDscho\n"},{"id":"67838","messageId":"76718490802071006j9eaa4bctedc18f4a62e2b91c@mail.gmail.com","threadId":"11912","inReplyTo":"alpine.LSU.1.00.0802071231540.8543@racer.site","subject":"Re: [PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","fromName":"Jay Soffian","fromEmail":"jaysoffian+git@gmail.com","sentAt":"2008-02-07T18:06:46Z","receivedAt":"2008-02-07T18:06:46Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Feb 7, 2008 7:33 AM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n>\n> On Thu, 7 Feb 2008, Jay Soffian wrote:\n>\n> > Is using something like \"__GIT_WORK_TREE_NOT_SET__\" that terrible?\n>\n> Yes.  First: it looks more like a C constant than a proper environment\n> variable.  Second: what to do _sanely_, when both GIT_WORK_TREE and\n> GIT_WORK_TREE_NOT_SET are true?\n\nSorry I was unclear. The discussion was about using a special value to\ndenote \"this is not set.\" So I meant something like:\n\nGIT_WORK_TREE=\"__GIT_WORK_TREE_NOT_SET\"\n\nThere may not be precedent in git, but it is not unusual to use a\ndouble-underbar prefix to denote private names and/or values. While in\ntheory a user could have a directory named as such, it would seem\nhighly unlikely. This looks a little cleaner to me than using \":\", \"\n\", or \"/dev/null\".\n\nj.\n"},{"id":"67846","messageId":"alpine.LSU.1.00.0802071855550.8543@racer.site","threadId":"11912","inReplyTo":"47A98F07.4000402@viscovery.net","subject":"Re: [PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-02-07T19:02:47Z","receivedAt":"2008-02-07T19:02:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 6 Feb 2008, Johannes Sixt wrote:\n\n> Jeff King schrieb:\n> > In setup_git_directory_gently, we have a special rule that says \"if \n> > GIT_DIR is set but GIT_WORK_TREE is not, then use the current working \n> > directory as the work tree.\" This is the intended behavior for the \n> > user perspective.\n> > \n> > However, setup_git_directory_gently sets GIT_DIR itself, meaning that \n> > further setups (either because we are executing a command via alias, \n> > or in a subprocess) will see the non-existent GIT_WORK_TREE and assume \n> > we fall into the \"current working directory is the working tree\" \n> > codepath.\n> > \n> > Instead, we now use a special value of GIT_WORK_TREE to indicate that \n> > we have already checked for a worktree and that there isn't one, \n> > setting it when we set GIT_DIR and checking for it in the special case \n> > path.\n> > \n> > The special value is a blank GIT_WORK_TREE; it could be any value, but \n> > this should not conflict with any user values (and as a bonus, you can \n> > now tell git \"I don't have a work tree\" with \"GIT_WORK_TREE= git\", \n> > though I suspect the use case for that is limited).\n> \n> Hrm. Unfortunately, on Windows there is no such thing as an empty \n> environment string. setenv(x, \"\") *removes* the environment variable.\n\nThat might be a shortcoming of our implementation of setenv():\n\n-- snip --\ncd /git\n\ncat > a1.c << EOF\n#include <stdio.h>\n#include \"compat/setenv.c\"\n#include \"compat/unsetenv.c\"\n\nstatic void p()\n{\n\tconst char *abc = getenv(\"ABC\");\n\tprintf(\"env ABC: %s\\n\", abc ? abc : \"(null)\");\n}\n\nint main()\n{\n\tp();\n\tgitsetenv(\"ABC\", \"Hello\", 1);\n\tp();\n\tgitsetenv(\"ABC\", \"\", 1);\n\tp();\n\tgitunsetenv(\"ABC\");\n\tp();\n\treturn 0;\n}\nEOF\n\ngcc -DNO_MMAP=1 -I. -Icompat -o a1.exe a1.c\n\nABC=\"\" ./a1.exe \n-- snap --\n\nThis will show\n\nenv ABC: \nenv ABC: Hello\nenv ABC: (null)\nenv ABC: (null)\n\nSo it seems that environment variables _can_ be empty.  Just our \nrelatively stupid implementation of setenv() does not do it.\n\nMaybe something like compat/unsetenv.c is needed in setenv(), too.\n\nCiao,\nDscho\n"},{"id":"67904","messageId":"47AC02F5.9080705@viscovery.net","threadId":"11912","inReplyTo":"alpine.LSU.1.00.0802071855550.8543@racer.site","subject":"Re: [PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-02-08T07:21:25Z","receivedAt":"2008-02-08T07:21:25Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Johannes Schindelin schrieb:\n> Hi,\n> \n> On Wed, 6 Feb 2008, Johannes Sixt wrote:\n> \n>> Jeff King schrieb:\n>>> In setup_git_directory_gently, we have a special rule that says \"if \n>>> GIT_DIR is set but GIT_WORK_TREE is not, then use the current working \n>>> directory as the work tree.\" This is the intended behavior for the \n>>> user perspective.\n>>>\n>>> However, setup_git_directory_gently sets GIT_DIR itself, meaning that \n>>> further setups (either because we are executing a command via alias, \n>>> or in a subprocess) will see the non-existent GIT_WORK_TREE and assume \n>>> we fall into the \"current working directory is the working tree\" \n>>> codepath.\n>>>\n>>> Instead, we now use a special value of GIT_WORK_TREE to indicate that \n>>> we have already checked for a worktree and that there isn't one, \n>>> setting it when we set GIT_DIR and checking for it in the special case \n>>> path.\n>>>\n>>> The special value is a blank GIT_WORK_TREE; it could be any value, but \n>>> this should not conflict with any user values (and as a bonus, you can \n>>> now tell git \"I don't have a work tree\" with \"GIT_WORK_TREE= git\", \n>>> though I suspect the use case for that is limited).\n>> Hrm. Unfortunately, on Windows there is no such thing as an empty \n>> environment string. setenv(x, \"\") *removes* the environment variable.\n> \n> That might be a shortcoming of our implementation of setenv():\n\nNo, it is not. It's Windows's putenv(), and it's even documented.\n\n> -- snip --\n> cd /git\n> \n> cat > a1.c << EOF\n> #include <stdio.h>\n> #include \"compat/setenv.c\"\n> #include \"compat/unsetenv.c\"\n> \n> static void p()\n> {\n> \tconst char *abc = getenv(\"ABC\");\n> \tprintf(\"env ABC: %s\\n\", abc ? abc : \"(null)\");\n> }\n> \n> int main()\n> {\n> \tp();\n> \tgitsetenv(\"ABC\", \"Hello\", 1);\n> \tp();\n> \tgitsetenv(\"ABC\", \"\", 1);\n> \tp();\n> \tgitunsetenv(\"ABC\");\n> \tp();\n> \treturn 0;\n> }\n> EOF\n> \n> gcc -DNO_MMAP=1 -I. -Icompat -o a1.exe a1.c\n> \n> ABC=\"\" ./a1.exe \n> -- snap --\n> \n> This will show\n> \n> env ABC: \n> env ABC: Hello\n> env ABC: (null)\n> env ABC: (null)\n> \n> So it seems that environment variables _can_ be empty.  Just our \n> relatively stupid implementation of setenv() does not do it.\n> \n> Maybe something like compat/unsetenv.c is needed in setenv(), too.\n\nThis only shows that, yes, variables _can_ be empty - if the setenv/putenv\nimplementation is \"sane\", like MSYS/bash's.\n\nThat said, we probably should modify environ directly in gitsetenv().\n\n-- Hannes\n"},{"id":"67937","messageId":"alpine.LSU.1.00.0802081203470.11591@racer.site","threadId":"11912","inReplyTo":"47AC02F5.9080705@viscovery.net","subject":"Re: [PATCH] allow setting GIT_WORK_TREE to \"no work tree\"","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-02-08T12:05:08Z","receivedAt":"2008-02-08T12:05:08Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 8 Feb 2008, Johannes Sixt wrote:\n\n> Johannes Schindelin schrieb:\n> \n> > On Wed, 6 Feb 2008, Johannes Sixt wrote:\n> > \n> >> Jeff King schrieb:\n> >>> In setup_git_directory_gently, we have a special rule that says \"if \n> >>> GIT_DIR is set but GIT_WORK_TREE is not, then use the current \n> >>> working directory as the work tree.\" This is the intended behavior \n> >>> for the user perspective.\n> >>>\n> >>> However, setup_git_directory_gently sets GIT_DIR itself, meaning \n> >>> that further setups (either because we are executing a command via \n> >>> alias, or in a subprocess) will see the non-existent GIT_WORK_TREE \n> >>> and assume we fall into the \"current working directory is the \n> >>> working tree\" codepath.\n> >>>\n> >>> Instead, we now use a special value of GIT_WORK_TREE to indicate \n> >>> that we have already checked for a worktree and that there isn't \n> >>> one, setting it when we set GIT_DIR and checking for it in the \n> >>> special case path.\n> >>>\n> >>> The special value is a blank GIT_WORK_TREE; it could be any value, \n> >>> but this should not conflict with any user values (and as a bonus, \n> >>> you can now tell git \"I don't have a work tree\" with \"GIT_WORK_TREE= \n> >>> git\", though I suspect the use case for that is limited).\n> >>\n> >> Hrm. Unfortunately, on Windows there is no such thing as an empty \n> >> environment string. setenv(x, \"\") *removes* the environment variable.\n> > \n> > That might be a shortcoming of our implementation of setenv():\n> \n> No, it is not. It's Windows's putenv(), and it's even documented.\n\nYes, that's what I said: our setenv() implementation uses putenv(), which \nintroduces that bug (setenv() is not supposed to unset variables, \nunsetenv() is).\n\n> That said, we probably should modify environ directly in gitsetenv().\n\nExactly.\n\nCiao,\nDscho\n"}]}