{"thread":{"id":"35444","subject":"git stash doesn't honor --work-tree or GIT_WORK_TREE","startedAt":"2013-11-30T19:04:03Z","lastAt":"2013-12-02T18:01:33Z","messageCount":7,"participants":["Aaron Brooks","Øystein Walle","Thomas Rast","Duy Nguyen","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"231311","messageId":"CABL6xpD9jvJWjUj0n+mgC419fGzA2N-b_yJho9zharCD6YTSiw@mail.gmail.com","threadId":"35444","inReplyTo":null,"subject":"git stash doesn't honor --work-tree or GIT_WORK_TREE","fromName":"Aaron Brooks","fromEmail":"aaron@brooks1.net","sentAt":"2013-11-30T19:04:03Z","receivedAt":"2013-11-30T19:04:03Z","isPatch":false,"sender":{"key":"aaron@brooks1.net","avatar":null},"body":"Unlike other commands, git stash doesn't work outside of the worktree,\neven when --work-tree is specified:\n\nabrooks@host:~/tmp$ mkdir test-repo\nabrooks@host:~/tmp$ cd !$\ncd test-repo\nabrooks@host:~/tmp/test-repo$ git init\nInitialized empty Git repository in /home/abrooks/tmp/test-repo/.git/\nabrooks@host:~/tmp/test-repo$ echo \"foo\" > foo.txt\nabrooks@host:~/tmp/test-repo$ git add foo.txt\nabrooks@host:~/tmp/test-repo$ git commit -m \"adding foo\"\n[master (root-commit) 9d0705e] adding foo\n 1 file changed, 1 insertion(+)\n create mode 100644 foo.txt\nabrooks@host:~/tmp/test-repo$ echo \"bar\" >> foo.txt\nabrooks@host:~/tmp/test-repo$ cd ..\nabrooks@host:~/tmp$ git --git-dir=./test-repo/.git --work-tree=./test-repo stash\nfatal: /usr/lib/git-core/git-stash cannot be used without a working tree.\nabrooks@host:~/tmp$ cd test-repo/\nabrooks@host:~/tmp/test-repo$ git stash\nSaved working directory and index state WIP on master: 9d0705e adding foo\nHEAD is now at 9d0705e adding foo\nabrooks@host:~/tmp/test-repo$ cd ../\nabrooks@host:~/tmp$ git --git-dir=./test-repo/.git\n--work-tree=./test-repo stash list\nfatal: /usr/lib/git-core/git-stash cannot be used without a working tree.\n\nThe same also does not work when setting GIT_DIR and GIT_WORK_TREE.\n\nAs a user, this seems wrong.\n\nIt looks like the \"require_work_tree\" function should check the\nenvironment variables in addition to the status of the PWD (via\ngit-rev-parse).\n\nHaving looked through several of the other git-*.sh scripts, I think\nother shell based git commands will have similar problems.\n\nThanks,\n\nAaron\n"},{"id":"231315","messageId":"loom.20131130T221443-682@post.gmane.org","threadId":"35444","inReplyTo":"CABL6xpD9jvJWjUj0n+mgC419fGzA2N-b_yJho9zharCD6YTSiw@mail.gmail.com","subject":"Re: git stash doesn't honor --work-tree or GIT_WORK_TREE","fromName":"Øystein Walle","fromEmail":"oystwa@gmail.com","sentAt":"2013-11-30T21:22:01Z","receivedAt":"2013-11-30T21:22:01Z","isPatch":false,"sender":{"key":"oystwa@gmail.com","avatar":"https://avatars.githubusercontent.com/u/794585?v=4"},"body":"Aaron Brooks <aaron <at> brooks1.net> writes:\n\n> \n> Unlike other commands, git stash doesn't work outside of the worktree,\n> even when --work-tree is specified:\n> \n> (...)\n> \n> It looks like the \"require_work_tree\" function should check the\n> environment variables in addition to the status of the PWD (via\n> git-rev-parse).\n> \n> Having looked through several of the other git-*.sh scripts, I think\n> other shell based git commands will have similar problems.\n> \n> Thanks,\n> \n> Aaron\n> \n\nThe environment variables are properly exported. I verified this by\nadding 'echo $GIT_WORK_TREE; echo $GIT_DIR' at the top of git-stash.sh.\nSo these should propagate to \"child gits\" just fine, and so it shouldn't\nbe necessary to test them explicitly.\n\nThe problem seems to be that git rev-parse --is-inside-work-tree does\nnot honor these. In fact it doesn't even honor --git-dir or --work-tree.\nJudging by the name this may be intentional.\n\nIn the mean time, if you are able to use Git 1.8.5, `git -C test-repo\nstash` will work just fine.\n\nØsse\n"},{"id":"231329","messageId":"874n6sddu7.fsf@thomasrast.ch","threadId":"35444","inReplyTo":"loom.20131130T221443-682@post.gmane.org","subject":"Re: git stash doesn't honor --work-tree or GIT_WORK_TREE","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-12-01T11:12:48Z","receivedAt":"2013-12-01T11:12:48Z","isPatch":false,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Øystein Walle <oystwa@gmail.com> writes:\n\n> Aaron Brooks <aaron <at> brooks1.net> writes:\n>\n>> Unlike other commands, git stash doesn't work outside of the worktree,\n>> even when --work-tree is specified:\n[...]\n> The environment variables are properly exported. I verified this by\n> adding 'echo $GIT_WORK_TREE; echo $GIT_DIR' at the top of git-stash.sh.\n> So these should propagate to \"child gits\" just fine, and so it shouldn't\n> be necessary to test them explicitly.\n>\n> The problem seems to be that git rev-parse --is-inside-work-tree does\n> not honor these. In fact it doesn't even honor --git-dir or --work-tree.\n> Judging by the name this may be intentional.\n\nThanks for investigating this.\n\nDuy, you are the expert on the worktree detection logic.  Do you know if\nthere is a reason for --is-inside-work-tree to not honor the\nGIT_WORK_TREE / GIT_DIR overrides?\n\n-- \nThomas Rast\ntr@thomasrast.ch\n"},{"id":"231330","messageId":"CACsJy8BFqqy8T1zwZd7Ly1-sAKGoxh0YfhFBgX6fBMTt_b5Dbw@mail.gmail.com","threadId":"35444","inReplyTo":"874n6sddu7.fsf@thomasrast.ch","subject":"Re: git stash doesn't honor --work-tree or GIT_WORK_TREE","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2013-12-01T11:50:14Z","receivedAt":"2013-12-01T11:50:14Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sun, Dec 1, 2013 at 6:12 PM, Thomas Rast <tr@thomasrast.ch> wrote:\n> Øystein Walle <oystwa@gmail.com> writes:\n>> The problem seems to be that git rev-parse --is-inside-work-tree does\n>> not honor these. In fact it doesn't even honor --git-dir or --work-tree.\n>> Judging by the name this may be intentional.\n>\n> Thanks for investigating this.\n>\n> Duy, you are the expert on the worktree detection logic.  Do you know if\n> there is a reason for --is-inside-work-tree to not honor the\n> GIT_WORK_TREE / GIT_DIR overrides?\n\nIt should. At the beginning of cmd_rev_parse(), setup_git_directory()\nis called, which will check and follow all GIT_* or their command line\nequivalent. I'll look into this some time later.\n-- \nDuy\n"},{"id":"231332","messageId":"87zjokpo47.fsf@linux-1gf2.Speedport_W723_V_Typ_A_1_00_098","threadId":"35444","inReplyTo":"CACsJy8BFqqy8T1zwZd7Ly1-sAKGoxh0YfhFBgX6fBMTt_b5Dbw@mail.gmail.com","subject":"Re: git stash doesn't honor --work-tree or GIT_WORK_TREE","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-12-01T15:50:00Z","receivedAt":"2013-12-01T15:50:00Z","isPatch":false,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Duy Nguyen <pclouds@gmail.com> writes:\n\n> On Sun, Dec 1, 2013 at 6:12 PM, Thomas Rast <tr@thomasrast.ch> wrote:\n>> Øystein Walle <oystwa@gmail.com> writes:\n>>> The problem seems to be that git rev-parse --is-inside-work-tree does\n>>> not honor these. In fact it doesn't even honor --git-dir or --work-tree.\n>>> Judging by the name this may be intentional.\n>>\n>> Thanks for investigating this.\n>>\n>> Duy, you are the expert on the worktree detection logic.  Do you know if\n>> there is a reason for --is-inside-work-tree to not honor the\n>> GIT_WORK_TREE / GIT_DIR overrides?\n>\n> It should. At the beginning of cmd_rev_parse(), setup_git_directory()\n> is called, which will check and follow all GIT_* or their command line\n> equivalent. I'll look into this some time later.\n\nHrm, I'm wrong, and it's not clear what to actually do in this case.\n--is-inside-work-tree works as claimed: if we can detect a git\nrepository and your current directory is inside it, you are \"inside a\nworktree\".\n\nThe problem here is that shell scripts that want to do something with a\nworktree tend to call require_work_tree in git-sh-setup:\n\nrequire_work_tree () {\n\ttest \"$(git rev-parse --is-inside-work-tree 2>/dev/null)\" = true ||\n\tdie \"fatal: $0 cannot be used without a working tree.\"\n}\n\nHowever, when an explicit GIT_WORK_TREE is in effect, that seems a bit\nsilly.  The _intent_ of that command is \"I need a worktree to work\nwith\".  But what it currently checks is something completely different,\nnamely \"am I _inside_ the worktree\".\n\n--show-cdup might be a better candidate, because it actually (and\ndespite what the docs suggest, sigh) shows the path to the worktree as\nwith --show-toplevel for the case where you are not --is-inside-work-tree.\n\nWhich means that the output --show-cdup is in fact not necessarily \"up\"\nfrom the worktree, but something you could cd to to get to its top.\n\nLong story short, this might work (and it passes tests):\n\n\ndiff --git i/git-sh-setup.sh w/git-sh-setup.sh\nindex 190a539..47c7f1d 100644\n--- i/git-sh-setup.sh\n+++ w/git-sh-setup.sh\n@@ -192,8 +192,12 @@ require_work_tree_exists () {\n }\n \n require_work_tree () {\n-\ttest \"$(git rev-parse --is-inside-work-tree 2>/dev/null)\" = true ||\n+\ttest \"$(git rev-parse --is-inside-work-tree 2>/dev/null)\" = true &&\n+\treturn 0\n+\tcdup=\"$(git rev-parse --show-cdup 2>/dev/null)\"\n+\ttest -z \"$cdup\" &&\n \tdie \"fatal: $0 cannot be used without a working tree.\"\n+\tcd \"$cdup\"\n }\n \n require_clean_work_tree () {\n\n\nBut it would give require_work_tree somewhat interesting and unintuitive\nside effects.\n\n-- \nThomas Rast\ntr@thomasrast.ch\n"},{"id":"231336","messageId":"loom.20131201T200904-80@post.gmane.org","threadId":"35444","inReplyTo":"CACsJy8BFqqy8T1zwZd7Ly1-sAKGoxh0YfhFBgX6fBMTt_b5Dbw@mail.gmail.com","subject":"Re: git stash doesn't honor --work-tree or GIT_WORK_TREE","fromName":"Øystein Walle","fromEmail":"oystwa@gmail.com","sentAt":"2013-12-01T19:12:30Z","receivedAt":"2013-12-01T19:12:30Z","isPatch":false,"sender":{"key":"oystwa@gmail.com","avatar":"https://avatars.githubusercontent.com/u/794585?v=4"},"body":"Duy Nguyen <pclouds <at> gmail.com> writes:\n\n> It should. At the beginning of cmd_rev_parse(), setup_git_directory()\n> is called, which will check and follow all GIT_* or their command line\n> equivalent. I'll look into this some time later.\n\nI think I was wrong and rev-parse --is-inside-work-tree *does* honor\nthem. It prints 'false'. If it hadn't honored them it would have printed\n\"fatal: Not a git repository (...)\".\n\nØsse\n"},{"id":"231377","messageId":"xmqqfvqbrv2a.fsf@gitster.dls.corp.google.com","threadId":"35444","inReplyTo":"87zjokpo47.fsf@linux-1gf2.Speedport_W723_V_Typ_A_1_00_098","subject":"Re: git stash doesn't honor --work-tree or GIT_WORK_TREE","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-12-02T18:01:33Z","receivedAt":"2013-12-02T18:01:33Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <tr@thomasrast.ch> writes:\n\n> The problem here is that shell scripts that want to do something with a\n> worktree tend to call require_work_tree in git-sh-setup:\n>\n> require_work_tree () {\n> \ttest \"$(git rev-parse --is-inside-work-tree 2>/dev/null)\" = true ||\n> \tdie \"fatal: $0 cannot be used without a working tree.\"\n> }\n>\n> However, when an explicit GIT_WORK_TREE is in effect, that seems a bit\n> silly.  The _intent_ of that command is \"I need a worktree to work\n> with\".  But what it currently checks is something completely different,\n> namely \"am I _inside_ the worktree\".\n\nCorrect.\n\nI have a few issues with the proposed \"solution\", though.\n\n - require_work_tree has always meant that \"This command has to be\n   run inside a working tree\".  That automatically implies that you\n   cannot be working with a bare repository but it is much stronger\n   than that.  You actually have to be inside one.\n\n - $GIT_WORK_TREE (and core.worktree) never meant \"I do not bother\n   to chdir there myself\".  More specifically, \"GIT_WORK_TREE=$there\n   git foo\" is not \"cd $there && git foo\".  It only means \"Because\n   the working tree may not have .git directory embedded in it, even\n   though you may be able to know where the .git repository is\n   (perhaps because I am telling you with $GIT_DIR), you may not be\n   able to tell where the top level of the working tree is---hence I\n   am telling you where it is\".\n\n - \"I do not bother to chdir there myself\" has long been treated as\n   a non-issue desire, but recently we added \"git -C $there\". We\n   should not conflate GIT_WORK_TREE, which is a discovery mechanism\n   for where the working tree is, with that.\n\n - Some command \"git foo\" may want to affect and/or look at only a\n   part of the working tree, and the $cwd is one way of specifying\n   that, e.g. \"cd doc && git grep foo\".  \"If a command that needs to\n   be run from somewhere in a working tree was run outside, error\n   out.\" has been the general design principle for commands that\n   interact with files in the working tree.\n\n   It may be OK to propose changing it to \"Instead of erroring out,\n   pretend as if the command were run from the top-level of the\n   working tree\", but there is an issue of what to do with the\n   command line arguments that are path-like.  For example,\n   should this command sequence:\n\n\tcd /tmp\n\tGIT_WORK_TREE=/var/tmp/work git foo -f inputFile\n\n   read from /tmp/inputFile, or /var/tmp/work/inputFile?  There may\n   be other \"unintuitive interactions with silent chdir\"; with \"git\n   -C $there\", we are very clear that chdir is the first thing that\n   happens and everything path-like are relative to $there, which is\n   similar to what \"make\" does, but doing the same for core.worktree\n   or $GIT_WORK_TREE may be surprising, given that environment is\n   \"set and forget\" (the examples in this message explicitly spell\n   it out with one-shot export syntax, but that is only for\n   illustration) and not visible during usual use of the commands.\n\n> But it would give require_work_tree somewhat interesting and unintuitive\n> side effects.\n\nExactly. My knee-jerk reaction is that I do not think we would want\nto go there, but I haven't thought things through.\n"}]}