Git aliases - command line autocompletion of branch names

前端 未结 2 588
悲&欢浪女
悲&欢浪女 2021-01-31 08:45

If I run a regular git command such as git checkout I get helpful autocompletion of branch names when hitting the tab key.

I have a few git aliases which ta

2条回答
  •  庸人自扰
    2021-01-31 09:06

    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 
    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  
    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().

提交回复
热议问题