{"thread":{"id":"40626","subject":"git --literal-pathspecs add -u says \"fatal: pathspec ':/' did not match any files\"","startedAt":"2015-10-23T23:39:29Z","lastAt":"2015-10-24T17:57:16Z","messageCount":4,"participants":["Noam Postavsky","Victor Leschuk","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"272160","messageId":"CAM-tV--Q=DjTwLk8sZVm7-xMQsGwKmyjy4XiT08QpQ5-dffL0w@mail.gmail.com","threadId":"40626","inReplyTo":null,"subject":"git --literal-pathspecs add -u says \"fatal: pathspec ':/' did not match any files\"","fromName":"Noam Postavsky","fromEmail":"npostavs@users.sourceforge.net","sentAt":"2015-10-23T23:39:29Z","receivedAt":"2015-10-23T23:39:29Z","isPatch":false,"sender":{"key":"npostavs@users.sourceforge.net","avatar":"https://avatars.githubusercontent.com/u/287742?v=4"},"body":"~/tmp/tmprepo$ git init\nInitialized empty Git repository in /home/npostavs/tmp/tmprepo/.git/\n~/tmp/tmprepo$ git --literal-pathspecs add -u\nfatal: pathspec ':/' did not match any files\n~/tmp/tmprepo$ git --version\ngit version 2.6.1\n\nIt was reported[1] that 2.0.2 and several following versions also fail\nwith the same error; I found that version 1.9.5 succeeds.\n\nAdding a \".\" argument:\n\n   git --literal-pathspecs add -u .\n\nsucceeds in all versions.\n\n[1]: https://github.com/magit/magit/issues/2354#issuecomment-150665961\n"},{"id":"272161","messageId":"562B2FB2.4080604@gmail.com","threadId":"40626","inReplyTo":"CAM-tV--Q=DjTwLk8sZVm7-xMQsGwKmyjy4XiT08QpQ5-dffL0w@mail.gmail.com","subject":"Re: git --literal-pathspecs add -u says \"fatal: pathspec ':/' did not match any files\"","fromName":"Victor Leschuk","fromEmail":"vleschuk@gmail.com","sentAt":"2015-10-24T07:13:54Z","receivedAt":"2015-10-24T07:13:54Z","isPatch":false,"sender":{"key":"vleschuk@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1045374?v=4"},"body":"Hello Noam,\n\nThe problem is that in the absence of explicit argument we set the list \nof files to special path \":/\" which means repo root:\n\n     if ((0 < addremove_explicit || take_worktree_changes) && !argc) {\n         static const char *whole[2] = { \":/\", NULL };\n         argc = 1;\n         argv = whole;\n     }\n\nAnd after that we treat it as regular file\n\n\n             if (!seen[i] && path[0] &&\n                 ((pathspec.items[i].magic &\n                   (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||\n                  !file_exists(path))) {          /* <======== \nfile_exists() here just checks lstat() result */\nMaybe it'll make sense to modify file_exists() to treat \":/\" specially. \nSomething like that:\n\ndiff --git a/dir.c b/dir.c\nindex 109ceea..6cae3b9 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -2103,6 +2103,10 @@ int read_directory(struct dir_struct *dir, const \nchar *path, int len, const stru\n  int file_exists(const char *f)\n  {\n         struct stat sb;\n+       if (!strcmp(f, \":/\")) {\n+               /* \":/\" - root dir, always exists */\n+               return 1;\n+       }\n         return lstat(f, &sb) == 0;\n  }\n\n--\nVictor\n\nOn 10/24/2015 02:39 AM, Noam Postavsky wrote:\n> ~/tmp/tmprepo$ git init\n> Initialized empty Git repository in /home/npostavs/tmp/tmprepo/.git/\n> ~/tmp/tmprepo$ git --literal-pathspecs add -u\n> fatal: pathspec ':/' did not match any files\n> ~/tmp/tmprepo$ git --version\n> git version 2.6.1\n>\n> It was reported[1] that 2.0.2 and several following versions also fail\n> with the same error; I found that version 1.9.5 succeeds.\n>\n> Adding a \".\" argument:\n>\n>     git --literal-pathspecs add -u .\n>\n> succeeds in all versions.\n>\n> [1]: https://github.com/magit/magit/issues/2354#issuecomment-150665961\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n"},{"id":"272174","messageId":"CAM-tV-8Qpy2fLMU=x7Yc4x2BhwpwN+0zZtJspYMZpamCij=z5A@mail.gmail.com","threadId":"40626","inReplyTo":"562B2FB2.4080604@gmail.com","subject":"Re: git --literal-pathspecs add -u says \"fatal: pathspec ':/' did not match any files\"","fromName":"Noam Postavsky","fromEmail":"npostavs@users.sourceforge.net","sentAt":"2015-10-24T16:55:47Z","receivedAt":"2015-10-24T16:55:47Z","isPatch":false,"sender":{"key":"npostavs@users.sourceforge.net","avatar":"https://avatars.githubusercontent.com/u/287742?v=4"},"body":"On Sat, Oct 24, 2015 at 3:13 AM, Victor Leschuk <vleschuk@gmail.com> wrote:\n> The problem is that in the absence of explicit argument we set the list of\n> files to special path \":/\" which means repo root:\n\n> And after that we treat it as regular file\n\nAha.\n\n> Maybe it'll make sense to modify file_exists() to treat \":/\" specially.\n\nI'm not sure how this would translate into code, but it would make\nmore sense to me if we undo the effect of --literal-pathspecs when\nsetting arguments to \":/\". After all, it's obviously not meant to be a\nliteral file so it shouldn't treated as one (also this way still\nallows a user to pass --literal-pathspecs with \":/\" to add an actual\ndirectory named \":\" (not that anyone should ever want that)).\n"},{"id":"272175","messageId":"xmqq37x0m9oj.fsf@gitster.mtv.corp.google.com","threadId":"40626","inReplyTo":"562B2FB2.4080604@gmail.com","subject":"Re* git --literal-pathspecs add -u says \"fatal: pathspec ':/' did not match any files\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-10-24T17:57:16Z","receivedAt":"2015-10-24T17:57:16Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Victor Leschuk <vleschuk@gmail.com> writes:\n\n> Maybe it'll make sense to modify file_exists() to treat \":/\"\n> specially.\n\nThe real problem is that the code assumes that it can internally use\n\":/\" to mean \"everything from the top\", and with global 'literal\npathspec' magic, that is not the case.  \"did not match\" is a red\nherring.  Even if you disable that typo-catcher, the resulting\npathspec will match only paths inside a directory whose name is ':',\nso you would break 'add -u' in a more grave way.\n\nDisabling the typo-catcher has another problem.  When an end user\nsays \"git --literal-pathspecs add -u :/\", the user means \"I happen\nto have this funnily named directory ':' and want to update\neverything under it, but because :/ is normally taken as special, I\nam passing --literal-pathspecs\".  And if that ':' does not exist,\nthe user must get the \"well you may have misspelt it\" error.\n\nBut a code you are changing cannot tell if \":/\" came from the end\nuser, or if it the one added by our code upon seeing \"-u\" or \"-A\"\nwithout any pathspecs, to make that distinction so that you disable\nit only for our internal \":/\".\n\nI think the right approach is something along the line of this patch\ninstead.\n\n-- >8 --\nSubject: add: simplify -u/-A without pathspec\n\nSince Git 2.0, \"add -u\" and \"add -A\" run from a subdirectory without\nany pathspec mean \"everything in the working tree\" (before 2.0, they\nwere limited to the current directory).  The limiting to the current\ndirectory was implemented by inserting \".\" to the command line when\nthe end user did not give us any pathspec.  At 2.0, we updated the\ncode to insert \":/\" (instead of '.') to consider everything from the\ntop-level, by using a pathspec magic \"top\".\n\nThe call to parse_pathspec() using the command line arguments is,\nhowever, made with PATHSPEC_PREFER_FULL option since 5a76aff1 (add:\nconvert to use parse_pathspec, 2013-07-14), which predates Git 2.0.\nIn retrospect, there was no need to turn \"adding . to limit to the\ndirectory\" into \"adding :/ to unlimit to everywhere\" in Git 2.0;\ninstead we could just have done \"if there is no pathspec on the\ncommand line, just let it be\".  The parse_pathspec() then would give\nus a pathspec that matches everything and all is well.\n\nIncidentally such a simplifcation also fixes a corner case bug that\nstems from the fact that \":/\" does not necessarily mean any magic.\nA user would say \"git --literal-pathspecs add -u :/\" from the\ncommand line when she has a directory ':' and wants to add\neverything in it (and she knows that her :/ will be taken as\n'everything under the sun' magic pathspec unless she disables the\nmagic with --literal-pathspecs).  The internal use of ':/' would\nbehave the same way as such an explicitly given \":/\" when run with\n\"--literal-pathspecs\", and will not add everything under the sun as\nthe code originally intended.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\n builtin/add.c | 8 +-------\n 1 file changed, 1 insertion(+), 7 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex b2a5c57..145f06e 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -336,14 +336,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \tif (!show_only && ignore_missing)\n \t\tdie(_(\"Option --ignore-missing can only be used together with --dry-run\"));\n \n-\tif ((0 < addremove_explicit || take_worktree_changes) && !argc) {\n-\t\tstatic const char *whole[2] = { \":/\", NULL };\n-\t\targc = 1;\n-\t\targv = whole;\n-\t}\n-\n \tadd_new_files = !take_worktree_changes && !refresh_only;\n-\trequire_pathspec = !take_worktree_changes;\n+\trequire_pathspec = !(take_worktree_changes || (0 < addremove_explicit));\n \n \thold_locked_index(&lock_file, 1);\n \n"}]}