{"thread":{"id":"32361","subject":"[PATCH] git-completion.bash: add support for path completion","startedAt":"2012-12-16T21:24:40Z","lastAt":"2012-12-19T23:50:22Z","messageCount":8,"participants":["Manlio Perillo","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"204988","messageId":"1355693080-4765-1-git-send-email-manlio.perillo@gmail.com","threadId":"32361","inReplyTo":null,"subject":"[PATCH] git-completion.bash: add support for path completion","fromName":"Manlio Perillo","fromEmail":"manlio.perillo@gmail.com","sentAt":"2012-12-16T21:24:40Z","receivedAt":"2012-12-16T21:24:40Z","isPatch":true,"sender":{"key":"manlio.perillo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6217088?v=4"},"body":"The git-completion.bash script did not implemented full support for\ncompletion, for git commands that operate on files from the current\nworking directory or the index.\n\nFor these commands, only options completion was available.\n\nFull support for completion is now implemented, for git commands where\nthe non-option arguments always refer to paths on the current working\ndirectory or the index, as the follow:\n\n* the path completion for the \"git mv\" and \"git rm\" commands is provided\n  using \"git ls-files --exclude-standard\"\n\n* the path completion for the \"git add\" command is provided using\n  \"git ls-files --exclude-standard -o -m\"\n\n* the path completion for the \"git clean\" command is provided using\n  \"git ls-files --exclude-standard -o\"\n\n* the path completion for the \"git commit\" command is provides using\n  \"git diff-index --name-only HEAD\"\n\nSigned-off-by: Manlio Perillo <manlio.perillo@gmail.com>\n---\n contrib/completion/git-completion.bash | 39 ++++++++++++++++++++++------------\n 1 file changed, 26 insertions(+), 13 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 0b77eb1..8b348c3 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -233,6 +233,25 @@ __gitcomp_nl ()\n \tCOMPREPLY=($(compgen -P \"${2-}\" -S \"${4- }\" -W \"$1\" -- \"${3-$cur}\"))\n }\n \n+__git_files ()\n+{\n+\tlocal dir=\"$(__gitdir)\"\n+\tif [ -d \"$dir\" ]; then\n+\t\tgit --git-dir=\"$dir\" ls-files --exclude-standard $*\n+\t\treturn\n+\tfi\n+}\n+\n+# Return all staged files with modification from current HEAD\n+__git_commit_files ()\n+{\n+\tlocal dir=\"$(__gitdir)\"\n+\tif [ -d \"$dir\" ]; then\n+\t\tgit --git-dir=\"$dir\" diff-index --name-only HEAD\n+\t\treturn\n+\tfi\n+}\n+\n __git_heads ()\n {\n \tlocal dir=\"$(__gitdir)\"\n@@ -770,8 +789,6 @@ _git_apply ()\n \n _git_add ()\n {\n-\t__git_has_doubledash && return\n-\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -780,7 +797,8 @@ _git_add ()\n \t\t\t\"\n \t\treturn\n \tesac\n-\tCOMPREPLY=()\n+\t# XXX should we care for --update and --all options ?\n+\t__gitcomp_nl \"$(__git_files -o -m)\" \"\" \"$cur\" \"\"\n }\n \n _git_archive ()\n@@ -930,15 +948,14 @@ _git_cherry_pick ()\n \n _git_clean ()\n {\n-\t__git_has_doubledash && return\n-\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--dry-run --quiet\"\n \t\treturn\n \t\t;;\n \tesac\n-\tCOMPREPLY=()\n+\t# TODO: check for -x option\n+\t__gitcomp_nl \"$(__git_files -o)\" \"\" \"$cur\" \"\"\n }\n \n _git_clone ()\n@@ -969,8 +986,6 @@ _git_clone ()\n \n _git_commit ()\n {\n-\t__git_has_doubledash && return\n-\n \tcase \"$cur\" in\n \t--cleanup=*)\n \t\t__gitcomp \"default strip verbatim whitespace\n@@ -998,7 +1013,7 @@ _git_commit ()\n \t\t\t\"\n \t\treturn\n \tesac\n-\tCOMPREPLY=()\n+\t__gitcomp_nl \"$(__git_commit_files)\" \"\" \"$cur\" \"\"\n }\n \n _git_describe ()\n@@ -1362,7 +1377,7 @@ _git_mv ()\n \t\treturn\n \t\t;;\n \tesac\n-\tCOMPREPLY=()\n+\t__gitcomp_nl \"$(__git_files)\" \"\" \"$cur\" \"\"\n }\n \n _git_name_rev ()\n@@ -2068,15 +2083,13 @@ _git_revert ()\n \n _git_rm ()\n {\n-\t__git_has_doubledash && return\n-\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --dry-run --ignore-unmatch --quiet\"\n \t\treturn\n \t\t;;\n \tesac\n-\tCOMPREPLY=()\n+\t__gitcomp_nl \"$(__git_files)\" \"\" \"$cur\" \"\"\n }\n \n _git_shortlog ()\n-- \n1.8.1.rc1.18.g9db0d25\n"},{"id":"205003","messageId":"7vy5gxnuy1.fsf@alter.siamese.dyndns.org","threadId":"32361","inReplyTo":"1355693080-4765-1-git-send-email-manlio.perillo@gmail.com","subject":"Re: [PATCH] git-completion.bash: add support for path completion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-12-17T04:50:30Z","receivedAt":"2012-12-17T04:50:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Manlio Perillo <manlio.perillo@gmail.com> writes:\n\n> The git-completion.bash script did not implemented full support for\n> completion, for git commands that operate on files from the current\n> working directory or the index.\n>\n> For these commands, only options completion was available.\n\nHrm, \"git mv CO<TAB>\" completes it to \"COPYING\" for me.  Same for:\n\n    git rm CO<TAB>\n    git clean Doc<TAB>\n    git commit --edit Doc<TAB>\n\nThere must be something missing from the above description, and the\nclaim the above two paragraphs make does no make sense without that\nsomething that is missing.\n\n> * the path completion for the \"git mv\" and \"git rm\" commands is provided\n>   using \"git ls-files --exclude-standard\"\n\nDoes the above mean \"git mv COPYING Doc<TAB>\" would complete the\ncommand line to move it to Documentation/ directory?  \n\nI think \"using X\" is of secondary importance.  Reviewers and future\ndevelopers (who are reading \"git log\" output) can read it from the\npatch.  What is expected in the log message is why the implemenation\nwas chosen, and in order to achieve what effect.\n\nFor example, something like:\n\n    Each parameter between the first one and the one before the last\n    one to 'git mv' is completed to a tracked path or a leading\n    directory of a tracked path\n\nshould come first to explain what your patch wanted to do.  It of\ncourse is helpful to explain how you implemented that behaviour, by\nappending \", using 'ls-files --exclude-standard'\" at the end.\n\n> * the path completion for the \"git add\" command is provided using\n>   \"git ls-files --exclude-standard -o -m\"\n\nLikewise.  You are adding \"either a modified, or a new and\nunignored\" and use \"ls-files --exclude-standard -o -m\" to achieve\nit.\n\n> * the path completion for the \"git clean\" command is provided using\n>   \"git ls-files --exclude-standard -o\"\n>\n> * the path completion for the \"git commit\" command is provides using\n>   \"git diff-index --name-only HEAD\"\n\nAs long as all of the above stops completion at directory boundary,\nI think the above sounds like a sensible thing to do.  e.g. when\n\"ls-files\" gives Documentation/Makefile and Documentation/git.txt,\n\"git cmd Doc<TAB>\" first would give \"git cmd Documentation/\" and\nthen the second <TAB> would offer these two paths as choices.  That\nway, the user can choose to just execute \"git cmd Documentation/\"\nwithout even looking at these individual paths.\n\nI am not sure how you would handle the last parameter to \"git mv\",\nthough.  That is by definition a path that does not exist,\ni.e. cannot be completed.\n\n> Signed-off-by: Manlio Perillo <manlio.perillo@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 39 ++++++++++++++++++++++------------\n>  1 file changed, 26 insertions(+), 13 deletions(-)\n>\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 0b77eb1..8b348c3 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -233,6 +233,25 @@ __gitcomp_nl ()\n>  \tCOMPREPLY=($(compgen -P \"${2-}\" -S \"${4- }\" -W \"$1\" -- \"${3-$cur}\"))\n>  }\n>  \n> +__git_files ()\n> +{\n> +\tlocal dir=\"$(__gitdir)\"\n> +\tif [ -d \"$dir\" ]; then\n> +\t\tgit --git-dir=\"$dir\" ls-files --exclude-standard $*\n> +\t\treturn\n> +\tfi\n> +}\n> +\n> +# Return all staged files with modification from current HEAD\n> +__git_commit_files ()\n> +{\n> +\tlocal dir=\"$(__gitdir)\"\n> +\tif [ -d \"$dir\" ]; then\n> +\t\tgit --git-dir=\"$dir\" diff-index --name-only HEAD\n> +\t\treturn\n> +\tfi\n> +}\n> +\n>  __git_heads ()\n>  {\n>  \tlocal dir=\"$(__gitdir)\"\n> @@ -770,8 +789,6 @@ _git_apply ()\n>  \n>  _git_add ()\n>  {\n> -\t__git_has_doubledash && return\n> -\n>  \tcase \"$cur\" in\n>  \t--*)\n>  \t\t__gitcomp \"\n> @@ -780,7 +797,8 @@ _git_add ()\n>  \t\t\t\"\n>  \t\treturn\n>  \tesac\n> -\tCOMPREPLY=()\n> +\t# XXX should we care for --update and --all options ?\n> +\t__gitcomp_nl \"$(__git_files -o -m)\" \"\" \"$cur\" \"\"\n>  }\n>  \n>  _git_archive ()\n> @@ -930,15 +948,14 @@ _git_cherry_pick ()\n>  \n>  _git_clean ()\n>  {\n> -\t__git_has_doubledash && return\n> -\n>  \tcase \"$cur\" in\n>  \t--*)\n>  \t\t__gitcomp \"--dry-run --quiet\"\n>  \t\treturn\n>  \t\t;;\n>  \tesac\n> -\tCOMPREPLY=()\n> +\t# TODO: check for -x option\n> +\t__gitcomp_nl \"$(__git_files -o)\" \"\" \"$cur\" \"\"\n>  }\n>  \n>  _git_clone ()\n> @@ -969,8 +986,6 @@ _git_clone ()\n>  \n>  _git_commit ()\n>  {\n> -\t__git_has_doubledash && return\n> -\n>  \tcase \"$cur\" in\n>  \t--cleanup=*)\n>  \t\t__gitcomp \"default strip verbatim whitespace\n> @@ -998,7 +1013,7 @@ _git_commit ()\n>  \t\t\t\"\n>  \t\treturn\n>  \tesac\n> -\tCOMPREPLY=()\n> +\t__gitcomp_nl \"$(__git_commit_files)\" \"\" \"$cur\" \"\"\n>  }\n>  \n>  _git_describe ()\n> @@ -1362,7 +1377,7 @@ _git_mv ()\n>  \t\treturn\n>  \t\t;;\n>  \tesac\n> -\tCOMPREPLY=()\n> +\t__gitcomp_nl \"$(__git_files)\" \"\" \"$cur\" \"\"\n>  }\n>  \n>  _git_name_rev ()\n> @@ -2068,15 +2083,13 @@ _git_revert ()\n>  \n>  _git_rm ()\n>  {\n> -\t__git_has_doubledash && return\n> -\n>  \tcase \"$cur\" in\n>  \t--*)\n>  \t\t__gitcomp \"--cached --dry-run --ignore-unmatch --quiet\"\n>  \t\treturn\n>  \t\t;;\n>  \tesac\n> -\tCOMPREPLY=()\n> +\t__gitcomp_nl \"$(__git_files)\" \"\" \"$cur\" \"\"\n>  }\n>  \n>  _git_shortlog ()\n"},{"id":"205045","messageId":"50CEFF3A.4050802@gmail.com","threadId":"32361","inReplyTo":"7vy5gxnuy1.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git-completion.bash: add support for path completion","fromName":"Manlio Perillo","fromEmail":"manlio.perillo@gmail.com","sentAt":"2012-12-17T11:17:14Z","receivedAt":"2012-12-17T11:17:14Z","isPatch":true,"sender":{"key":"manlio.perillo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6217088?v=4"},"body":"-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA1\n\nIl 17/12/2012 05:50, Junio C Hamano ha scritto:\n> Manlio Perillo <manlio.perillo@gmail.com> writes:\n> \n>> The git-completion.bash script did not implemented full support for\n>> completion, for git commands that operate on files from the current\n>> working directory or the index.\n>>\n>> For these commands, only options completion was available.\n> \n> Hrm, \"git mv CO<TAB>\" completes it to \"COPYING\" for me.  Same for:\n> \n>     git rm CO<TAB>\n>     git clean Doc<TAB>\n>     git commit --edit Doc<TAB>\n> \n> There must be something missing from the above description, and the\n> claim the above two paragraphs make does no make sense without that\n> something that is missing.\n> \n\nThanks.\n\nWhat is missing is that I forgot to explain that by \"completion not\nsupported\" I meant \"*git aware* completion is not supported\".\n\nIf you try, as an example, \"git add <TAB>\", bash will suggest *all*\nfiles in your working directory, including ignored files and files with\nno modifications.\n\n\n>> * the path completion for the \"git mv\" and \"git rm\" commands is provided\n>>   using \"git ls-files --exclude-standard\"\n> \n> Does the above mean \"git mv COPYING Doc<TAB>\" would complete the\n> command line to move it to Documentation/ directory?  \n> \n\nIt will suggest all tracked files from the Documentation directory.\nOne important detail is that it will recurse into sub directories.\n\nThis is not the behaviour of the current completion code.\nThe problem is that current code use ls-tree, and works only for paths\nlike <rev>:<path>.\n\nMy implementation use ls-files, that has a completly different interface\nfrom ls-tree (and since I'm very new to git, this caused be some confusion).\n\nIt seems that with ls-files it is impossible to:\n\n* get a list of path names without recursing into sub directories.\n  (this is only possible for untracked directories)\n\n* get the file mode for all \"modified\" or \"deleted\" files.\n\n  If I do \"git ls-files --stage --modified\", git ignores the modified\n  option and will list all files\n\n> I think \"using X\" is of secondary importance.  Reviewers and future\n> developers (who are reading \"git log\" output) can read it from the\n> patch.  What is expected in the log message is why the implemenation\n> was chosen, and in order to achieve what effect.\n> \n\nOk, thanks.\n\n> \n>> * the path completion for the \"git clean\" command is provided using\n>>   \"git ls-files --exclude-standard -o\"\n>>\n>> * the path completion for the \"git commit\" command is provides using\n>>   \"git diff-index --name-only HEAD\"\n> \n> As long as all of the above stops completion at directory boundary,\n> I think the above sounds like a sensible thing to do.  e.g. when\n> \"ls-files\" gives Documentation/Makefile and Documentation/git.txt,\n> \"git cmd Doc<TAB>\" first would give \"git cmd Documentation/\" and\n> then the second <TAB> would offer these two paths as choices.  That\n> way, the user can choose to just execute \"git cmd Documentation/\"\n> without even looking at these individual paths.\n> \n\nRight, this is what bash usually do.\nHowever I don't know how to implement this with git.\n\n> I am not sure how you would handle the last parameter to \"git mv\",\n> though.  That is by definition a path that does not exist,\n> i.e. cannot be completed.\n> \n\nRight, the code should be changed.\nNo completion should be done for the second parameter.\n\n\n\nRegards   Manlio\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.4.10 (GNU/Linux)\nComment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/\n\niEYEARECAAYFAlDO/zoACgkQscQJ24LbaUSD1ACfXeH2GizdNG/uzlSneEpdi1Na\n6IoAni3ZrhhCMXbVoTqIVjH4mEX/XmaH\n=w56v\n-----END PGP SIGNATURE-----\n"},{"id":"205065","messageId":"7vzk1clb3n.fsf@alter.siamese.dyndns.org","threadId":"32361","inReplyTo":"50CEFF3A.4050802@gmail.com","subject":"Re: [PATCH] git-completion.bash: add support for path completion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-12-17T19:42:04Z","receivedAt":"2012-12-17T19:42:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Manlio Perillo <manlio.perillo@gmail.com> writes:\n\n>> As long as all of the above stops completion at directory boundary,\n>> I think the above sounds like a sensible thing to do.  e.g. when\n>> \"ls-files\" gives Documentation/Makefile and Documentation/git.txt,\n>> \"git cmd Doc<TAB>\" first would give \"git cmd Documentation/\" and\n>> then the second <TAB> would offer these two paths as choices.  That\n>> way, the user can choose to just execute \"git cmd Documentation/\"\n>> without even looking at these individual paths.\n>\n> Right, this is what bash usually do.\n> However I don't know how to implement this with git.\n\nThat sounds like a regression to me.\n\n>> I am not sure how you would handle the last parameter to \"git mv\",\n>> though.  That is by definition a path that does not exist,\n>> i.e. cannot be completed.\n>\n> Right, the code should be changed.\n> No completion should be done for the second parameter.\n\nI deliberately wrote \"the last\" not \"the second\", as you can do\n\n\t$ mkdir X\n        $ git mv COPYING README X/.\n\nYou do need to expand the second parameter to README when the user\ntypes\n\n\tgit mv COPYING REAMDE X\n\nthen goes back with \\C-b to \"M\", types \\C-d three times to remove\n\"MDE\", and then finally says <TAB>, to result in\n\n\tgit mv COPYING README X\n"},{"id":"205130","messageId":"50D09908.6020007@gmail.com","threadId":"32361","inReplyTo":"7vzk1clb3n.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git-completion.bash: add support for path completion","fromName":"Manlio Perillo","fromEmail":"manlio.perillo@gmail.com","sentAt":"2012-12-18T16:25:44Z","receivedAt":"2012-12-18T16:25:44Z","isPatch":true,"sender":{"key":"manlio.perillo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6217088?v=4"},"body":"-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA1\n\nIl 17/12/2012 20:42, Junio C Hamano ha scritto:\n> [...]\n>>> I am not sure how you would handle the last parameter to \"git mv\",\n>>> though.  That is by definition a path that does not exist,\n>>> i.e. cannot be completed.\n>>\n>> Right, the code should be changed.\n>> No completion should be done for the second parameter.\n> \n> I deliberately wrote \"the last\" not \"the second\", as you can do\n> \n> \t$ mkdir X\n>         $ git mv COPYING README X/.\n> \n\nThe patch is ready, however I decided to leave git mv completion simple.\nPressing <TAB> will always try to autocomplete using all cached files.\nI have added a note to remember it needs more work.\n\n\nP.S.:\ngit-completion.bash has a lot of other things that may be improved:\n\n* adding missing commands\n (as an example, there is strangely no custom support fot \"git status\")\n\n* completion support for commands like \"git checkout\" is not complete.\n  \"git checkout <TAB>\" will correctly try to complete the tree-ish,\n  however \"git checkout HEAD -- <TAB>\" will try to complete the path\n  using *all* files in the working directory.\n\n  This is easy to fix, using the new functions I have added\n\n* not all long options are supported.\n  The script documentation says that only common long options are\n  supported, so I'm not sure it is ok to add support for all available\n  long options.\n\n\nRegards   Manlio\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.4.10 (GNU/Linux)\nComment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/\n\niEYEARECAAYFAlDQmQgACgkQscQJ24LbaUSw9QCfT1lCH/yjA4Lgmb2nMspNWM3l\nhMMAn26UxWesuoOxMbuwhqaypPjkmN84\n=Wh4c\n-----END PGP SIGNATURE-----\n"},{"id":"205221","messageId":"50D23960.4070108@gmail.com","threadId":"32361","inReplyTo":"7vzk1clb3n.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git-completion.bash: add support for path completion","fromName":"Manlio Perillo","fromEmail":"manlio.perillo@gmail.com","sentAt":"2012-12-19T22:02:08Z","receivedAt":"2012-12-19T22:02:08Z","isPatch":true,"sender":{"key":"manlio.perillo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6217088?v=4"},"body":"-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA1\n\nIl 17/12/2012 20:42, Junio C Hamano ha scritto:\n> [...]\n>>> I am not sure how you would handle the last parameter to \"git mv\",\n>>> though.  That is by definition a path that does not exist,\n>>> i.e. cannot be completed.\n>>\n>> Right, the code should be changed.\n>> No completion should be done for the second parameter.\n> \n> I deliberately wrote \"the last\" not \"the second\", as you can do\n> \n> \t$ mkdir X\n>         $ git mv COPYING README X/.\n> \n> You do need to expand the second parameter to README when the user\n> types\n> \n> \tgit mv COPYING REAMDE X\n> \n> then goes back with \\C-b to \"M\", types \\C-d three times to remove\n> \"MDE\", and then finally says <TAB>, to result in\n> \n> \tgit mv COPYING README X\n> \n\nAssuming X is a new untracked directory, do you think it is an usability\nproblem if an user try to do:\n\n\tgit mv COPYING README <TAB>\n\nand X does not appear in the completion list?\n\nAs far as I know, the solution is to only support custom expansion the\nfirst parameter, unless the user will do something like:\n\n\tgit mv COPYING README -- <TAB>\n\n\nRegards  Manlio\n\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.4.10 (GNU/Linux)\nComment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/\n\niEYEARECAAYFAlDSOWAACgkQscQJ24LbaUSOnACfds93RtX1CDOeGbwCGM5/N8HI\nyVwAn0AZEO6rE083gKgFimGIbiRTyN5Z\n=z7K5\n-----END PGP SIGNATURE-----\n"},{"id":"205227","messageId":"7vy5gt7j3c.fsf@alter.siamese.dyndns.org","threadId":"32361","inReplyTo":"50D23960.4070108@gmail.com","subject":"Re: [PATCH] git-completion.bash: add support for path completion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-12-19T22:49:59Z","receivedAt":"2012-12-19T22:49:59Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Manlio Perillo <manlio.perillo@gmail.com> writes:\n\n>> \tgit mv COPYING README X\n>\n> Assuming X is a new untracked directory, do you think it is an usability\n> problem if an user try to do:\n>\n> \tgit mv COPYING README <TAB>\n>\n> and X does not appear in the completion list?\n\nIt is hard to say.  Will it show \"Documentation/\" in the list?  Will\nit show \"git.c\" in the list?\n\nYour \"git mv git.<TAB>\" completing to \"git mv git.c\" would be an\nimprovement compared to the stock \"less git.<TAB>\" that offers\n\"git.c\" and \"git.o\" as choices.  For things like \"mv\" and \"rm\", this\nmay not make too much of a difference, \"git add <TAB>\" would be a\nvast improvement from the stock one.  The users will notice that the\ncompletion knows what it is doing, and will come to depend on it.\n\nBut at that point, if \"git mv COPYING README <TAB>\" offers only\ndirectories that contain tracked files, the users may get irritated,\nbecause it is likely that the destination directory was created\nimmediately before the user started typing \"git mv\".  You will hear\n\"Surely I created X, it is there, why aren't you showing it to me?\"\n\nThe updated completion knows what it is doing everywhere else, and\nit sets the user-expectation at that level.  Uneven cleverness will\nstand out like a sore thumb and hurts the user perception, which is\narguably unfair, but nothing in life is fair X-<.\n\nI think over-showing the choices is much better than hiding some\nchoices, if we cannot do a perfect completion in some cases.  \"You\nshould know that I won't be moving these files in Y, as I already\nmarked it to be ignored in the .gitignore file!\" is less grave a\ngripe than \"You know I created X just a minute ago, and it is there,\nwhy aren't you showing it to me?\" because you can simply say \"but Y\nis there as a directory.\" admitting that you are less clever than\nthe user expects you to be, but at least you are giving the choice\nto the user of not picking it.\n\nIn the ideal world (read: I am *not* saying \"you should implement it\nthis way, or we won't look at your patch\"), I think you would want\nto show tracked files (because it may be the third path that the\nuser wants to move with the command, not the destination directory)\nand any directory on the filesystem (it could be the third path that\nis being moved if it has tracked files, or it could be the final\ndestination directory argument).\n"},{"id":"205231","messageId":"50D252BE.1070808@gmail.com","threadId":"32361","inReplyTo":"7vy5gt7j3c.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git-completion.bash: add support for path completion","fromName":"Manlio Perillo","fromEmail":"manlio.perillo@gmail.com","sentAt":"2012-12-19T23:50:22Z","receivedAt":"2012-12-19T23:50:22Z","isPatch":true,"sender":{"key":"manlio.perillo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6217088?v=4"},"body":"-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA1\n\nIl 19/12/2012 23:49, Junio C Hamano ha scritto:\n> Manlio Perillo <manlio.perillo@gmail.com> writes:\n> \n>>> \tgit mv COPYING README X\n>>\n>> Assuming X is a new untracked directory, do you think it is an usability\n>> problem if an user try to do:\n>>\n>> \tgit mv COPYING README <TAB>\n>>\n>> and X does not appear in the completion list?\n> \n> It is hard to say.  Will it show \"Documentation/\" in the list?  Will\n> it show \"git.c\" in the list?\n> \n\nCurrently all cached files will be showed.\n\n> Your \"git mv git.<TAB>\" completing to \"git mv git.c\" would be an\n> improvement compared to the stock \"less git.<TAB>\" that offers\n> \"git.c\" and \"git.o\" as choices.  For things like \"mv\" and \"rm\", this\n> may not make too much of a difference, \"git add <TAB>\" would be a\n> vast improvement from the stock one.  The users will notice that the\n> completion knows what it is doing, and will come to depend on it.\n> \n\nYes, this is precisely the reason why I'm implementing it ;-).\n\nI also use Mercurial (I discovered Git just a few weeks ago, after\nreading Pro Git), and Mercurial do have path completion (completion list\ndoes not stop at directory boundary, however).\n\nWhen I started to use Git, one of the first thing I noticed was the lack\nof path completion for git add.\n\n> [...]\n> In the ideal world (read: I am *not* saying \"you should implement it\n> this way, or we won't look at your patch\"), I think you would want\n> to show tracked files (because it may be the third path that the\n> user wants to move with the command, not the destination directory)\n> and any directory on the filesystem (it could be the third path that\n> is being moved if it has tracked files, or it could be the final\n> destination directory argument).\n\nWhat about this?\n\n* show all and only cached files for the first argument\n* show all cached + untracked directories and files for all other\n  arguments\n\nThis should solve most of the problem, and will still not show ignored\nfiles.  And, most important, it is very easy to implement.\n\n\nThe only issue is that \"git ls-files -o\" does not show empty\ndirectories, and \"git ls-files --directory -o\" will add a trailing slash.\n\n\n\nThanks   Manlio\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.4.10 (GNU/Linux)\nComment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/\n\niEYEARECAAYFAlDSUr4ACgkQscQJ24LbaURf0gCeJVZviwfKHgHNZ8vYBjnjwP8+\nWF4AnAn3/KPJciJg9r387qIzCajx4j0s\n=/10k\n-----END PGP SIGNATURE-----\n"}]}