{"thread":{"id":"25386","subject":"[PATCH] completion: Support the DWIM mode for git checkout","startedAt":"2010-10-08T00:08:12Z","lastAt":"2010-10-12T21:38:12Z","messageCount":4,"participants":["Kevin Ballard","SZEDER Gábor"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"152940","messageId":"1286496492-65221-1-git-send-email-kevin@sb.org","threadId":"25386","inReplyTo":null,"subject":"[PATCH] completion: Support the DWIM mode for git checkout","fromName":"Kevin Ballard","fromEmail":"kevin@sb.org","sentAt":"2010-10-08T00:08:12Z","receivedAt":"2010-10-08T00:08:12Z","isPatch":true,"sender":{"key":"kevin@sb.org","avatar":"https://avatars.githubusercontent.com/u/714?v=4"},"body":"Signed-off-by: Kevin Ballard <kevin@sb.org>\n---\n contrib/completion/git-completion.bash |   35 +++++++++++++++++++++++++++++--\n 1 files changed, 32 insertions(+), 3 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex f83f019..be0498c 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -380,16 +380,19 @@ __git_tags ()\n \tdone\n }\n \n-# __git_refs accepts 0 or 1 arguments (to pass to __gitdir)\n+# __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments\n+# presence of 2nd argument means use the guess heuristic employed\n+# by checkout for tracking branches\n __git_refs ()\n {\n-\tlocal i is_hash=y dir=\"$(__gitdir \"${1-}\")\"\n+\tlocal i is_hash=y dir=\"$(__gitdir \"${1-}\")\" track=\"${2-}\"\n \tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" format refs\n \tif [ -d \"$dir\" ]; then\n \t\tcase \"$cur\" in\n \t\trefs|refs/*)\n \t\t\tformat=\"refname\"\n \t\t\trefs=\"${cur%/*}\"\n+\t\t\ttrack=\"\"\n \t\t\t;;\n \t\t*)\n \t\t\tfor i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do\n@@ -397,10 +400,26 @@ __git_refs ()\n \t\t\tdone\n \t\t\tformat=\"refname:short\"\n \t\t\trefs=\"refs/tags refs/heads refs/remotes\"\n+\t\t\tif [ -z \"$cur\" ]; then track=\"\"; fi\n \t\t\t;;\n \t\tesac\n \t\tgit --git-dir=\"$dir\" for-each-ref --format=\"%($format)\" \\\n \t\t\t$refs\n+\t\tif [ -n \"$track\" ]; then\n+\t\t\t# employ the heuristic used by git checkout\n+\t\t\t# Try to find a remote branch that matches the completion word\n+\t\t\t# but only output if the branch name is unique\n+\t\t\tlocal ref entry\n+\t\t\tgit --git-dir=\"$dir\" for-each-ref --shell --format=\"ref=%(refname:short)\" \\\n+\t\t\t\t\"refs/remotes/\" | \\\n+\t\t\twhile read entry; do\n+\t\t\t\teval \"$entry\"\n+\t\t\t\tref=\"${ref#*/}\"\n+\t\t\t\tif [[ \"$ref\" == \"$cur\"* ]]; then\n+\t\t\t\t\techo \"$ref\"\n+\t\t\t\tfi\n+\t\t\tdone | uniq -u\n+\t\tfi\n \t\treturn\n \tfi\n \tfor i in $(git ls-remote \"$dir\" 2>/dev/null); do\n@@ -988,7 +1007,17 @@ _git_checkout ()\n \t\t\t\"\n \t\t;;\n \t*)\n-\t\t__gitcomp \"$(__git_refs)\"\n+\t\t# check if --track, --no-track, or --no-guess was specified\n+\t\t# if so, disable DWIM mode\n+\t\tlocal i c=1 track=1\n+\t\twhile [ $c -lt $COMP_CWORD ]; do\n+\t\t\ti=\"${COMP_WORDS[c]}\"\n+\t\t\tcase \"$i\" in\n+\t\t\t--track|--no-track|--no-guess) track=''; break ;;\n+\t\t\tesac\n+\t\t\tc=$((++c))\n+\t\tdone\n+\t\t__gitcomp \"$(__git_refs '' $track)\"\n \t\t;;\n \tesac\n }\n-- \n1.7.3.1.184.g5b1fd\n"},{"id":"153179","messageId":"20101010211634.GA4730@neumann","threadId":"25386","inReplyTo":"1286496492-65221-1-git-send-email-kevin@sb.org","subject":"Re: [PATCH] completion: Support the DWIM mode for git checkout","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-10-10T21:16:34Z","receivedAt":"2010-10-10T21:16:34Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Hi,\n\n\nOn Thu, Oct 07, 2010 at 05:08:12PM -0700, Kevin Ballard wrote:\n> Signed-off-by: Kevin Ballard <kevin@sb.org>\n> ---\n\nI think the commit message should add some details about how the patch\nchanges the completion script's behavior.  At least I didn't know\noffhand what \"DWIM mode for git checkout\" is, and once I found it\n(70c9ac2 (DWIM \"git checkout frotz\" to \"git checkout -b frotz\norigin/frotz\", 2009-10-18), right?), I didn't know how the completion\nscript is supposed to support that, and once I applied the patch and\nplayed around a bit, I was surprised that only 'git checkout h<tab>'\nincludes the 'html' branch but 'git checkout <tab>' don't.\n\n\n>  contrib/completion/git-completion.bash |   35 +++++++++++++++++++++++++++++--\n>  1 files changed, 32 insertions(+), 3 deletions(-)\n> \n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index f83f019..be0498c 100755\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n\n\n> @@ -988,7 +1007,17 @@ _git_checkout ()\n>  \t\t\t\"\n>  \t\t;;\n>  \t*)\n> -\t\t__gitcomp \"$(__git_refs)\"\n> +\t\t# check if --track, --no-track, or --no-guess was specified\n> +\t\t# if so, disable DWIM mode\n> +\t\tlocal i c=1 track=1\n> +\t\twhile [ $c -lt $COMP_CWORD ]; do\n> +\t\t\ti=\"${COMP_WORDS[c]}\"\n> +\t\t\tcase \"$i\" in\n> +\t\t\t--track|--no-track|--no-guess) track=''; break ;;\n> +\t\t\tesac\n> +\t\t\tc=$((++c))\n> +\t\tdone\n> +\t\t__gitcomp \"$(__git_refs '' $track)\"\n\nYou could use the __git_find_on_cmdline() helper function instead.\n\n\nBest,\nGábor\n"},{"id":"153200","messageId":"DE3CFB0F-A774-4170-A74D-3BE400E33CEC@sb.org","threadId":"25386","inReplyTo":"20101010211634.GA4730@neumann","subject":"Re: [PATCH] completion: Support the DWIM mode for git checkout","fromName":"Kevin Ballard","fromEmail":"kevin@sb.org","sentAt":"2010-10-10T23:18:26Z","receivedAt":"2010-10-10T23:18:26Z","isPatch":true,"sender":{"key":"kevin@sb.org","avatar":"https://avatars.githubusercontent.com/u/714?v=4"},"body":"On Oct 10, 2010, at 2:16 PM, SZEDER Gábor wrote:\n\n> Hi,\n> \n> \n> On Thu, Oct 07, 2010 at 05:08:12PM -0700, Kevin Ballard wrote:\n>> Signed-off-by: Kevin Ballard <kevin@sb.org>\n>> ---\n> \n> I think the commit message should add some details about how the patch\n> changes the completion script's behavior.  At least I didn't know\n> offhand what \"DWIM mode for git checkout\" is, and once I found it\n> (70c9ac2 (DWIM \"git checkout frotz\" to \"git checkout -b frotz\n> origin/frotz\", 2009-10-18), right?), I didn't know how the completion\n> script is supposed to support that, and once I applied the patch and\n> played around a bit, I was surprised that only 'git checkout h<tab>'\n> includes the 'html' branch but 'git checkout <tab>' don't.\n\nGood point. I'll write a real commit message for the next version. And another good point about 'git checkout <tab>'. I don't remember why, but for some reason I explicitly avoided DWIM mode if the current word was empty. But you're right, there's no good reason to do that.\n\n>> contrib/completion/git-completion.bash |   35 +++++++++++++++++++++++++++++--\n>> 1 files changed, 32 insertions(+), 3 deletions(-)\n>> \n>> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n>> index f83f019..be0498c 100755\n>> --- a/contrib/completion/git-completion.bash\n>> +++ b/contrib/completion/git-completion.bash\n> \n> \n>> @@ -988,7 +1007,17 @@ _git_checkout ()\n>> \t\t\t\"\n>> \t\t;;\n>> \t*)\n>> -\t\t__gitcomp \"$(__git_refs)\"\n>> +\t\t# check if --track, --no-track, or --no-guess was specified\n>> +\t\t# if so, disable DWIM mode\n>> +\t\tlocal i c=1 track=1\n>> +\t\twhile [ $c -lt $COMP_CWORD ]; do\n>> +\t\t\ti=\"${COMP_WORDS[c]}\"\n>> +\t\t\tcase \"$i\" in\n>> +\t\t\t--track|--no-track|--no-guess) track=''; break ;;\n>> +\t\t\tesac\n>> +\t\t\tc=$((++c))\n>> +\t\tdone\n>> +\t\t__gitcomp \"$(__git_refs '' $track)\"\n> \n> You could use the __git_find_on_cmdline() helper function instead.\n\nI'll look into that, thanks.\n\n-Kevin Ballard"},{"id":"153347","messageId":"1286919493-8397-1-git-send-email-kevin@sb.org","threadId":"25386","inReplyTo":"DE3CFB0F-A774-4170-A74D-3BE400E33CEC@sb.org","subject":"[PATCH v2] completion: Support the DWIM mode for git checkout","fromName":"Kevin Ballard","fromEmail":"kevin@sb.org","sentAt":"2010-10-12T21:38:12Z","receivedAt":"2010-10-12T21:38:12Z","isPatch":true,"sender":{"key":"kevin@sb.org","avatar":"https://avatars.githubusercontent.com/u/714?v=4"},"body":"Ever since commit 70c9ac2 (DWIM: \"git checkout frotz\" to \"git checkout\n-b frotz origin/frotz\"), git checkout has supported a DWIM mode where\nit creates a local tracking branch for a remote branch if just the name\nof the remote branch is specified on the command-line and only one remote\nhas a branch with that name. Teach the bash completion script to understand\nthis DWIM mode and provide such remote-tracking branch names as possible\ncompletions.\n\nSigned-off-by: Kevin Ballard <kevin@sb.org>\n---\n contrib/completion/git-completion.bash |   30 +++++++++++++++++++++++++++---\n 1 files changed, 27 insertions(+), 3 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 64341d5..59ed345 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -386,16 +386,19 @@ __git_tags ()\n \tdone\n }\n \n-# __git_refs accepts 0 or 1 arguments (to pass to __gitdir)\n+# __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments\n+# presence of 2nd argument means use the guess heuristic employed\n+# by checkout for tracking branches\n __git_refs ()\n {\n-\tlocal i is_hash=y dir=\"$(__gitdir \"${1-}\")\"\n+\tlocal i is_hash=y dir=\"$(__gitdir \"${1-}\")\" track=\"${2-}\"\n \tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\" format refs\n \tif [ -d \"$dir\" ]; then\n \t\tcase \"$cur\" in\n \t\trefs|refs/*)\n \t\t\tformat=\"refname\"\n \t\t\trefs=\"${cur%/*}\"\n+\t\t\ttrack=\"\"\n \t\t\t;;\n \t\t*)\n \t\t\tfor i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do\n@@ -407,6 +410,21 @@ __git_refs ()\n \t\tesac\n \t\tgit --git-dir=\"$dir\" for-each-ref --format=\"%($format)\" \\\n \t\t\t$refs\n+\t\tif [ -n \"$track\" ]; then\n+\t\t\t# employ the heuristic used by git checkout\n+\t\t\t# Try to find a remote branch that matches the completion word\n+\t\t\t# but only output if the branch name is unique\n+\t\t\tlocal ref entry\n+\t\t\tgit --git-dir=\"$dir\" for-each-ref --shell --format=\"ref=%(refname:short)\" \\\n+\t\t\t\t\"refs/remotes/\" | \\\n+\t\t\twhile read entry; do\n+\t\t\t\teval \"$entry\"\n+\t\t\t\tref=\"${ref#*/}\"\n+\t\t\t\tif [[ \"$ref\" == \"$cur\"* ]]; then\n+\t\t\t\t\techo \"$ref\"\n+\t\t\t\tfi\n+\t\t\tdone | uniq -u\n+\t\tfi\n \t\treturn\n \tfi\n \tfor i in $(git ls-remote \"$dir\" 2>/dev/null); do\n@@ -994,7 +1012,13 @@ _git_checkout ()\n \t\t\t\"\n \t\t;;\n \t*)\n-\t\t__gitcomp \"$(__git_refs)\"\n+\t\t# check if --track, --no-track, or --no-guess was specified\n+\t\t# if so, disable DWIM mode\n+\t\tlocal flags=\"--track --no-track --no-guess\" track=1\n+\t\tif [ -n \"$(__git_find_on_cmdline \"$flags\")\" ]; then\n+\t\t\ttrack=''\n+\t\tfi\n+\t\t__gitcomp \"$(__git_refs '' $track)\"\n \t\t;;\n \tesac\n }\n-- \n1.7.3.1.185.gd09c4\n"}]}