{"thread":{"id":"25503","subject":"[completion] Request: Include remote heads as push targets","startedAt":"2010-10-21T15:37:47Z","lastAt":"2010-10-24T16:28:30Z","messageCount":10,"participants":["Marc Branchaud","Jonathan Nieder","Peter van der Does","Kevin Ballard","SZEDER Gábor"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"153973","messageId":"4CC05E4B.1010106@xiplink.com","threadId":"25503","inReplyTo":null,"subject":"[completion] Request: Include remote heads as push targets","fromName":"Marc Branchaud","fromEmail":"marcnarc@xiplink.com","sentAt":"2010-10-21T15:37:47Z","receivedAt":"2010-10-21T15:37:47Z","isPatch":false,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"Hi Shawn,\n\nI find myself wishing that completion would support the following:\n\n\tgit push origin HEAD:<tab>\n\nThe options presented at this point should include all the origin/* heads,\nwithout the \"origin/\" prefix.  Right now (git 1.7.3.1) completion only lets\nme choose from local refs.\n\nI tried looking at the completion script myself, but my completion-fu is weak\nand I'm really not sure how to go about implementing this.\n\nSo I'm just throwing this request out to see what happens.\n\nThanks!\n\n\t\tM.\n"},{"id":"153975","messageId":"4CC06439.8040003@xiplink.com","threadId":"25503","inReplyTo":"4CC05E4B.1010106@xiplink.com","subject":"Re: [completion] Request: Include remote heads as push targets","fromName":"Marc Branchaud","fromEmail":"marcnarc@xiplink.com","sentAt":"2010-10-21T16:03:05Z","receivedAt":"2010-10-21T16:03:05Z","isPatch":false,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"On 10-10-21 11:37 AM, Marc Branchaud wrote:\n> Hi Shawn,\n> \n> I find myself wishing that completion would support the following:\n> \n> \tgit push origin HEAD:<tab>\n> \n> The options presented at this point should include all the origin/* heads,\n> without the \"origin/\" prefix.  Right now (git 1.7.3.1) completion only lets\n> me choose from local refs.\n\nHmmm, perhaps this is really a bug.\n\nWhen I double-tab, the remote branch name I want is in the list of\npossibilities.  But when I try to complete by typing a couple of leading\ncharacters then hitting <tab> again, I don't get that name.  Instead I get a\ntag that starts with the same letters.\n\nMore concretely:\n\n$ echo $BASH_VERSION\n4.1.5(1)-release\n\n$ git branch -a\n  bar\n  baz\n* master\n  remotes/origin/HEAD -> origin/master\n  remotes/origin/battle\n  remotes/origin/battle.hardened\n  remotes/origin/master\n\n$ git tag\nbassinet\n\n$ git push origin HEAD:<tab><tab>\nbattle            battle.hardened   HEAD              master\n\n$ git push origin HEAD:ba<tab><tab>\nbar        bassinet   baz\n\nWacky!\n\n\t\tM.\n"},{"id":"154001","messageId":"20101021191045.GC11759@burratino","threadId":"25503","inReplyTo":"4CC06439.8040003@xiplink.com","subject":"Re: [completion] Request: Include remote heads as push targets","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-10-21T19:10:45Z","receivedAt":"2010-10-21T19:10:45Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Marc Branchaud wrote:\n\n> Hmmm, perhaps this is really a bug.\n\nCompare:\nhttp://thread.gmane.org/gmane.comp.version-control.git/159448\n\nGábor, would it be possible to summarize the problem with a simple\ntest case that could be used to get help on this from the (upstream\nor distro-specific) bash maintainers?\n"},{"id":"154085","messageId":"20101021210842.6545a661@montecarlo.grandprix.int","threadId":"25503","inReplyTo":"20101021191045.GC11759@burratino","subject":"Re: [completion] Request: Include remote heads as push targets","fromName":"Peter van der Does","fromEmail":"peter@avirtualhome.com","sentAt":"2010-10-22T01:08:42Z","receivedAt":"2010-10-22T01:08:42Z","isPatch":false,"sender":{"key":"peter@avirtualhome.com","avatar":"https://avatars.githubusercontent.com/u/380071?v=4"},"body":"On Thu, 21 Oct 2010 14:10:45 -0500\nJonathan Nieder <jrnieder@gmail.com> wrote:\n\n> Marc Branchaud wrote:\n> \n> > Hmmm, perhaps this is really a bug.\n> \n> Compare:\n> http://thread.gmane.org/gmane.comp.version-control.git/159448\n> \n> Gábor, would it be possible to summarize the problem with a simple\n> test case that could be used to get help on this from the (upstream\n> or distro-specific) bash maintainers?\n> --\n\nIn the case of Marc's problem, it would be helpful to see what the\nresult is in Bash 3.\n\nAs for Gábor find:\nThe problem resides in Bash 4. Bash 4 has a new set of characters that\nare defined as break up characters\nThanks to Brain Gernhard: \nFrom the Bash 4.0 changelog:\ni.  The programmable completion code now uses the same set of\ncharacters as readline when breaking the command line into a list of\nwords.\n\nAs far as I can tell, from the Bash 4.0 source, these are the\ncharacters: \" \\t\\n\\\"'@><=;|&(:\" \nIn the completion script checks are performed if an option is given.\nThe test includes the equal sign but the array with words does not the\nequal sign. Example to clarify:\n\nlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" dir=\"$(__gitdir)\"\ncase \"$cur\" in\n  --whitespace=*)\n      __gitcomp \"$__git_whitespacelist\" \"\" \"${cur##--whitespace=}\"\n      return\n      ;;\n\nIf you execute:\n$ git am --whitespace=<tab><tab>\n\nThe variable cur holds the equal sign and so the __gitcomp function is\nnever executed.\n\nI have patched the entire completion script which fixes this, and some\nother issues related to the Bash 4 change, but it will only work in Bash\n4.0 and I am sure it will dramatically fail in Bash 3.0.\nI don't have the knowledge to determine which Bash version is running\nin the git.spec.in file. If you could that would be a way to either\ninstall the new version or the old one.\n\n\n-- \nPeter van der Does\n\nGPG key: E77E8E98\n\nIRC: Ganseki on irc.freenode.net\nTwitter: @petervanderdoes\n\nWordPress Plugin Developer\nBlog: http://blog.avirtualhome.com\nForums: http://forums.avirtualhome.com\nTwitter: @avhsoftware\n"},{"id":"154086","messageId":"7FC32402-F0D4-4420-B984-ACAB45DBDDB3@sb.org","threadId":"25503","inReplyTo":"20101021210842.6545a661@montecarlo.grandprix.int","subject":"Re: [completion] Request: Include remote heads as push targets","fromName":"Kevin Ballard","fromEmail":"kevin@sb.org","sentAt":"2010-10-22T01:11:34Z","receivedAt":"2010-10-22T01:11:34Z","isPatch":false,"sender":{"key":"kevin@sb.org","avatar":"https://avatars.githubusercontent.com/u/714?v=4"},"body":"On Oct 21, 2010, at 6:08 PM, Peter van der Does wrote:\n\n> I don't have the knowledge to determine which Bash version is running\n> in the git.spec.in file. If you could that would be a way to either\n> install the new version or the old one.\n\nCould you instead teach the script how to work on both Bash 3 or Bash 4? If you could extract the references to the completion words into a function, you could define one function for Bash 3 and one for Bash 4, and use ${BASH_VERSINFO[0]} to determine which to use.\n\n-Kevin Ballard"},{"id":"154150","messageId":"4CC1A4A9.3040703@xiplink.com","threadId":"25503","inReplyTo":"20101021210842.6545a661@montecarlo.grandprix.int","subject":"Re: [completion] Request: Include remote heads as push targets","fromName":"Marc Branchaud","fromEmail":"marcnarc@xiplink.com","sentAt":"2010-10-22T14:50:17Z","receivedAt":"2010-10-22T14:50:17Z","isPatch":false,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"On 10-10-21 09:08 PM, Peter van der Does wrote:\n> \n> In the case of Marc's problem, it would be helpful to see what the\n> result is in Bash 3.\n\nBash v3 seems to work fine:\n\n$ echo $BASH_VERSION\n3.2.0(1)-release\n\n$ git branch -a\n  bar\n  baz\n* master\n  remotes/origin/HEAD -> origin/master\n  remotes/origin/battle\n  remotes/origin/battle.hardened\n  remotes/origin/master\n\n$ git tag\nbassinet\n\n$ git push origin HEAD:<tab><tab>\nbattle            battle.hardened   HEAD              master\n\n$ git push origin HEAD:ba<tab>\n  git push origin HEAD:battle<tab><tab>\nbattle            battle.hardened\n\n\t\tM.\n"},{"id":"154238","messageId":"20101023130434.GA29386@neumann","threadId":"25503","inReplyTo":"20101021210842.6545a661@montecarlo.grandprix.int","subject":"Re: [completion] Request: Include remote heads as push targets","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-10-23T13:04:34Z","receivedAt":"2010-10-23T13:04:34Z","isPatch":false,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Hi,\n\n\nOn Thu, Oct 21, 2010 at 09:08:42PM -0400, Peter van der Does wrote:\n> On Thu, 21 Oct 2010 14:10:45 -0500\n> Jonathan Nieder <jrnieder@gmail.com> wrote:\n> \n> > Marc Branchaud wrote:\n> > \n> > > Hmmm, perhaps this is really a bug.\n> > \n> > Compare:\n> > http://thread.gmane.org/gmane.comp.version-control.git/159448\n\nYeah, it seems that the two issues are related.  I can confirm what\nMarc saw, and below is a PoC patch to fix it.\n\n> In the case of Marc's problem, it would be helpful to see what the\n> result is in Bash 3.\n\nOn an oldish server with bash 3.2 it works as expected, i.e. I get\nonly the matching branches and tags from the remote repo.\n\n(Sidenote: hm, offering _tags_ to _push to_?!  That doesn't seem quite\nright at first sight.)\n\n\n> > Gábor, would it be possible to summarize the problem with a simple\n> > test case that could be used to get help on this from the (upstream\n> > or distro-specific) bash maintainers?\n\nGit's bash completion is not the first to suffer from changes in bash\n4, and fortunately the bash-completion developers already provide a\nsolution for such issues.  Details below.\n\n> As for Gábor find:\n> The problem resides in Bash 4.\n\nI agree.\n\n> Bash 4 has a new set of characters that\n> are defined as break up characters\n> Thanks to Brain Gernhard: \n> From the Bash 4.0 changelog:\n> i.  The programmable completion code now uses the same set of\n> characters as readline when breaking the command line into a list of\n> words.\n> \n> As far as I can tell, from the Bash 4.0 source, these are the\n> characters: \" \\t\\n\\\"'@><=;|&(:\" \n\nUm, well, I suspect that there are other subtle differences between\nbash 4 and 3 besides the change of word-breaking characters that\ntrigger this breakage.  In fact, the oldish server mentioned above\nwith bash 3.2 has the exact same characters in $COMP_WORDBREAKS, and\nneither Marc's nor my issue occur there.\n\n> In the completion script checks are performed if an option is given.\n> The test includes the equal sign but the array with words does not the\n> equal sign. Example to clarify:\n> \n> local cur=\"${COMP_WORDS[COMP_CWORD]}\" dir=\"$(__gitdir)\"\n> case \"$cur\" in\n>   --whitespace=*)\n>       __gitcomp \"$__git_whitespacelist\" \"\" \"${cur##--whitespace=}\"\n>       return\n>       ;;\n> \n> If you execute:\n> $ git am --whitespace=<tab><tab>\n> \n> The variable cur holds the equal sign and so the __gitcomp function is\n> never executed.\n\nThat's exactly what I observed.  This ${COMP_WORDS[COMP_CWORD]}\nconstruct apparently is not the right way to find the word to complete\nanymore, assuming you want your completion script to work with bash 4\nand 3 as well.  Unfortunately, we use this construct all over the\nplace.\n\nNow, the bash completion project has some functions that could be used\nto circumvent these issues.  In particular, look at the description of\nthe _get_comp_words_by_ref() function here, especially at the -n\noption:\n\nhttp://git.debian.org/?p=bash-completion/bash-completion.git;a=blob;f=bash_completion;h=589c2e5afe283d2e6d7628b683ae6714ab70d3d9;hb=HEAD#l371\n\nThat would allow us to remove characters from $COMP_WORDBREAKS on a\nper-function basis, without influencing unrelated completion functions\nwithin or outside of git completion, and in a way that works with bash\n4 and 3 as well.\n\nHere is a proof of concept patch to use that function instead of\n${COMP_WORDS[COMP_CWORD]} in two places.  The second hunk fixes the\ncompletion of pretty aliases for 'git log --pretty='.  The first hunk\nseems to fix Marc's issue with the completion of remotes after 'git\npush origin HEAD:', but I haven't thought this one through (there's a\nlot going on with scanning the previous words on the command line and\nsuch, so it might actually break something else).  Both fixes seem to\nwork under bash 4 and 3.2.\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex f83f019..5608e9b 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -551,7 +551,8 @@ __git_complete_revlist ()\n __git_complete_remote_or_refspec ()\n {\n \tlocal cmd=\"${COMP_WORDS[1]}\"\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n ':' cur\n \tlocal i c=2 remote=\"\" pfx=\"\" lhs=1 no_complete_refspec=0\n \twhile [ $c -lt $COMP_CWORD ]; do\n \t\ti=\"${COMP_WORDS[c]}\"\n@@ -1360,7 +1361,8 @@ _git_log ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur\n+\t_get_comp_words_by_ref -n '=' cur\n \tlocal g=\"$(git rev-parse --git-dir 2>/dev/null)\"\n \tlocal merge=\"\"\n \tif [ -f \"$g/MERGE_HEAD\" ]; then\n\nThis patch assumes that you use fairly recent bash-completion, because\n_get_comp_words_by_ref() was first included in bash-completion v1.2,\nwhich was released just this summer.\n\nHowever, git completion is currently a standalone completion script,\ni.e. to use it you need only bash, git-completion.bash, and nothing\nelse.  If we start to use _get_comp_words_by_ref() directly, as in the\nPoC patch above, then git completion will inherently depend on\nbash-completion, too.  This could be considered as a regression.\n\nAlternatively, we could just copy the necessary functions from\nbash-completion to git-completion.bash (with the name changed, of\ncourse, e.g. to __git_get_comp_words_by_ref()), keeping git completion\nstandalone but still getting the benefits of this function, and\ngetting these bash 4 vs. 3 issues fixed.\n\nThoughts?\n\n\nBest,\nGábor\n"},{"id":"154289","messageId":"20101023200739.28b6eb1e@montecarlo.grandprix.int","threadId":"25503","inReplyTo":"20101023130434.GA29386@neumann","subject":"Re: [completion] Request: Include remote heads as push targets","fromName":"Peter van der Does","fromEmail":"peter@avirtualhome.com","sentAt":"2010-10-24T00:07:39Z","receivedAt":"2010-10-24T00:07:39Z","isPatch":false,"sender":{"key":"peter@avirtualhome.com","avatar":"https://avatars.githubusercontent.com/u/380071?v=4"},"body":"On Sat, 23 Oct 2010 15:04:34 +0200\nSZEDER Gábor <szeder@ira.uka.de> wrote:\n\n\n> Here is a proof of concept patch to use that function instead of\n> ${COMP_WORDS[COMP_CWORD]} in two places.  The second hunk fixes the\n> completion of pretty aliases for 'git log --pretty='.  The first hunk\n> seems to fix Marc's issue with the completion of remotes after 'git\n> push origin HEAD:', but I haven't thought this one through (there's a\n> lot going on with scanning the previous words on the command line and\n> such, so it might actually break something else).  Both fixes seem to\n> work under bash 4 and 3.2.\n> \n> diff --git a/contrib/completion/git-completion.bash\n> b/contrib/completion/git-completion.bash index f83f019..5608e9b 100755\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -551,7 +551,8 @@ __git_complete_revlist ()\n>  __git_complete_remote_or_refspec ()\n>  {\n>  \tlocal cmd=\"${COMP_WORDS[1]}\"\n> -\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n> +\tlocal cur\n> +\t_get_comp_words_by_ref -n ':' cur\n>  \tlocal i c=2 remote=\"\" pfx=\"\" lhs=1 no_complete_refspec=0\n>  \twhile [ $c -lt $COMP_CWORD ]; do\n>  \t\ti=\"${COMP_WORDS[c]}\"\n> @@ -1360,7 +1361,8 @@ _git_log ()\n>  {\n>  \t__git_has_doubledash && return\n>  \n> -\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n> +\tlocal cur\n> +\t_get_comp_words_by_ref -n '=' cur\n>  \tlocal g=\"$(git rev-parse --git-dir 2>/dev/null)\"\n>  \tlocal merge=\"\"\n>  \tif [ -f \"$g/MERGE_HEAD\" ]; then\n> \n> This patch assumes that you use fairly recent bash-completion, because\n> _get_comp_words_by_ref() was first included in bash-completion v1.2,\n> which was released just this summer.\n> \n> However, git completion is currently a standalone completion script,\n> i.e. to use it you need only bash, git-completion.bash, and nothing\n> else.  If we start to use _get_comp_words_by_ref() directly, as in the\n> PoC patch above, then git completion will inherently depend on\n> bash-completion, too.  This could be considered as a regression.\n> \n> Alternatively, we could just copy the necessary functions from\n> bash-completion to git-completion.bash (with the name changed, of\n> course, e.g. to __git_get_comp_words_by_ref()), keeping git completion\n> standalone but still getting the benefits of this function, and\n> getting these bash 4 vs. 3 issues fixed.\n> \n> Thoughts?\n> \n\nInstead of using [code]_get_comp_words_by_ref -n '=' cur[/code] you can\nuse [code]local cur=`_get_cword \"=\"`[/code].\n\nTo keep git completion standalone we need to, like Gábor mentioned, add\nthe necessary functions, but we don't have to rename them. There is\nan option to check if a function exists. I've changed the entire git\ncompletion script and hopefully covered all options. From my tests it\nworks on bash 4.\n\nTo give an idea of what the change is, here's part of the entire diff.\n\ndiff --git a/contrib/completion/git-completion.bash\nb/contrib/completion/git-completion.bash index f83f019..a2c0589 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -71,12 +71,159 @@\n #\n #       git@vger.kernel.org\n #\n+# Updated for Bash 4.0\n \n case \"$COMP_WORDBREAKS\" in\n *:*) : great ;;\n *)   COMP_WORDBREAKS=\"$COMP_WORDBREAKS:\"\n esac\n \n+# If the function _get_cword does not exists, we can assume the\n+# bash_completion script isn't loaded and therefor we're defining the\n+# necessary functions ourselves.\n+if ! type _get_cword &> /dev/null ; then\n+\t# features supported by bash 4.0 and higher\n+\tif [ ${BASH_VERSINFO[0]} -gt 3 ]; then\n+\t    declare -r git_bash4=$BASH_VERSION 2>/dev/null || :\n+\tfi\n+\n+\t# Get the word to complete.\n+\t# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it\nhandles cases\n+\t# where the user is completing in the middle of a word.\n+\t# (For example, if the line is \"ls foobar\",\n+\t# and the cursor is here -------->   ^\n+\t# it will complete just \"foo\", not \"foobar\", which is what the\nuser wants.)\n+\t# @param $1 string  (optional) Characters out of\n$COMP_WORDBREAKS which should\n+\t#     NOT be considered word breaks. This is useful for things\nlike scp where\n+\t#     we want to return host:path and not only path.\n+\t#     NOTE: This parameter only applies to bash-4.\n+\t_get_cword()\n+\t{\n+    \tif [ -n \"$git_bash4\" ] ; then\n+        \t__get_cword4 \"$@\"\n+    \telse\n+        \t__get_cword3\n+    \tfi\n+\t} # _get_cword()\n+\n+\n+\t# Get the word to complete on bash-3, where words are not\nbroken by\n+\t# COMP_WORDBREAKS characters and the COMP_CWORD variables look\nlike this, for\n+\t# example:\n+\t#\n+\t#     $ a b:c<TAB>\n+\t#     COMP_CWORD: 1\n+\t#     COMP_CWORDS:\n+\t#     0: a\n+\t#     1: b:c\n+\t#\n+\t# See also:\n+\t# _get_cword, main routine\n+\t# __get_cword4, bash-4 variant\n+\t#\n+\t__get_cword3()\n+\t{\n+\t    if [[ \"${#COMP_WORDS[COMP_CWORD]}\" -eq 0 ]] ||\n[[ \"$COMP_POINT\" == \"${#COMP_LINE}\" ]]; then\n+        \tprintf \"%s\" \"${COMP_WORDS[COMP_CWORD]}\"\n+    \telse\n+\t        local i\n+        \tlocal cur=\"$COMP_LINE\"\n+        \tlocal index=\"$COMP_POINT\"\n+        \tfor (( i = 0; i <= COMP_CWORD; ++i )); do\n+\t            while [[\n+                \t# Current COMP_WORD fits in $cur?\n+                \t\"${#cur}\" -ge ${#COMP_WORDS[i]} &&\n+                \t# $cur doesn't match COMP_WORD?\n+                \t\"${cur:0:${#COMP_WORDS[i]}}\" !=\n\"${COMP_WORDS[i]}\"\n+                \t]]; do\n+                \t# Strip first character\n+                \tcur=\"${cur:1}\"\n+                \t# Decrease cursor position\n+                \tindex=\"$(( index - 1 ))\"\n+            \tdone\n+\t\n+            \t# Does found COMP_WORD matches COMP_CWORD?\n+            \tif [[ \"$i\" -lt \"$COMP_CWORD\" ]]; then\n+\t                # No, COMP_CWORD lies further;\n+                \tlocal old_size=\"${#cur}\"\n+                \tcur=\"${cur#${COMP_WORDS[i]}}\"\n+                \tlocal new_size=\"${#cur}\"\n+                \tindex=\"$(( index - old_size + new_size ))\"\n+            \tfi\n+        \tdone\n+\n+\t        if [[ \"${COMP_WORDS[COMP_CWORD]:0:${#cur}}\" !=\n\"$cur\" ]]; then\n+            \t# We messed up! At least return the whole word so\nthings\n+            \t# keep working\n+            \tprintf \"%s\" \"${COMP_WORDS[COMP_CWORD]}\"\n+        \telse\n+\t            printf \"%s\" \"${cur:0:$index}\"\n+        \tfi\n+    \tfi\n+\t} # __get_cword3()\n+\n+\n+\t# Get the word to complete on bash-4, where words are splitted\nby\n+\t# COMP_WORDBREAKS characters (default is \" \\t\\n\\\"'><=;|&(:\")\nand the COMP_CWORD\n+\t# variables look like this, for example:\n+\t#\n+\t#     $ a b:c<TAB>\n+\t#     COMP_CWORD: 3\n+\t#     COMP_CWORDS:\n+\t#     0: a\n+\t#     1: b\n+\t#     2: :\n+\t#     3: c\n+\t#\n+\t# @oaram $1 string\n+\t# $1 string  (optional) Characters out of $COMP_WORDBREAKS\nwhich should\n+\t#     NOT be considered word breaks. This is useful for things\nlike scp where\n+\t#     we want to return host:path and not only path.\n+\t# See also:\n+\t# _get_cword, main routine\n+\t# __get_cword3, bash-3 variant\n+\t#\n+\t__get_cword4()\n+\t{\n+\t    local i\n+\t    local LC_CTYPE=C\n+\t    local WORDBREAKS=$COMP_WORDBREAKS\n+\t    # Strip single quote (') and double quote (\") from\nWORDBREAKS to\n+\t    # workaround a bug in bash-4.0, where quoted words are\nsplit\n+\t    # unintended, see:\n+\t    #\nhttp://www.mail-archive.com/bug-bash@gnu.org/msg06095.html\n+\t    # This fixes simple quoting (e.g. $ a \"b<TAB> returns \"b\ninstead of b)\n+\t    # but still fails quoted spaces (e.g. $ a \"b c<TAB>\nreturns c instead\n+\t    # of \"b c).\n+\t    WORDBREAKS=${WORDBREAKS//\\\"/}\n+\t    WORDBREAKS=${WORDBREAKS//\\'/}\n+\t    if [ -n \"$1\" ]; then\n+        \tfor (( i=0; i<${#1}; ++i )); do\n+\t            local char=${1:$i:1}\n+            \tWORDBREAKS=${WORDBREAKS//$char/}\n+        \tdone\n+    \tfi\n+    \tlocal cur=${COMP_LINE:0:$COMP_POINT}\n+    \tlocal tmp=$cur\n+    \tlocal word_start=`expr \"$tmp\" : '.*['\"$WORDBREAKS\"']'`\n+    \twhile [ \"$word_start\" -ge 2 ]; do\n+\t        # Get character before $word_start\n+        \tlocal char=${cur:$(( $word_start - 2 )):1}\n+        \t# If the WORDBREAK character isn't escaped, exit loop\n+        \tif [ \"$char\" != \"\\\\\" ]; then\n+\t            break\n+        \tfi\n+        \t# The WORDBREAK character is escaped;\n+        \t# Recalculate $word_start\n+        \ttmp=${COMP_LINE:0:$(( $word_start - 2 ))}\n+        \tword_start=`expr \"$tmp\" : '.*['\"$WORDBREAKS\"']'`\n+    \tdone\n+\n+\t    cur=${cur:$word_start}\n+\t    printf \"%s\" \"$cur\"\n+\t} # __get_cword4()\n+fi\n+\n@@ -551,7 +698,7 @@ __git_complete_revlist ()\n __git_complete_remote_or_refspec ()\n {\n \tlocal cmd=\"${COMP_WORDS[1]}\"\n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur=`_get_cword \":\"`\n \tlocal i c=2 remote=\"\" pfx=\"\" lhs=1 no_complete_refspec=0\n \twhile [ $c -lt $COMP_CWORD ]; do\n \t\ti=\"${COMP_WORDS[c]}\"\n@@ -1360,7 +1508,7 @@ _git_log ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur=`_get_cword \"=\"`\n \tlocal g=\"$(git rev-parse --git-dir 2>/dev/null)\"\n \tlocal merge=\"\"\n \tif [ -f \"$g/MERGE_HEAD\" ]; then\n@@ -1419,7 +1567,7 @@ _git_merge ()\n {\n \t__git_complete_strategy && return\n \n-\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\tlocal cur=`_get_cword`\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"$__git_merge_options\"\n\n\nI just need someone to test the new script on Bash 3. If somebody is\nwilling to test, drop me an private email and I can send the new script.\n\nPeter\n\n-- \nGPG key: E77E8E98\n\nIRC: Ganseki on irc.freenode.net\nTwitter: @petervanderdoes\n\nWordPress Plugin Developer\nBlog: http://blog.avirtualhome.com\nForums: http://forums.avirtualhome.com\nTwitter: @avhsoftware\n"},{"id":"154311","messageId":"20101024112325.GB29386@neumann","threadId":"25503","inReplyTo":"20101023200739.28b6eb1e@montecarlo.grandprix.int","subject":"Re: [completion] Request: Include remote heads as push targets","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-10-24T11:23:26Z","receivedAt":"2010-10-24T11:23:26Z","isPatch":false,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Sat, Oct 23, 2010 at 08:07:39PM -0400, Peter van der Does wrote:\n> On Sat, 23 Oct 2010 15:04:34 +0200\n> SZEDER Gábor <szeder@ira.uka.de> wrote:\n>\n> > This patch assumes that you use fairly recent bash-completion, because\n> > _get_comp_words_by_ref() was first included in bash-completion v1.2,\n> > which was released just this summer.\n> > \n> > However, git completion is currently a standalone completion script,\n> > i.e. to use it you need only bash, git-completion.bash, and nothing\n> > else.  If we start to use _get_comp_words_by_ref() directly, as in the\n> > PoC patch above, then git completion will inherently depend on\n> > bash-completion, too.  This could be considered as a regression.\n> > \n> > Alternatively, we could just copy the necessary functions from\n> > bash-completion to git-completion.bash (with the name changed, of\n> > course, e.g. to __git_get_comp_words_by_ref()), keeping git completion\n> > standalone but still getting the benefits of this function, and\n> > getting these bash 4 vs. 3 issues fixed.\n> > \n> > Thoughts?\n> > \n> \n> Instead of using [code]_get_comp_words_by_ref -n '=' cur[/code] you can\n> use [code]local cur=`_get_cword \"=\"`[/code].\n> \n> To keep git completion standalone we need to, like Gábor mentioned, add\n> the necessary functions, but we don't have to rename them. There is\n> an option to check if a function exists. I've changed the entire git\n> completion script and hopefully covered all options. From my tests it\n> works on bash 4.\n\nChecking for the function first, and declaring it if it doesn't exists\ncould be a viewable alternative, but not with _get_cword().  The\n_get_cword() implementation you are adding below is outdated.  It is\nfrom bash-completion 1.1, changed quite a bit after that, and in the\nend became deprecated in 1.2 in favor of _get_comp_words_by_ref().\n\n\n> To give an idea of what the change is, here's part of the entire diff.\n> \n> diff --git a/contrib/completion/git-completion.bash\n> b/contrib/completion/git-completion.bash index f83f019..a2c0589 100755\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -71,12 +71,159 @@\n>  #\n>  #       git@vger.kernel.org\n>  #\n> +# Updated for Bash 4.0\n>  \n>  case \"$COMP_WORDBREAKS\" in\n>  *:*) : great ;;\n>  *)   COMP_WORDBREAKS=\"$COMP_WORDBREAKS:\"\n>  esac\n>  \n> +# If the function _get_cword does not exists, we can assume the\n> +# bash_completion script isn't loaded and therefor we're defining the\n> +# necessary functions ourselves.\n> +if ! type _get_cword &> /dev/null ; then\n> +\t# features supported by bash 4.0 and higher\n> +\tif [ ${BASH_VERSINFO[0]} -gt 3 ]; then\n> +\t    declare -r git_bash4=$BASH_VERSION 2>/dev/null || :\n> +\tfi\n> +\n> +\t# Get the word to complete.\n> +\t# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it\n> handles cases\n> +\t# where the user is completing in the middle of a word.\n> +\t# (For example, if the line is \"ls foobar\",\n> +\t# and the cursor is here -------->   ^\n> +\t# it will complete just \"foo\", not \"foobar\", which is what the\n> user wants.)\n> +\t# @param $1 string  (optional) Characters out of\n> $COMP_WORDBREAKS which should\n> +\t#     NOT be considered word breaks. This is useful for things\n> like scp where\n> +\t#     we want to return host:path and not only path.\n> +\t#     NOTE: This parameter only applies to bash-4.\n> +\t_get_cword()\n> +\t{\n> +    \tif [ -n \"$git_bash4\" ] ; then\n> +        \t__get_cword4 \"$@\"\n> +    \telse\n> +        \t__get_cword3\n> +    \tfi\n> +\t} # _get_cword()\n> +\n> +\n> +\t# Get the word to complete on bash-3, where words are not\n> broken by\n> +\t# COMP_WORDBREAKS characters and the COMP_CWORD variables look\n> like this, for\n> +\t# example:\n> +\t#\n> +\t#     $ a b:c<TAB>\n> +\t#     COMP_CWORD: 1\n> +\t#     COMP_CWORDS:\n> +\t#     0: a\n> +\t#     1: b:c\n> +\t#\n> +\t# See also:\n> +\t# _get_cword, main routine\n> +\t# __get_cword4, bash-4 variant\n> +\t#\n> +\t__get_cword3()\n> +\t{\n> +\t    if [[ \"${#COMP_WORDS[COMP_CWORD]}\" -eq 0 ]] ||\n> [[ \"$COMP_POINT\" == \"${#COMP_LINE}\" ]]; then\n> +        \tprintf \"%s\" \"${COMP_WORDS[COMP_CWORD]}\"\n> +    \telse\n> +\t        local i\n> +        \tlocal cur=\"$COMP_LINE\"\n> +        \tlocal index=\"$COMP_POINT\"\n> +        \tfor (( i = 0; i <= COMP_CWORD; ++i )); do\n> +\t            while [[\n> +                \t# Current COMP_WORD fits in $cur?\n> +                \t\"${#cur}\" -ge ${#COMP_WORDS[i]} &&\n> +                \t# $cur doesn't match COMP_WORD?\n> +                \t\"${cur:0:${#COMP_WORDS[i]}}\" !=\n> \"${COMP_WORDS[i]}\"\n> +                \t]]; do\n> +                \t# Strip first character\n> +                \tcur=\"${cur:1}\"\n> +                \t# Decrease cursor position\n> +                \tindex=\"$(( index - 1 ))\"\n> +            \tdone\n> +\t\n> +            \t# Does found COMP_WORD matches COMP_CWORD?\n> +            \tif [[ \"$i\" -lt \"$COMP_CWORD\" ]]; then\n> +\t                # No, COMP_CWORD lies further;\n> +                \tlocal old_size=\"${#cur}\"\n> +                \tcur=\"${cur#${COMP_WORDS[i]}}\"\n> +                \tlocal new_size=\"${#cur}\"\n> +                \tindex=\"$(( index - old_size + new_size ))\"\n> +            \tfi\n> +        \tdone\n> +\n> +\t        if [[ \"${COMP_WORDS[COMP_CWORD]:0:${#cur}}\" !=\n> \"$cur\" ]]; then\n> +            \t# We messed up! At least return the whole word so\n> things\n> +            \t# keep working\n> +            \tprintf \"%s\" \"${COMP_WORDS[COMP_CWORD]}\"\n> +        \telse\n> +\t            printf \"%s\" \"${cur:0:$index}\"\n> +        \tfi\n> +    \tfi\n> +\t} # __get_cword3()\n> +\n> +\n> +\t# Get the word to complete on bash-4, where words are splitted\n> by\n> +\t# COMP_WORDBREAKS characters (default is \" \\t\\n\\\"'><=;|&(:\")\n> and the COMP_CWORD\n> +\t# variables look like this, for example:\n> +\t#\n> +\t#     $ a b:c<TAB>\n> +\t#     COMP_CWORD: 3\n> +\t#     COMP_CWORDS:\n> +\t#     0: a\n> +\t#     1: b\n> +\t#     2: :\n> +\t#     3: c\n> +\t#\n> +\t# @oaram $1 string\n> +\t# $1 string  (optional) Characters out of $COMP_WORDBREAKS\n> which should\n> +\t#     NOT be considered word breaks. This is useful for things\n> like scp where\n> +\t#     we want to return host:path and not only path.\n> +\t# See also:\n> +\t# _get_cword, main routine\n> +\t# __get_cword3, bash-3 variant\n> +\t#\n> +\t__get_cword4()\n> +\t{\n> +\t    local i\n> +\t    local LC_CTYPE=C\n> +\t    local WORDBREAKS=$COMP_WORDBREAKS\n> +\t    # Strip single quote (') and double quote (\") from\n> WORDBREAKS to\n> +\t    # workaround a bug in bash-4.0, where quoted words are\n> split\n> +\t    # unintended, see:\n> +\t    #\n> http://www.mail-archive.com/bug-bash@gnu.org/msg06095.html\n> +\t    # This fixes simple quoting (e.g. $ a \"b<TAB> returns \"b\n> instead of b)\n> +\t    # but still fails quoted spaces (e.g. $ a \"b c<TAB>\n> returns c instead\n> +\t    # of \"b c).\n> +\t    WORDBREAKS=${WORDBREAKS//\\\"/}\n> +\t    WORDBREAKS=${WORDBREAKS//\\'/}\n> +\t    if [ -n \"$1\" ]; then\n> +        \tfor (( i=0; i<${#1}; ++i )); do\n> +\t            local char=${1:$i:1}\n> +            \tWORDBREAKS=${WORDBREAKS//$char/}\n> +        \tdone\n> +    \tfi\n> +    \tlocal cur=${COMP_LINE:0:$COMP_POINT}\n> +    \tlocal tmp=$cur\n> +    \tlocal word_start=`expr \"$tmp\" : '.*['\"$WORDBREAKS\"']'`\n> +    \twhile [ \"$word_start\" -ge 2 ]; do\n> +\t        # Get character before $word_start\n> +        \tlocal char=${cur:$(( $word_start - 2 )):1}\n> +        \t# If the WORDBREAK character isn't escaped, exit loop\n> +        \tif [ \"$char\" != \"\\\\\" ]; then\n> +\t            break\n> +        \tfi\n> +        \t# The WORDBREAK character is escaped;\n> +        \t# Recalculate $word_start\n> +        \ttmp=${COMP_LINE:0:$(( $word_start - 2 ))}\n> +        \tword_start=`expr \"$tmp\" : '.*['\"$WORDBREAKS\"']'`\n> +    \tdone\n> +\n> +\t    cur=${cur:$word_start}\n> +\t    printf \"%s\" \"$cur\"\n> +\t} # __get_cword4()\n> +fi\n> +\n> @@ -551,7 +698,7 @@ __git_complete_revlist ()\n>  __git_complete_remote_or_refspec ()\n>  {\n>  \tlocal cmd=\"${COMP_WORDS[1]}\"\n> -\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n> +\tlocal cur=`_get_cword \":\"`\n>  \tlocal i c=2 remote=\"\" pfx=\"\" lhs=1 no_complete_refspec=0\n>  \twhile [ $c -lt $COMP_CWORD ]; do\n>  \t\ti=\"${COMP_WORDS[c]}\"\n> @@ -1360,7 +1508,7 @@ _git_log ()\n>  {\n>  \t__git_has_doubledash && return\n>  \n> -\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n> +\tlocal cur=`_get_cword \"=\"`\n>  \tlocal g=\"$(git rev-parse --git-dir 2>/dev/null)\"\n>  \tlocal merge=\"\"\n>  \tif [ -f \"$g/MERGE_HEAD\" ]; then\n> @@ -1419,7 +1567,7 @@ _git_merge ()\n>  {\n>  \t__git_complete_strategy && return\n>  \n> -\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n> +\tlocal cur=`_get_cword`\n>  \tcase \"$cur\" in\n>  \t--*)\n>  \t\t__gitcomp \"$__git_merge_options\"\n> \n> \n> I just need someone to test the new script on Bash 3. If somebody is\n> willing to test, drop me an private email and I can send the new script.\n> \n"},{"id":"154341","messageId":"20101024122830.791ce80e@montecarlo.grandprix.int","threadId":"25503","inReplyTo":"20101024112325.GB29386@neumann","subject":"Re: [completion] Request: Include remote heads as push targets","fromName":"Peter van der Does","fromEmail":"peter@avirtualhome.com","sentAt":"2010-10-24T16:28:30Z","receivedAt":"2010-10-24T16:28:30Z","isPatch":false,"sender":{"key":"peter@avirtualhome.com","avatar":"https://avatars.githubusercontent.com/u/380071?v=4"},"body":"On Sun, 24 Oct 2010 13:23:26 +0200\nSZEDER Gábor <szeder@ira.uka.de> wrote:\n\n\n> Checking for the function first, and declaring it if it doesn't exists\n> could be a viewable alternative, but not with _get_cword().  The\n> _get_cword() implementation you are adding below is outdated.  It is\n> from bash-completion 1.1, changed quite a bit after that, and in the\n> end became deprecated in 1.2 in favor of _get_comp_words_by_ref().\n> \n> \n\nOk, I just used the bash_completion version installed with Ubuntu Lucid.\nI think we should use the 1.2 version.\n\n-- \nPeter van der Does\n\nGPG key: E77E8E98\n\nIRC: Ganseki on irc.freenode.net\nTwitter: @petervanderdoes\n\nWordPress Plugin Developer\nBlog: http://blog.avirtualhome.com\nForums: http://forums.avirtualhome.com\nTwitter: @avhsoftware\n"}]}