{"thread":{"id":"3338","subject":"[PATCH] commit: detect misspelled pathspec while making a partial commit.","startedAt":"2006-02-14T20:46:03Z","lastAt":"2006-02-14T21:25:52Z","messageCount":2,"participants":["Junio C Hamano","Petr Baudis"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"16146","messageId":"7vfymlr7n8.fsf@assigned-by-dhcp.cox.net","threadId":"3338","inReplyTo":null,"subject":"[PATCH] commit: detect misspelled pathspec while making a partial commit.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-02-14T20:46:03Z","receivedAt":"2006-02-14T20:46:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"When you say \"git commit Documentaiton\" to make partial commit\nfor the files only in that directory, we did not detect that as\na misspelled pathname and attempted to commit index without\nchange.  If nothing matched, there is no harm done, but if the\nindex gets modified otherwise by having another valid pathspec\nor after an explicit update-index, a user will not notice\nwithout paying attention to the \"git status\" preview.\n\nThis introduces --error-unmatch option to ls-files, and uses it\nto detect this common user error.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n * Pasky, does this address the issue you mentioned earlier on\n   the #git channnel?\n\n git-commit.sh |   16 +++++++++-------\n ls-files.c    |   51 ++++++++++++++++++++++++++++++++++++++++++++-------\n 2 files changed, 53 insertions(+), 14 deletions(-)\n\nc49ee6e0bba6c800f2c36df819973f3caac20fa4\ndiff --git a/git-commit.sh b/git-commit.sh\nindex ab5e6bc..f7ee1aa 100755\n--- a/git-commit.sh\n+++ b/git-commit.sh\n@@ -180,6 +180,7 @@ verify=t\n verbose=\n signoff=\n force_author=\n+only_include_assumed=\n while case \"$#\" in 0) break;; esac\n do\n   case \"$1\" in\n@@ -340,12 +341,8 @@ case \"$#,$also$only\" in\n 0,)\n   ;;\n *,)\n-  echo >&2 \"assuming --only paths...\"\n+  only_include_assumed=\"# Explicit paths specified without -i nor -o; assuming --only paths...\"\n   also=\n-\n-  # If we are going to launch an editor, the message won't be\n-  # shown without this...\n-  test -z \"$log_given$status_only\" && sleep 1\n   ;;\n esac\n unset only\n@@ -380,6 +377,8 @@ t,)\n \t;;\n ,t)\n \tsave_index &&\n+\tgit-ls-files --error-unmatch -- \"$@\" >/dev/null || exit\n+\n \tgit-diff-files --name-only -z -- \"$@\"  |\n \t(\n \t\tcd \"$TOP\"\n@@ -408,7 +407,7 @@ t,)\n \t\trefuse_partial \"Different in index and the last commit:\n $dirty_in_index\"\n \t    fi\n-\t    commit_only=`git-ls-files -- \"$@\"`\n+\t    commit_only=`git-ls-files --error-unmatch -- \"$@\"` || exit\n \n \t    # Build the temporary index and update the real index\n \t    # the same way.\n@@ -569,7 +568,10 @@ else\n \tPARENTS=\"\"\n fi\n \n-run_status >>\"$GIT_DIR\"/COMMIT_EDITMSG\n+{\n+\ttest -z \"$only_include_assumed\" || echo \"$only_include_assumed\"\n+\trun_status\n+} >>\"$GIT_DIR\"/COMMIT_EDITMSG\n if [ \"$?\" != \"0\" -a ! -f \"$GIT_DIR/MERGE_HEAD\" ]\n then\n \trm -f \"$GIT_DIR/COMMIT_EDITMSG\"\ndiff --git a/ls-files.c b/ls-files.c\nindex 7024cf1..a716e5f 100644\n--- a/ls-files.c\n+++ b/ls-files.c\n@@ -25,6 +25,8 @@ static int line_terminator = '\\n';\n static int prefix_len = 0, prefix_offset = 0;\n static const char *prefix = NULL;\n static const char **pathspec = NULL;\n+static int error_unmatch = 0;\n+static char *ps_matched = NULL;\n \n static const char *tag_cached = \"\";\n static const char *tag_unmerged = \"\";\n@@ -325,7 +327,8 @@ static int cmp_name(const void *p1, cons\n  * Match a pathspec against a filename. The first \"len\" characters\n  * are the common prefix\n  */\n-static int match(const char **spec, const char *filename, int len)\n+static int match(const char **spec, char *ps_matched,\n+\t\t const char *filename, int len)\n {\n \tconst char *m;\n \n@@ -333,17 +336,24 @@ static int match(const char **spec, cons\n \t\tint matchlen = strlen(m + len);\n \n \t\tif (!matchlen)\n-\t\t\treturn 1;\n+\t\t\tgoto matched;\n \t\tif (!strncmp(m + len, filename + len, matchlen)) {\n \t\t\tif (m[len + matchlen - 1] == '/')\n-\t\t\t\treturn 1;\n+\t\t\t\tgoto matched;\n \t\t\tswitch (filename[len + matchlen]) {\n \t\t\tcase '/': case '\\0':\n-\t\t\t\treturn 1;\n+\t\t\t\tgoto matched;\n \t\t\t}\n \t\t}\n \t\tif (!fnmatch(m + len, filename + len, 0))\n-\t\t\treturn 1;\n+\t\t\tgoto matched;\n+\t\tif (ps_matched)\n+\t\t\tps_matched++;\n+\t\tcontinue;\n+\tmatched:\n+\t\tif (ps_matched)\n+\t\t\t*ps_matched = 1;\n+\t\treturn 1;\n \t}\n \treturn 0;\n }\n@@ -356,7 +366,7 @@ static void show_dir_entry(const char *t\n \tif (len >= ent->len)\n \t\tdie(\"git-ls-files: internal error - directory entry not superset of prefix\");\n \n-\tif (pathspec && !match(pathspec, ent->name, len))\n+\tif (pathspec && !match(pathspec, ps_matched, ent->name, len))\n \t\treturn;\n \n \tfputs(tag, stdout);\n@@ -444,7 +454,7 @@ static void show_ce_entry(const char *ta\n \tif (len >= ce_namelen(ce))\n \t\tdie(\"git-ls-files: internal error - cache entry not superset of prefix\");\n \n-\tif (pathspec && !match(pathspec, ce->name, len))\n+\tif (pathspec && !match(pathspec, ps_matched, ce->name, len))\n \t\treturn;\n \n \tif (!show_stage) {\n@@ -699,6 +709,10 @@ int main(int argc, const char **argv)\n \t\t\tprefix_offset = 0;\n \t\t\tcontinue;\n \t\t}\n+\t\tif (!strcmp(arg, \"--error-unmatch\")) {\n+\t\t\terror_unmatch = 1;\n+\t\t\tcontinue;\n+\t\t}\n \t\tif (*arg == '-')\n \t\t\tusage(ls_files_usage);\n \t\tbreak;\n@@ -710,6 +724,14 @@ int main(int argc, const char **argv)\n \tif (pathspec)\n \t\tverify_pathspec();\n \n+\t/* Treat unmatching pathspec elements as errors */\n+\tif (pathspec && error_unmatch) {\n+\t\tint num;\n+\t\tfor (num = 0; pathspec[num]; num++)\n+\t\t\t;\n+\t\tps_matched = xcalloc(1, num);\n+\t}\n+\n \tif (show_ignored && !exc_given) {\n \t\tfprintf(stderr, \"%s: --ignored needs some exclude pattern\\n\",\n \t\t\targv[0]);\n@@ -725,5 +747,20 @@ int main(int argc, const char **argv)\n \tif (prefix)\n \t\tprune_cache();\n \tshow_files();\n+\n+\tif (ps_matched) {\n+\t\t/* We need to make sure all pathspec matched otherwise\n+\t\t * it is an error.\n+\t\t */\n+\t\tint num, errors = 0;\n+\t\tfor (num = 0; pathspec[num]; num++) {\n+\t\t\tif (ps_matched[num])\n+\t\t\t\tcontinue;\n+\t\t\terror(\"pathspec '%s' did not match any.\",\n+\t\t\t      pathspec[num] + prefix_len);\n+\t\t}\n+\t\treturn errors ? 1 : 0;\n+\t}\n+\n \treturn 0;\n }\n-- \n1.2.0.g6552\n"},{"id":"16152","messageId":"20060214212552.GH31278@pasky.or.cz","threadId":"3338","inReplyTo":"7vfymlr7n8.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] commit: detect misspelled pathspec while making a partial commit.","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-02-14T21:25:52Z","receivedAt":"2006-02-14T21:25:52Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Tue, Feb 14, 2006 at 09:46:03PM CET, I got a letter\nwhere Junio C Hamano <junkio@cox.net> said that...\n> When you say \"git commit Documentaiton\" to make partial commit\n> for the files only in that directory, we did not detect that as\n> a misspelled pathname and attempted to commit index without\n> change.  If nothing matched, there is no harm done, but if the\n> index gets modified otherwise by having another valid pathspec\n> or after an explicit update-index, a user will not notice\n> without paying attention to the \"git status\" preview.\n> \n> This introduces --error-unmatch option to ls-files, and uses it\n> to detect this common user error.\n> \n> Signed-off-by: Junio C Hamano <junkio@cox.net>\n> \n> ---\n> \n>  * Pasky, does this address the issue you mentioned earlier on\n>    the #git channnel?\n\nYes, this is what I meant. I actually have no practical experience with\nthis since I'm not a git-commit user, I merely expressed horror ;) on\nwhat you mentioned during the night. BUT it turns out that this affects\nCogito as well, albeit in a milder version - only when you pass multiple\nexplicit paths to cg-commit and some of them are misspelled, they are\nignored quietly (unless all of them are misspelled).\n\nSo, thanks for the fix on behalf of Cogito users as well. ;-)\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nOf the 3 great composers Mozart tells us what it's like to be human,\nBeethoven tells us what it's like to be Beethoven and Bach tells us\nwhat it's like to be the universe.  -- Douglas Adams\n"}]}