Git Aliases - Command Line Autocompletion of Branch Names

Git aliases - command line autocompletion of branch names

For git aliases, the autocomplete function for the git command (__git()) uses a call to git config --get "alias.$1" to determine that equivalent autocomplete function. This works for simple mappings but will choke on more complex aliases.

To get around this, define an autocomplete function with a name that matches your alias, i.e. _git_tagarchive(). The autocomplete function for git should pick that up and use it for autocompletion.

For example:

[me@home]$ git tagarchive <TAB><TAB>
AUTHORS gentleSelect/ .gitignore LICENSE test_multiple.html
cron/ .git/ index.html README.md
[me@home]$ _git_tagarchive() {
> _git_branch # reuse that of git branch
> }
[me@home]$ git tagarchive <TAB><TAB>
enable_multiple master origin/gh-pages v0.1 v0.1.3
FETCH_HEAD ORIG_HEAD origin/HEAD v0.1.1 v0.1.3.1
HEAD origin/enable_multiple origin/master v0.1.2

For a more permanent solution simply add the function definition to your bashrc file. Eg:

_git_tagarchive() 
{
_git_branch
}

Note that I've simply reused the autocomplete function for git branch; you may wish to change this to something more suitable or write your own.

More info

This solution was identified based on an exploration of /etc/bash_completion.d/git.

Typically, aliased git commands are handled by the __git_aliased_commands() function which parses the output of git config --get "alias.$1" to decide on the autocomplete function to use. Using a more complex shell command as the alias target would understandably foil this approach.

Looking further, it appears the autocomplete function for git (_git()) chains in autocomplete function for subcommands by simple prepending the function with _git_ (with dashes (-) in the command replaced by underscores). This is done before __git_aliased_command() is checked so this is something we could use.

_git ()
{
# .....
local completion_func="_git_${command//-/_}"
declare -f $completion_func >/dev/null && $completion_func && return

local expansion=$(__git_aliased_command "$command")
if [ -n "$expansion" ]; then
completion_func="_git_${expansion//-/_}"
declare -f $completion_func >/dev/null && $completion_func
fi

}

The approach I've gone for is therefore to ensure that a function that matches your alias exists, i.e. _git_tagarchive().

Git autocomplete in bash aliases?

After using complete -F:

complete -F _git_checkout go

Tabbing after go may result in:

bash: [: 1: unary operator expected

Instead of complete, use __git_complete

This is git bash completion's built-in function for this purpose.

After declaring your alias, bind the correct auto-complete function to it:

# Main git completions (prior to git 2.30, you an use _git instead of __git_main)
alias g="git"
__git_complete g __git_main

alias go="git checkout"
__git_complete go _git_checkout

alias gp="git push"
__git_complete gp _git_push

How do I add autocomplete to git aliases?

here we have two options for windows operating system:

msysgit

  1. Download and place git-flow-completion.bash in home directory (~/ in
    msysgit shell)
  2. Add a .bashrc file to your home directory with the following line
    (or add this line to existing .bashrc file):

    source ~/git-flow-completion.bash

Cygwin

  1. Download and place git-flow-completion.bash in

    %CYGWIN_INSTALLATION_DIR%\etc\bash_completion.d

  2. Rename it to git-flow

    you can autocomplete as following: git flow init etc.

Branch autocompletion does not work with git alias for push

It's a bug!

git-completion.bash does go through your git aliases, wiring each up to the right completion function.

But then four of those—the functions for git push, fetch, pull, and remote—delegate to __git_complete_remote_or_refspec(), which starts like this:

__git_complete_remote_or_refspec ()
{
local cur_="$cur" cmd="${words[1]}"
...

$words is just the list of tokens from the command line, and a few lines down, it starts checking $cmd without expanding aliases, for example:

case "$cmd" in
fetch)
# ...
pull|remote)
# ...


As far as I can tell, Gábor Szeder first reported this two years ago in a thread about making completion work with shell aliases.

He mentioned it again in 2012 in reply to a patch from Felipe Contreras (@felipec). Last month, Felipe announced his fork of git, which actually has a self-contained patch for this: b7b6be72.

I don't know if that's been submitted upstream, but in the meantime... if you want to test it out, apply the patch to your git-completion.bash:

curl https://github.com/felipec/git/commit/b7b6be72d60d.diff |
patch -d [directory containing git-completion.bash]
# useful options for patch: --verbose --dry-run

If you don't know where your current git-completion.bash lives, try declare -F:

dirname "$(shopt -s extdebug; declare -F __git_complete | awk '{ print $3 }')"

(After patching git-completion.bash, it'll prompt you for the location of git-completion.zsh to apply the second hunk... you can just hit ^C to skip it.)

How do I get bash completion to work with aliases?

As stated in the comments above,

complete -o default -o nospace -F _git_checkout gco

will no longer work. However, there's a __git_complete function in git-completion.bash which can be used to set up completion for aliases like so:

__git_complete gco _git_checkout

How to setup auto complete alias for git commands?

Do not define completions like complete -F _git_checkout .o.
Use the alias completion code (pointed to by Ansgar Wiechers above). After sourcing that script, completions like

complete -o bashdefault -o default -o nospace -F _alias_completion::.o .o

have been defined.

Custom git command autocompletion

Figured it out. I needed to download git bash completion (here), create a new file in /etc/bash_completion.d with the following contents:

source ~/.git-completion.bash
_git_install ()
{
__gitcomp_nl "$(__git_refs)"
}

and then exec bash to reload completion scripts.



Related Topics



Leave a reply



Submit