{"thread":{"id":"29829","subject":"[PATCH v3 0/4] submodules: Use relative paths to gitdir and work tree","startedAt":"2012-03-04T21:11:49Z","lastAt":"2012-03-07T20:40:46Z","messageCount":7,"participants":["Jens Lehmann","Junio C Hamano","Johannes Sixt"],"isPatch":true,"patchVersion":3,"patchTotal":4},"messages":[{"id":"186049","messageId":"4F53DA95.2020402@web.de","threadId":"29829","inReplyTo":null,"subject":"[PATCH v3 0/4] submodules: Use relative paths to gitdir and work tree","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2012-03-04T21:11:49Z","receivedAt":"2012-03-04T21:11:49Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"This is the third round of the former two patch series. It applies\ncleanly on current master and maint and IMO is maint stuff as it fixes\nbugs related to submodules. Those were introduced when moving the git\ndirectory into that of the superproject and using a gitfile instead.\n\nThe first patch is unchanged from version one, in the second I did\naddress the concerns raised about the while loop. Those two patches\nmake superprojects movable again.\n\nThe third patch started as a mere refactoring, but while working on\nit I noticed it also fixes an issue when submodules are moved around\ninside a superproject.\n\nThe forth patch is provided by Johannes Sixt and addresses the issue\nthat under windows both POSIX and Windows style paths may occur which\nsometimes broke the computation of relative paths.\n\nNow all issues I'm aware of are fixed and tested for. In the next step\nI'll be looking into teaching git mv to handle submodules, as just\nmv'ing them someplace else, upating .gitmodules and adding the paths\nisn't sufficient anymore. The core.worktree setting - and sometimes the\ngitfile too (when the submodule is moved to a different directory level)\n- have to be updated too to make that work (That would be easier if git\ncould treat the directory a gitfile was found in as a candidate for the\nwork tree, as then we could get rid of the core.worktree setting, but\nwe don't have that functionality).\n\nJens Lehmann (4):\n  submodules: always use a relative path to gitdir\n  submodules: always use a relative path from gitdir to work tree\n  submodules: refactor computation of relative gitdir path\n  submodules: fix ambiguous absolute paths under Windows\n\n git-submodule.sh            |   58 +++++++++++++++++++++----------------------\n t/t7400-submodule-basic.sh  |   22 ++++++++++++++++\n t/t7406-submodule-update.sh |   17 +++++++++++++\n 3 files changed, 68 insertions(+), 29 deletions(-)\n\n-- \n1.7.9.2.362.g684a8\n"},{"id":"186050","messageId":"4F53DB36.2030500@web.de","threadId":"29829","inReplyTo":"4F53DA95.2020402@web.de","subject":"[PATCH v3 1/4] submodules: always use a relative path to gitdir","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2012-03-04T21:14:30Z","receivedAt":"2012-03-04T21:14:30Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Since recently a submodule with name <name> has its git directory in the\n.git/modules/<name> directory of the superproject while the work tree\ncontains a gitfile pointing there. When the submodule git directory needs\nto be cloned because it is not found in .git/modules/<name> the clone\ncommand will write an absolute path into the gitfile. When no clone is\nnecessary the git directory will be reactivated by the git-submodule.sh\nscript by writing a relative path into the gitfile.\n\nThis is inconsistent, as the behavior depends on the submodule having been\ncloned before into the .git/modules of the superproject. A relative path\nis preferable here because it allows the superproject to be moved around\nwithout invalidating the gitfile. We do that by always writing the\nrelative path into the gitfile, which overwrites the absolute path the\nclone command may have written there.\n\nThis is only the first step to make superprojects movable again like they\nwere before the separate-git-dir approach was introduced. The second step\nis to use a relative path in core.worktree too.\n\nEnhance t7400 to ensure that future versions won't re-add absolute paths\nby accident.\n\nWhile at it also replace an if/else construct evaluating the presence\nof the 'reference' option with a single line of bash code.\n\nReported-by: Antony Male <antony.male@gmail.com>\nSigned-off-by: Jens Lehmann <Jens.Lehmann@web.de>\n---\n git-submodule.sh           |   11 ++++-------\n t/t7400-submodule-basic.sh |    2 ++\n 2 files changed, 6 insertions(+), 7 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 9bb2e13..2a93c61 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -160,18 +160,15 @@ module_clone()\n \tif test -d \"$gitdir\"\n \tthen\n \t\tmkdir -p \"$path\"\n-\t\techo \"gitdir: $rel_gitdir\" >\"$path/.git\"\n \t\trm -f \"$gitdir/index\"\n \telse\n \t\tmkdir -p \"$gitdir_base\"\n-\t\tif test -n \"$reference\"\n-\t\tthen\n-\t\t\tgit-clone $quiet \"$reference\" -n \"$url\" \"$path\" --separate-git-dir \"$gitdir\"\n-\t\telse\n-\t\t\tgit-clone $quiet -n \"$url\" \"$path\" --separate-git-dir \"$gitdir\"\n-\t\tfi ||\n+\t\tgit clone $quiet -n ${reference:+\"$reference\"} \\\n+\t\t\t--separate-git-dir \"$gitdir\" \"$url\" \"$path\" ||\n \t\tdie \"$(eval_gettext \"Clone of '\\$url' into submodule path '\\$path' failed\")\"\n \tfi\n+\n+\techo \"gitdir: $rel_gitdir\" >\"$path/.git\"\n }\n\n #\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 695f7af..2b70b22 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -79,6 +79,8 @@ test_expect_success 'submodule add' '\n \t\tcd addtest &&\n \t\tgit submodule add -q \"$submodurl\" submod >actual &&\n \t\ttest ! -s actual &&\n+\t\techo \"gitdir: ../.git/modules/submod\" >expect &&\n+\t\ttest_cmp expect submod/.git &&\n \t\tgit submodule init\n \t) &&\n\n-- \n1.7.9.2.362.g684a8\n"},{"id":"186051","messageId":"4F53DB5C.2060104@web.de","threadId":"29829","inReplyTo":"4F53DA95.2020402@web.de","subject":"[PATCH v3 2/4] submodules: always use a relative path from gitdir to work tree","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2012-03-04T21:15:08Z","receivedAt":"2012-03-04T21:15:08Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Since recently a submodule with name <name> has its git directory in the\n.git/modules/<name> directory of the superproject while the work tree\ncontains a gitfile pointing there. To make that work the git directory has\nthe core.worktree configuration set in its config file to point back to\nthe work tree.\n\nThat core.worktree is an absolute path set by the initial clone of the\nsubmodule. A relative path is preferable here because it allows the\nsuperproject to be moved around without invalidating that setting, so\ncompute and set that relative path after cloning or reactivating the\nsubmodule.\n\nThis also fixes a bug when moving a submodule around inside the\nsuperproject, as the current code forgot to update the setting to the new\nsubmodule work tree location.\n\nEnhance t7400 to ensure that future versions won't re-add absolute paths\nby accident and that moving a superproject won't break submodules.\n\nSigned-off-by: Jens Lehmann <Jens.Lehmann@web.de>\n---\n git-submodule.sh           |   18 ++++++++++++++++++\n t/t7400-submodule-basic.sh |   20 ++++++++++++++++++++\n 2 files changed, 38 insertions(+)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 2a93c61..c405caa 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -169,6 +169,24 @@ module_clone()\n \tfi\n\n \techo \"gitdir: $rel_gitdir\" >\"$path/.git\"\n+\n+\ta=$(cd \"$gitdir\" && pwd)/\n+\tb=$(cd \"$path\" && pwd)/\n+\t# Remove all common leading directories after a sanity check\n+\tif test \"${a#$b}\" != \"$a\" || test \"${b#$a}\" != \"$b\"; then\n+\t\tdie \"$(eval_gettext \"Gitdir '\\$a' is part of the submodule path '\\$b' or vice versa\")\"\n+\tfi\n+\twhile test \"${a%%/*}\" = \"${b%%/*}\"\n+\tdo\n+\t\ta=${a#*/}\n+\t\tb=${b#*/}\n+\tdone\n+\t# Now chop off the trailing '/'s that were added in the beginning\n+\ta=${a%/}\n+\tb=${b%/}\n+\n+\trel=$(echo $a | sed -e 's|[^/]*|..|g')\n+\t(clear_local_git_env; cd \"$path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n }\n\n #\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 2b70b22..b377a7a 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -81,6 +81,13 @@ test_expect_success 'submodule add' '\n \t\ttest ! -s actual &&\n \t\techo \"gitdir: ../.git/modules/submod\" >expect &&\n \t\ttest_cmp expect submod/.git &&\n+\t\t(\n+\t\t\tcd submod &&\n+\t\t\tgit config core.worktree >actual &&\n+\t\t\techo \"../../../submod\" >expect &&\n+\t\t\ttest_cmp expect actual &&\n+\t\t\trm -f actual expect\n+\t\t) &&\n \t\tgit submodule init\n \t) &&\n\n@@ -500,4 +507,17 @@ test_expect_success 'relative path works with user@host:path' '\n \t)\n '\n\n+test_expect_success 'moving the superproject does not break submodules' '\n+\t(\n+\t\tcd addtest &&\n+\t\tgit submodule status >expect\n+\t)\n+\tmv addtest addtest2 &&\n+\t(\n+\t\tcd addtest2 &&\n+\t\tgit submodule status >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n test_done\n-- \n1.7.9.2.362.g684a8\n"},{"id":"186052","messageId":"4F53DB78.1010109@web.de","threadId":"29829","inReplyTo":"4F53DA95.2020402@web.de","subject":"[PATCH v3 3/4] submodules: refactor computation of relative gitdir path","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2012-03-04T21:15:36Z","receivedAt":"2012-03-04T21:15:36Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"In module_clone() the rel_gitdir variable was computed differently when\n\"git rev-parse --git-dir\" returned a relative path than when it returned\nan absolute path. This is not optimal, as different code paths are used\ndepending on the return value of that command.\n\nFix that by reusing the differing path components computed for setting the\ncore.worktree config setting, which leaves a single code path for setting\nboth instead of having three and makes the code much shorter.\n\nThis also fixes the bug that in the computation of how many directories\nhave to be traversed up to hit the root directory of the submodule the\nname of the submodule was used where the path should have been used. This\nlead to problems after renaming submodules into another directory level.\n\nEven though the \"(cd $somewhere && pwd)\" approach breaks the flexibility\nof symlinks, that is no issue here as we have to have one relative path\npointing from the work tree to the gitdir and another pointing back, which\nwill never work anyway when a symlink along one of those paths is changed\nbecause the directory it points to was moved.\n\nAlso add a test moving a submodule into a deeper directory to catch any\nfuture breakage here and to document what has to be done when a submodule\nneeds to be moved until git mv learns to do that. Simply moving it to the\nnew location doesn't work, as the core.worktree and possibly the gitfile\nsetting too will be wrong. So it has to be removed from filesystem and\nindex, then the new location has to be added into the index and the\n.gitmodules file has to be updated. After that a git submodule update will\ncheck out the submodule at the new location.\n\nSigned-off-by: Jens Lehmann <Jens.Lehmann@web.de>\n---\n git-submodule.sh            |   30 ++++++------------------------\n t/t7406-submodule-update.sh |   17 +++++++++++++++++\n 2 files changed, 23 insertions(+), 24 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex c405caa..a9e9822 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -132,30 +132,11 @@ module_clone()\n \tgitdir_base=\n \tname=$(module_name \"$path\" 2>/dev/null)\n \ttest -n \"$name\" || name=\"$path\"\n-\tbase_path=$(dirname \"$path\")\n+\tbase_name=$(dirname \"$name\")\n\n \tgitdir=$(git rev-parse --git-dir)\n-\tgitdir_base=\"$gitdir/modules/$base_path\"\n-\tgitdir=\"$gitdir/modules/$path\"\n-\n-\tcase $gitdir in\n-\t/*)\n-\t\ta=\"$(cd_to_toplevel && pwd)/\"\n-\t\tb=$gitdir\n-\t\twhile [ \"$b\" ] && [ \"${a%%/*}\" = \"${b%%/*}\" ]\n-\t\tdo\n-\t\t\ta=${a#*/} b=${b#*/};\n-\t\tdone\n-\n-\t\trel=\"$a$name\"\n-\t\trel=`echo $rel | sed -e 's|[^/]*|..|g'`\n-\t\trel_gitdir=\"$rel/$b\"\n-\t\t;;\n-\t*)\n-\t\trel=`echo $name | sed -e 's|[^/]*|..|g'`\n-\t\trel_gitdir=\"$rel/$gitdir\"\n-\t\t;;\n-\tesac\n+\tgitdir_base=\"$gitdir/modules/$base_name\"\n+\tgitdir=\"$gitdir/modules/$name\"\n\n \tif test -d \"$gitdir\"\n \tthen\n@@ -168,8 +149,6 @@ module_clone()\n \t\tdie \"$(eval_gettext \"Clone of '\\$url' into submodule path '\\$path' failed\")\"\n \tfi\n\n-\techo \"gitdir: $rel_gitdir\" >\"$path/.git\"\n-\n \ta=$(cd \"$gitdir\" && pwd)/\n \tb=$(cd \"$path\" && pwd)/\n \t# Remove all common leading directories after a sanity check\n@@ -185,6 +164,9 @@ module_clone()\n \ta=${a%/}\n \tb=${b%/}\n\n+\trel=$(echo $b | sed -e 's|[^/]*|..|g')\n+\techo \"gitdir: $rel/$a\" >\"$path/.git\"\n+\n \trel=$(echo $a | sed -e 's|[^/]*|..|g')\n \t(clear_local_git_env; cd \"$path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n }\ndiff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\nindex 5b97222..dcb195b 100755\n--- a/t/t7406-submodule-update.sh\n+++ b/t/t7406-submodule-update.sh\n@@ -619,4 +619,21 @@ test_expect_success 'submodule add properly re-creates deeper level submodules'\n \t)\n '\n\n+test_expect_success 'submodule update properly revives a moved submodule' '\n+\t(cd super &&\n+\t git commit -am \"pre move\" &&\n+\t git status >expect&&\n+\t H=$(cd submodule2; git rev-parse HEAD) &&\n+\t git rm --cached submodule2 &&\n+\t rm -rf submodule2 &&\n+\t mkdir -p \"moved/sub module\" &&\n+\t git update-index --add --cacheinfo 160000 $H \"moved/sub module\" &&\n+\t git config -f .gitmodules submodule.submodule2.path \"moved/sub module\"\n+\t git commit -am \"post move\" &&\n+\t git submodule update &&\n+\t git status >actual &&\n+\t test_cmp expect actual\n+\t)\n+'\n+\n test_done\n-- \n1.7.9.2.362.g684a8\n"},{"id":"186053","messageId":"4F53DBA3.4010500@web.de","threadId":"29829","inReplyTo":"4F53DA95.2020402@web.de","subject":"[PATCH v3 4/4] submodules: fix ambiguous absolute paths under Windows","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2012-03-04T21:16:19Z","receivedAt":"2012-03-04T21:16:19Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"From: Johannes Sixt <j6t@kdbg.org>\n\nUnder Windows the \"git rev-parse --git-dir\" and \"pwd\" commands may return\neither drive-letter-colon or POSIX style paths. This makes module_clone()\nbehave badly because it expects absolute paths to always start with a '/'.\n\nFix that by always converting the \"c:/\" notation into \"/c/\" when computing\nthe relative paths from gitdir to the submodule work tree and back.\n\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n git-submodule.sh |    3 +++\n 1 file changed, 3 insertions(+)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex a9e9822..efc86ad 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -151,6 +151,9 @@ module_clone()\n\n \ta=$(cd \"$gitdir\" && pwd)/\n \tb=$(cd \"$path\" && pwd)/\n+\t# normalize Windows-style absolute paths to POSIX-style absolute paths\n+\tcase $a in [a-zA-Z]:/*) a=/${a%%:*}${a#*:} ;; esac\n+\tcase $b in [a-zA-Z]:/*) b=/${b%%:*}${b#*:} ;; esac\n \t# Remove all common leading directories after a sanity check\n \tif test \"${a#$b}\" != \"$a\" || test \"${b#$a}\" != \"$b\"; then\n \t\tdie \"$(eval_gettext \"Gitdir '\\$a' is part of the submodule path '\\$b' or vice versa\")\"\n-- \n1.7.9.2.362.g684a8\n"},{"id":"186290","messageId":"7v8vjcq5v3.fsf@alter.siamese.dyndns.org","threadId":"29829","inReplyTo":"4F53DA95.2020402@web.de","subject":"Re: [PATCH v3 0/4] submodules: Use relative paths to gitdir and work tree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-03-07T06:31:44Z","receivedAt":"2012-03-07T06:31:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jens Lehmann <Jens.Lehmann@web.de> writes:\n\n> This is the third round of the former two patch series. It applies\n> cleanly on current master and maint and IMO is maint stuff as it fixes\n> bugs related to submodules. Those were introduced when moving the git\n> directory into that of the superproject and using a gitfile instead.\n\nI looked at this again and think this addresses the review comments\nmade during the previous round, but I would like to get \"Yay\" from\npeople who helped reviewing the previous round.\n\nThanks.\n"},{"id":"186335","messageId":"4F57C7CE.1050005@kdbg.org","threadId":"29829","inReplyTo":"7v8vjcq5v3.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 0/4] submodules: Use relative paths to gitdir and work tree","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2012-03-07T20:40:46Z","receivedAt":"2012-03-07T20:40:46Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 07.03.2012 07:31, schrieb Junio C Hamano:\n> Jens Lehmann <Jens.Lehmann@web.de> writes:\n>> This is the third round of the former two patch series. It applies\n>> cleanly on current master and maint and IMO is maint stuff as it fixes\n>> bugs related to submodules. Those were introduced when moving the git\n>> directory into that of the superproject and using a gitfile instead.\n> \n> I looked at this again and think this addresses the review comments\n> made during the previous round, but I would like to get \"Yay\" from\n> people who helped reviewing the previous round.\n\nYay. The topic passes the test suite.\n\n-- Hannes\n"}]}