Git autocomplete in bash aliases?

GitBash

Git Problem Overview


I'm using go as a simple bash alias for git checkout branchname. The thing that I miss is the autocomplete feature that works with the full git checkout branchna... command, but not in the alias.

Is there a way to instruct Bash to "inherit" the autocomplete "driver" for another command?

Git Solutions


Solution 1 - Git

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

Solution 2 - Git

If you can find out the completion function used by the original command, you can assign it to the alias using complete -F.

For example, on my ubuntu box, the completion function used by git checkout is _git_checkout (found in /etc/bash_complete.d/git).

Example

Before running complete -F:

[me@home]$ git checkout <TAB><TAB>
HEAD            master          origin/HEAD     origin/master

[me@home]$ alias go="git checkout"

[me@home]$$ go <TAB><TAB>
.git/                precommit_config.py  README.md            SvnSentinel/         
.gitignore           precommit.py         startcommit.py       tests/ 

After:

[me@home]$$ complete -F _git_checkout go

[me@home]$$ go <TAB><TAB>
HEAD            master          origin/HEAD     origin/master 

Solution 3 - Git

On Ubuntu 18.04 (Bionic) the following works. Add something like this snippet (with your aliases) to your preferred bash configuration file e.g. .bashrc, .bash_aliases .bash_profile.

# define aliases
alias gc='git checkout'
alias gp='git pull'

# setup autocompletion
if [ -f "/usr/share/bash-completion/completions/git" ]; then
  source /usr/share/bash-completion/completions/git
  __git_complete gc _git_checkout
  __git_complete gp _git_pull
else
  echo "Error loading git completions"
fi

In general the format of the __git_complete directive is the following:

__git_complete <YOUR ALIAS> _git_<GIT COMMAND NAME>

This combines wisdom from the existing answers in a single up-to-date answer, thank you all.

Solution 4 - Git

In Ubuntu 16.04.3 LTS, the file I needed to source was /usr/share/bash-completion/completions/git. So in .bash_custom (or .bashrc, whatever):

[ -f /usr/share/bash-completion/completions/git ] && . /usr/share/bash-completion/completions/git
__git_complete g __git_main

Solution 5 - Git

To add to other excellent answers: normally you have a lot of Git aliases and it may be tedious to manually forward completions for all of them. Here's a small trick to do this automatically:

if [ -f "/usr/share/bash-completion/completions/git" ]; then
  # Enable Git completions for aliases
  . /usr/share/bash-completion/completions/git
  for a in $(alias | sed -n 's/^alias \(g[^=]*\)=.git .*/\1/p'); do
    c=$(alias $a | sed 's/^[^=]*=.git \([a-z0-9\-]\+\).*/\1/' | tr '-' '_')
    if set | grep -q "^_git_$c *()"; then
      eval "__git_complete $a _git_$c"
    fi
  done
fi

Solution 6 - Git

As somebody else answered you should use __git_complete, otherwise the script will fail.

alias g="git"
__git_complete g __git_main

alias g="gl"
__git_complete gl _git_log

But you shouldn't use _git for the main command, it's __git_main.

Unfortunately a lot of information about the completion is hidden, but you can find more on the README of my fork: git-completion.

Solution 7 - Git

I realize you're specifically asking about bash aliases, but for those coming here looking for autocomplete in bash for complex git aliases, see here.

In particular:

# If you use complex aliases of form '!f() { ... }; f', you can use the null
# command ':' as the first command in the function body to declare the desired
# completion style.  For example '!f() { : git commit ; ... }; f' will
# tell the completion to use commit completion.  This also works with aliases
# of form "!sh -c '...'".  For example, "!sh -c ': git commit ; ... '".

Solution 8 - Git

On Linux Mint, this didn't work for me. I was getting bash: [: 1: unary operator expected .

I found the following response worked quite well - with the troubleshooting section the user provided to be quite helpful. https://superuser.com/questions/436314/how-can-i-get-bash-to-perform-tab-completion-for-my-aliases

Solution 9 - Git

For macOS, run the following to install bash completion

 brew install bash-completion

Then add the following

[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh" 

to your .bashrc or .bash_profile

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionClaudioView Question on Stackoverflow
Solution 1 - GittheprogrammerinView Answer on Stackoverflow
Solution 2 - GitShawn ChinView Answer on Stackoverflow
Solution 3 - GitadamnfishView Answer on Stackoverflow
Solution 4 - GitSeamusJView Answer on Stackoverflow
Solution 5 - GityugrView Answer on Stackoverflow
Solution 6 - GitFelipeCView Answer on Stackoverflow
Solution 7 - GitDylanYoungView Answer on Stackoverflow
Solution 8 - GitMario Olivio FloresView Answer on Stackoverflow
Solution 9 - GitAnthony KongView Answer on Stackoverflow