{"thread":{"id":"26859","subject":"git-add says 'pathspec did not match any files' for git repository in /","startedAt":"2011-03-25T10:02:54Z","lastAt":"2011-03-26T07:59:52Z","messageCount":7,"participants":["Matthijs Kooijman","Nguyen Thai Ngoc Duy","Nguyễn Thái Ngọc Duy","Michael J Gruber"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"164290","messageId":"20110325100254.GH30350@login.drsnuggles.stderr.nl","threadId":"26859","inReplyTo":null,"subject":"git-add says 'pathspec did not match any files' for git repository in /","fromName":"Matthijs Kooijman","fromEmail":"matthijs@stdin.nl","sentAt":"2011-03-25T10:02:54Z","receivedAt":"2011-03-25T10:02:54Z","isPatch":false,"sender":{"key":"matthijs@stdin.nl","avatar":"https://avatars.githubusercontent.com/u/194491?v=4"},"body":"Hey folks,\n\nI've been using git for keeping config files using a repository in /.\nIn 1.7.4.1, this seems to be broken again. Committing, diffing and\nstatus work this time, but git add gives a pathspec did not match any\nfiles error when adding a file while the current working directory is\nnot /.\n\nThis is best illustrated by an example:\n\nroot@ldap:/# git init\nInitialized empty Git repository in /.git/\nroot@ldap:/# cd etc/\nroot@ldap:/etc# gt add fstab \nbash: gt: command not found\nroot@ldap:/etc# git add fstab\nfatal: pathspec 'fstab' did not match any files\nroot@ldap:/etc# ls -l fstab \n-rw-r--r-- 1 root root 37 Mar 24 16:58 fstab\nroot@ldap:/etc# cd /\nroot@ldap:/# git add /etc/fstab\nroot@ldap:/etc# git --version \ngit version 1.7.4.1\n\n\nAll of this worked properly in 1.7.1. There was a different problem in\n1.7.2, but that was fixed then (and with that fix, the above problem\ndidn't occur). I haven't tested 1.7.3.\n\nI don't have time to fix this right now, so I'll be sticking to 1.7.1\nfor now. Perhaps someone else want to look into this.\n\nGr.\n\nMatthijs\n"},{"id":"164293","messageId":"20110325125635.GA28118@do","threadId":"26859","inReplyTo":"20110325100254.GH30350@login.drsnuggles.stderr.nl","subject":"Re: git-add says 'pathspec did not match any files' for git repository in /","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-03-25T12:56:35Z","receivedAt":"2011-03-25T12:56:35Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Mar 25, 2011 at 11:02:54AM +0100, Matthijs Kooijman wrote:\n> Hey folks,\n> \n> I've been using git for keeping config files using a repository in /.\n> In 1.7.4.1, this seems to be broken again. Committing, diffing and\n> status work this time, but git add gives a pathspec did not match any\n> files error when adding a file while the current working directory is\n> not /.\n\nWe have t1509 to guard these cases (and it does indeed show\nbreakages). The problem is that the test requires chroot and cannot be\nrun automatically. I need to think of writing better tests.\n\nThe following makes t1509 pass again for me. You may want to try and\nsee if it fixes it for you.\n\ndiff --git a/setup.c b/setup.c\nindex 03cd84f..c18ea9c 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -390,15 +390,25 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t\treturn NULL;\n \t}\n \n-\tif (!prefixcmp(cwd, worktree) &&\n-\t    cwd[strlen(worktree)] == '/') { /* cwd inside worktree */\n-\t\tset_git_dir(real_path(gitdirenv));\n-\t\tif (chdir(worktree))\n-\t\t\tdie_errno(\"Could not chdir to '%s'\", worktree);\n-\t\tcwd[len++] = '/';\n-\t\tcwd[len] = '\\0';\n-\t\tfree(gitfile);\n-\t\treturn cwd + strlen(worktree) + 1;\n+\tif (!prefixcmp(cwd, worktree)) {\n+\t\tif (strlen(worktree) == offset_1st_component(worktree)) {\n+\t\t\tset_git_dir(real_path(gitdirenv));\n+\t\t\tif (chdir(worktree))\n+\t\t\t\tdie_errno(\"Could not chdir to '%s'\", worktree);\n+\t\t\tcwd[len++] = '/';\n+\t\t\tcwd[len] = '\\0';\n+\t\t\tfree(gitfile);\n+\t\t\treturn cwd + offset_1st_component(worktree);\n+\t\t}\n+\t\tif (cwd[strlen(worktree)] == '/') { /* cwd inside worktree */\n+\t\t\tset_git_dir(real_path(gitdirenv));\n+\t\t\tif (chdir(worktree))\n+\t\t\t\tdie_errno(\"Could not chdir to '%s'\", worktree);\n+\t\t\tcwd[len++] = '/';\n+\t\t\tcwd[len] = '\\0';\n+\t\t\tfree(gitfile);\n+\t\t\treturn cwd + strlen(worktree) + 1;\n+\t\t}\n \t}\n \n \t/* cwd outside worktree */\n\n-- \nDuy\n"},{"id":"164296","messageId":"1301060989-7246-1-git-send-email-pclouds@gmail.com","threadId":"26859","inReplyTo":"20110325100254.GH30350@login.drsnuggles.stderr.nl","subject":"[PATCH] setup: return correct prefix if worktree is '/'","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-03-25T13:49:49Z","receivedAt":"2011-03-25T13:49:49Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"The same old problem reappears after setup code is reworked. We tend\nto assume there is at least one path component in a path and forget\nthat path can be simply '/'.\n\nReported-by: Matthijs Kooijman <matthijs@stdin.nl>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n cache.h |    2 ++\n path.c  |   35 +++++++++++++++++++++++++++++++++++\n setup.c |    5 ++---\n 3 files changed, 39 insertions(+), 3 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex f765cf5..f579807 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -741,6 +741,8 @@ int longest_ancestor_length(const char *path, const char *prefix_list);\n char *strip_path_suffix(const char *path, const char *suffix);\n int daemon_avoid_alias(const char *path);\n int offset_1st_component(const char *path);\n+int is_subdir_or_same(const char *subdir, const char *dir);\n+const char *skip_dir(const char *dir, int skip);\n \n /* Read and unpack a sha1 file into memory, write memory to a sha1 file */\n extern int sha1_object_info(const unsigned char *, unsigned long *);\ndiff --git a/path.c b/path.c\nindex 4d73cc9..9f77aea 100644\n--- a/path.c\n+++ b/path.c\n@@ -662,3 +662,38 @@ int offset_1st_component(const char *path)\n \t\treturn 2 + is_dir_sep(path[2]);\n \treturn is_dir_sep(path[0]);\n }\n+\n+/* return 1 if subdir is either dir or inside dir */\n+int is_subdir_or_same(const char *subdir, const char *dir)\n+{\n+\tif (!*subdir || !*dir)\n+\t\tdie(\"BUG: how can I compare a dir to empty?\");\n+\n+\twhile (*dir && *subdir && *dir == *subdir) {\n+\t\tdir++;\n+\t\tsubdir++;\n+\t}\n+\n+\t/* help/me vs hell/yeah */\n+\tif (*dir && *subdir)\n+\t\treturn 0;\n+\n+\tif (!*subdir)\n+\t\treturn !*dir;\t/* same dir */\n+\n+\t/* foo/bar vs foo/ */\n+\tif (is_dir_sep(dir[-1]))\n+\t\treturn is_dir_sep(subdir[-1]);\n+\n+\t/* foo/bar vs foo */\n+\treturn is_dir_sep(*subdir);\n+}\n+\n+/* skip 'skip' chars and the trailing separator if any */\n+const char *skip_dir(const char *dir, int skip)\n+{\n+\tdir += skip;\n+\tif (is_dir_sep(*dir))\n+\t\tdir++;\n+\treturn dir;\n+}\ndiff --git a/setup.c b/setup.c\nindex 03cd84f..79f8ea7 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -390,15 +390,14 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,\n \t\treturn NULL;\n \t}\n \n-\tif (!prefixcmp(cwd, worktree) &&\n-\t    cwd[strlen(worktree)] == '/') { /* cwd inside worktree */\n+\tif (is_subdir_or_same(cwd, worktree)) {\t/* cwd inside worktree? */\n \t\tset_git_dir(real_path(gitdirenv));\n \t\tif (chdir(worktree))\n \t\t\tdie_errno(\"Could not chdir to '%s'\", worktree);\n \t\tcwd[len++] = '/';\n \t\tcwd[len] = '\\0';\n \t\tfree(gitfile);\n-\t\treturn cwd + strlen(worktree) + 1;\n+\t\treturn skip_dir(cwd, strlen(worktree));\n \t}\n \n \t/* cwd outside worktree */\n-- \n1.7.4.74.g639db\n"},{"id":"164297","messageId":"4D8CA3EF.3010403@drmicha.warpmail.net","threadId":"26859","inReplyTo":"1301060989-7246-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH] setup: return correct prefix if worktree is '/'","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-03-25T14:17:19Z","receivedAt":"2011-03-25T14:17:19Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Nguyễn Thái Ngọc Duy venit, vidit, dixit 25.03.2011 14:49:\n> The same old problem reappears after setup code is reworked. We tend\n> to assume there is at least one path component in a path and forget\n> that path can be simply '/'.\n> \n> Reported-by: Matthijs Kooijman <matthijs@stdin.nl>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  cache.h |    2 ++\n>  path.c  |   35 +++++++++++++++++++++++++++++++++++\n>  setup.c |    5 ++---\n>  3 files changed, 39 insertions(+), 3 deletions(-)\n> \n\nWait wait, the bug bisects to\n\n490544b (get_cwd_relative(): do not misinterpret suffix as subdirectory,\n2010-05-22)\n\nfor me, using\n\ngit bisect run sh -c \"make || exit 125; cd /etc; GIT_DIR=/tmp/a/.git\n~/src/git/git-add fstab || exit 1\"\n\nand a repo in /tmp/a/.git with core.worktree set to \"/\".\n\nThe issue is that in get_relative_cwd() of dir.c, \"dir\" (and maybe\n(\"cwd\") may or may not end in \"/\", so even with dir=\"/etc/\" and\ncwd=\"/etc\" we would not recognize we are within the repo. Patch for that\nis coming.\n\nNote that by doing something like the above, we can test / without being\nroot as long as we have files there which we can rely on being readable,\nor can rely on /tmp being there.\n\nMichael\n"},{"id":"164299","messageId":"AANLkTi=tZiVvBPy-VoTp+nWTPTrvpgY9OBPR-D0b7K5-@mail.gmail.com","threadId":"26859","inReplyTo":"4D8CA3EF.3010403@drmicha.warpmail.net","subject":"Re: [PATCH] setup: return correct prefix if worktree is '/'","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-03-25T15:11:56Z","receivedAt":"2011-03-25T15:11:56Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2011/3/25 Michael J Gruber <git@drmicha.warpmail.net>:\n> Wait wait, the bug bisects to\n>\n> 490544b (get_cwd_relative(): do not misinterpret suffix as subdirectory,\n> 2010-05-22)\n\nWell, we've had a few bugs in this area lately :) That one was fixed\nby fbbb4e1 (get_cwd_relative(): do not misinterpret root path -\n2010-11-20), which was also noticed by Mathijs.\n\n> for me, using\n>\n> git bisect run sh -c \"make || exit 125; cd /etc; GIT_DIR=/tmp/a/.git\n> ~/src/git/git-add fstab || exit 1\"\n>\n> and a repo in /tmp/a/.git with core.worktree set to \"/\".\n>\n> The issue is that in get_relative_cwd() of dir.c, \"dir\" (and maybe\n> (\"cwd\") may or may not end in \"/\", so even with dir=\"/etc/\" and\n> cwd=\"/etc\" we would not recognize we are within the repo. Patch for that\n> is coming.\n>\n> Note that by doing something like the above, we can test / without being\n> root as long as we have files there which we can rely on being readable,\n> or can rely on /tmp being there.\n\nSounds good, as long as we stick to standard paths, like /etc/fstab.\nBut that won't work on Windows. I don't even know if any file is\nalways at a known location in C:\\.\n-- \nDuy\n"},{"id":"164301","messageId":"b28c22b42c43f5dced45bee8ba4c76965b736d9a.1301068238.git.git@drmicha.warpmail.net","threadId":"26859","inReplyTo":"1301060989-7246-1-git-send-email-pclouds@gmail.com","subject":"[PATCH] dir.c: do not trip over difference in \"/\"","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-03-25T15:52:22Z","receivedAt":"2011-03-25T15:52:22Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"get_relative_cwd() tries to determine a common prefix for dir and cwd.\nThe fix in\n490544b (get_cwd_relative(): do not misinterpret suffix as subdirectory, 2010-05-22)\nmade the logic less naive (so that foo-bar is not misdetected as being\nwithin foo) but broke some other cases, in particular foo not being\ndetected as being within foo/ any more.\n\nFix it by taking into a account that a directory name may or may not end\nin /.\n\nDocument with a test.\n\nReported-by: Matthijs Kooijman <matthijs@stdin.nl>\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\nSo I think this would be a proper fix.\n\nI tried to be nice and base it on the commit which I bisected the problem to. I\nsaw much too late that their were later (failed) attempts at fixing this and a\nmajor rewrite of the test, which is quite a nuisance. Anyway, this problem needs a fix,\nand by taking get_cwd_relative() from this patch on top of next the problem is fixed.\nI have not looked into resolving the merge conflict in the test.\n\n dir.c               |   23 +++++++++++++++--------\n t/t1501-worktree.sh |   13 +++++++++++++\n 2 files changed, 28 insertions(+), 8 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 5615f33..b090cd0 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -956,16 +956,23 @@ char *get_relative_cwd(char *buffer, int size, const char *dir)\n \t\tdir++;\n \t\tcwd++;\n \t}\n-\tif (*dir)\n+\n+\t/* dir has more than just '/' left */\n+\tif (*dir && ((*dir != '/') || *(dir+1)))\n \t\treturn NULL;\n-\tswitch (*cwd) {\n-\tcase '\\0':\n+\t/* *dir is now '\\0' or '/' followed by '\\0' */\n+\tif (cwd == buffer) /* we did not move */\n+\t\treturn (*cwd) ? NULL : cwd;\n+\t/* we have moved at least by 1 */\n+\tif (*dir) /* == '/' */\n+\t\treturn (*cwd) ? NULL : cwd;\n+\tif (!(*cwd)) /* both ended */\n \t\treturn cwd;\n-\tcase '/':\n-\t\treturn cwd + 1;\n-\tdefault:\n-\t\treturn NULL;\n-\t}\n+\tif (*(dir-1) == '/') /* must have been common */\n+\t\treturn cwd;\n+\tif (*cwd == '/')\n+\t\treturn cwd+1;\n+\treturn NULL;\n }\n \n int is_inside_dir(const char *dir)\ndiff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh\nindex bd8b607..f0dbdd8 100755\n--- a/t/t1501-worktree.sh\n+++ b/t/t1501-worktree.sh\n@@ -63,6 +63,19 @@ cd sub/dir || exit 1\n test_rev_parse 'subdirectory' false false true sub/dir/\n cd ../../.. || exit 1\n \n+say \"core.worktree = absolute path/\"\n+GIT_DIR=$(pwd)/repo.git\n+GIT_CONFIG=$GIT_DIR/config\n+git config core.worktree \"$(pwd)/work/\"\n+test_rev_parse 'outside'      false false false\n+cd work2\n+test_rev_parse 'outside2'     false false false\n+cd ../work || exit 1\n+test_rev_parse 'inside'       false false true ''\n+cd sub/dir || exit 1\n+test_rev_parse 'subdirectory' false false true sub/dir/\n+cd ../../.. || exit 1\n+\n say \"GIT_WORK_TREE=relative path (override core.worktree)\"\n GIT_DIR=$(pwd)/repo.git\n GIT_CONFIG=$GIT_DIR/config\n-- \n1.7.4.1.607.g888da\n"},{"id":"164352","messageId":"AANLkTi=s1+BhwWrG_8S6kaF+_m9FHKdBEUMT5hgUGSvu@mail.gmail.com","threadId":"26859","inReplyTo":"b28c22b42c43f5dced45bee8ba4c76965b736d9a.1301068238.git.git@drmicha.warpmail.net","subject":"Re: [PATCH] dir.c: do not trip over difference in \"/\"","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-03-26T07:59:52Z","receivedAt":"2011-03-26T07:59:52Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2011/3/25 Michael J Gruber <git@drmicha.warpmail.net>:\n> get_relative_cwd() tries to determine a common prefix for dir and cwd.\n> The fix in\n> 490544b (get_cwd_relative(): do not misinterpret suffix as subdirectory, 2010-05-22)\n> made the logic less naive (so that foo-bar is not misdetected as being\n> within foo) but broke some other cases, in particular foo not being\n> detected as being within foo/ any more.\n\nI'd rather kill this function off. It's only used in is_inside_dir(),\nwe can be replaced with is_subdir_or_same() in my previous patch (more\nor less the same function with get_relative_cwd, but less cryptic).\n\n> diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh\n> index bd8b607..f0dbdd8 100755\n> --- a/t/t1501-worktree.sh\n> +++ b/t/t1501-worktree.sh\n> @@ -63,6 +63,19 @@ cd sub/dir || exit 1\n>  test_rev_parse 'subdirectory' false false true sub/dir/\n>  cd ../../.. || exit 1\n>\n> +say \"core.worktree = absolute path/\"\n> +GIT_DIR=$(pwd)/repo.git\n> +GIT_CONFIG=$GIT_DIR/config\n> +git config core.worktree \"$(pwd)/work/\"\n> +test_rev_parse 'outside'      false false false\n> +cd work2\n> +test_rev_parse 'outside2'     false false false\n> +cd ../work || exit 1\n> +test_rev_parse 'inside'       false false true ''\n> +cd sub/dir || exit 1\n> +test_rev_parse 'subdirectory' false false true sub/dir/\n> +cd ../../.. || exit 1\n> +\n>  say \"GIT_WORK_TREE=relative path (override core.worktree)\"\n>  GIT_DIR=$(pwd)/repo.git\n>  GIT_CONFIG=$GIT_DIR/config\n\nI tried something similar (basically core.worktree = $(pwd)/work/) but\ncould not reproduce. Note that worktree will be normalized by\nreal_path() (or get_absolute_path() earlier) and the trailing '/' may\nhave been removed.\n-- \nDuy\n"}]}