{"thread":{"id":"22437","subject":"Custom git completion","startedAt":"2010-01-29T12:57:16Z","lastAt":"2010-02-26T20:17:43Z","messageCount":25,"participants":["David Rhodes Clymer","Shawn O. Pearce","Junio C Hamano","SZEDER Gábor"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"132955","messageId":"9b69cfcf1001290457s6b7fad6cs5a915f16a11f5782@mail.gmail.com","threadId":"22437","inReplyTo":null,"subject":"Custom git completion","fromName":"David Rhodes Clymer","fromEmail":"david@zettazebra.com","sentAt":"2010-01-29T12:57:16Z","receivedAt":"2010-01-29T12:57:16Z","isPatch":false,"sender":{"key":"david@zettazebra.com","avatar":"https://gravatar.com/avatar/cdcfe06796c2f046978e5667e21c2e6567f8db8c91d8eb81d7eb86f3f6bc77b7?d=mp&s=160"},"body":"Unless I read it incorrectly, the completion script included with\ngit-core does not make it easy for users to write completion scripts\nfor custom git commands. I can extend git itself by creating a command\n\"git-foo\", and placing it in my path. The command can then be used\nlike so: \"git foo\". However, if I want to add command completion for\nthat command without modifying (I may not have permission) or\nduplicating the system git completion, I can't write a completion\nscript which matches works on \"git foo\", only \"git-foo\", which is not\nhow I would ever call the script.\n\nAnyway, so I made a simple modification which looks for completion\ncode for custom commands, and calls that as appropriate. If the\nattached patch (or something like it) were applied to the git\ncompletion script, it would be awfully handy.\n\n-davidc\n\nps. I'm not subscribed to the list, so please copy me on any replies, thanks!\n\n\n--- /etc/bash_completion.d/git.orig\t2010-01-12 14:50:16.000000000 -0500\n+++ /etc/bash_completion.d/git\t2010-01-12 15:28:27.000000000 -0500\n@@ -1403,7 +1403,10 @@\n \tsvn)         _git_svn ;;\n \ttag)         _git_tag ;;\n \twhatchanged) _git_log ;;\n-\t*)           COMPREPLY=() ;;\n+\t*)\n+    COMPREPLY=()\n+    $(complete -p |awk '/ '\"git-${command}\"'$/{print $(NF-1)}')\n+  ;;\n \tesac\n }\n \n"},{"id":"132961","messageId":"20100129151127.GA21821@spearce.org","threadId":"22437","inReplyTo":"9b69cfcf1001290457s6b7fad6cs5a915f16a11f5782@mail.gmail.com","subject":"Re: Custom git completion","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-01-29T15:11:27Z","receivedAt":"2010-01-29T15:11:27Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"David Rhodes Clymer <david@zettazebra.com> wrote:\n> Unless I read it incorrectly, the completion script included with\n> git-core does not make it easy for users to write completion scripts\n> for custom git commands. I can extend git itself by creating a command\n> \"git-foo\", and placing it in my path.\n\ngit config --global alias.foo /home/me/bin/my-git-foo\n\ngit foo will now complete correctly.  No need to modify the\ncompletion code.\n\n-- \nShawn.\n"},{"id":"132969","messageId":"7v4om4kdt3.fsf@alter.siamese.dyndns.org","threadId":"22437","inReplyTo":"20100129151127.GA21821@spearce.org","subject":"Re: Custom git completion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-29T17:42:48Z","receivedAt":"2010-01-29T17:42:48Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n> David Rhodes Clymer <david@zettazebra.com> wrote:\n>> Unless I read it incorrectly, the completion script included with\n>> git-core does not make it easy for users to write completion scripts\n>> for custom git commands. I can extend git itself by creating a command\n>> \"git-foo\", and placing it in my path.\n>\n> git config --global alias.foo /home/me/bin/my-git-foo\n>\n> git foo will now complete correctly.  No need to modify the\n> completion code.\n\nYes.  Aliases and custom subcommands are found from 'git help\" output just\nfine (you need to install new subcommand in exec-path).\n\nBut.\n\nHow does the completion code learn what options and arguments such aliases\nand subcommands (e.g. \"git foo\") take without being told?\n\nAn alias that uses another git subcommand (i.e. the ones that do not start\nwith a bang \"!\") seems to be handled correctly, but one of my aliases is\nthis:\n\n    [alias]\n\tlgm = \"!sh -c 'GIT_NOTES_REF=refs/notes/amlog git log \\\"$@\\\" || :' -\"\n\nand the completion code doesn't (and it is unfair to expect it to) notice\nthat \"git log\" is run under the hood.  I cannot say \"git lgm sp/<TAB>\" and\nchoose from the list of topics from you.\n"},{"id":"132970","messageId":"20100129175950.GE21821@spearce.org","threadId":"22437","inReplyTo":"7v4om4kdt3.fsf@alter.siamese.dyndns.org","subject":"Re: Custom git completion","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-01-29T17:59:50Z","receivedAt":"2010-01-29T17:59:50Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <gitster@pobox.com> wrote:\n> \"Shawn O. Pearce\" <spearce@spearce.org> writes:\n> \n> > David Rhodes Clymer <david@zettazebra.com> wrote:\n> >> Unless I read it incorrectly, the completion script included with\n> >> git-core does not make it easy for users to write completion scripts\n> >> for custom git commands. I can extend git itself by creating a command\n> >> \"git-foo\", and placing it in my path.\n> >\n> > git config --global alias.foo /home/me/bin/my-git-foo\n> >\n> > git foo will now complete correctly.  No need to modify the\n> > completion code.\n> \n> Yes.  Aliases and custom subcommands are found from 'git help\" output just\n> fine (you need to install new subcommand in exec-path).\n> \n> But.\n> \n> How does the completion code learn what options and arguments such aliases\n> and subcommands (e.g. \"git foo\") take without being told?\n\nSure.  But the patch offered by the original poster also suffered\nfrom this problem, it didn't know how to complete arguments for\nthe subcommand.\n\n \n> An alias that uses another git subcommand (i.e. the ones that do not start\n> with a bang \"!\") seems to be handled correctly, but one of my aliases is\n> this:\n> \n>     [alias]\n> \tlgm = \"!sh -c 'GIT_NOTES_REF=refs/notes/amlog git log \\\"$@\\\" || :' -\"\n\nDoing this is difficult, because its hard to parse that string and\ndo completion on it.  On the other hand, we could do something like:\n\n  [completion]\n  \tlgm = log\n\nand have `git lgm` complete using the same rules as `git log`.\nIts somewhat ugly though...\n \n-- \nShawn.\n"},{"id":"132971","messageId":"7vockciyb8.fsf@alter.siamese.dyndns.org","threadId":"22437","inReplyTo":"20100129175950.GE21821@spearce.org","subject":"Re: Custom git completion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-29T18:02:51Z","receivedAt":"2010-01-29T18:02:51Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n>> An alias that uses another git subcommand (i.e. the ones that do not start\n>> with a bang \"!\") seems to be handled correctly, but one of my aliases is\n>> this:\n>> \n>>     [alias]\n>> \tlgm = \"!sh -c 'GIT_NOTES_REF=refs/notes/amlog git log \\\"$@\\\" || :' -\"\n>\n> Doing this is difficult, because its hard to parse that string and\n> do completion on it.\n\nThat is why I said it is unfair to expect completion code to do that.\n\n>   [completion]\n>   \tlgm = log\n>\n> and have `git lgm` complete using the same rules as `git log`.\n\nI actually like that.  It matches _my_ expectation as a user to be able to\nsay \"this subcommand has args that look like those given to 'log'\".\n"},{"id":"132978","messageId":"20100129190642.GA31303@neumann","threadId":"22437","inReplyTo":"7vockciyb8.fsf@alter.siamese.dyndns.org","subject":"[PATCH] bash: support user-supplied completion scripts for user's git commands","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-01-29T19:06:42Z","receivedAt":"2010-01-29T19:06:42Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"The bash completion script already provides support to complete\naliases, options and refs for aliases (if the alias can be traced back\nto a supported git command by __git_aliased_command()), and the user's\ncustom git commands, but it does not support the options of the user's\ncustom git commands (of course; how could it know about the options of\na custom git command?).  Users of such custom git commands could\nextend git's bash completion script by writing functions to support\ntheir commands, but they might have issues with it: they might not\nhave the rights to modify a system-wide git completion script, and\nthey will need to track and merge upstream changes in the future.\n\nThis patch addresses this by providing means for users to supply\ncustom completion scriplets for their custom git commands without\nmodifying the main git bash completion script.\n\nInstead of having a huge hard-coded list of command-completion\nfunction pairs (in _git()), the completion script will figure out\nwhich completion function to call based on the command's name.  That\nis, when completing the options of 'git foo', the main completion\nscript will check whether the function '_git_foo' is declared, and if\ndeclared, it will invoke that function to perform the completion.  If\nsuch a function is not declared, it will fall back to complete file\nnames.  So, users will only need to provide this '_git_foo' completion\nfunction in a separate file, source that file, and it will be used the\nnext time they press TAB after 'git foo '.\n\nThere are two git commands (stage and whatchanged), for which the\ncompletion functions of other commands were used, therefore they\ngot their own completion function.\n\nSigned-off-by: SZEDER Gábor <szeder@ira.uka.de>\n---\n\nHow about something like this for subcommands (not aliases)?  It's a\ngood code size reduction anyway.\n\n contrib/completion/git-completion.bash |   67 ++++++--------------------------\n 1 files changed, 12 insertions(+), 55 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex da46bf8..2cecf4f 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1433,6 +1433,11 @@ _git_send_email ()\n \tCOMPREPLY=()\n }\n \n+_git_stage ()\n+{\n+\t_git_add\n+}\n+\n __git_config_get_set_variables ()\n {\n \tlocal prevword word config_file= c=$COMP_CWORD\n@@ -2164,6 +2169,11 @@ _git_tag ()\n \tesac\n }\n \n+_git_whatchanged ()\n+{\n+\t_git_log\n+}\n+\n _git ()\n {\n \tlocal i c=1 command __git_dir\n@@ -2203,61 +2213,8 @@ _git ()\n \tlocal expansion=$(__git_aliased_command \"$command\")\n \t[ \"$expansion\" ] && command=\"$expansion\"\n \n-\tcase \"$command\" in\n-\tam)          _git_am ;;\n-\tadd)         _git_add ;;\n-\tapply)       _git_apply ;;\n-\tarchive)     _git_archive ;;\n-\tbisect)      _git_bisect ;;\n-\tbundle)      _git_bundle ;;\n-\tbranch)      _git_branch ;;\n-\tcheckout)    _git_checkout ;;\n-\tcherry)      _git_cherry ;;\n-\tcherry-pick) _git_cherry_pick ;;\n-\tclean)       _git_clean ;;\n-\tclone)       _git_clone ;;\n-\tcommit)      _git_commit ;;\n-\tconfig)      _git_config ;;\n-\tdescribe)    _git_describe ;;\n-\tdiff)        _git_diff ;;\n-\tdifftool)    _git_difftool ;;\n-\tfetch)       _git_fetch ;;\n-\tformat-patch) _git_format_patch ;;\n-\tfsck)        _git_fsck ;;\n-\tgc)          _git_gc ;;\n-\tgrep)        _git_grep ;;\n-\thelp)        _git_help ;;\n-\tinit)        _git_init ;;\n-\tlog)         _git_log ;;\n-\tls-files)    _git_ls_files ;;\n-\tls-remote)   _git_ls_remote ;;\n-\tls-tree)     _git_ls_tree ;;\n-\tmerge)       _git_merge;;\n-\tmergetool)   _git_mergetool;;\n-\tmerge-base)  _git_merge_base ;;\n-\tmv)          _git_mv ;;\n-\tname-rev)    _git_name_rev ;;\n-\tnotes)       _git_notes ;;\n-\tpull)        _git_pull ;;\n-\tpush)        _git_push ;;\n-\trebase)      _git_rebase ;;\n-\tremote)      _git_remote ;;\n-\treplace)     _git_replace ;;\n-\treset)       _git_reset ;;\n-\trevert)      _git_revert ;;\n-\trm)          _git_rm ;;\n-\tsend-email)  _git_send_email ;;\n-\tshortlog)    _git_shortlog ;;\n-\tshow)        _git_show ;;\n-\tshow-branch) _git_show_branch ;;\n-\tstash)       _git_stash ;;\n-\tstage)       _git_add ;;\n-\tsubmodule)   _git_submodule ;;\n-\tsvn)         _git_svn ;;\n-\ttag)         _git_tag ;;\n-\twhatchanged) _git_log ;;\n-\t*)           COMPREPLY=() ;;\n-\tesac\n+\tlocal completion_func=\"_git_${command//-/_}\"\n+\tdeclare -F $completion_func >/dev/null && $completion_func\n }\n \n _gitk ()\n-- \n1.7.0.rc0.78.g2070a\n"},{"id":"132979","messageId":"20100129191326.GD22101@spearce.org","threadId":"22437","inReplyTo":"20100129190642.GA31303@neumann","subject":"Re: [PATCH] bash: support user-supplied completion scripts for user's git commands","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-01-29T19:13:26Z","receivedAt":"2010-01-29T19:13:26Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"SZEDER G?bor <szeder@ira.uka.de> wrote:\n> The bash completion script already provides support to complete\n> aliases, options and refs for aliases (if the alias can be traced back\n> to a supported git command by __git_aliased_command()), and the user's\n> custom git commands, but it does not support the options of the user's\n> custom git commands (of course; how could it know about the options of\n> a custom git command?).  Users of such custom git commands could\n> extend git's bash completion script by writing functions to support\n> their commands, but they might have issues with it: they might not\n> have the rights to modify a system-wide git completion script, and\n> they will need to track and merge upstream changes in the future.\n> \n> This patch addresses this by providing means for users to supply\n> custom completion scriplets for their custom git commands without\n> modifying the main git bash completion script.\n> \n> Instead of having a huge hard-coded list of command-completion\n> function pairs (in _git()), the completion script will figure out\n> which completion function to call based on the command's name.  That\n> is, when completing the options of 'git foo', the main completion\n> script will check whether the function '_git_foo' is declared, and if\n> declared, it will invoke that function to perform the completion.  If\n> such a function is not declared, it will fall back to complete file\n> names.  So, users will only need to provide this '_git_foo' completion\n> function in a separate file, source that file, and it will be used the\n> next time they press TAB after 'git foo '.\n> \n> There are two git commands (stage and whatchanged), for which the\n> completion functions of other commands were used, therefore they\n> got their own completion function.\n> \n> Signed-off-by: SZEDER G?bor <szeder@ira.uka.de>\n> ---\n> \n> How about something like this for subcommands (not aliases)?  It's a\n> good code size reduction anyway.\n\nHmm, I like this.  I just didn't know how to implement it...  :-)\n\nAcked-by: Shawn O. Pearce <spearce@spearce.org>\n\n> +\tlocal completion_func=\"_git_${command//-/_}\"\n> +\tdeclare -F $completion_func >/dev/null && $completion_func\n\nYay for knowing bash.  :-)\n\n-- \nShawn.\n"},{"id":"132981","messageId":"20100129200033.GA32636@neumann","threadId":"22437","inReplyTo":"20100129191326.GD22101@spearce.org","subject":"Re: [PATCH] bash: support user-supplied completion scripts for user's git commands","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-01-29T20:00:33Z","receivedAt":"2010-01-29T20:00:33Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Hi Shawn,\n\nOn Fri, Jan 29, 2010 at 11:13:26AM -0800, Shawn O. Pearce wrote:\n> SZEDER G?bor <szeder@ira.uka.de> wrote:\n> > How about something like this for subcommands (not aliases)?  It's a\n> > good code size reduction anyway.\n> \n> Hmm, I like this.  I just didn't know how to implement it...  :-)\n> \n> Acked-by: Shawn O. Pearce <spearce@spearce.org>\n> \n> > +\tlocal completion_func=\"_git_${command//-/_}\"\n> > +\tdeclare -F $completion_func >/dev/null && $completion_func\n> \n> Yay for knowing bash.  :-)\n\nHeh.  I've found out about this 'declare -F' thing about two hours ago\n(;\n\n\nHowever.\n\nI thought this should actually \"Just Work\" for aliases, too.  e.g.\nJunio could use the following completion function to get 'git log's\noptions for his lgm alias:\n\n_git_lgm () {\n        _git_log\n}\n\nUnfortunately, it doesn't work at all.\n\nIn _git() first we have 'lgm' in $command, which is ok, but then comes\nthis alias handling thing\n\n        local expansion=$(__git_aliased_command \"$command\")\n        [ \"$expansion\" ] && command=\"$expansion\"\n\nwhich writes '!sh' into $command, and that doesn't look quite right\nfor me, although I admit that I can't seem to figure out how this\n__git_aliased_command() is supposed to work (so much about knowing\nbash ;).  Any insight?\n\n\nBest,\nGábor\n"},{"id":"132983","messageId":"20100129200431.GE22101@spearce.org","threadId":"22437","inReplyTo":"20100129200033.GA32636@neumann","subject":"Re: [PATCH] bash: support user-supplied completion scripts for user's git commands","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-01-29T20:04:31Z","receivedAt":"2010-01-29T20:04:31Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"SZEDER G?bor <szeder@ira.uka.de> wrote:\n> \n> _git_lgm () {\n>         _git_log\n> }\n> \n> Unfortunately, it doesn't work at all.\n> \n> In _git() first we have 'lgm' in $command, which is ok, but then comes\n> this alias handling thing\n> \n>         local expansion=$(__git_aliased_command \"$command\")\n>         [ \"$expansion\" ] && command=\"$expansion\"\n> \n> which writes '!sh' into $command, and that doesn't look quite right\n\n__git_aliased_command is returning the first word out of the alias.\nI think we need to change this block here to:\n\n  case \"$expansion\" of\n  \\!*) : leave command as alias ;;\n  '')  : leave command alone ;;\n  *)   command=\"$expansion\" ;;\n  esac\n\nOr something like that.  Because an alias whose value starts with\n! is a shell command to be executed, so we want to use _git_$command\nfor completion, but other aliases are builtin commands and we should\nuse their first word token (what __git_aliased_command returns)\nas the name of the completion function.\n\nI think.  :-)\n\n-- \nShawn.\n"},{"id":"132987","messageId":"7viqakireb.fsf@alter.siamese.dyndns.org","threadId":"22437","inReplyTo":"20100129190642.GA31303@neumann","subject":"Re: [PATCH] bash: support user-supplied completion scripts for user's git commands","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-29T20:32:12Z","receivedAt":"2010-01-29T20:32:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"SZEDER Gábor <szeder@ira.uka.de> writes:\n\n> Instead of having a huge hard-coded list of command-completion\n> function pairs (in _git()), the completion script will figure out\n> which completion function to call based on the command's name.  That\n> is, when completing the options of 'git foo', the main completion\n> script will check whether the function '_git_foo' is declared, and if\n> declared, it will invoke that function to perform the completion.  If\n> such a function is not declared, it will fall back to complete file\n> names.  So, users will only need to provide this '_git_foo' completion\n> function in a separate file, source that file, and it will be used the\n> next time they press TAB after 'git foo '.\n\nI think the basic idea is sound, but I have a minor issue with the names.\n\nAdmittedly, we have already taken over _git_foo (and \"_git\") namespace,\nand anybody who uses bash with the completion support cannot write their\nown shell function with these names for purposes that are unrelated to\ncompletion, so in that sense, the patch is not introducing a new problem,\nbut making it a documented interface and casting it in stone will make the\nnamespace contamination issue harder to rectify later.\n\nSo if we were to go in the direction as the patch proposes (which I think\nis a good idea), we might want to rename them to __git_completion_foo or\nsomething that is less likely to collide with whatever names users might\nwant to use.  It is my understanding that the only published interface so\nfar is __git_ps1.\n"},{"id":"133154","messageId":"9b69cfcf1001301500s48fcc476p1fd2c14e4310b892@mail.gmail.com","threadId":"22437","inReplyTo":"20100129151127.GA21821@spearce.org","subject":"Re: Custom git completion","fromName":"David Rhodes Clymer","fromEmail":"david@zettazebra.com","sentAt":"2010-01-30T23:00:15Z","receivedAt":"2010-01-30T23:00:15Z","isPatch":false,"sender":{"key":"david@zettazebra.com","avatar":"https://gravatar.com/avatar/cdcfe06796c2f046978e5667e21c2e6567f8db8c91d8eb81d7eb86f3f6bc77b7?d=mp&s=160"},"body":"On Fri, Jan 29, 2010 at 10:11 AM, Shawn O. Pearce <spearce@spearce.org> wrote:\n> David Rhodes Clymer <david@zettazebra.com> wrote:\n>> Unless I read it incorrectly, the completion script included with\n>> git-core does not make it easy for users to write completion scripts\n>> for custom git commands. I can extend git itself by creating a command\n>> \"git-foo\", and placing it in my path.\n>\n> git config --global alias.foo /home/me/bin/my-git-foo\n>\n> git foo will now complete correctly.  No need to modify the\n> completion code.\n\nThis doesn't do what I want. This workaround only allows the command\nname itself to be completed. I want my _custom_ completion code  to be\nused for my custom command.\n\n-davidc\n"},{"id":"133155","messageId":"9b69cfcf1001301503n455191cdse93a7d4e86c0e6a0@mail.gmail.com","threadId":"22437","inReplyTo":"20100129175950.GE21821@spearce.org","subject":"Re: Custom git completion","fromName":"David Rhodes Clymer","fromEmail":"david@zettazebra.com","sentAt":"2010-01-30T23:03:43Z","receivedAt":"2010-01-30T23:03:43Z","isPatch":false,"sender":{"key":"david@zettazebra.com","avatar":"https://gravatar.com/avatar/cdcfe06796c2f046978e5667e21c2e6567f8db8c91d8eb81d7eb86f3f6bc77b7?d=mp&s=160"},"body":"On Fri, Jan 29, 2010 at 12:59 PM, Shawn O. Pearce <spearce@spearce.org> wrote:\n> Junio C Hamano <gitster@pobox.com> wrote:\n>>\n>> How does the completion code learn what options and arguments such aliases\n>> and subcommands (e.g. \"git foo\") take without being told?\n>\n> Sure.  But the patch offered by the original poster also suffered\n> from this problem, it didn't know how to complete arguments for\n> the subcommand.\n>\n\nMy patch allows custom completion code to be called if available. I\ndon't expect git completion to know anything about my new command.\n\n-davidc\n"},{"id":"133157","messageId":"9b69cfcf1001301534v734f8c9ao3143854c2ca5093f@mail.gmail.com","threadId":"22437","inReplyTo":"20100129190642.GA31303@neumann","subject":"Re: [PATCH] bash: support user-supplied completion scripts for user's git commands","fromName":"David Rhodes Clymer","fromEmail":"david@zettazebra.com","sentAt":"2010-01-30T23:34:06Z","receivedAt":"2010-01-30T23:34:06Z","isPatch":true,"sender":{"key":"david@zettazebra.com","avatar":"https://gravatar.com/avatar/cdcfe06796c2f046978e5667e21c2e6567f8db8c91d8eb81d7eb86f3f6bc77b7?d=mp&s=160"},"body":"2010/1/29 SZEDER Gábor <szeder@ira.uka.de>:\n> The bash completion script already provides support to complete\n> aliases, options and refs for aliases (if the alias can be traced back\n> to a supported git command by __git_aliased_command()), and the user's\n> custom git commands, but it does not support the options of the user's\n> custom git commands (of course; how could it know about the options of\n> a custom git command?).  Users of such custom git commands could\n> extend git's bash completion script by writing functions to support\n> their commands, but they might have issues with it: they might not\n> have the rights to modify a system-wide git completion script, and\n> they will need to track and merge upstream changes in the future.\n>\n> This patch addresses this by providing means for users to supply\n> custom completion scriplets for their custom git commands without\n> modifying the main git bash completion script.\n>\n> Instead of having a huge hard-coded list of command-completion\n> function pairs (in _git()), the completion script will figure out\n> which completion function to call based on the command's name.  That\n> is, when completing the options of 'git foo', the main completion\n> script will check whether the function '_git_foo' is declared, and if\n> declared, it will invoke that function to perform the completion.  If\n> such a function is not declared, it will fall back to complete file\n> names.  So, users will only need to provide this '_git_foo' completion\n> function in a separate file, source that file, and it will be used the\n> next time they press TAB after 'git foo '.\n>\n> There are two git commands (stage and whatchanged), for which the\n> completion functions of other commands were used, therefore they\n> got their own completion function.\n>\n\nExcellent! This looks just like what I was after. Among other things,\nthis is much better than my use of awk. ;o)\n\n-davidc\n"},{"id":"133189","messageId":"20100131191936.GA30466@neumann","threadId":"22437","inReplyTo":"20100129200431.GE22101@spearce.org","subject":"Re: [PATCH] bash: support user-supplied completion scripts for user's git commands","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-01-31T19:19:36Z","receivedAt":"2010-01-31T19:19:36Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Fri, Jan 29, 2010 at 12:04:31PM -0800, Shawn O. Pearce wrote:\n> SZEDER G?bor <szeder@ira.uka.de> wrote:\n> > \n> > _git_lgm () {\n> >         _git_log\n> > }\n> > \n> > Unfortunately, it doesn't work at all.\n> > \n> > In _git() first we have 'lgm' in $command, which is ok, but then comes\n> > this alias handling thing\n> > \n> >         local expansion=$(__git_aliased_command \"$command\")\n> >         [ \"$expansion\" ] && command=\"$expansion\"\n> > \n> > which writes '!sh' into $command, and that doesn't look quite right\n> \n> __git_aliased_command is returning the first word out of the alias.\n\nActually, it returns the first word from the alias which does not\nstart with a dash.  It behaves this way since its introduction in\n367dce2a (Bash completion support for aliases, 2006-10-28).  I'm not\nsure what the original intent was behind ignoring words starting with\na dash, but it gave me some ideas.\n\n> I think we need to change this block here to:\n> \n>   case \"$expansion\" of\n>   \\!*) : leave command as alias ;;\n>   '')  : leave command alone ;;\n>   *)   command=\"$expansion\" ;;\n>   esac\n> \n> Or something like that.  Because an alias whose value starts with\n> ! is a shell command to be executed, so we want to use _git_$command\n> for completion, but other aliases are builtin commands and we should\n> use their first word token (what __git_aliased_command returns)\n> as the name of the completion function.\n\nAfter pondering about it for a while, I think that in this case the\nreal issue is not _git() not handling __git_aliased_command()'s return\nvalue corretly, but rather __git_aliased_command() returning junk in\ncase of a more advanced alias.  And while fixing it up, we can also\nimprove on it to return the right command in some more cases, too.\n\nLet's have an other look at Junio's alias:\n\n    [alias]\n        lgm = \"!sh -c 'GIT_NOTES_REF=refs/notes/amlog git log \\\"$@\\\" || :' -\"\n\nWhile it's clear that full parsing of something like that in the\ncompletion code is unfeasible, we can easily get rid of stuff that is\ndefinitely not a git command: !sh shell commands, options, and\nenvironment variables.\n\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 45a393f..faddbdf 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -625,10 +625,15 @@ __git_aliased_command ()\n \tlocal word cmdline=$(git --git-dir=\"$(__gitdir)\" \\\n \t\tconfig --get \"alias.$1\")\n \tfor word in $cmdline; do\n-\t\tif [ \"${word##-*}\" ]; then\n-\t\t\techo $word\n+\t\tcase \"$word\" in\n+\t\t\\!*)\t: shell command alias ;;\n+\t\t-*)\t: option ;;\n+\t\t*=*)\t: setting env ;;\n+\t\tgit)\t: git itself ;;\n+\t\t*)\n+\t\t\techo \"$word\"\n \t\t\treturn\n-\t\tfi\n+\t\tesac\n \tdone\n }\n\n \nand this way it would correctly return 'log' for Junio's 'lgm' alias.\nWith a bit tweaking we could also extend it to handle !gitk aliases,\ntoo.\n\nOf course, it isn't perfect either, and could be fooled easily.  It's\nnot hard to construct an alias, in which a word does not match any of\nthese filter patterns, but is still not a git command (e.g.  by\nsetting an environment variable to a value which contains spaces).  It\nmay even return false positives, when the output of a git command is\npiped into an other git command, and the second gets the command line\noptions via $@, but the first command will be returned.  However, such\nproblematic cases could be handled by a custom completion function\nprovided by the user.\n\nWhat do you think?\n\n\nBest,\nGábor\n"},{"id":"135460","messageId":"cover.1266958460.git.szeder@ira.uka.de","threadId":"22437","inReplyTo":"20100131191936.GA30466@neumann","subject":"[PATCH 0/4] bash: support user-supplied completion scripts for custom git commands and aliases","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-02-23T21:02:56Z","receivedAt":"2010-02-23T21:02:56Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Hi,\n\nhere is the full series, extended for aliases.\n\nI didn't want to push an obviously post-v1.7.0 change during the -rc\nperiod, and then forgot about it until Teemu (on CC) sent similar\npatches today[*].  His two patches do basically the same as my 2/4 (with\nminor differences).\n\nJunio was concerned about possible namespace issues.  This series does\nnot addresses his concern, but I have some thoughts about it, and I will\ntry to discuss it after dinner.\n\nBest,\nGábor\n\n[*] gmane: http://thread.gmane.org/gmane.comp.version-control.git/140804\n    message id: <1266936193-10644-1-git-send-email-teemu.matilainen@iki.fi>\n\n\nSZEDER Gábor (4):\n  bash: improve aliased command recognition\n  bash: support user-supplied completion scripts for user's git\n    commands\n  bash: support user-supplied completion scripts for aliases\n  bash: completion for gitk aliases\n\n contrib/completion/git-completion.bash |   94 ++++++++++++--------------------\n 1 files changed, 34 insertions(+), 60 deletions(-)\n"},{"id":"135461","messageId":"90724961a941edd1317514dea0a1c64112dab61d.1266958460.git.szeder@ira.uka.de","threadId":"22437","inReplyTo":"20100131191936.GA30466@neumann","subject":"[PATCH 1/4] bash: improve aliased command recognition","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-02-23T21:02:57Z","receivedAt":"2010-02-23T21:02:57Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"To support completion for aliases, the completion script tries to\nfigure out which git command is invoked by an alias.  Its\nimplementation in __git_aliased_command() is rather straightforward:\nit returns the first word from the alias.  For simple aliases starting\nwith the git command (e.g. alias.last = cat-file commit HEAD) this\ngives the right results.  Unfortunately, it does not work with shell\ncommand aliases, which can get rather complex, as illustrated by one\nof Junio's aliases:\n\n[alias]\n    lgm = \"!sh -c 'GIT_NOTES_REF=refs/notes/amlog git log \\\"$@\\\" || :' -\"\n\nIn this case the current implementation returns \"!sh\" as the aliased\ngit command, which is obviosly wrong.\n\nThe full parsing of a shell command alias like that in the completion\ncode is clearly unfeasible.  However, we can easily improve on aliased\ncommand recognition by eleminating stuff that is definitely not a git\ncommand: shell commands (anything starting with '!'), command line\noptions (anything starting with '-'), environment variables (anything\nwith a '=' in it), and git itself.  This way the above alias would be\nhandled correctly, and the completion script would correctly recognize\n\"log\" as the aliased git command.\n\nOf course, this solution is not perfect either, and could be fooled\neasily.  It's not hard to construct an alias, in which a word does not\nmatch any of these filter patterns, but is still not a git command\n(e.g.  by setting an environment variable to a value which contains\nspaces).  It may even return false positives, when the output of a git\ncommand is piped into an other git command, and the second gets the\ncommand line options via $@, but options for the first one are\noffered.  However, the following patches will enable the user to\nsupply custom completion scripts for aliases, which can be used to\nremedy these problematic cases.\n\nSigned-off-by: SZEDER Gábor <szeder@ira.uka.de>\n---\n contrib/completion/git-completion.bash |   11 ++++++++---\n 1 files changed, 8 insertions(+), 3 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex fe93747..78c4983 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -625,10 +625,15 @@ __git_aliased_command ()\n \tlocal word cmdline=$(git --git-dir=\"$(__gitdir)\" \\\n \t\tconfig --get \"alias.$1\")\n \tfor word in $cmdline; do\n-\t\tif [ \"${word##-*}\" ]; then\n-\t\t\techo $word\n+\t\tcase \"$word\" in\n+\t\t\\!*)\t: shell command alias ;;\n+\t\t-*)\t: option ;;\n+\t\t*=*)\t: setting env ;;\n+\t\tgit)\t: git itself ;;\n+\t\t*)\n+\t\t\techo \"$word\"\n \t\t\treturn\n-\t\tfi\n+\t\tesac\n \tdone\n }\n \n-- \n1.7.0.119.g9b76\n"},{"id":"135463","messageId":"7e1bdca5a57eeef86b8aca93de50a6927a840a68.1266958460.git.szeder@ira.uka.de","threadId":"22437","inReplyTo":"20100131191936.GA30466@neumann","subject":"[PATCH 2/4] bash: support user-supplied completion scripts for user's git commands","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-02-23T21:02:58Z","receivedAt":"2010-02-23T21:02:58Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"The bash completion script already provides support to complete\naliases, options and refs for aliases (if the alias can be traced back\nto a supported git command by __git_aliased_command()), and the user's\ncustom git commands, but it does not support the options of the user's\ncustom git commands (of course; how could it know about the options of\na custom git command?).  Users of such custom git commands could\nextend git's bash completion script by writing functions to support\ntheir commands, but they might have issues with it: they might not\nhave the rights to modify a system-wide git completion script, and\nthey will need to track and merge upstream changes in the future.\n\nThis patch addresses this by providing means for users to supply\ncustom completion scriplets for their custom git commands without\nmodifying the main git bash completion script.\n\nInstead of having a huge hard-coded list of command-completion\nfunction pairs (in _git()), the completion script will figure out\nwhich completion function to call based on the command's name.  That\nis, when completing the options of 'git foo', the main completion\nscript will check whether the function '_git_foo' is declared, and if\ndeclared, it will invoke that function to perform the completion.  If\nsuch a function is not declared, it will fall back to complete file\nnames.  So, users will only need to provide this '_git_foo' completion\nfunction in a separate file, source that file, and it will be used the\nnext time they press TAB after 'git foo '.\n\nThere are two git commands (stage and whatchanged), for which the\ncompletion functions of other commands were used, therefore they\ngot their own completion function.\n\nSigned-off-by: SZEDER Gábor <szeder@ira.uka.de>\n---\n contrib/completion/git-completion.bash |   67 ++++++--------------------------\n 1 files changed, 12 insertions(+), 55 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 78c4983..2ac3567 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1439,6 +1439,11 @@ _git_send_email ()\n \tCOMPREPLY=()\n }\n \n+_git_stage ()\n+{\n+\t_git_add\n+}\n+\n __git_config_get_set_variables ()\n {\n \tlocal prevword word config_file= c=$COMP_CWORD\n@@ -2170,6 +2175,11 @@ _git_tag ()\n \tesac\n }\n \n+_git_whatchanged ()\n+{\n+\t_git_log\n+}\n+\n _git ()\n {\n \tlocal i c=1 command __git_dir\n@@ -2209,61 +2219,8 @@ _git ()\n \tlocal expansion=$(__git_aliased_command \"$command\")\n \t[ \"$expansion\" ] && command=\"$expansion\"\n \n-\tcase \"$command\" in\n-\tam)          _git_am ;;\n-\tadd)         _git_add ;;\n-\tapply)       _git_apply ;;\n-\tarchive)     _git_archive ;;\n-\tbisect)      _git_bisect ;;\n-\tbundle)      _git_bundle ;;\n-\tbranch)      _git_branch ;;\n-\tcheckout)    _git_checkout ;;\n-\tcherry)      _git_cherry ;;\n-\tcherry-pick) _git_cherry_pick ;;\n-\tclean)       _git_clean ;;\n-\tclone)       _git_clone ;;\n-\tcommit)      _git_commit ;;\n-\tconfig)      _git_config ;;\n-\tdescribe)    _git_describe ;;\n-\tdiff)        _git_diff ;;\n-\tdifftool)    _git_difftool ;;\n-\tfetch)       _git_fetch ;;\n-\tformat-patch) _git_format_patch ;;\n-\tfsck)        _git_fsck ;;\n-\tgc)          _git_gc ;;\n-\tgrep)        _git_grep ;;\n-\thelp)        _git_help ;;\n-\tinit)        _git_init ;;\n-\tlog)         _git_log ;;\n-\tls-files)    _git_ls_files ;;\n-\tls-remote)   _git_ls_remote ;;\n-\tls-tree)     _git_ls_tree ;;\n-\tmerge)       _git_merge;;\n-\tmergetool)   _git_mergetool;;\n-\tmerge-base)  _git_merge_base ;;\n-\tmv)          _git_mv ;;\n-\tname-rev)    _git_name_rev ;;\n-\tnotes)       _git_notes ;;\n-\tpull)        _git_pull ;;\n-\tpush)        _git_push ;;\n-\trebase)      _git_rebase ;;\n-\tremote)      _git_remote ;;\n-\treplace)     _git_replace ;;\n-\treset)       _git_reset ;;\n-\trevert)      _git_revert ;;\n-\trm)          _git_rm ;;\n-\tsend-email)  _git_send_email ;;\n-\tshortlog)    _git_shortlog ;;\n-\tshow)        _git_show ;;\n-\tshow-branch) _git_show_branch ;;\n-\tstash)       _git_stash ;;\n-\tstage)       _git_add ;;\n-\tsubmodule)   _git_submodule ;;\n-\tsvn)         _git_svn ;;\n-\ttag)         _git_tag ;;\n-\twhatchanged) _git_log ;;\n-\t*)           COMPREPLY=() ;;\n-\tesac\n+\tlocal completion_func=\"_git_${command//-/_}\"\n+\tdeclare -F $completion_func >/dev/null && $completion_func\n }\n \n _gitk ()\n-- \n1.7.0.119.g9b76\n"},{"id":"135462","messageId":"aa69c6475cf011192f9e721cf07a2b569e51acf6.1266958460.git.szeder@ira.uka.de","threadId":"22437","inReplyTo":"20100131191936.GA30466@neumann","subject":"[PATCH 3/4] bash: support user-supplied completion scripts for aliases","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-02-23T21:02:59Z","receivedAt":"2010-02-23T21:02:59Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Shell command aliases can get rather complex, and the completion\nscript can not always determine correctly the git command invoked by\nsuch an alias.  For such cases users might want to provide custom\ncompletion scripts the same way like for their custom commands made\npossible by the previous patch.\n\nThe current completion script does not allow this, because if it\nencounters an alias, then it will unconditionally perform completion\nfor the aliased git command (in case it can determine the aliased git\ncommand, of course).  With this patch the completion script will first\nsearch for a completion function for the command given on the command\nline, be it a git command, a custom git command of the user, or an\nalias, and invoke that function to perform the completion.  This has\nno effect on git commands, because they can not be aliased anyway.  If\nit is an alias and there is a completion function for that alias (e.g.\n_git_foo() for the alias 'foo'), then it will be invoked to perform\ncompletion, allowing users to provide custom completion functions for\naliases.  If such a completion function can not be found, only then\nwill the completion script check whether the command given on the\ncommand line is an alias or not, and proceed as usual (i.e. find out\nthe aliased git command and provide completion for it).\n\nSigned-off-by: SZEDER Gábor <szeder@ira.uka.de>\n---\n contrib/completion/git-completion.bash |   11 +++++++----\n 1 files changed, 7 insertions(+), 4 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 2ac3567..8593fd7 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2216,11 +2216,14 @@ _git ()\n \t\treturn\n \tfi\n \n-\tlocal expansion=$(__git_aliased_command \"$command\")\n-\t[ \"$expansion\" ] && command=\"$expansion\"\n-\n \tlocal completion_func=\"_git_${command//-/_}\"\n-\tdeclare -F $completion_func >/dev/null && $completion_func\n+\tdeclare -F $completion_func >/dev/null && $completion_func && return\n+\n+\tlocal expansion=$(__git_aliased_command \"$command\")\n+\tif [ -n \"$expansion\" ]; then\n+\t\tcompletion_func=\"_git_${expansion//-/_}\"\n+\t\tdeclare -F $completion_func >/dev/null && $completion_func\n+\tfi\n }\n \n _gitk ()\n-- \n1.7.0.119.g9b76\n"},{"id":"135464","messageId":"45bffa3348f19ef549ec2fcae88da6f1ebb17f1e.1266958460.git.szeder@ira.uka.de","threadId":"22437","inReplyTo":"20100131191936.GA30466@neumann","subject":"[PATCH 4/4] bash: completion for gitk aliases","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-02-23T21:03:00Z","receivedAt":"2010-02-23T21:03:00Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"gitk aliases either start with \"!gitk\", or look something like \"!sh -c\nFOO=bar gitk\", IOW they contain the \"gitk\" word.  With this patch the\ncompletion script will recognize these cases and will offer gitk's\noptions.\n\nJust like the earlier change improving on aliased command recognition,\nthis change can also be fooled easily by some complex aliases, but\nusers of such aliases could remedy it with custom completion\nfunctions.\n\nSigned-off-by: SZEDER Gábor <szeder@ira.uka.de>\n---\n contrib/completion/git-completion.bash |    9 +++++++++\n 1 files changed, 9 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 8593fd7..3029f16 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -626,6 +626,10 @@ __git_aliased_command ()\n \t\tconfig --get \"alias.$1\")\n \tfor word in $cmdline; do\n \t\tcase \"$word\" in\n+\t\t\\!gitk|gitk)\n+\t\t\techo \"gitk\"\n+\t\t\treturn\n+\t\t\t;;\n \t\t\\!*)\t: shell command alias ;;\n \t\t-*)\t: option ;;\n \t\t*=*)\t: setting env ;;\n@@ -1087,6 +1091,11 @@ _git_gc ()\n \tCOMPREPLY=()\n }\n \n+_git_gitk ()\n+{\n+\t_gitk\n+}\n+\n _git_grep ()\n {\n \t__git_has_doubledash && return\n-- \n1.7.0.119.g9b76\n"},{"id":"135481","messageId":"7v3a0rd2lz.fsf@alter.siamese.dyndns.org","threadId":"22437","inReplyTo":"90724961a941edd1317514dea0a1c64112dab61d.1266958460.git.szeder@ira.uka.de","subject":"Re: [PATCH 1/4] bash: improve aliased command recognition","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-23T22:11:20Z","receivedAt":"2010-02-23T22:11:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"SZEDER Gábor <szeder@ira.uka.de> writes:\n\n> [alias]\n>     lgm = \"!sh -c 'GIT_NOTES_REF=refs/notes/amlog git log \\\"$@\\\" || :' -\"\n>\n> The full parsing of a shell command alias like that in the completion\n> code is clearly unfeasible.  However, we can easily improve on aliased\n> command recognition by eleminating stuff that is definitely not a git\n> command: shell commands (anything starting with '!'), command line\n> options (anything starting with '-'), environment variables (anything\n> with a '=' in it), and git itself.  This way the above alias would be\n> handled correctly, and the completion script would correctly recognize\n> \"log\" as the aliased git command.\n\nI personally do not think such a heuristic is worth the trouble (both for\nwriting and maintaining the completion code nor runtime overhead to\niterate over words on the expansion).\n\nI vaguely recall somebody floated an idea to tell completion code that\n\"you may not know what lgm is, but it takes the same set of options as\nlog\" (either via config or a shell function---I don't recall the details).\nI think that would be a lot more robust, efficient and easy to explain\nsolution to the same problem.\n"},{"id":"135512","messageId":"20100224010459.GP4431@neumann","threadId":"22437","inReplyTo":"7v3a0rd2lz.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/4] bash: improve aliased command recognition","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-02-24T01:04:59Z","receivedAt":"2010-02-24T01:04:59Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Hi,\n\nOn Tue, Feb 23, 2010 at 02:11:20PM -0800, Junio C Hamano wrote:\n> SZEDER Gábor <szeder@ira.uka.de> writes:\n> \n> > [alias]\n> >     lgm = \"!sh -c 'GIT_NOTES_REF=refs/notes/amlog git log \\\"$@\\\" || :' -\"\n> >\n> > The full parsing of a shell command alias like that in the completion\n> > code is clearly unfeasible.  However, we can easily improve on aliased\n> > command recognition by eleminating stuff that is definitely not a git\n> > command: shell commands (anything starting with '!'), command line\n> > options (anything starting with '-'), environment variables (anything\n> > with a '=' in it), and git itself.  This way the above alias would be\n> > handled correctly, and the completion script would correctly recognize\n> > \"log\" as the aliased git command.\n> \n> I personally do not think such a heuristic is worth the trouble (both for\n> writing and maintaining the completion code nor runtime overhead to\n> iterate over words on the expansion).\n\nWell, the code is already written, so ;)\n\nRuntime overhead seems not to be an issue:\n\n$ git config alias.shortalias log\n$ git config alias.longalias \\!\"sh -c '$(for i in $(seq 1 100) ;do echo -n \"A=$i \" ;done) git log -1'\"\n$ time __git_aliased_command shortalias\nlog\n\nreal    0m0.008s\nuser    0m0.004s\nsys     0m0.004s\n$ time __git_aliased_command longalias\nlog\n\nreal    0m0.017s\nuser    0m0.012s\nsys     0m0.004s\n\nThat is, although it takes around twice as long in case of a 100+ word\nlong alias than with a trivial one, it is still in the hundredth of a\nsecond range.  And I doubt that many people have that long aliases.\n\nMaintenance might be an issue, or, erm...  well, it already is.  An\nalias like \"!sh -c 'git log -1'\" does not work, because \"'git\" does\nnot match any of the patterns, therefore it is returned as the aliased\ncommand.\n\n> I vaguely recall somebody floated an idea to tell completion code that\n> \"you may not know what lgm is, but it takes the same set of options as\n> log\" (either via config or a shell function---I don't recall the details).\n\nShawn proposed the approach via config variables and patches 2/4 and\n3/4 actually implement the shell function approach.\n\nPersonally, I prefer the shell function approach.  It needs less 'git\nconfig' queries; actually, in this respect it is better than current\nmaster, because there is no 'git config' query at all for the git\ncommand case.  Furthermore, I don't really like the idea of putting\ncompletion related stuff into git configuration files, but this is, of\ncourse, subjective.\n\n> I think that would be a lot more robust, efficient and easy to explain\n> solution to the same problem.\n\nI agree that this heuristic is not 100% robust.  Efficiency is not an\nissue, as shown above.  But I think we should also look at efficiency\nand overhead at the user, too.  That is, this heuristic will work\nwithout any action required from the user, while the other two\napproaches require the user to explicitly specify the completion rules\nfor his non-trivial aliases.  Finally, I think it is not all that\ndifficult to explain:\n\n  \"The bash completion script uses some heuristics to find out the git\n  command invoked by aliases.  If you have an alias for which the\n  completion script does nothing or outputs garbage, then you should\n  write a one-liner shell function, which ...\" and here comes what you\n  would need to explain anyway.\n\n\nNote, that patches 1/4 and 4/4 are independent from the changes in 2/4\nand 3/4, so if you are not satisfied with these heuristic changes, you\ncan still drop only those but not the custom completion patches.\n\n\nBest,\nGábor\n\n(and it's already tomorrow here, so the thoughts about completion\nnamespaces will have to wait)\n"},{"id":"135516","messageId":"7vr5obpcj7.fsf@alter.siamese.dyndns.org","threadId":"22437","inReplyTo":"20100224010459.GP4431@neumann","subject":"Re: [PATCH 1/4] bash: improve aliased command recognition","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-24T02:56:12Z","receivedAt":"2010-02-24T02:56:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"SZEDER Gábor <szeder@ira.uka.de> writes:\n\n> Personally, I prefer the shell function approach.  It needs less 'git\n> config' queries; actually, in this respect it is better than current\n> master, because there is no 'git config' query at all for the git\n> command case.  Furthermore, I don't really like the idea of putting\n> completion related stuff into git configuration files, but this is, of\n> course, subjective.\n\nWell, at least both of us seem to share the same subjective criteria ;-).\nThe custom shell function approach is the most straightforward.\n"},{"id":"135758","messageId":"20100226152710.GA17460@neumann","threadId":"22437","inReplyTo":"7viqakireb.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] bash: support user-supplied completion scripts for user's git commands","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-02-26T15:27:10Z","receivedAt":"2010-02-26T15:27:10Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Hi,\n\nOn Fri, Jan 29, 2010 at 12:32:12PM -0800, Junio C Hamano wrote:\n> Admittedly, we have already taken over _git_foo (and \"_git\") namespace,\n> and anybody who uses bash with the completion support cannot write their\n> own shell function with these names for purposes that are unrelated to\n> completion,\n\nActually, the \"_\" namespace is taken over by bash completion in\ngeneral, so writing shell functions starting with \"_\" is probably\nnot a good idea anyway.  E.g. to see all non-completion-related shell\nfunctions you can do a \"declare -F |grep -v ' _'\", but if you name\nshell functions not related to completion as _git_foo(), then this\nwill no longer work.\n\n> so in that sense, the patch is not introducing a new problem,\n> but making it a documented interface and casting it in stone will make the\n> namespace contamination issue harder to rectify later.\n> \n> So if we were to go in the direction as the patch proposes (which I think\n> is a good idea), we might want to rename them to __git_completion_foo or\n> something that is less likely to collide with whatever names users might\n> want to use. It is my understanding that the only published interface so\n> far is __git_ps1.\n\nI would say that __git_ps1() is the only interface that is advertised\nas being public.  If someone is unsatisfied with the completion\nscript, because he wanted completion for a custom git command or for a\nfrequently used plumbing command, then I bet he just reused existing\nfunctions, e.g. when he needed refs, he just used __git_refs(), or\nwhen he needed git log's options, he used _git_log().  I did that,\nprobably others too.  If we were to rename completion functions, these\npeople's setup will break (although they will likely get merge\nconflicts caused by this patch anyway).  On the other hand: should we\nreally care that much about such users, who use non-pulic interfaces\nfrom contrib/ ?\n\nHaving said all that, I don't really care either way.  If you or Shawn\nwould prefer to have the completion functions renamed, I will do a\ns/this/that/ preparation patch for the series.  BTW, Mercurial's\ncompletion script uses _hg_cmd_foo() for hg commands and\n_hg_ext_bar() for extensions, so we might as well be a bit consistent,\nand call our completion functions _git_cmd_foo().\n\n\nBest,\nGábor\n"},{"id":"135770","messageId":"7vmxyvsqzn.fsf@alter.siamese.dyndns.org","threadId":"22437","inReplyTo":"20100226152710.GA17460@neumann","subject":"Re: [PATCH] bash: support user-supplied completion scripts for user's git commands","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-26T20:04:44Z","receivedAt":"2010-02-26T20:04:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"SZEDER Gábor <szeder@ira.uka.de> writes:\n\n>> so in that sense, the patch is not introducing a new problem,\n>> but making it a documented interface and casting it in stone will make the\n>> namespace contamination issue harder to rectify later.\n\nI won't quote the first paragraph where you are repeating what I said,\nwhile sounding as if you were disagreeing with me.\n\n>> So if we were to ...\n>> ... It is my understanding that the only published interface so\n>> far is __git_ps1.\n>\n> I would say that __git_ps1() is the only interface that is advertised\n> as being public.  ...\n> ...  If we were to rename completion functions, these\n> people's setup will break (although they will likely get merge\n> conflicts caused by this patch anyway).  On the other hand: should we\n> really care that much about such users, who use non-pulic interfaces\n> from contrib/ ?\n\nI see we are in agreement in the first half of your paragraph; my answer\nto the question in the latter half is:\n\n - we shouldn't care about people who already used unpublished interface\n   in contrib/ so far; _but_\n\n - because we will be advertising it as a way to override and enhance\n   completion to define your own shell functions, the naming _will_ become\n   part of published interface---what we decide _now_ will matter.\n\nThat is why I wanted people to at least think about renaming _git_frotz to\nsomething less generic.  The name tells us that it is a helper shell\nfunction about the \"git frotz\" command, but it does not say what aspect of\n\"git frotz\" it is meant to help, i.e. completion.  _git_complete_frotz or\na variant of such would not have that problem, and will keep the door open\nfor future shell helpers that are about different aspect \"xxx\" that is\nunrelated to completion---they can then name theirs _git_xxx_frotz.\n\n> ...  BTW, Mercurial's\n> completion script uses _hg_cmd_foo() for hg commands and\n> _hg_ext_bar() for extensions, so we might as well be a bit consistent,\n> and call our completion functions _git_cmd_foo().\n\nIn Hg's context it might make sense to name a function _hg_cmd_foo vs\n_hg_ext_bar iff the end users need to be very aware of the distinction\nbetween commands and extensions, but for us I think \"git_cmd_foo\" is\nprobably the most meaningless rename, as it doesn't add any extra\ninformation (we know 'git foo' is a command already without 'cmd').\n"},{"id":"135771","messageId":"20100226201743.GB24776@spearce.org","threadId":"22437","inReplyTo":"7vmxyvsqzn.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] bash: support user-supplied completion scripts for user's git commands","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-02-26T20:17:43Z","receivedAt":"2010-02-26T20:17:43Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <gitster@pobox.com> wrote:\n> > ...  BTW, Mercurial's\n> > completion script uses _hg_cmd_foo() for hg commands and\n> > _hg_ext_bar() for extensions, so we might as well be a bit consistent,\n> > and call our completion functions _git_cmd_foo().\n> \n> In Hg's context it might make sense to name a function _hg_cmd_foo vs\n> _hg_ext_bar iff the end users need to be very aware of the distinction\n> between commands and extensions, but for us I think \"git_cmd_foo\" is\n> probably the most meaningless rename, as it doesn't add any extra\n> information (we know 'git foo' is a command already without 'cmd').\n\nI agree.  _git_cmd_foo is pointless.\n\nBut I would be ok with _git_completion_foo for the completion\nfunction of git foo.  As Junio pointed out, better to do it now\nbefore users start to really build their own extension library on\ntop of the package.\n\n-- \nShawn.\n"}]}