{"thread":{"id":"27014","subject":"[PATCH 0/4] Redoing the \"add -u\" migration plan","startedAt":"2011-04-07T01:16:32Z","lastAt":"2011-05-03T16:17:04Z","messageCount":35,"participants":["Junio C Hamano","Nguyen Thai Ngoc Duy","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"165330","messageId":"1302138996-10006-1-git-send-email-gitster@pobox.com","threadId":"27014","inReplyTo":null,"subject":"[PATCH 0/4] Redoing the \"add -u\" migration plan","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-07T01:16:32Z","receivedAt":"2011-04-07T01:16:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"So here is the new migration plan to make \"add -u\" without pathspec to\ndefault to the tree wide operation at 1.8.0 boundary.\n\nThe first patch is more or less the same as the \"heads-up\" version I sent\nearlier to implement the magic \":/\" pathspec at a wrong level as a hack,\nbut with some documentation updates.\n\nIt should apply on top of a91df69 (the parent of the first commit in the\n\"jc/add-u-migration\" series).  Then merge the 33c33ca (the first commit in\nthe \"jc/add-u-migration\" series) to the result, and then apply the\nremainder of this series.\n\nThe second patch gets rid of treewideupdate configuration variable, as we\nno longer rely on user preference for this migration plan, and rewords the\nwarning message.  I did it this way only because the first commit in the\nold series is already in 'next'; I will redo the series after 1.7.5 ships\nso that we do not have to have this patch, nor \"a configuration appears\nand then disappears\".\n\nThe third (step 2) patch is what should happen at 1.8.0 boundary by\nflipping the default, but still keeps the warning for people who missed\nthe late 1.7.X series.\n\nThe last (step 3) patch is to remove the warning long after 1.8.0 boundary\nwhen everybody got used to the new behaviour.\n\nJunio C Hamano (4):\n  magic pathspec: add tentative \":/path/from/top/level\" pathspec support\n  add -u: get rid of \"treewideupdate\" configuration\n  add: make \"add -u/-A\" update full tree without pathspec (step 2)\n  add: make \"add -u/-A\" update full tree without pathspec (step 3)\n"},{"id":"165331","messageId":"1302138996-10006-2-git-send-email-gitster@pobox.com","threadId":"27014","inReplyTo":"1302138996-10006-1-git-send-email-gitster@pobox.com","subject":"[PATCH 1/4] magic pathspec: add tentative \":/path/from/top/level\" pathspec support","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-07T01:16:33Z","receivedAt":"2011-04-07T01:16:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Support \":/\" magic string that can be prefixed to a pathspec element to\nsay \"this names the path from the top-level of the working tree\", when\nyou are in the subdirectory.\n\nFor example, you should be able to say:\n\n    $ edit Makefile ;# top-level\n    $ cd Documentation\n    $ edit git.txt ;# in the subdirectory\n\nand then do one of three things, still inside the subdirectory:\n\n    $ git add -u .  ;# add only Documentation/git.txt\n    $ git add -u :/ ;# add everything, including paths outside Documentation\n    $ git add -u    ;# whatever the default setting is.\n\nTo truly support magic pathspec, the API needs to be restructured so that\nget_pathspec() and init_pathspec() are unified into one call.  Currently,\nthe former just prefixes the user supplied pathspec with the current\nsubdirectory path, and the latter takes the output from the former and\npre-parses them into a bit richer structure for easier handling.  They\nshould become a single API function that takes the current subdirectory\npath and the remainder of argv[] (after parsing --options and revision\narguments from the command line) and returns an array of parsed pathspec\nelements, and \"magic\" should become attributes of struct pathspec_item.\n\nThis patch implements only \"top\" magic because it is the only kind of\nmagic that can be hacked into the system without such a refactoring.\nOther types of magic that are envisioned (e.g. \"icase\") needs to be able\nto express more than what a simple string can encode and needs to wait.\n\nThe syntax for magic pathspec prefix is designed to be extensible yet\nsimple to type to invoke a simple magic like \"from the top\".  The parser\nfor the magic prefix is hooked into get_pathspec() function in this patch,\nand it needs to be moved when we refactor the API.\n\nBut we have to start from somewhere.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/glossary-content.txt |   31 +++++++++++-\n setup.c                            |   98 +++++++++++++++++++++++++++++++++++-\n 2 files changed, 126 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt\nindex 33716a3..e51d7e6 100644\n--- a/Documentation/glossary-content.txt\n+++ b/Documentation/glossary-content.txt\n@@ -277,7 +277,8 @@ This commit is referred to as a \"merge commit\", or sometimes just a\n        Pattern used to specify paths.\n +\n Pathspecs are used on the command line of \"git ls-files\", \"git\n-ls-tree\", \"git grep\", \"git checkout\", and many other commands to\n+ls-tree\", \"git add\", \"git grep\", \"git diff\", \"git checkout\",\n+and many other commands to\n limit the scope of operations to some subset of the tree or\n worktree.  See the documentation of each command for whether\n paths are relative to the current directory or toplevel.  The\n@@ -296,6 +297,34 @@ For example, Documentation/*.jpg will match all .jpg files\n in the Documentation subtree,\n including Documentation/chapter_1/figure_1.jpg.\n \n++\n+A pathspec that begins with a colon `:` has special meaning.  In the\n+short form, the leading colon `:` is followed by zero or more \"magic\n+signature\" letters (which optionally is terminated by another colon `:`),\n+and the remainder is the pattern to match against the path. The optional\n+colon that terminates the \"magic signature\" can be omitted if the pattern\n+begins with a character that cannot be a \"magic signature\" and is not a\n+colon.\n++\n+In the long form, the leading colon `:` is followed by a open\n+parenthesis `(`, a comma-separated list of zero or more \"magic words\",\n+and a close parentheses `)`, and the remainder is the pattern to match\n+against the path.\n++\n+The \"magic signature\" consists of an ASCII symbol that is not\n+alphanumeric.\n++\n+--\n+top `/`;;\n+\tThe magic word `top` (mnemonic: `/`) makes the pattern match\n+\tfrom the root of the working tree, even when you are running\n+\tthe command from inside a subdirectory.\n+--\n++\n+Currently only the slash `/` is recognized as the \"magic signature\",\n+but it is envisioned that we will support more types of magic in later\n+versions of git.\n+\n [[def_parent]]parent::\n \tA <<def_commit_object,commit object>> contains a (possibly empty) list\n \tof the logical predecessor(s) in the line of development, i.e. its\ndiff --git a/setup.c b/setup.c\nindex 03cd84f..820ed05 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -126,6 +126,101 @@ void verify_non_filename(const char *prefix, const char *arg)\n \t    \"Use '--' to separate filenames from revisions\", arg);\n }\n \n+/*\n+ * Magic pathspec\n+ *\n+ * NEEDSWORK: These need to be moved to dir.h or even to a new\n+ * pathspec.h when we restructure get_pathspec() users to use the\n+ * \"struct pathspec\" interface.\n+ *\n+ * Possible future magic semantics include stuff like:\n+ *\n+ *\t{ PATHSPEC_NOGLOB, '!', \"noglob\" },\n+ *\t{ PATHSPEC_ICASE, '\\0', \"icase\" },\n+ *\t{ PATHSPEC_RECURSIVE, '*', \"recursive\" },\n+ *\t{ PATHSPEC_REGEXP, '\\0', \"regexp\" },\n+ *\n+ */\n+#define PATHSPEC_FROMTOP    (1<<0)\n+\n+struct pathspec_magic {\n+\tunsigned bit;\n+\tchar mnemonic; /* this cannot be ':'! */\n+\tconst char *name;\n+} pathspec_magic[] = {\n+\t{ PATHSPEC_FROMTOP, '/', \"top\" },\n+};\n+\n+/*\n+ * Take an element of a pathspec and check for magic signatures.\n+ * Append the result to the prefix.\n+ *\n+ * For now, we only parse the syntax and throw out anything other than\n+ * \"top\" magic.\n+ *\n+ * NEEDSWORK: This needs to be rewritten when we start migrating\n+ * get_pathspec() users to use the \"struct pathspec\" interface.  For\n+ * example, a pathspec element may be marked as case-insensitive, but\n+ * the prefix part must always match literally, and a single stupid\n+ * string cannot express such a case.\n+ */\n+const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)\n+{\n+\tunsigned magic = 0;\n+\tconst char *copyfrom = elt;\n+\tint i;\n+\n+\tif (elt[0] != ':') {\n+\t\t; /* nothing to do */\n+\t} else if (elt[1] == '(') {\n+\t\t/* longhand */\n+\t\tconst char *nextat;\n+\t\tfor (copyfrom = elt + 2;\n+\t\t     *copyfrom && *copyfrom != ')';\n+\t\t     copyfrom = nextat) {\n+\t\t\tsize_t len = strcspn(copyfrom, \",)\");\n+\t\t\tif (copyfrom[len] == ')')\n+\t\t\t\tnextat = copyfrom + len;\n+\t\t\telse\n+\t\t\t\tnextat = copyfrom + len + 1;\n+\t\t\tif (!len)\n+\t\t\t\tcontinue;\n+\t\t\tfor (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)\n+\t\t\t\tif (strlen(pathspec_magic[i].name) == len &&\n+\t\t\t\t    !strncmp(pathspec_magic[i].name, copyfrom, len)) {\n+\t\t\t\t\tmagic |= pathspec_magic[i].bit;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\tif (ARRAY_SIZE(pathspec_magic) <= i)\n+\t\t\t\tdie(\"Invalid pathspec magic '%.*s' in '%s'\",\n+\t\t\t\t    (int) len, copyfrom, elt);\n+\t\t}\n+\t\tif (*copyfrom == ')')\n+\t\t\tcopyfrom++;\n+\t} else {\n+\t\t/* shorthand */\n+\t\tfor (copyfrom = elt + 1;\n+\t\t     *copyfrom && *copyfrom != ':';\n+\t\t     copyfrom++) {\n+\t\t\tchar ch = *copyfrom;\n+\t\t\tfor (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)\n+\t\t\t\tif (pathspec_magic[i].mnemonic == ch) {\n+\t\t\t\t\tmagic |= pathspec_magic[i].bit;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\tif (ARRAY_SIZE(pathspec_magic) <= i)\n+\t\t\t\tbreak;\n+\t\t}\n+\t\tif (*copyfrom == ':')\n+\t\t\tcopyfrom++;\n+\t}\n+\n+\tif (magic & PATHSPEC_FROMTOP)\n+\t\treturn xstrdup(copyfrom);\n+\telse\n+\t\treturn prefix_path(prefix, prefixlen, copyfrom);\n+}\n+\n const char **get_pathspec(const char *prefix, const char **pathspec)\n {\n \tconst char *entry = *pathspec;\n@@ -147,8 +242,7 @@ const char **get_pathspec(const char *prefix, const char **pathspec)\n \tdst = pathspec;\n \tprefixlen = prefix ? strlen(prefix) : 0;\n \twhile (*src) {\n-\t\tconst char *p = prefix_path(prefix, prefixlen, *src);\n-\t\t*(dst++) = p;\n+\t\t*(dst++) = prefix_pathspec(prefix, prefixlen, *src);\n \t\tsrc++;\n \t}\n \t*dst = NULL;\n-- \n1.7.5.rc1\n"},{"id":"165334","messageId":"1302138996-10006-3-git-send-email-gitster@pobox.com","threadId":"27014","inReplyTo":"1302138996-10006-1-git-send-email-gitster@pobox.com","subject":"[PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-07T01:16:34Z","receivedAt":"2011-04-07T01:16:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thanks to the magic \":/\" pathspec, it is much easier to invoke both\ntree-wide operation and limited-to-cwd operation on demand from the\ncommand line.  What remains is the downside of the configuration variable,\nnamely, that it makes git behave differently depending on who you are and\nin which repository you are using it, hence making it harder to help\nand/or teach others.\n\nRemove the configuration variable, and adjust the warning message.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/add.c         |   26 ++++++--------------------\n t/t2200-add-update.sh |   29 +++++++++++++++++++----------\n 2 files changed, 25 insertions(+), 30 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 595f5cc..f58d1cf 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -310,7 +310,6 @@ static const char ignore_error[] =\n \n static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;\n static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0;\n-static int default_tree_wide_update = -1;\n \n static struct option builtin_add_options[] = {\n \tOPT__DRY_RUN(&show_only, \"dry run\"),\n@@ -336,10 +335,6 @@ static int add_config(const char *var, const char *value, void *cb)\n \t\tignore_add_errors = git_config_bool(var, value);\n \t\treturn 0;\n \t}\n-\tif (!strcasecmp(var, \"add.treewideupdate\")) {\n-\t\tdefault_tree_wide_update = git_config_bool(var, value);\n-\t\treturn 0;\n-\t}\n \treturn git_default_config(var, value, cb);\n }\n \n@@ -368,15 +363,10 @@ static const char *warn_add_uA_180_migration_msg[] = {\n \t\"In release 1.8.0, running 'git add -u' (or 'git add -A') from\",\n \t\"a subdirectory without giving any pathspec WILL take effect\",\n \t\"on the whole working tree, not just the part under the current\",\n-\t\"directory. You can set add.treewideupdate configuration variable\",\n-\t\"to 'false' to keep the current behaviour.\",\n-\t\"You can set the configuration variable to 'true' to make the\",\n-\t\"'git add -u/-A' command without pathspec take effect on the whole\",\n-\t\"working tree now. If you do so, you can use '.' at the end of\",\n-\t\"the command, e.g. 'git add -u .' when you want to limit the\",\n-\t\"operation to the current directory.\",\n-\t\"This warning will be issued until you set the configuration variable\",\n-\t\"to either 'true' or 'false'.\"\n+\t\"directory. Please make it a habit to add '.' when you want to\",\n+\t\"limit the operation to the current directory and below.\",\n+\t\"You can use ':/' at the end of the command to affect the operation\",\n+\t\"on the whole working tree.\",\n };\n \n static int warn_180_migration(void)\n@@ -419,12 +409,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\tdie(\"Option --ignore-missing can only be used together with --dry-run\");\n \tif ((addremove || take_worktree_changes) && !argc) {\n \t\twhole_tree_add = 1;\n-\t\tif (prefix) {\n-\t\t\tif (default_tree_wide_update < 0)\n-\t\t\t\tdefault_tree_wide_update = warn_180_migration();\n-\t\t\tif (!default_tree_wide_update)\n-\t\t\t\twhole_tree_add = 0;\n-\t\t}\n+\t\tif (prefix)\n+\t\t\twhole_tree_add = warn_180_migration();\n \t}\n \n \tadd_new_files = !take_worktree_changes && !refresh_only;\ndiff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh\nindex 7ac8b70..f7711ba 100755\n--- a/t/t2200-add-update.sh\n+++ b/t/t2200-add-update.sh\n@@ -80,10 +80,9 @@ test_expect_success 'change gets noticed' '\n \n '\n \n-test_expect_success 'update from a subdirectory without pathspec (no config)' '\n+test_expect_success 'update from a subdirectory without pathspec' '\n \t# This test needs to be updated to expect the whole tree\n \t# update after 1.8.0 migration.\n-\ttest_might_fail git config --remove add.treewideupdate &&\n \ttest_might_fail git reset check dir1 &&\n \techo changed >check &&\n \t(\n@@ -97,15 +96,13 @@ test_expect_success 'update from a subdirectory without pathspec (no config)' '\n \tgrep warning expect.warning\n '\n \n-test_expect_success 'update from a subdirectory without pathspec (local)' '\n-\ttest_when_finished \"git config --remove add.treewideupdate; :\" &&\n-\tgit config add.treewideupdate false &&\n+test_expect_success 'update from a subdirectory with local pathspec' '\n \ttest_might_fail git reset check dir1 &&\n \techo changed >check &&\n \t(\n \t\tcd dir1 &&\n \t\techo even more >sub2 &&\n-\t\tgit add -u 2>../expect.warning\n+\t\tgit add -u . 2>../expect.warning\n \t) &&\n \tgit diff-files --name-only dir1 check >actual &&\n \techo check >expect &&\n@@ -113,15 +110,27 @@ test_expect_success 'update from a subdirectory without pathspec (local)' '\n \t! grep warning expect.warning\n '\n \n-test_expect_success 'update from a subdirectory without pathspec (global)' '\n-\ttest_when_finished \"git config --remove add.treewideupdate; :\" &&\n-\tgit config add.treewideupdate true &&\n+test_expect_success 'update from a subdirectory with magic pathspec (mnemonic)' '\n \ttest_might_fail git reset check dir1 &&\n \techo changed >check &&\n \t(\n \t\tcd dir1 &&\n \t\techo even more >sub2 &&\n-\t\tgit add -u 2>../expect.warning\n+\t\tgit add -u :/ 2>../expect.warning\n+\t) &&\n+\tgit diff-files --name-only dir1 check >actual &&\n+\t: >expect &&\n+\ttest_cmp expect actual &&\n+\t! grep warning expect.warning\n+'\n+\n+test_expect_success 'update from a subdirectory with magic pathspec (longhand)' '\n+\ttest_might_fail git reset check dir1 &&\n+\techo changed >check &&\n+\t(\n+\t\tcd dir1 &&\n+\t\techo even more >sub2 &&\n+\t\tgit add -u \":(top)\" 2>../expect.warning\n \t) &&\n \tgit diff-files --name-only dir1 check >actual &&\n \t: >expect &&\n-- \n1.7.5.rc1\n"},{"id":"165332","messageId":"1302138996-10006-4-git-send-email-gitster@pobox.com","threadId":"27014","inReplyTo":"1302138996-10006-1-git-send-email-gitster@pobox.com","subject":"[PATCH 3/4] add: make \"add -u/-A\" update full tree without pathspec (step 2)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-07T01:16:35Z","receivedAt":"2011-04-07T01:16:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Flip the default behaviour when \"git add -u/-A\" is run without a\npathspec from a subdirectory to tree-wide, and reword the advice\nmessage.\n\nWe will need to keep the advice message for a while to help people\nwho skipped the 1.8.0 boundary.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/add.c         |    8 ++++----\n t/t2200-add-update.sh |    2 +-\n 2 files changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex f58d1cf..6e6cdc0 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -360,13 +360,13 @@ static int add_files(struct dir_struct *dir, int flags)\n }\n \n static const char *warn_add_uA_180_migration_msg[] = {\n-\t\"In release 1.8.0, running 'git add -u' (or 'git add -A') from\",\n-\t\"a subdirectory without giving any pathspec WILL take effect\",\n+\t\"Since release 1.8.0, running 'git add -u' (or 'git add -A')\",\n+\t\"from a subdirectory without giving any pathspec takes effect\",\n \t\"on the whole working tree, not just the part under the current\",\n \t\"directory. Please make it a habit to add '.' when you want to\",\n \t\"limit the operation to the current directory and below.\",\n \t\"You can use ':/' at the end of the command to affect the operation\",\n-\t\"on the whole working tree.\",\n+\t\"on the whole working tree, if you want to be explicit.\",\n };\n \n static int warn_180_migration(void)\n@@ -374,7 +374,7 @@ static int warn_180_migration(void)\n \tint i;\n \tfor (i = 0; i < ARRAY_SIZE(warn_add_uA_180_migration_msg); i++)\n \t\twarning(\"%s\", warn_add_uA_180_migration_msg[i]);\n-\treturn 0; /* default to \"no\" (not tree-wide, i.e. local) */\n+\treturn 1; /* default to \"true\" (tree-wide, i.e. not local) */\n }\n \n int cmd_add(int argc, const char **argv, const char *prefix)\ndiff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh\nindex f7711ba..a601394 100755\n--- a/t/t2200-add-update.sh\n+++ b/t/t2200-add-update.sh\n@@ -91,7 +91,7 @@ test_expect_success 'update from a subdirectory without pathspec' '\n \t\tgit add -u 2>../expect.warning\n \t) &&\n \tgit diff-files --name-only dir1 check >actual &&\n-\techo check >expect &&\n+\t: >expect &&\n \ttest_cmp expect actual &&\n \tgrep warning expect.warning\n '\n-- \n1.7.5.rc1\n"},{"id":"165333","messageId":"1302138996-10006-5-git-send-email-gitster@pobox.com","threadId":"27014","inReplyTo":"1302138996-10006-1-git-send-email-gitster@pobox.com","subject":"[PATCH 4/4] add: make \"add -u/-A\" update full tree without pathspec (step 3)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-07T01:16:36Z","receivedAt":"2011-04-07T01:16:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Now long after 1.8.0 happened, people should have got used to the\nnew default behaviour and it is no longer necessary to give the\nmigration advice anymore.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/add.c         |   23 +----------------------\n t/t2200-add-update.sh |    4 +---\n 2 files changed, 2 insertions(+), 25 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 6e6cdc0..3564d7e 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -359,24 +359,6 @@ static int add_files(struct dir_struct *dir, int flags)\n \treturn exit_status;\n }\n \n-static const char *warn_add_uA_180_migration_msg[] = {\n-\t\"Since release 1.8.0, running 'git add -u' (or 'git add -A')\",\n-\t\"from a subdirectory without giving any pathspec takes effect\",\n-\t\"on the whole working tree, not just the part under the current\",\n-\t\"directory. Please make it a habit to add '.' when you want to\",\n-\t\"limit the operation to the current directory and below.\",\n-\t\"You can use ':/' at the end of the command to affect the operation\",\n-\t\"on the whole working tree, if you want to be explicit.\",\n-};\n-\n-static int warn_180_migration(void)\n-{\n-\tint i;\n-\tfor (i = 0; i < ARRAY_SIZE(warn_add_uA_180_migration_msg); i++)\n-\t\twarning(\"%s\", warn_add_uA_180_migration_msg[i]);\n-\treturn 1; /* default to \"true\" (tree-wide, i.e. not local) */\n-}\n-\n int cmd_add(int argc, const char **argv, const char *prefix)\n {\n \tint exit_status = 0;\n@@ -407,11 +389,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\tdie(\"-A and -u are mutually incompatible\");\n \tif (!show_only && ignore_missing)\n \t\tdie(\"Option --ignore-missing can only be used together with --dry-run\");\n-\tif ((addremove || take_worktree_changes) && !argc) {\n+\tif ((addremove || take_worktree_changes) && !argc)\n \t\twhole_tree_add = 1;\n-\t\tif (prefix)\n-\t\t\twhole_tree_add = warn_180_migration();\n-\t}\n \n \tadd_new_files = !take_worktree_changes && !refresh_only;\n \trequire_pathspec = !take_worktree_changes;\ndiff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh\nindex a601394..3ad6bff 100755\n--- a/t/t2200-add-update.sh\n+++ b/t/t2200-add-update.sh\n@@ -81,8 +81,6 @@ test_expect_success 'change gets noticed' '\n '\n \n test_expect_success 'update from a subdirectory without pathspec' '\n-\t# This test needs to be updated to expect the whole tree\n-\t# update after 1.8.0 migration.\n \ttest_might_fail git reset check dir1 &&\n \techo changed >check &&\n \t(\n@@ -93,7 +91,7 @@ test_expect_success 'update from a subdirectory without pathspec' '\n \tgit diff-files --name-only dir1 check >actual &&\n \t: >expect &&\n \ttest_cmp expect actual &&\n-\tgrep warning expect.warning\n+\t! grep warning expect.warning\n '\n \n test_expect_success 'update from a subdirectory with local pathspec' '\n-- \n1.7.5.rc1\n"},{"id":"165335","messageId":"7v62qqhm9h.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"1302138996-10006-2-git-send-email-gitster@pobox.com","subject":"Re: [PATCH 1/4] magic pathspec: add tentative \":/path/from/top/level\" pathspec support","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-07T01:40:26Z","receivedAt":"2011-04-07T01:40:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> This patch implements only \"top\" magic because it is the only kind of\n> magic that can be hacked into the system without such a refactoring.\n> Other types of magic that are envisioned (e.g. \"icase\") needs to be able\n> to express more than what a simple string can encode and needs to wait.\n\nActually \"icase\" could be implemented inside get_pathspec() by doing\nsomething like the attached patch.\n\nBut \"noglob\" needs support from the \"struct pathspec_item\" infrastructure.\nIt is insufficient to parse the magic signature at get_pathspec() level,\nas I do not see a way to encode these magic in the match string.\n\nI suspect that Duy's favourite \"negate\" cannot be done if we discard the\nmagic information at the get_pathspec() level, either.\n\n---\n Documentation/glossary-content.txt |    7 +++++--\n setup.c                            |   31 +++++++++++++++++++++++++++----\n 2 files changed, 32 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt\nindex e51d7e6..0ca029b 100644\n--- a/Documentation/glossary-content.txt\n+++ b/Documentation/glossary-content.txt\n@@ -319,10 +319,13 @@ top `/`;;\n \tThe magic word `top` (mnemonic: `/`) makes the pattern match\n \tfrom the root of the working tree, even when you are running\n \tthe command from inside a subdirectory.\n+icase;;\n+\tThe magic word `icase` (there is no mnemonic for it) makes the\n+\tpattern match case insensitively.  E.g. `:(icase)makefile` matches\n+\tboth `Makefile` and `makefile`.\n --\n +\n-Currently only the slash `/` is recognized as the \"magic signature\",\n-but it is envisioned that we will support more types of magic in later\n+It is envisioned that we will support more types of magic in later\n versions of git.\n \n [[def_parent]]parent::\ndiff --git a/setup.c b/setup.c\nindex 820ed05..e66ffbe 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -136,12 +136,12 @@ void verify_non_filename(const char *prefix, const char *arg)\n  * Possible future magic semantics include stuff like:\n  *\n  *\t{ PATHSPEC_NOGLOB, '!', \"noglob\" },\n- *\t{ PATHSPEC_ICASE, '\\0', \"icase\" },\n  *\t{ PATHSPEC_RECURSIVE, '*', \"recursive\" },\n  *\t{ PATHSPEC_REGEXP, '\\0', \"regexp\" },\n  *\n  */\n #define PATHSPEC_FROMTOP    (1<<0)\n+#define PATHSPEC_ICASE      (1<<1)\n \n struct pathspec_magic {\n \tunsigned bit;\n@@ -149,6 +149,7 @@ struct pathspec_magic {\n \tconst char *name;\n } pathspec_magic[] = {\n \t{ PATHSPEC_FROMTOP, '/', \"top\" },\n+\t{ PATHSPEC_ICASE, '\\0', \"icase\" },\n };\n \n /*\n@@ -168,7 +169,8 @@ const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)\n {\n \tunsigned magic = 0;\n \tconst char *copyfrom = elt;\n-\tint i;\n+\tconst char *retval;\n+\tint i, free_source = 0;\n \n \tif (elt[0] != ':') {\n \t\t; /* nothing to do */\n@@ -215,10 +217,31 @@ const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)\n \t\t\tcopyfrom++;\n \t}\n \n+\tif (magic & PATHSPEC_ICASE) {\n+\t\tstruct strbuf sb = STRBUF_INIT;\n+\t\tfor (i = 0; copyfrom[i]; i++) {\n+\t\t\tint ch = copyfrom[i];\n+\t\t\tif (('a' <= ch && ch <= 'z') ||\n+\t\t\t    ('A' <= ch && ch <= 'Z')) {\n+\t\t\t\tstrbuf_addf(&sb, \"[%c%c]\",\n+\t\t\t\t\t    tolower(ch), toupper(ch));\n+\t\t\t} else {\n+\t\t\t\tstrbuf_addch(&sb, ch);\n+\t\t\t}\n+\t\t}\n+\t\tif (sb.len) {\n+\t\t\tfree_source = 1;\n+\t\t\tcopyfrom = strbuf_detach(&sb, NULL);\n+\t\t}\n+\t}\n+\n \tif (magic & PATHSPEC_FROMTOP)\n-\t\treturn xstrdup(copyfrom);\n+\t\tretval = xstrdup(copyfrom);\n \telse\n-\t\treturn prefix_path(prefix, prefixlen, copyfrom);\n+\t\tretval = prefix_path(prefix, prefixlen, copyfrom);\n+\tif (free_source)\n+\t\tfree((char *)copyfrom);\n+\treturn retval;\n }\n \n const char **get_pathspec(const char *prefix, const char **pathspec)\n"},{"id":"165352","messageId":"BANLkTinkXVSFYqqZ+pHK0w8ij5YtPMfKEA@mail.gmail.com","threadId":"27014","inReplyTo":"7v62qqhm9h.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/4] magic pathspec: add tentative \":/path/from/top/level\" pathspec support","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-04-07T13:09:43Z","receivedAt":"2011-04-07T13:09:43Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2011/4/7 Junio C Hamano <gitster@pobox.com>:\n> +                       if (('a' <= ch && ch <= 'z') ||\n> +                           ('A' <= ch && ch <= 'Z')) {\n> +                               strbuf_addf(&sb, \"[%c%c]\",\n> +                                           tolower(ch), toupper(ch));\n\nNice try. You know you are going to pay a high performance price for\nthat, don't you ;) Maybe also worth mentioning in document that this\napplies to ASCII charset only (as opposed to Unicode).\n-- \nDuy\n"},{"id":"165353","messageId":"BANLkTint7sGCg7_seu1-SWJC=_sKF-FKYw@mail.gmail.com","threadId":"27014","inReplyTo":"1302138996-10006-2-git-send-email-gitster@pobox.com","subject":"Re: [PATCH 1/4] magic pathspec: add tentative \":/path/from/top/level\" pathspec support","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-04-07T13:23:21Z","receivedAt":"2011-04-07T13:23:21Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Apr 7, 2011 at 8:16 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> +The \"magic signature\" consists of an ASCII symbol that is not\n> +alphanumeric.\n\nExcept dot, as Michael pointed out in another email, so we can write\n\":/.foo\" instead of \":/:.foo\". I'm tempted to rule out wildcards as\nwell (star, backslash, question mark and square brackets)\n\nAlso the patch does not catch this (ie. not die() on unrecognized signature).\n-- \nDuy\n"},{"id":"165359","messageId":"7vd3kyf327.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"BANLkTint7sGCg7_seu1-SWJC=_sKF-FKYw@mail.gmail.com","subject":"Re: [PATCH 1/4] magic pathspec: add tentative \":/path/from/top/level\" pathspec support","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-07T16:18:08Z","receivedAt":"2011-04-07T16:18:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> Also the patch does not catch this (ie. not die() on unrecognized signature).\n\nOf course it doesn't.\n\nI didn't say \"everything that is not alphanumeric is magic\". I only said\n\"all the magic are not alphanumeric\".  Notice the difference.\n\n\nThis is so that you can say \":/.gitignore\" and do not have to say\n\":/:.gitignore\".\n\nI am also tempted to special case a ':' followed by a zero magic as if it\nspecifies the top magic, e.g. \":Makefile\" is the same as \":(top)Makefile\",\naka \":/Makefile\".  It is not in the published code, but the short-cut\nwould help \":.gitignore\".\n\nYou don't require, nor allowed to have, a colon after ')' when writing a\nlong hand, by the way.  There is no reason to require one for disambiguation.\n"},{"id":"165364","messageId":"7v8vvlgblx.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"BANLkTinkXVSFYqqZ+pHK0w8ij5YtPMfKEA@mail.gmail.com","subject":"Re: [PATCH 1/4] magic pathspec: add tentative \":/path/from/top/level\" pathspec support","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-07T18:28:10Z","receivedAt":"2011-04-07T18:28:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> 2011/4/7 Junio C Hamano <gitster@pobox.com>:\n>> +                       if (('a' <= ch && ch <= 'z') ||\n>> +                           ('A' <= ch && ch <= 'Z')) {\n>> +                               strbuf_addf(&sb, \"[%c%c]\",\n>> +                                           tolower(ch), toupper(ch));\n>\n> Nice try. You know you are going to pay a high performance price for\n> that, don't you ;) Maybe also worth mentioning in document that this\n> applies to ASCII charset only (as opposed to Unicode).\n\nYou know this is a throw-away patch, just to illustrate that some things\nare doable with a hack to add more code to get_pathspec(), while others\nwould need a bigger restructuring, don't you?\n\nBesides, _if_ the user wants to do something costly, as long as the\nimplementation does not harm common cases, it _still_ is better to make\nthe code do the work, no?\n"},{"id":"165416","messageId":"BANLkTimqeFxO5dSX2J3w9rBqkNALZzTWyQ@mail.gmail.com","threadId":"27014","inReplyTo":"7v8vvlgblx.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/4] magic pathspec: add tentative \":/path/from/top/level\" pathspec support","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-04-08T11:39:58Z","receivedAt":"2011-04-08T11:39:58Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Apr 8, 2011 at 1:28 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n>\n>> 2011/4/7 Junio C Hamano <gitster@pobox.com>:\n>>> +                       if (('a' <= ch && ch <= 'z') ||\n>>> +                           ('A' <= ch && ch <= 'Z')) {\n>>> +                               strbuf_addf(&sb, \"[%c%c]\",\n>>> +                                           tolower(ch), toupper(ch));\n>>\n>> Nice try. You know you are going to pay a high performance price for\n>> that, don't you ;) Maybe also worth mentioning in document that this\n>> applies to ASCII charset only (as opposed to Unicode).\n>\n> You know this is a throw-away patch, just to illustrate that some things\n> are doable with a hack to add more code to get_pathspec(), while others\n> would need a bigger restructuring, don't you?\n>\n> Besides, _if_ the user wants to do something costly, as long as the\n> implementation does not harm common cases, it _still_ is better to make\n> the code do the work, no?\n\nI was thinking of the latter rather than the former. And I agree. Just\nwondering how slow it (fnmatch in general) can be compared to plain\nprefix. I guess we will know soon if this patch gets in and users\nstart to use it.\n-- \nDuy\n"},{"id":"165417","messageId":"BANLkTi=YK-4TOxoD1qR8TO4SymLK6sPnQA@mail.gmail.com","threadId":"27014","inReplyTo":"7vd3kyf327.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/4] magic pathspec: add tentative \":/path/from/top/level\" pathspec support","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-04-08T12:00:08Z","receivedAt":"2011-04-08T12:00:08Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Apr 7, 2011 at 11:18 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n>\n>> Also the patch does not catch this (ie. not die() on unrecognized signature).\n>\n> Of course it doesn't.\n>\n> I didn't say \"everything that is not alphanumeric is magic\". I only said\n> \"all the magic are not alphanumeric\".  Notice the difference.\n>\n>\n> This is so that you can say \":/.gitignore\" and do not have to say\n> \":/:.gitignore\".\n\nBut then, say people have a file named @foo at top dir. They can write\n\":/@foo\" to address the file. Some time later we decide to use '@' as\nmagic, how can we re-train user's fingers?\n\n> I am also tempted to special case a ':' followed by a zero magic as if it\n> specifies the top magic, e.g. \":Makefile\" is the same as \":(top)Makefile\",\n> aka \":/Makefile\".  It is not in the published code, but the short-cut\n> would help \":.gitignore\".\n\nIf you're not too tempted to do it, then reserve the case (ie. die()).\nAlthough I quite like it, one less keystroke for me.\n-- \nDuy\n"},{"id":"165424","messageId":"7vtye84wc3.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"BANLkTi=YK-4TOxoD1qR8TO4SymLK6sPnQA@mail.gmail.com","subject":"Re: [PATCH 1/4] magic pathspec: add tentative \":/path/from/top/level\" pathspec support","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-08T15:05:48Z","receivedAt":"2011-04-08T15:05:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> On Thu, Apr 7, 2011 at 11:18 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>\n>> This is so that you can say \":/.gitignore\" and do not have to say\n>> \":/:.gitignore\".\n>\n> But then, say people have a file named @foo at top dir. They can write\n> \":/@foo\" to address the file. Some time later we decide to use '@' as\n> magic, how can we re-train user's fingers?\n\nYou don't.  The primary goal of short form is to be short to type from the\ncommand line, and if you are in doubt, you can always disambiguate by\nsaying \":/:@foo\", and you can use the terminating colon even if you are\nsure \"@\" is not a magic in your version of git.\n\nScripts can and should use the long form for readability and compatibility.\n\n> Although I quite like it, one less keystroke for me.\n\nExactly.  It is Ok if the short form is a bit more complex to explain than\nthe long form (which should be very easy to explain).  The goal of the\nshort form is to make the end result is short to type, once the user\nunderstands the rules.\n"},{"id":"165426","messageId":"BANLkTi=h9idi70KtaSALaozYoJaTxzoMPA@mail.gmail.com","threadId":"27014","inReplyTo":"7vtye84wc3.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/4] magic pathspec: add tentative \":/path/from/top/level\" pathspec support","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-04-08T15:39:41Z","receivedAt":"2011-04-08T15:39:41Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Apr 8, 2011 at 10:05 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n>\n>> On Thu, Apr 7, 2011 at 11:18 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>>\n>>> This is so that you can say \":/.gitignore\" and do not have to say\n>>> \":/:.gitignore\".\n>>\n>> But then, say people have a file named @foo at top dir. They can write\n>> \":/@foo\" to address the file. Some time later we decide to use '@' as\n>> magic, how can we re-train user's fingers?\n>\n> You don't.  The primary goal of short form is to be short to type from the\n> command line, and if you are in doubt, you can always disambiguate by\n> saying \":/:@foo\", and you can use the terminating colon even if you are\n> sure \"@\" is not a magic in your version of git.\n\nIf you allow me to use \":/@foo\", I would (because it's convenient).\nAnd over time it will be carved in my muscle memory. Doubts and\nsurprises after that are not good. Suppose I usually do \"git co\n:/@foo\", then '@' in later versions means many files, not just '@foo'\nat top. The '@' magic surprise would upset (enrage in the first few\nminutes maybe) me. My argument would be \"it used to work fine\"\n(against \"you should use 'git co :/:@foo'\" because it's less\nconvenient that way).\n-- \nDuy\n"},{"id":"165429","messageId":"7vpqow4s3f.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"7vtye84wc3.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/4] magic pathspec: add tentative \":/path/from/top/level\" pathspec support","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-08T16:37:24Z","receivedAt":"2011-04-08T16:37:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n>\n>> On Thu, Apr 7, 2011 at 11:18 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>>\n>>> This is so that you can say \":/.gitignore\" and do not have to say\n>>> \":/:.gitignore\".\n>>\n>> But then, say people have a file named @foo at top dir. They can write\n>> \":/@foo\" to address the file. Some time later we decide to use '@' as\n>> magic, how can we re-train user's fingers?\n>\n> You don't.  The primary goal of short form is to be short to type from the\n> command line, and if you are in doubt, you can always disambiguate by\n> saying \":/:@foo\", and you can use the terminating colon even if you are\n> sure \"@\" is not a magic in your version of git.\n\nActually, after thinking a bit more about it, I changed my mind.\n\nIt is not such a big deal to require the terminating colon for a pathname\nthat begins with a nonalnum (except for '.' and we might find some others\nperhaps '_'), as they are rare.\n\nI agree that we should reserve most of the nonalnum ASCII as potential\nmagic, and require the terminating colon if the user wants to start the\npattern part with a potential magic signature letter and error out if we\nsee a magic that we do not support yet.  The reason I said \"most of\" is\nthat we should exclude some non-alnum letters that often begin a filename.\n\nOff the top of my head, we should exclude \".\" (period -- dot-files are\ncommon), \"_\" (underscore), and possibly \"+\" (plus) and \"=\" (equal), as I\nsaw these used to start filenames, but the latter two are rather rare and\nI don't mind requiring the terminating colon after the magic signature.\n"},{"id":"165430","messageId":"BANLkTimTm3L62J-bErmxYNE0=CRChvaKQQ@mail.gmail.com","threadId":"27014","inReplyTo":"7vpqow4s3f.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/4] magic pathspec: add tentative \":/path/from/top/level\" pathspec support","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-04-08T17:02:09Z","receivedAt":"2011-04-08T17:02:09Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Apr 8, 2011 at 11:37 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Off the top of my head, we should exclude \".\" (period -- dot-files are\n> common), \"_\" (underscore), and possibly \"+\" (plus) and \"=\" (equal), as I\n> saw these used to start filenames, but the latter two are rather rare and\n> I don't mind requiring the terminating colon after the magic signature.\n\nTotally agree on dot and underscore. I don't really care the other\ntwo. While '*' is not actually part of path name, '*.[ch]' is commonly\nused, and I usually have to quote once to avoid bash expansion\nalready. So put asterisk in exclude list too, to avoid another quote?\n-- \nDuy\n"},{"id":"165431","messageId":"20110408175149.GA3917@sigill.intra.peff.net","threadId":"27014","inReplyTo":"1302138996-10006-3-git-send-email-gitster@pobox.com","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-04-08T17:54:32Z","receivedAt":"2011-04-08T17:54:32Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Apr 06, 2011 at 06:16:34PM -0700, Junio C Hamano wrote:\n\n> Thanks to the magic \":/\" pathspec, it is much easier to invoke both\n> tree-wide operation and limited-to-cwd operation on demand from the\n> command line.\n\nI am mildly negative on this patch. Having the config variable helps two\ntypes of users:\n\n  1. Ones who see the warning for new behavior, say \"great, I've been\n     informed and am ready to use it\", and don't want to see the message\n     again. They are stuck typing \"./\" or \":/\" every time, or end up\n     getting spammed by the migration message.\n\n  2. Users who prefer the current behavior and would rather keep it. We\n     give them no out except to type \"./\" every time. Changing the\n     default is one thing; an irate user can see the change and fix it.\n     But to give them no way of changing the default back seems\n     unnecessarily limiting.\n\n> What remains is the downside of the configuration variable,\n> namely, that it makes git behave differently depending on who you are and\n> in which repository you are using it, hence making it harder to help\n> and/or teach others.\n\nI have never been a fan of this reasoning. Sure, it is slightly harder\nto help people when the system is configurable. But dropping\nconfigurability comes at the cost of people who are using the system\nday-to-day. And isn't making it pleasant to use every day more important\nthan the minority of times you are telling somebody else how to use it?\n\nBesides which, if you are helping somebody remotely or sitting at an\nunfamiliar git installation, it still wouldn't be safe to recommend\npathspec-less \"git add -u\" without first checking which version of git\nthe person is running (though to be fair, in 2 or 3 years it will be\nreasonable to assume a certain behavior, and a config option would still\nexist).\n\n-Peff\n"},{"id":"165441","messageId":"7vaag04k8m.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"20110408175149.GA3917@sigill.intra.peff.net","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-08T19:27:05Z","receivedAt":"2011-04-08T19:27:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n>> What remains is the downside of the configuration variable,\n>> namely, that it makes git behave differently depending on who you are and\n>> in which repository you are using it, hence making it harder to help\n>> and/or teach others.\n>\n> I have never been a fan of this reasoning. Sure, it is slightly harder\n> to help people when the system is configurable. But dropping\n> configurability comes at the cost of people who are using the system\n> day-to-day. And isn't making it pleasant to use every day more important\n> than the minority of times you are telling somebody else how to use it?\n\nI probably should stated it differently.  I dropped it during this round\nbecause they are _not_ needed to help the transition, but it is a possible\nadditional feature.\n\nLet me try to explain the train of throught a bit better.\n\nPeople seem to expect \"add -u\" without any pathspec to work on the whole\nworking tree structure even when you are in a subdirectory, similar to\n\"git commit -a\".  We will be changing \"add -u\" in the longer term to do\nso.\n\nAfter the transition happens, people can easily say \"add -u .\" to limit it\nto the current subdirectory, and people can say \"add -u .\" even today to\nbe explicit (which would help them transitioning).\n\nBefore the transition, however, there is no pleasant way to cause \"add -u\"\nto add everything when you work in a subdirectory, short of saying:\n\n\t(cd $(git rev-parse --show-cdup)/. && git add -u)\n\nWith \":/\", we gain an easy way, \"git add -u :/\", to say \"whole tree\".\nThat is the only thing this series does.\n\nUp to this part, I think we both agree are good thing.\n\nNow, imagine you were born in a world where we had the :/ magic from day\none of git.  Different commands \"git add -u\", \"git grep\", \"git ls-files\"\nwithout pathspec operate differently, and for some reason (e.g. usability,\nsimilarity to other people's corresponding command, or historical reasons)\nsome of them operate only within the current subdirectory while others\noperate on the whole tree.  The default behaviour might even be different\nbetween versions of git or user configuration.\n\nBecause we assume that you already have both \".\" and \":/\" to easily be\nexplicit in that world, \"teachers and helpers may have to scratch there\nhead wasting their time\" is no longer an issue.  If you are teaching\nothers, you ought to know about \".\" and \":/\", and whether we add the\nconfiguration mechanism or not, you ought to know that you should be\nexplicit to protect yourself from the differences between 1.7.X and 1.8.0\nversions in the first place.\n\nSo I agree that \"costs teachers and helpers\" is much less of an issue.\n\nYou can certainly introduce configuration variables e.g. \"addu.treewide\",\n\"grep.treewide\", \"lsfiles.treewide\" (or even \"core.treewide\" to cover them\nall) to change the default behaviour for each user or each repository.\n\nThe real question would become: if it is worth the maintenance cost of\nadditional code to help users who want to avoid typing \".\" (or \":/\") all\nthe time in the environment they control.  I don't know the answer to this\nquestion yet.\n\nA good new is that we had to conflate the discussion with \"but there is no\npleasant way to tell 'default to local' commands to work on the whole\ntree\" justification for configuration variables before \":/\".  With \":/\",\nthat excuse will be gone and the discussion can be much more simplified.\n"},{"id":"165452","messageId":"20110408202404.GA16540@sigill.intra.peff.net","threadId":"27014","inReplyTo":"7vaag04k8m.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-04-08T20:24:04Z","receivedAt":"2011-04-08T20:24:04Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Apr 08, 2011 at 12:27:05PM -0700, Junio C Hamano wrote:\n\n> > I have never been a fan of this reasoning. Sure, it is slightly harder\n> > to help people when the system is configurable. But dropping\n> > configurability comes at the cost of people who are using the system\n> > day-to-day. And isn't making it pleasant to use every day more important\n> > than the minority of times you are telling somebody else how to use it?\n> \n> I probably should stated it differently.  I dropped it during this round\n> because they are _not_ needed to help the transition, but it is a possible\n> additional feature.\n\nBut in my earlier email, one of the users who is helped by this is one\nwho wants to silence the migration warning. So it is somewhat related to\nthe transition.\n\nIf we were in a world where \".\" and \":/\" had always worked and there was\nno variable, would I write a patch for the variable? Probably not,\nespecially because I think the full-tree behavior is what I would set it\nto (and that is going to become the default).\n\nBut we don't live in that world. We are making a transition, and so it\nmay be worth it to help:\n\n  1. People who want the new behavior _now_ without extra typing.\n\n  2. Placate people who say \"...but I liked the old behavior better\".\n\nI am in group (1). I don't know if people in group (2) need placating or\nnot, but I have grown to assume there will always be people to complain\nabout a change. :)\n\n-Peff\n"},{"id":"165460","messageId":"7vmxk01izn.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"20110408202404.GA16540@sigill.intra.peff.net","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-08T22:22:20Z","receivedAt":"2011-04-08T22:22:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> But we don't live in that world. We are making a transition, and so it\n> may be worth it to help:\n>\n>   1. People who want the new behavior _now_ without extra typing.\n>\n>   2. Placate people who say \"...but I liked the old behavior better\".\n>\n> I am in group (1). I don't know if people in group (2) need placating or\n> not, but I have grown to assume there will always be people to complain\n> about a change. :)\n\nOk, first things first.  Any new feature we add we would need to keep\nforever.  I would rather not to see us having to maintain the default\nbehaviour configuration variable forever into the future for these\ncommands (not just add-u, but also grep, ls-files, ...).\n\nNow, having said that, we could vastly simplify things.\n\nI think the real cause of this confusion is because we have been dead-set\nassuming that we _have_ to change the default.  The logic goes like this:\n\n - We will change the default, but we do not want to harm existing users;\n   therefore\n\n - We need to introduce the variable to keep the old default not to harm\n   existing users, but it would add to the uncertainty of the default when\n   you do not know which version of git you are using. You now have to\n   also worry about unknown configurations, so we need to train people to\n   explicitly say '.' or ':/'; therefore\n\n - We need to issue warnings to train the user, but we do not want to show\n   warnings to users who already learned the change is coming; therefore\n\n - We do need the configuration variable, and everybody needs to set it to\n   squelch the warning. Otherwise \"add -u\" without any pathspec is too\n   noisy to be usable.\n\nBut I am not happy with the last step of the above deduction for two\nreasons.\n\nThe configuration will only help people who have total control of the\nversion of git they have on their boxes.  They can say \"Ok, I know what I\nwant, and I know which default the version of git I installed on this box,\nso I set the variable and can forget about it forever, and keep typing\n'git add -u' without any pathspec.\"\n\nBut that would not work for people who need to work on multiple boxes,\nsome of the boxes still running late 1.7.X while others running 1.8.0 or\nlater, and the version of git they will be running is under sysadmin's\ncontrol (your \"a site that runs unknown version\" example).  These people\nneed to train their fingers to be explicit when working in a subdirectory\nand running the command without a pathspec during the transition period\nanyway.  It is a _good_ thing not to have any way to squelch the warning\nwithout being explicit in that sense, _if_ we are going to change the\ndefault.\n\nAnother reason, which is worse, is that it would make it _harder_ to help\nmigrating scripts, if the presense of the configuration variable squelched\nthe warning.  \"Warn when run without pathspec from a subdirectory\" would\nissue the warning every time until the invocation is changed to an\nexplicit one, and your script that runs 'add -u' without pathspec will\nkeep emitting the message until all such invocations are fixed.\n\nSo let's step back a bit.\n\nHow about we'd just add ':/' to make it equally easy to switch between\n\"local only\" vs \"tree-wide\" in 1.7.6 release, and be done with it.  We\ndon't change the default for any of the commands at all.\n\nNo need to issue warnings because there won't be any backward imcompatible\nchange.  The users fingers do not need any re-training.  There is no need\nto rewrite scripts, either.\n\nOne good attribute of the combination of short-and-sweet ':/' and existing\nshort-and-sweet '.' is that they make the default immaterial.\n\nSince more than a year ago, I've been saying that the ideal is to make the\ndefault not matter:\n\n  http://thread.gmane.org/gmane.comp.version-control.git/133570/focus=133683\n\nIf the default does not matter, why change it?  It just causes us more\nheadaches for dubious gain, no?\n\nIIRC, I think the two reasons why we started discussing of \"add -u\" and\nfriends were that (1) some commands default to whole-tree while others\nlimit to $cwd --- inconsistency is bad; and (2) when the user wants to do\na full tree \"add -u\", there is no way other than counting the current\ndepth and typing \"../\" that many times.\n\nBut when we looked at the current set of commands that limit them to the $cwd,\nwe found that \"add -u\" was the only one that may make sense to switch the\ndefault, meaning that the \"consistency\" was not something we would even\nwant to shoot for.  For example, we want our \"git grep -e pattern\" to\nmimic \"grep -r -e pattern .\".\n\nAnd the second reason is going away, thanks to Michael and Duy's ':/'.\n"},{"id":"165463","messageId":"20110408223206.GA7343@sigill.intra.peff.net","threadId":"27014","inReplyTo":"7vmxk01izn.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-04-08T22:32:07Z","receivedAt":"2011-04-08T22:32:07Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Apr 08, 2011 at 03:22:20PM -0700, Junio C Hamano wrote:\n\n> So let's step back a bit.\n> \n> How about we'd just add ':/' to make it equally easy to switch between\n> \"local only\" vs \"tree-wide\" in 1.7.6 release, and be done with it.  We\n> don't change the default for any of the commands at all.\n\nYeah, I am beginning to think that is a sensible route. And it commits\nus to nothing, so if we decide much later that a change of default is\nsensible, that is still open to us.\n\n> Since more than a year ago, I've been saying that the ideal is to make the\n> default not matter:\n> \n>   http://thread.gmane.org/gmane.comp.version-control.git/133570/focus=133683\n> \n> If the default does not matter, why change it?  It just causes us more\n> headaches for dubious gain, no?\n\nI'm not sure how much you can achieve the \"make it not matter\". The\nshorthands go a long way, but I still want git to read my mind about\nwhich I wanted to use (and the closest approximation of that, from my\nexperience, would be a per-repo variable). However, having the\nshorthands mean that we can try them out in the real world and revisit\nthe topic in a year if people still care.\n\n> IIRC, I think the two reasons why we started discussing of \"add -u\" and\n> friends were that (1) some commands default to whole-tree while others\n> limit to $cwd --- inconsistency is bad; and (2) when the user wants to do\n> a full tree \"add -u\", there is no way other than counting the current\n> depth and typing \"../\" that many times.\n> \n> But when we looked at the current set of commands that limit them to the $cwd,\n> we found that \"add -u\" was the only one that may make sense to switch the\n> default, meaning that the \"consistency\" was not something we would even\n> want to shoot for.  For example, we want our \"git grep -e pattern\" to\n> mimic \"grep -r -e pattern .\".\n\nI am not sure of that. I thought there was interest in full-tree grep\n(OK, _I_ had some interst in it).  But the same transition pain\narguments apply there, and we should be able to do \"git grep pattern :/\"\nsoon, right?\n\n-Peff\n"},{"id":"165464","messageId":"7vei5c1iat.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"20110408223206.GA7343@sigill.intra.peff.net","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-08T22:37:14Z","receivedAt":"2011-04-08T22:37:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> I am not sure of that. I thought there was interest in full-tree grep\n> (OK, _I_ had some interst in it).  But the same transition pain\n> arguments apply there, and we should be able to do \"git grep pattern :/\"\n> soon, right?\n\nI never tested it myself, but the earlier \"support :/ at a wrong level\nget_pathspec()\" patch should take care of \"git grep\" as well.  It is\nequivalent to the \"alternative approach\" Michael posted as RFC as a\nfollow-up to his earlier \"grep --full-tree\" thread.\n"},{"id":"165468","messageId":"7vaag01gdl.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"7vei5c1iat.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-08T23:18:46Z","receivedAt":"2011-04-08T23:18:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Jeff King <peff@peff.net> writes:\n>\n>> ... I thought there was interest in full-tree grep\n>> (OK, _I_ had some interst in it).  But the same transition pain\n>> arguments apply there, and we should be able to do \"git grep pattern :/\"\n>> soon, right?\n>\n> I never tested it myself, but the earlier \"support :/ at a wrong level\n> get_pathspec()\" patch should take care of \"git grep\" as well.  It is\n> equivalent to the \"alternative approach\" Michael posted as RFC as a\n> follow-up to his earlier \"grep --full-tree\" thread.\n\nIt appears that we might want to further tweak the code that tries to\ndisambiguate between revs and paths (we error out when argv[i] does not\nname a rev and lstat(argv[i]) fails), but other than that, this command\nsequence\n\n    $ cd Documentation\n    $ git grep -e purple -- :\n\nseems to hit ../contrib/emacs/git.el and ../gitk-git/gitk correctly.\n\nOf course, from the same directory:\n\n    $ git grep -e purple -- :/*.el\n\nhits ../contrib/emacs/git.el as expected.\n\nThe following patch will apply on top of 8a42c98 (magic pathspec: add\ntentative \":/path/from/top/level\" pathspec support, 2011-04-06).\n\nPer our discussion, I think 'add -u' migration topics should be scrapped\nfor now, and rethought after giving time for people to get familiar with\nthe new :/ facility.\n\nThanks.\n\n-- >8 --\nSubject: [PATCH] magic pathspec: futureproof shorthand form\n\nThe earlier design was to take whatever non-alnum that the short format\nparser happens to support, leaving the rest as part of the pattern, so a\nversion of git that knows '*' magic and a version that does not would have\nbehaved differently when given \":*Makefile\".  The former would have\napplied the '*' magic to the pattern \"Makefile\", while the latter would\nused no magic to the pattern \"*Makefile\".\n\nInstead, just reserve all non-alnum ASCII letters that are neither glob\nnor regexp special as potential magic signature, and when we see a magic\nthat is not supported, die with an error message, just like the longhand\ncodepath does.\n\nWith this, \":%#!*Makefile\" will always mean \"%#!\" magic applied to the\npattern \"*Makefile\", no matter what version of git is used (it is a\ndifferent matter if the version of git supports all of these three magic\nmatching rules).\n\nAlso make ':' without anything else to mean \"there is no pathspec\".  This\nwould allow differences between \"git log\" and \"git log .\" run from the top\nlevel of the working tree (the latter simplifies no-op commits away from\nthe history) to be expressed from a subdirectory by saying \"git log :\".\n\nHelped-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n ctype.c           |   15 ++++++++-------\n git-compat-util.h |    2 ++\n setup.c           |    9 ++++++++-\n 3 files changed, 18 insertions(+), 8 deletions(-)\n\ndiff --git a/ctype.c b/ctype.c\nindex de60027..b5d856f 100644\n--- a/ctype.c\n+++ b/ctype.c\n@@ -10,17 +10,18 @@ enum {\n \tA = GIT_ALPHA,\n \tD = GIT_DIGIT,\n \tG = GIT_GLOB_SPECIAL,\t/* *, ?, [, \\\\ */\n-\tR = GIT_REGEX_SPECIAL\t/* $, (, ), +, ., ^, {, | */\n+\tR = GIT_REGEX_SPECIAL,\t/* $, (, ), +, ., ^, {, | */\n+\tP = GIT_PATHSPEC_MAGIC  /* other non-alnum, except for ] and } */\n };\n \n unsigned char sane_ctype[256] = {\n \t0, 0, 0, 0, 0, 0, 0, 0, 0, S, S, 0, 0, S, 0, 0,\t\t/*   0.. 15 */\n \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\t\t/*  16.. 31 */\n-\tS, 0, 0, 0, R, 0, 0, 0, R, R, G, R, 0, 0, R, 0,\t\t/*  32.. 47 */\n-\tD, D, D, D, D, D, D, D, D, D, 0, 0, 0, 0, 0, G,\t\t/*  48.. 63 */\n-\t0, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,\t\t/*  64.. 79 */\n-\tA, A, A, A, A, A, A, A, A, A, A, G, G, 0, R, 0,\t\t/*  80.. 95 */\n-\t0, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,\t\t/*  96..111 */\n-\tA, A, A, A, A, A, A, A, A, A, A, R, R, 0, 0, 0,\t\t/* 112..127 */\n+\tS, P, P, P, R, P, P, P, R, R, G, R, P, P, R, P,\t\t/*  32.. 47 */\n+\tD, D, D, D, D, D, D, D, D, D, P, P, P, P, P, G,\t\t/*  48.. 63 */\n+\tP, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,\t\t/*  64.. 79 */\n+\tA, A, A, A, A, A, A, A, A, A, A, G, G, 0, R, P,\t\t/*  80.. 95 */\n+\tP, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,\t\t/*  96..111 */\n+\tA, A, A, A, A, A, A, A, A, A, A, R, R, 0, P, 0,\t\t/* 112..127 */\n \t/* Nothing in the 128.. range */\n };\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 49b50ee..d88cf8a 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -462,6 +462,7 @@ extern unsigned char sane_ctype[256];\n #define GIT_ALPHA 0x04\n #define GIT_GLOB_SPECIAL 0x08\n #define GIT_REGEX_SPECIAL 0x10\n+#define GIT_PATHSPEC_MAGIC 0x20\n #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n #define isascii(x) (((x) & ~0x7f) == 0)\n #define isspace(x) sane_istest(x,GIT_SPACE)\n@@ -472,6 +473,7 @@ extern unsigned char sane_ctype[256];\n #define is_regex_special(x) sane_istest(x,GIT_GLOB_SPECIAL | GIT_REGEX_SPECIAL)\n #define tolower(x) sane_case((unsigned char)(x), 0x20)\n #define toupper(x) sane_case((unsigned char)(x), 0)\n+#define is_pathspec_magic(x) sane_istest(x,GIT_PATHSPEC_MAGIC)\n \n static inline int sane_case(int x, int high)\n {\ndiff --git a/setup.c b/setup.c\nindex 820ed05..5048252 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -197,19 +197,26 @@ const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)\n \t\t}\n \t\tif (*copyfrom == ')')\n \t\t\tcopyfrom++;\n+\t} else if (!elt[1]) {\n+\t\t/* Just ':' -- no element! */\n+\t\treturn NULL;\n \t} else {\n \t\t/* shorthand */\n \t\tfor (copyfrom = elt + 1;\n \t\t     *copyfrom && *copyfrom != ':';\n \t\t     copyfrom++) {\n \t\t\tchar ch = *copyfrom;\n+\n+\t\t\tif (!is_pathspec_magic(ch))\n+\t\t\t\tbreak;\n \t\t\tfor (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)\n \t\t\t\tif (pathspec_magic[i].mnemonic == ch) {\n \t\t\t\t\tmagic |= pathspec_magic[i].bit;\n \t\t\t\t\tbreak;\n \t\t\t\t}\n \t\t\tif (ARRAY_SIZE(pathspec_magic) <= i)\n-\t\t\t\tbreak;\n+\t\t\t\tdie(\"Unimplemented pathspec magic '%c' in '%s'\",\n+\t\t\t\t    ch, elt);\n \t\t}\n \t\tif (*copyfrom == ':')\n \t\t\tcopyfrom++;\n-- \n1.7.5.rc1\n"},{"id":"165474","messageId":"20110409043824.GA22543@do","threadId":"27014","inReplyTo":"7vaag01gdl.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-04-09T04:38:24Z","receivedAt":"2011-04-09T04:38:24Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Apr 08, 2011 at 04:18:46PM -0700, Junio C Hamano wrote:\n> It appears that we might want to further tweak the code that tries to\n> disambiguate between revs and paths (we error out when argv[i] does not\n> name a rev and lstat(argv[i]) fails)\n\nSomething like below? The additional goodness is, instead of writing\n\ngit grep foo -- '*.a'\n\nI can now write a shorter version\n\ngit grep foo :./*.a\n\nPerhaps we can use the first pathspec with magic as a mark of\npathspec arguments, equivalent to \"--\"\n\n--8<--\ndiff --git a/setup.c b/setup.c\nindex 03cd84f..a00a23f 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -73,6 +73,8 @@ int check_filename(const char *prefix, const char *arg)\n \tconst char *name;\n \tstruct stat st;\n \n+\tif (*arg == ':')\t/* pathspec magic */\n+\t\treturn 1;\n \tname = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;\n \tif (!lstat(name, &st))\n \t\treturn 1; /* file exists */\n--8<--\n-- \nDuy\n"},{"id":"165475","messageId":"7v39ls10q6.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"20110409043824.GA22543@do","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-09T04:56:49Z","receivedAt":"2011-04-09T04:56:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> On Fri, Apr 08, 2011 at 04:18:46PM -0700, Junio C Hamano wrote:\n>> It appears that we might want to further tweak the code that tries to\n>> disambiguate between revs and paths (we error out when argv[i] does not\n>> name a rev and lstat(argv[i]) fails)\n>\n> Something like below?\n\nThat's too loose for my taste.  At that point in the codepath, don't we\nsometimes expect the argv[i] might name a blob in the index?\n\nBy \"we might want to further...\", I meant \"when we properly redesign the\nget_pathspec vs init_pathspec combination\".\n\n\nThere are places in the current code that call verify_filename() to make\nsure that argv[i] is a pathspec after making sure argv[i] cannot be an\nobject name.  Currently it just does lstat() on it to see if it names a\npath.\n\nInstead, when we refactor get/init-pathspec API, we could expose an\ninterface to turn one element from argv[] into a \"struct pathspec_item\".\nThen we can try to feed argv[i] to that string-to-pathspec_item function,\nand consider that argv[i] _is_ a proper pathspec only if it parses\ncorrectly *and* if it matches either an item in the current working tree.\n\nThat would be a moral equivalent of the current verify_filename() check\nbut is far more precise one; e.g. the current code rejects\n\n\tgit grep -e foo '*.c' ;# bad\n\nbecause '*.c' is not an object name, but lstat(\"*.c\") fails, and you need\nto disambiguate with '--'.  If you rewrite the verify_filename() in the\nway I outlined above, you wouldn't have to.\n"},{"id":"165476","messageId":"BANLkTimCbr+hnJNGWDBVbjZKEBDW1KR4=g@mail.gmail.com","threadId":"27014","inReplyTo":"7vaag01gdl.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-04-09T04:58:09Z","receivedAt":"2011-04-09T04:58:09Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Apr 9, 2011 at 6:18 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Also make ':' without anything else to mean \"there is no pathspec\".  This\n> would allow differences between \"git log\" and \"git log .\" run from the top\n> level of the working tree (the latter simplifies no-op commits away from\n> the history) to be expressed from a subdirectory by saying \"git log :\".\n\nThe intention is good, but reality may need more work. I assume that\n\"git add -u :\" is equivalent to \"git add -u\" (or \"git add -u .\" to be\nprecise). Unfortunately, cmd_add() checks argc for no arguments to\nturn \"add -u <nothing>\" to \"add -u .\", not the result from\nget_pathspec(). It can be fixed. Just heads up as there can be similar\ntraps elsewhere.\n-- \nDuy\n"},{"id":"165477","messageId":"BANLkTinSZeNizg+8wEu_wjc09E_1dius5Q@mail.gmail.com","threadId":"27014","inReplyTo":"7v39ls10q6.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-04-09T05:05:45Z","receivedAt":"2011-04-09T05:05:45Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Apr 9, 2011 at 11:56 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Instead, when we refactor get/init-pathspec API, we could expose an\n> interface to turn one element from argv[] into a \"struct pathspec_item\".\n> Then we can try to feed argv[i] to that string-to-pathspec_item function,\n> and consider that argv[i] _is_ a proper pathspec only if it parses\n> correctly *and* if it matches either an item in the current working tree.\n>\n> That would be a moral equivalent of the current verify_filename() check\n> but is far more precise one; e.g. the current code rejects\n>\n>        git grep -e foo '*.c' ;# bad\n>\n> because '*.c' is not an object name, but lstat(\"*.c\") fails, and you need\n> to disambiguate with '--'.  If you rewrite the verify_filename() in the\n> way I outlined above, you wouldn't have to.\n\nI considered that, but we may need to go through the whole worktree\njust to verify \"*.c\" matches something. The worst case scenario can be\nexpensive (eg. doing that on a-forest-with-no-c-file gentoo-x86.git).\nAlternative approach is recognize \"*.c\" has wildcard and let it pass\nwithout actually matching.\n-- \nDuy\n"},{"id":"165478","messageId":"7vy63kyp9n.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"BANLkTimCbr+hnJNGWDBVbjZKEBDW1KR4=g@mail.gmail.com","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-09T05:20:20Z","receivedAt":"2011-04-09T05:20:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> The intention is good, but reality may need more work.\n\nYes, I knew about \"add -u\", as I was touching in its neighbourhood\nrecently.  The way \"git grep\" does this may be more appropriate as a short\nterm solution.\n\nThe updated init_pathspec() should at least take (prefix, argc, argv[]),\nand in addition a hint as to what to do when there is no pathspec from the\ncommand line (i.e. argc == 0), so that it can behave differently when the\nuser gave only \":\".\n\nBy the way, the field in \"struct pathspec_item\" would need to be updated,\nand the matcher would need to be changed, so that each item knows up to\nwhich part of the \"match\" string came from the prefix (and remainder is a\nuser supplied pattern).  Then from a subdirectory a?a/bbb,\n\n  - \"c\" should parse into prefix \"a?a/bbb/\" plus pattern \"c\"\n\n  - \":../c\" should become prefix \"a?a/\" plus pattern \"c\"\n\nand the matcher should match the prefix part _literally_ without\nfnmatch(3), while using whatever magic (e.g. use_wildcard) to match the\npattern part.  I think we currently match the whole thing with fnmatch(3),\nwhich in practice may be OK only because not many people use glob\ncharacters in their directory names, but what the current matcher does\nlogically is wrong.\n\nOf course, both of the above are tasks after 1.7.5 ships, but I thought I\nshould mention them now, as you seem to be already thinking about the\nfuture.\n"},{"id":"165483","messageId":"BANLkTi=yvA1Pa2dVa2zC4ED8ZXcWDoqLPQ@mail.gmail.com","threadId":"27014","inReplyTo":"7vy63kyp9n.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-04-09T10:15:12Z","receivedAt":"2011-04-09T10:15:12Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Apr 9, 2011 at 12:20 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> By the way, the field in \"struct pathspec_item\" would need to be updated,\n> and the matcher would need to be changed, so that each item knows up to\n> which part of the \"match\" string came from the prefix (and remainder is a\n> user supplied pattern).  Then from a subdirectory a?a/bbb,\n>\n>  - \"c\" should parse into prefix \"a?a/bbb/\" plus pattern \"c\"\n>\n>  - \":../c\" should become prefix \"a?a/\" plus pattern \"c\"\n>\n> and the matcher should match the prefix part _literally_ without\n> fnmatch(3), while using whatever magic (e.g. use_wildcard) to match the\n> pattern part.  I think we currently match the whole thing with fnmatch(3),\n> which in practice may be OK only because not many people use glob\n> characters in their directory names, but what the current matcher does\n> logically is wrong.\n\nOK. Let's add nomagic_len (or plain_len) to pathspec_item for that. I\nwas thinking of noglob_len but changed my mind because the same can\nalso be applied for icase magic. We don't want to do strcasecmp on\nprefix.\n\n> Of course, both of the above are tasks after 1.7.5 ships, but I thought I\n> should mention them now, as you seem to be already thinking about the\n> future.\n-- \nDuy\n"},{"id":"165484","messageId":"BANLkTik32jvmJOtFRB9+vCnd_NWC2ft1fA@mail.gmail.com","threadId":"27014","inReplyTo":"BANLkTimCbr+hnJNGWDBVbjZKEBDW1KR4=g@mail.gmail.com","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-04-09T11:24:44Z","receivedAt":"2011-04-09T11:24:44Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Apr 9, 2011 at 11:58 AM, Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:\n> On Sat, Apr 9, 2011 at 6:18 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Also make ':' without anything else to mean \"there is no pathspec\".  This\n>> would allow differences between \"git log\" and \"git log .\" run from the top\n>> level of the working tree (the latter simplifies no-op commits away from\n>> the history) to be expressed from a subdirectory by saying \"git log :\".\n>\n> The intention is good, but reality may need more work.\n\nWait, what if I say \"git grep -- : foo : bar\"? I take it we should\nreject on this case?\n-- \nDuy\n"},{"id":"165501","messageId":"7voc4fyuqj.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"BANLkTinSZeNizg+8wEu_wjc09E_1dius5Q@mail.gmail.com","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-09T21:34:28Z","receivedAt":"2011-04-09T21:34:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> On Sat, Apr 9, 2011 at 11:56 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>\n>> ... If you rewrite the verify_filename() in the\n>> way I outlined above, you wouldn't have to.\n>\n> I considered that, but we may need to go through the whole worktree\n> just to verify \"*.c\" matches something.\n\nYou are absolutely right.  After all, this is only meant to be a quick\nsanity check to ensure that we got the user's intention absolutely right\nwhen the user did not disambiguate with '--'.  When we see all earlier\nones are object names (and cannot be filenames) and all later ones have\nworking tree entries (and cannot be object names), we are sure that we got\nthe missing '--' boundary right.\n\nAnd we error out when there is any doubt, and that is a good feature.\nEven when there is no glob involved, e.g. \"git log builtin-add.c\", we fail\nthe parsing, because there is no builtin-add.c in the filesystem in\ntoday's checkou.  That behaviour is coming exactly from that reasoning: we\nmay be sure that \"builtin-add.c\" cannot be an object name, but we don't\nknow if it is a typo of builtin/add.c (or builtin-add.o, etc.), and we\ndon't want to make the user wait while we are guessing.\n\nSo let's forget about the suggestion.  Thanks for injecting sanity to the\ndiscussion and stopping me from going overboard.\n"},{"id":"165502","messageId":"7vk4f3yuj9.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"BANLkTik32jvmJOtFRB9+vCnd_NWC2ft1fA@mail.gmail.com","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-09T21:38:50Z","receivedAt":"2011-04-09T21:38:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> On Sat, Apr 9, 2011 at 11:58 AM, Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:\n>> On Sat, Apr 9, 2011 at 6:18 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> Also make ':' without anything else to mean \"there is no pathspec\".  This\n>>> would allow differences between \"git log\" and \"git log .\" run from the top\n>>> level of the working tree (the latter simplifies no-op commits away from\n>>> the history) to be expressed from a subdirectory by saying \"git log :\".\n>>\n>> The intention is good, but reality may need more work.\n>\n> Wait, what if I say \"git grep -- : foo : bar\"? I take it we should\n> reject on this case?\n\nThe patch probably would stuff NULL, \"foo\", NULL, \"bar\" in the array, and\nthe first NULL would make the caller turn the array itself into NULL; it\nis a user error I didn't have to bother while the topic is still in a PoC\nstage.\n"},{"id":"166926","messageId":"BANLkTimfT87-vV0GCvsVmRJ6nBZt7jSkkw@mail.gmail.com","threadId":"27014","inReplyTo":"7vaag01gdl.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-05-03T07:52:12Z","receivedAt":"2011-05-03T07:52:12Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Apr 9, 2011 at 6:18 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Subject: [PATCH] magic pathspec: futureproof shorthand form\n>\n> ...\n>\n> Also make ':' without anything else to mean \"there is no pathspec\".  This\n> would allow differences between \"git log\" and \"git log .\" run from the top\n> level of the working tree (the latter simplifies no-op commits away from\n> the history) to be expressed from a subdirectory by saying \"git log :\".\n\nI need someone to enlighten me again. Why do we need \":\" for \"no\npathspec\" when we can simply specify no pathspec for the same effect?\n\n\"git log\" and \"git log .\" at top worktree are not different because\nany changes in the tree will make top tree object different, hence no\npruning (unless someone commits the same tree, which is really rare).\nSo\n\n - \"git log\" in subdirectory is exactly the same as \"git log\" at top.\n - \"git log :/\" in subdir can do whatever \"git log .\" at top can.\n - \"git log .\" in subdir will prune commits that does not change\nsubdir (current behavior)\n\nI don't (or no longer) see the point of reserving \":\" for \"no pathspec\".\n-- \nDuy\n"},{"id":"166938","messageId":"7v4o5bkevi.fsf@alter.siamese.dyndns.org","threadId":"27014","inReplyTo":"BANLkTimfT87-vV0GCvsVmRJ6nBZt7jSkkw@mail.gmail.com","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-05-03T15:01:05Z","receivedAt":"2011-05-03T15:01:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> I need someone to enlighten me again. Why do we need \":\" for \"no\n> pathspec\" when we can simply specify no pathspec for the same effect?\n\nFutureproofing.  Currently \"log\" family defaults to \"tree-wide\" when there\nis no pathspec, but imagine what happens when a command like \"log\" that\nknows how to simplify history defaults to \"current directory\".  You cannot\noverride it by \"git that-cmd :/\", which would give it a single tree-wide\npathspec, not \"no pathspec\".  It will still cull empty commits.\n"},{"id":"166945","messageId":"BANLkTimVg2sDZzeRyVEJC-Sq4ojs=AQ=rg@mail.gmail.com","threadId":"27014","inReplyTo":"7v4o5bkevi.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/4] add -u: get rid of \"treewideupdate\" configuration","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-05-03T16:17:04Z","receivedAt":"2011-05-03T16:17:04Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Tue, May 3, 2011 at 10:01 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n>\n>> I need someone to enlighten me again. Why do we need \":\" for \"no\n>> pathspec\" when we can simply specify no pathspec for the same effect?\n>\n> Futureproofing.  Currently \"log\" family defaults to \"tree-wide\" when there\n> is no pathspec, but imagine what happens when a command like \"log\" that\n> knows how to simplify history defaults to \"current directory\".  You cannot\n> override it by \"git that-cmd :/\", which would give it a single tree-wide\n> pathspec, not \"no pathspec\".  It will still cull empty commits.\n\nOK, empty commits. I see. Will test it that way.\n-- \nDuy\n"}]}