{"thread":{"id":"14465","subject":"git-rev-parse --show-cdup returns a relative path instead of absolute (problem with git pull --rebase not finding the git dir)","startedAt":"2008-07-15T14:13:28Z","lastAt":"2008-07-15T20:26:27Z","messageCount":8,"participants":["Yves Orton","Petr Baudis","Johannes Schindelin","Rogan Dawes"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"83393","messageId":"1216131208.19334.171.camel@gemini","threadId":"14465","inReplyTo":null,"subject":"git-rev-parse --show-cdup returns a relative path instead of absolute (problem with git pull --rebase not finding the git dir)","fromName":"Yves Orton","fromEmail":"yves.orton@booking.com","sentAt":"2008-07-15T14:13:28Z","receivedAt":"2008-07-15T14:13:28Z","isPatch":false,"sender":{"key":"yves.orton@booking.com","avatar":null},"body":"Hi,\n\nIm reporting this based on a conversation I had in the #git channel on\nfreenode.\n\nI have a setup where various subdirectories of a number of git repos are\nsymlinked into a common directory tree. Something like what the\nfollowing would create but with more repositories involved:\n\ncd ~; mkdir foo; chdir foo; git init; mkdir bar; git add bar ; git\ncommit -m'add bar' ; cd ~; ln -s foo/bar bar ; cd bar; \n\n[try various git commands, not all will work]\n\nMost git command seem perfectly happy to work on the correct repos from\nthis symlinked tree. However at least one doesnt, git pull --rebase, in\nparticular.\n\nDoing a \n\n\tgit-rev-parse --git-dir \n\nseems to behave correctly (always finding the correct location) and \n\n\tgit-rev-parse --is-inside-work-dir\n\nreports true. However git-pull --rebase responds with lots of \"fatal:\nNot a git repository\" messages. Example is below.\n\nDuring discussion about this on #git it was suggested this was because \n\n\tgit-rev-parse --show-cdup \n\nreturns a relative path. (../).\n\nIm not on list so id appreciate it if anyone replying to this could cc\nme on the mail.\n\nOh, i am aware of submodules but i have to work with what i have now. \n\nCheers,\nyves\n\n\nExample of git pull --rebase failing yet git commit working:\n\n[dmq@somewhere apps]$ echo test > test.txt\n[dmq@somewhere apps]$ git add test.txt\n[dmq@somewhere apps]$ git commit -m'add a test file -- will remove next\ncommit'\nCreated commit 45ab725: add a test file -- will remove next commit\n 1 files changed, 1 insertions(+), 0 deletions(-)\n create mode 100644 apps/test.txt\n[dmq@somewhere apps]$ git rm test.txt\nrm 'apps/test.txt'\n[dmq@somewhere apps]$ git commit -m'removed test file'\nCreated commit 2768e6d: removed test file\n 1 files changed, 0 insertions(+), 1 deletions(-)\n delete mode 100644 apps/test.txt\n[dmq@somewhere apps]$ git pull --rebase\nfatal: Not a git repository\nfatal: Not a git repository\nfatal: Not a git repository\nfatal: Not a git repository\n"},{"id":"83398","messageId":"20080715145920.13529.25603.stgit@localhost","threadId":"14465","inReplyTo":"1216131208.19334.171.camel@gemini","subject":"[PATCH] git rev-parse: Fix --show-cdup inside symlinked directory","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2008-07-15T14:59:45Z","receivedAt":"2008-07-15T14:59:45Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Consider the scenario when someone makes a symlink into a working tree\nsubdirectory at an unrelated place, then attempts to work inside the\nsymlinked directory. The scenario is a bit unwieldly, but most of\nthe Git will handle it fine - except git rev-parse --show-cdup. That\nwill output a sequence of ../ which will work wrong inside the symlink\nusing shell cd builtin.\n\nThis patch changes --show-cdup to always show absolute workdir path\ninstead. I think this should hopefully cause no compatibility problems;\nthe testsuite is passing fine, at least.  The patch also adds\na --show-cdup check and this particular scenartio to the t1500 test.\n\nSigned-off-by: Petr Baudis <pasky@suse.cz>\n---\n\n Documentation/git-rev-parse.txt |    4 ++--\n builtin-rev-parse.c             |   15 +++++----------\n t/t1500-rev-parse.sh            |   18 ++++++++++++++++--\n 3 files changed, 23 insertions(+), 14 deletions(-)\n\ndiff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt\nindex 088f971..4c289d0 100644\n--- a/Documentation/git-rev-parse.txt\n+++ b/Documentation/git-rev-parse.txt\n@@ -103,8 +103,8 @@ OPTIONS\n \n --show-cdup::\n \tWhen the command is invoked from a subdirectory, show the\n-\tpath of the top-level directory relative to the current\n-\tdirectory (typically a sequence of \"../\", or an empty string).\n+\tpath of the top-level directory, or an empty string if the\n+\tcurrent directory is the top-level directory.\n \n --git-dir::\n \tShow `$GIT_DIR` if defined else show the path to the .git directory.\ndiff --git a/builtin-rev-parse.c b/builtin-rev-parse.c\nindex a7860ed..011d16c 100644\n--- a/builtin-rev-parse.c\n+++ b/builtin-rev-parse.c\n@@ -500,22 +500,17 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--show-cdup\")) {\n-\t\t\t\tconst char *pfx = prefix;\n-\t\t\t\tif (!is_inside_work_tree()) {\n+\t\t\t\tif (prefix) {\n+\t\t\t\t\t/* We are not at the top level yet */\n \t\t\t\t\tconst char *work_tree =\n \t\t\t\t\t\tget_git_work_tree();\n \t\t\t\t\tif (work_tree)\n \t\t\t\t\t\tprintf(\"%s\\n\", work_tree);\n \t\t\t\t\tcontinue;\n+\t\t\t\t} else {\n+\t\t\t\t\t/* Backwards compatibility */\n+\t\t\t\t\tputchar('\\n');\n \t\t\t\t}\n-\t\t\t\twhile (pfx) {\n-\t\t\t\t\tpfx = strchr(pfx, '/');\n-\t\t\t\t\tif (pfx) {\n-\t\t\t\t\t\tpfx++;\n-\t\t\t\t\t\tprintf(\"../\");\n-\t\t\t\t\t}\n-\t\t\t\t}\n-\t\t\t\tputchar('\\n');\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--git-dir\")) {\ndiff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh\nindex 85da4ca..2f0bf15 100755\n--- a/t/t1500-rev-parse.sh\n+++ b/t/t1500-rev-parse.sh\n@@ -26,9 +26,14 @@ test_rev_parse() {\n \t\"test '$1' = \\\"\\$(git rev-parse --show-prefix)\\\"\"\n \tshift\n \t[ $# -eq 0 ] && return\n+\n+\ttest_expect_success \"$name: cdup\" \\\n+\t\"test '$1' = \\\"\\$(git rev-parse --show-cdup)\\\"\"\n+\tshift\n+\t[ $# -eq 0 ] && return\n }\n \n-# label is-bare is-inside-git is-inside-work prefix\n+# label is-bare is-inside-git is-inside-work prefix cdup\n \n test_rev_parse toplevel false false true ''\n \n@@ -38,11 +43,20 @@ cd objects || exit 1\n test_rev_parse .git/objects/ false true false ''\n cd ../.. || exit 1\n \n+basedir=$(pwd)\n mkdir -p sub/dir || exit 1\n cd sub/dir || exit 1\n-test_rev_parse subdirectory false false true sub/dir/\n+test_rev_parse subdirectory false false true sub/dir/ \"$basedir\"\n cd ../.. || exit 1\n \n+# Scenario: Working within a subdirectory symlinked out of the working tree\n+mkdir -p maindir || exit 1\n+(mv .git maindir && mkdir -p maindir/sub2 && ln -s maindir/sub2 .) || exit 1\n+cd sub2 || exit 1\n+test_rev_parse 'symlinked subdirectory' false false true sub2/ \"$basedir\"/maindir\n+cd .. || exit 1\n+(rm sub2 && mv maindir/.git . && rm -r maindir) || exit 1\n+\n git config core.bare true\n test_rev_parse 'core.bare = true' true false false\n \n"},{"id":"83401","messageId":"alpine.DEB.1.00.0807151614510.8950@racer","threadId":"14465","inReplyTo":"20080715145920.13529.25603.stgit@localhost","subject":"Re: [PATCH] git rev-parse: Fix --show-cdup inside symlinked directory","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-07-15T15:19:30Z","receivedAt":"2008-07-15T15:19:30Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 15 Jul 2008, Petr Baudis wrote:\n\n> Consider the scenario when someone makes a symlink into a working tree\n> subdirectory at an unrelated place, then attempts to work inside the\n> symlinked directory. The scenario is a bit unwieldly, but most of\n> the Git will handle it fine - except git rev-parse --show-cdup. That\n> will output a sequence of ../ which will work wrong inside the symlink\n> using shell cd builtin.\n\nShort version: do not use symlinks in the working directory, if you do not \nwant to track the _symlink_.\n\nLong version: there are a lot of problems with that, and --show-cdup is \nthe least of the problems.  A checkout, for example, is able to kill the \nsymlink and check out a fresh copy of the subdirectory.\n\nAFAICT this is a concious decision: If you want to track a symlink, track \na symlink, but if you want to track a subdirectory, you will have to track \na subdirectory, and it cannot be a symlink.\n\n> This patch changes --show-cdup to always show absolute workdir path\n> instead. I think this should hopefully cause no compatibility problems;\n> the testsuite is passing fine, at least.\n\nSee the thread where I proposed a change like this, back with the infamous \nworktree desaster, and Junio NACKed; or the thread where Linus rightfully \ninsists that git_dir should be relative if possible, for performance \nreasons.\n\nHth,\nDscho\n"},{"id":"83409","messageId":"20080715154036.GR10151@machine.or.cz","threadId":"14465","inReplyTo":"alpine.DEB.1.00.0807151614510.8950@racer","subject":"Re: [PATCH] git rev-parse: Fix --show-cdup inside symlinked directory","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2008-07-15T15:40:36Z","receivedAt":"2008-07-15T15:40:36Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"  Hi,\n\nOn Tue, Jul 15, 2008 at 04:19:30PM +0100, Johannes Schindelin wrote:\n> On Tue, 15 Jul 2008, Petr Baudis wrote:\n> \n> > Consider the scenario when someone makes a symlink into a working tree\n> > subdirectory at an unrelated place, then attempts to work inside the\n> > symlinked directory. The scenario is a bit unwieldly, but most of\n> > the Git will handle it fine - except git rev-parse --show-cdup. That\n> > will output a sequence of ../ which will work wrong inside the symlink\n> > using shell cd builtin.\n> \n> Short version: do not use symlinks in the working directory, if you do not \n> want to track the _symlink_.\n> \n> Long version: there are a lot of problems with that, and --show-cdup is \n> the least of the problems.  A checkout, for example, is able to kill the \n> symlink and check out a fresh copy of the subdirectory.\n> \n> AFAICT this is a concious decision: If you want to track a symlink, track \n> a symlink, but if you want to track a subdirectory, you will have to track \n> a subdirectory, and it cannot be a symlink.\n\n  no, no, this is for the scenario other way around: you have a normal\nsubdirectory in the working tree, and point a symlink _at_ it from\n$somewhere_else. Then you try to work in $somewhere_else/symlink.\n\n> > This patch changes --show-cdup to always show absolute workdir path\n> > instead. I think this should hopefully cause no compatibility problems;\n> > the testsuite is passing fine, at least.\n> \n> See the thread where I proposed a change like this, back with the infamous \n> worktree desaster, and Junio NACKed; or the thread where Linus rightfully \n> insists that git_dir should be relative if possible, for performance \n> reasons.\n\n  I see, <7vk5sly3h9.fsf@assigned-by-dhcp.cox.net>. But noone was aware\nof this possible user case. Performance reasons sound reasonable, though\nI'm not really sure if for cdup in particular this ever matters.\n\n  P.S.: Either way, there is a possible workaround to tell git about the\nworking directory manually using git --work-tree=... that I missed to\nmention on IRC, Yves.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nGNU, n. An animal of South Africa, which in its domesticated state\nresembles a horse, a buffalo and a stag. In its wild condition it is\nsomething like a thunderbolt, an earthquake and a cyclone. -- A. Pierce\n"},{"id":"83413","messageId":"1216140100.19334.189.camel@gemini","threadId":"14465","inReplyTo":"20080715154036.GR10151@machine.or.cz","subject":"Re: [PATCH] git rev-parse: Fix --show-cdup inside symlinked directory","fromName":"Yves Orton","fromEmail":"yves.orton@booking.com","sentAt":"2008-07-15T16:41:40Z","receivedAt":"2008-07-15T16:41:40Z","isPatch":true,"sender":{"key":"yves.orton@booking.com","avatar":null},"body":"On Tue, 2008-07-15 at 17:40 +0200, Petr Baudis wrote:\n>   no, no, this is for the scenario other way around: you have a normal\n> subdirectory in the working tree, and point a symlink _at_ it from\n> $somewhere_else. Then you try to work in $somewhere_else/symlink.\n\nYes correct. We have a number of different repositories like so:\n\nbanana.git/apps\nbanana.git/lib\norange.git/config\nkiwi.git/refdata\n\nand its convenient for many of our existing apps to be able to symlink\nthem all together into a common tree\n\njoined/apps -> banana.git/apps\njoined/lib -> banana.git/lib\njoined/config -> orange.git/config\njoined/refdata -> kiwi.git/refdata\n\nthis way for instance we can swap bits around easily on the fly and say,\nrestart a webserver or whatever.\n\nCurrently we can do this and all our other stuff works, and you\ncan /mostly/ work with git from the \"joined\" tree, with the exception of\ngit pull --rebase and apparently anything else that relies on\n--show-cdup\n\n> > > This patch changes --show-cdup to always show absolute workdir path\n> > > instead. I think this should hopefully cause no compatibility problems;\n> > > the testsuite is passing fine, at least.\n> > \n> > See the thread where I proposed a change like this, back with the infamous \n> > worktree desaster, and Junio NACKed; or the thread where Linus rightfully \n> > insists that git_dir should be relative if possible, for performance \n> > reasons.\n> \n>   I see, <7vk5sly3h9.fsf@assigned-by-dhcp.cox.net>. But noone was aware\n> of this possible user case. Performance reasons sound reasonable, though\n> I'm not really sure if for cdup in particular this ever matters.\n\nWould it be so bad to detect if the show-cdup actually resolves to the\nright place, and if it doesnt go absolute?\n\n> \n>   P.S.: Either way, there is a possible workaround to tell git about the\n> working directory manually using git --work-tree=... that I missed to\n> mention on IRC, Yves.\n\nHmm, am i using it wrong then?\n\n[dmq@somewhere apps]$ git-rev-parse --git-dir\n/home/dmq/git_tree/main/.git\n[dmq@somewhere apps]$ git --work-tree=\"$(git-rev-parse --git-dir)\" pull\n--rebase\n/usr/bin/git-sh-setup: line 139: cd: .git: No such file or directory\nUnable to determine absolute path of git directory\n\ncheers,\nyves\nps: not on list, please cc me on replies (sorry for the hassle)\n"},{"id":"83417","messageId":"1216141099.19334.196.camel@gemini","threadId":"14465","inReplyTo":"1216140100.19334.189.camel@gemini","subject":"Re: [PATCH] git rev-parse: Fix --show-cdup inside symlinked directory","fromName":"Yves Orton","fromEmail":"yves.orton@booking.com","sentAt":"2008-07-15T16:58:19Z","receivedAt":"2008-07-15T16:58:19Z","isPatch":true,"sender":{"key":"yves.orton@booking.com","avatar":null},"body":"On Tue, 2008-07-15 at 18:41 +0200, Yves Orton wrote:\n> On Tue, 2008-07-15 at 17:40 +0200, Petr Baudis wrote:\n> > \n> >   P.S.: Either way, there is a possible workaround to tell git about the\n> > working directory manually using git --work-tree=... that I missed to\n> > mention on IRC, Yves.\n> \n> Hmm, am i using it wrong then?\n> \n> [dmq@somewhere apps]$ git-rev-parse --git-dir\n> /home/dmq/git_tree/main/.git\n> [dmq@somewhere apps]$ git --work-tree=\"$(git-rev-parse --git-dir)\" pull\n> --rebase\n> /usr/bin/git-sh-setup: line 139: cd: .git: No such file or directory\n> Unable to determine absolute path of git directory\n\nHmm, realizing that was the workdir it wanted i tried it like so:\n\n[dmq@somewhere apps]$ git --work-tree=\"$(git-rev-parse --git-dir)/..\"\npull --rebase\n/usr/bin/git-sh-setup: line 139: cd: /home/dmq/git_tree/main/apps/.git:\nNo such file or directory\nUnable to determine absolute path of git directory\n\nYet:\n\n[dmq@somewhere apps]$ git-rev-parse --git-dir\n/home/dmq/git_tree/main/.git\n\nis correct.\n\n> cheers,\n> yves\n> ps: not on list, please cc me on replies (sorry for the hassle)\n> \n"},{"id":"83424","messageId":"487CF5A4.2070700@dawes.za.net","threadId":"14465","inReplyTo":"1216141099.19334.196.camel@gemini","subject":"Re: [PATCH] git rev-parse: Fix --show-cdup inside symlinked directory","fromName":"Rogan Dawes","fromEmail":"lists@dawes.za.net","sentAt":"2008-07-15T19:08:20Z","receivedAt":"2008-07-15T19:08:20Z","isPatch":true,"sender":{"key":"lists@dawes.za.net","avatar":null},"body":"Yves Orton wrote:\n\n> Hmm, realizing that was the workdir it wanted i tried it like so:\n> \n> [dmq@somewhere apps]$ git --work-tree=\"$(git-rev-parse --git-dir)/..\"\n> pull --rebase\n> /usr/bin/git-sh-setup: line 139: cd: /home/dmq/git_tree/main/apps/.git:\n> No such file or directory\n> Unable to determine absolute path of git directory\n> \n> Yet:\n> \n> [dmq@somewhere apps]$ git-rev-parse --git-dir\n> /home/dmq/git_tree/main/.git\n> \n> is correct.\n> \n\nAre you sure you don't want to specify the --git-dir rather than the \nwork dir?\n\ni.e.\n\ngit --git-dir=\"$(git-rev-parse --git-dir)\" pull --rebase\n\nRogan\n"},{"id":"83429","messageId":"1216153587.19334.204.camel@gemini","threadId":"14465","inReplyTo":"487CF5A4.2070700@dawes.za.net","subject":"Re: [PATCH] git rev-parse: Fix --show-cdup inside symlinked directory","fromName":"Yves Orton","fromEmail":"yves.orton@booking.com","sentAt":"2008-07-15T20:26:27Z","receivedAt":"2008-07-15T20:26:27Z","isPatch":true,"sender":{"key":"yves.orton@booking.com","avatar":null},"body":"On Tue, 2008-07-15 at 21:08 +0200, Rogan Dawes wrote:\n> Yves Orton wrote:\n> \n> > Hmm, realizing that was the workdir it wanted i tried it like so:\n> > \n> > [dmq@somewhere apps]$ git --work-tree=\"$(git-rev-parse --git-dir)/..\"\n> > pull --rebase\n> > /usr/bin/git-sh-setup: line 139: cd: /home/dmq/git_tree/main/apps/.git:\n> > No such file or directory\n> > Unable to determine absolute path of git directory\n> > \n> > Yet:\n> > \n> > [dmq@somewhere apps]$ git-rev-parse --git-dir\n> > /home/dmq/git_tree/main/.git\n> > \n> > is correct.\n> > \n> \n> Are you sure you don't want to specify the --git-dir rather than the \n> work dir?\n> \n> i.e.\n> \n> git --git-dir=\"$(git-rev-parse --git-dir)\" pull --rebase\n\nThat doesnt seem to work correctly either. If i do it from the symlinked\ndirectory i get a notice about each file needing an update. While it\nworks as expected from the real repo directory.\n\nI think this shows what i mean:\n\ndemerphq@gemini:~/git_test/bar$ git status\n# On branch master\n# Changed but not updated:\n#   (use \"git add <file>...\" to update what will be committed)\n#\n#       modified:   bar\n#\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\ndemerphq@gemini:~/git_test/bar$ git commit -a -m'changed bar'\nCreated commit 7cbbdc9: changed bar\n 1 files changed, 1 insertions(+), 0 deletions(-)\ndemerphq@gemini:~/git_test/bar$ git --git-dir=\"$(git-rev-parse\n--git-dir)\" pull --rebase\nbar/bar: needs update\nrefusing to pull with rebase: your working tree is not up-to-date\ndemerphq@gemini:~/git_test/bar$ cd ../foo2\ndemerphq@gemini:~/git_test/foo2$ git --git-dir=\"$(git-rev-parse\n--git-dir)\" pull --rebase\nCurrent branch master is up to date.\ndemerphq@gemini:~/git_test/foo2$ cd ..\ndemerphq@gemini:~/git_test$ ls -lart\ntotal 24\ndrwxr-xr-x   4 demerphq demerphq  4096 2008-07-15 22:17 foo\ndrwxr-xr-x 116 demerphq demerphq 12288 2008-07-15 22:18 ..\nlrwxrwxrwx   1 demerphq demerphq     8 2008-07-15 22:20 bar -> foo2/bar\ndrwxr-xr-x   4 demerphq demerphq  4096 2008-07-15 22:20 .\ndrwxr-xr-x   4 demerphq demerphq  4096 2008-07-15 22:21 foo2\n\n\n\nYves\n"}]}