{"thread":{"id":"27167","subject":"symlinked working tree gotcha","startedAt":"2011-04-24T16:58:25Z","lastAt":"2011-04-26T03:41:29Z","messageCount":4,"participants":["Joey Hess","Junio C Hamano","Jay Soffian"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"166280","messageId":"20110424165825.GA21062@gnu.kitenet.net","threadId":"27167","inReplyTo":null,"subject":"symlinked working tree gotcha","fromName":"Joey Hess","fromEmail":"joey@kitenet.net","sentAt":"2011-04-24T16:58:25Z","receivedAt":"2011-04-24T16:58:25Z","isPatch":false,"sender":{"key":"joey@kitenet.net","avatar":"https://avatars.githubusercontent.com/u/16392?v=4"},"body":"joey@gnu:/tmp>mkdir foo\njoey@gnu:/tmp>cd foo\njoey@gnu:/tmp/foo>git init\nInitialized empty Git repository in /tmp/foo/.git/\njoey@gnu:/tmp/foo>touch foo\njoey@gnu:/tmp/foo>git add /tmp/foo/foo\njoey@gnu:/tmp/foo>cd ..\njoey@gnu:/tmp>ln -s foo bar\njoey@gnu:/tmp>cd bar\njoey@gnu:/tmp/bar>touch bar\njoey@gnu:/tmp/bar>git add /tmp/bar/bar\nfatal: '/tmp/bar/bar' is outside repository\n\nIs this a bug or a feature of git? I had some code where I had, lazily,\nassumed that passing the full path to the file would always work, since\nit did, in my experience.\n\n-- \nsee shy jo\n"},{"id":"166320","messageId":"7vpqoajiz0.fsf@alter.siamese.dyndns.org","threadId":"27167","inReplyTo":"20110424165825.GA21062@gnu.kitenet.net","subject":"Re: symlinked working tree gotcha","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-25T18:15:15Z","receivedAt":"2011-04-25T18:15:15Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Joey Hess <joey@kitenet.net> writes:\n\n> joey@gnu:/tmp>mkdir foo\n> joey@gnu:/tmp>cd foo\n> joey@gnu:/tmp/foo>git init\n> Initialized empty Git repository in /tmp/foo/.git/\n> joey@gnu:/tmp/foo>touch foo\n> joey@gnu:/tmp/foo>git add /tmp/foo/foo\n> joey@gnu:/tmp/foo>cd ..\n> joey@gnu:/tmp>ln -s foo bar\n> joey@gnu:/tmp>cd bar\n> joey@gnu:/tmp/bar>touch bar\n> joey@gnu:/tmp/bar>git add /tmp/bar/bar\n> fatal: '/tmp/bar/bar' is outside repository\n>\n> Is this a bug or a feature of git?\n\nTwo 'foo's makes it confusing to read so let's rephrase.\n\nGiven this structure:\n\n    /tmp/foo/\n    /tmp/foo/.git/\n    /tmp/foo/hello\n    /tmp/sym@ -> foo\n\nwhen you refer to /tmp/sym/hello where $(/bin/pwd) is /tmp/foo, should it\nbe considered to be within the bounds of the working tree that is governed\nby your current $GIT_DIR (which is \".git\")?\n\nThe answer is \"perhaps yes, ideally speaking, but does it really matter in\npractice, or is it just nice to have?\".\n\nI think we do not run realpath to a pathspec given by the end user to\ncanonicalize it.  And we cannot blindly run realpath.\n\nThink of this structure (the above with some additions):\n\n    /tmp/foo/\n    /tmp/foo/.git/\n    /tmp/foo/hello\n    /tmp/foo/dir/bye\n    /tmp/foo/link@ -> dir\n    /tmp/sym@ -> foo\n\nand you refer to /tmp/sym/link/bye from /tmp/foo directory.  If we run\nrealpath to the whole thing, we would get /tmp/foo/dir/bye but as far as\nthe repository data is concerned, link/bye is beyond a tracked symbolic\nlink and we should error it out (\"git add link/bye\" should fail).\n\nIf we choose to make your example work, we would need to resolve symbolic\nlinks stepwise until we get into the working tree, and then use the\nremainder without resolving symbolic links, e.g.\n\n 0. We get /tmp/sym/hello  and /tmp/sym/link/bye from the user;\n\n 1. Notice /tmp is a directory and outside the working tree;\n\n 2. Notice /tmp/sym is a symlink; resolve it to get /tmp/foo, notice\n    that directory is now within the working tree, and stop resolving\n    symbolic links for the remainder;\n\n 3. Append the remainder to come up with /tmp/foo/hello and\n   /tmp/foo/link/bye;\n\n 4. Strip /tmp/foo/, to get hello and link/bye as pathspec relative to the\n    root of the working tree;\n\n 5. Use them as the pathspec. hello is a valid pathspec within the working\n    tree. link/bye is beyond symlink and an error should be reported.\n\nOr something like that.  We would also have to deal with \"../\" in the\npathspec, so we cannot just \"stop resolving and tack the remainder\", but\nwould probably need to check if the directory is within bounds of the\nworking tree in each step.\n\nAt least I would say it would be a sensible thing to aim for.\n"},{"id":"166324","messageId":"20110425190938.GA24744@gnu.kitenet.net","threadId":"27167","inReplyTo":"7vpqoajiz0.fsf@alter.siamese.dyndns.org","subject":"Re: symlinked working tree gotcha","fromName":"Joey Hess","fromEmail":"joey@kitenet.net","sentAt":"2011-04-25T19:09:38Z","receivedAt":"2011-04-25T19:09:38Z","isPatch":false,"sender":{"key":"joey@kitenet.net","avatar":"https://avatars.githubusercontent.com/u/16392?v=4"},"body":"Junio C Hamano wrote:\n> Two 'foo's makes it confusing to read so let's rephrase.\n> \n> Given this structure:\n> \n>     /tmp/foo/\n>     /tmp/foo/.git/\n>     /tmp/foo/hello\n>     /tmp/sym@ -> foo\n> \n> when you refer to /tmp/sym/hello where $(/bin/pwd) is /tmp/foo, should it\n> be considered to be within the bounds of the working tree that is governed\n> by your current $GIT_DIR (which is \".git\")?\n\nHmm, my /bin/pwd does not return \"/tmp/foo\" when I've cd'd to \"/tmp/sym\".\n\n> The answer is \"perhaps yes, ideally speaking, but does it really matter in\n> practice, or is it just nice to have?\".\n\nFWIW, my motivation for using the absolute path was that I wanted to\nalways add $GIT_WORK_TREE/hello, but the add could be run when in a\nsubdirectory of the repository, so \"git add hello\" might not add the\nright file.\n\n-- \nsee shy jo\n"},{"id":"166348","messageId":"BANLkTik8Pn0b9sgejb2Uawkb=J5tYR9MAA@mail.gmail.com","threadId":"27167","inReplyTo":"20110425190938.GA24744@gnu.kitenet.net","subject":"Re: symlinked working tree gotcha","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2011-04-26T03:41:29Z","receivedAt":"2011-04-26T03:41:29Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Mon, Apr 25, 2011 at 3:09 PM, Joey Hess <joey@kitenet.net> wrote:\n> Hmm, my /bin/pwd does not return \"/tmp/foo\" when I've cd'd to \"/tmp/sym\".\n\nA pwd misfeature IMO. Try:\n\n$ pwd -P\n\nYou can make -P the default in bash with \"shopt -s -o physical\"\n\nj.\n"}]}