{"thread":{"id":"30957","subject":"git-submodule path computation bug with recursive submodules","startedAt":"2012-07-05T12:09:06Z","lastAt":"2012-07-05T18:34:24Z","messageCount":3,"participants":["Bob Halley","Phil Hord","Jens Lehmann"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"194651","messageId":"0B4C40CC-862E-4B15-9A4F-903DC8DBBAEC@play-bow.org","threadId":"30957","inReplyTo":null,"subject":"git-submodule path computation bug with recursive submodules","fromName":"Bob Halley","fromEmail":"halley@play-bow.org","sentAt":"2012-07-05T12:09:06Z","receivedAt":"2012-07-05T12:09:06Z","isPatch":false,"sender":{"key":"halley@play-bow.org","avatar":null},"body":"\nThe git-submodule command has problems in some cases when there is a symlink\nin the path returned by pwd.\n\nI've created a repository at http://www.play-bow.org/repos/product to\ndemonstrate the issue.\n\n$ git --version\ngit version 1.7.11.1.116.g8228a23\n\nI copied and built the head of the master branch today.\n\nFirst we need a symlink.  I discovered this problem because I had a symlink\nin / to a directory under my home directory for typing convenience.\n\n$ ls -al /bug\nlrwxr-xr-x  1 root  admin  17  5 Jul 12:26 /bug@ -> /Users/halley/bug\n\n$ cd /bug\n$ pwd\n/bug\n\nNote that pwd does not resolve the symlink (though pwd -P would on many\nplatforms)\n\n$ pwd -P\n/Users/halley/bug/product\n\n$ git clone http://www.play-bow.org/repos/product\nCloning into 'product'...\n\nI'm purposely not using 'clone --recursive' as the bug doesn't appear if you\ndo that.\n\n$ cd product/\n$ ls\nfile1\tfile2\tfoo/\n\nLet's get those submodules...\n\n$ git submodule update --init --recursive\nSubmodule 'foo' (http://www.play-bow.org/repos/foo) registered for path 'foo'\nCloning into 'foo'...\nSubmodule path 'foo': checked out '2b02e1eb2e34961d807cfc5fc7e477e0ca844600'\nSubmodule 'bar' (http://www.play-bow.org/repos/bar) registered for path 'bar'\nCloning into 'bar'...\nfatal: Not a git repository: ../../../../Users/halley/bug/product/.git/modules/foo/modules/bar\nFailed to recurse into submodule path 'foo'\n\nThe first level of submodule clones successfully, but submodule 'foo'\ncontains submodule 'bar', and cloning it fails.\n\nNow we'll try it again, but this time we'll take the symlink out of the picture.\n\n$ cd /Users/halley/bug\n$ rm -rf product\n$ pwd\n/Users/halley/bug\n$ git clone http://www.play-bow.org/repos/product\nCloning into 'product'...\n$ cd product\n$ git submodule update --init --recursive\nSubmodule 'foo' (http://www.play-bow.org/repos/foo) registered for path 'foo'\nCloning into 'foo'...\nSubmodule path 'foo': checked out '2b02e1eb2e34961d807cfc5fc7e477e0ca844600'\nSubmodule 'bar' (http://www.play-bow.org/repos/bar) registered for path 'bar'\nCloning into 'bar'...\nSubmodule path 'bar': checked out '00f1d87d3bd6948ef861f2b134daafabb10f7d6f'\n\nAll good.\n\nThe problem occurs in git-submodule when it replaces path components\nwith '..'.  It's assuming this will create a valid relative path by\ngoing up to the common root and then down, but this is an invalid\nassumption if any of the path components are symlinks.\n\nHere's some partial output of git-submodule running with sh -x set, in a\nsituation when the pwd is /bug:\n\n++ git clone -n --separate-git-dir /Users/halley/bug/product/.git/modules/foo/modules/bar http://www.play-bow.org/repos/bar bar\nCloning into 'bar'...\n+++ cd /Users/halley/bug/product/.git/modules/foo/modules/bar\n+++ pwd\n++ a=/Users/halley/bug/product/.git/modules/foo/modules/bar/\n+++ cd bar\n+++ pwd\n++ b=/bug/product/foo/bar/\n++ case $a in\n++ case $b in\n++ test /Users/halley/bug/product/.git/modules/foo/modules/bar/ '!=' /Users/halley/bug/product/.git/modules/foo/modules/bar/\n++ test /bug/product/foo/bar/ '!=' /bug/product/foo/bar/\n++ test '' = ''\n++ a=Users/halley/bug/product/.git/modules/foo/modules/bar/\n++ b=bug/product/foo/bar/\n++ test Users = bug\n++ a=Users/halley/bug/product/.git/modules/foo/modules/bar\n++ b=bug/product/foo/bar\n+++ echo bug/product/foo/bar\n+++ sed -e 's|[^/][^/]*|..|g'\n++ rel=../../../..\n++ echo 'gitdir: ../../../../Users/halley/bug/product/.git/modules/foo/modules/bar'\n+++ echo Users/halley/bug/product/.git/modules/foo/modules/bar\n+++ sed -e 's|[^/][^/]*|..|g'\n++ rel=../../../../../../../../..\n++ clear_local_git_env\n+++ git rev-parse --local-env-vars\n++ unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_CONFIG GIT_CONFIG_PARAMETERS GIT_OBJECT_DIRECTORY GIT_DIR GIT_WORK_TREE GIT_GRAFT_FILE GIT_INDEX_FILE GIT_NO_REPLACE_OBJECTS\n++ cd bar\n++ GIT_WORK_TREE=.\n++ git config core.worktree ../../../../../../../../../bug/product/foo/bar\nfatal: Not a git repository: ../../../../Users/halley/bug/product/.git/modules/foo/modules/bar\n\nThis bit:\n\n++ rel=../../../..\n++ echo 'gitdir: ../../../../Users/halley/bug/product/.git/modules/foo/modules/bar'\n\nis wrong, because from /bug/product/foo/bar, ../../../.. is\n/Users/halley, not /.\n\nIf I replace the calls to \"pwd\" with \"pwd -P\", the problem goes away.\nUnfortunately I'm not sure how to fix the script portably, as neither pwd -P\nnor readlink(1) seem to be universally available.\n\nRegards,\n\n/Bob\n"},{"id":"194654","messageId":"CABURp0qtbSsiRX9sJ1F5WS3wtKq32hpV=3pGmM6Ysn=9Nvw_nQ@mail.gmail.com","threadId":"30957","inReplyTo":"0B4C40CC-862E-4B15-9A4F-903DC8DBBAEC@play-bow.org","subject":"Re: git-submodule path computation bug with recursive submodules","fromName":"Phil Hord","fromEmail":"phil.hord@gmail.com","sentAt":"2012-07-05T14:18:59Z","receivedAt":"2012-07-05T14:18:59Z","isPatch":false,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"On Thu, Jul 5, 2012 at 8:09 AM, Bob Halley <halley@play-bow.org> wrote:\n>\n> The git-submodule command has problems in some cases when there is a symlink\n> in the path returned by pwd.\n>\n> I've created a repository at http://www.play-bow.org/repos/product to\n> demonstrate the issue.\n>\n> $ git --version\n> git version 1.7.11.1.116.g8228a23\n>\n> I copied and built the head of the master branch today.\n>\n> First we need a symlink.  I discovered this problem because I had a symlink\n> in / to a directory under my home directory for typing convenience.\n>\n> $ ls -al /bug\n> lrwxr-xr-x  1 root  admin  17  5 Jul 12:26 /bug@ -> /Users/halley/bug\n>\n> $ cd /bug\n> $ pwd\n> /bug\n>\n> Note that pwd does not resolve the symlink (though pwd -P would on many\n> platforms)\n>\n> $ pwd -P\n> /Users/halley/bug/product\n>\n> $ git clone http://www.play-bow.org/repos/product\n> Cloning into 'product'...\n>\n> I'm purposely not using 'clone --recursive' as the bug doesn't appear if you\n> do that.\n>\n> $ cd product/\n> $ ls\n> file1   file2   foo/\n>\n> Let's get those submodules...\n>\n> $ git submodule update --init --recursive\n> Submodule 'foo' (http://www.play-bow.org/repos/foo) registered for path 'foo'\n> Cloning into 'foo'...\n> Submodule path 'foo': checked out '2b02e1eb2e34961d807cfc5fc7e477e0ca844600'\n> Submodule 'bar' (http://www.play-bow.org/repos/bar) registered for path 'bar'\n> Cloning into 'bar'...\n> fatal: Not a git repository: ../../../../Users/halley/bug/product/.git/modules/foo/modules/bar\n> Failed to recurse into submodule path 'foo'\n>\n> The first level of submodule clones successfully, but submodule 'foo'\n> contains submodule 'bar', and cloning it fails.\n\nIt fails for me too, running zsh and stock Linux.\n\nSeems to originate here.\n\nCommit: 69c3051780d6cacfe242563296160634dc667a90:\nAuthor: Jens Lehmann <Jens.Lehmann@web.de>\nDate:   Sun Mar 4 22:15:36 2012 +0100\n\n    submodules: refactor computation of relative gitdir path\n\nPhil\n"},{"id":"194667","messageId":"4FF5DE30.6030100@web.de","threadId":"30957","inReplyTo":"CABURp0qtbSsiRX9sJ1F5WS3wtKq32hpV=3pGmM6Ysn=9Nvw_nQ@mail.gmail.com","subject":"Re: git-submodule path computation bug with recursive submodules","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2012-07-05T18:34:24Z","receivedAt":"2012-07-05T18:34:24Z","isPatch":false,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 05.07.2012 16:18, schrieb Phil Hord:\n> On Thu, Jul 5, 2012 at 8:09 AM, Bob Halley <halley@play-bow.org> wrote:\n>> The first level of submodule clones successfully, but submodule 'foo'\n>> contains submodule 'bar', and cloning it fails.\n> \n> It fails for me too, running zsh and stock Linux.\n> \n> Seems to originate here.\n> \n> Commit: 69c3051780d6cacfe242563296160634dc667a90:\n> Author: Jens Lehmann <Jens.Lehmann@web.de>\n> Date:   Sun Mar 4 22:15:36 2012 +0100\n> \n>     submodules: refactor computation of relative gitdir path\n\nYup, thanks both for reporting and nailing that one down.\n\nThis diff fixes the problem for me and should be a portable way to\navoid \"pwd -P\" or \"cd -P\", I'll cook up a patch with test for that:\n\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 5c61ae2..4a22555 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -150,8 +150,8 @@ module_clone()\n                die \"$(eval_gettext \"Clone of '\\$url' into submodule path '\\$sm_\n        fi\n\n-       a=$(cd \"$gitdir\" && pwd)/\n-       b=$(cd \"$sm_path\" && pwd)/\n+       a=$(cd_to_toplevel && cd \"$gitdir\" && pwd)/\n+       b=$(cd_to_toplevel && cd \"$sm_path\" && pwd)/\n        # normalize Windows-style absolute paths to POSIX-style absolute paths\n        case $a in [a-zA-Z]:/*) a=/${a%%:*}${a#*:} ;; esac\n        case $b in [a-zA-Z]:/*) b=/${b%%:*}${b#*:} ;; esac\n"}]}