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
- Download and place
git-flow-completion.bash
in home directory (~/
in
msysgit shell) 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
Download and place
git-flow-completion.bash
in%CYGWIN_INSTALLATION_DIR%\etc\bash_completion.d
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
Setting Environment Variable Globally Without Restarting Ubuntu
How the Util of iOStat Is Computed
How to Check Syslog in Bash on Linux
How to Tell Which Unix Shell I am Using
Remove the Last Page of a PDF File Using PDFtk
How to View Log Files in Linux and Apply Custom Filters While Viewing
How to Make Stdout and Stderr Output Be of Different Colors in Xterm or Konsole
What Is the Reason and How to Avoid the [Fin, Ack] , [Rst] and [Rst, Ack]
Building Linux Kernel on MAC Os X
When Grep "\\" Xxfile I Got "Trailing Backslash"
Is It Better to Use Git Grep Than Plain Grep If We Want to Search in Versioned Source Code
How to Delete a User in Linux When the System Says Its Currently Used in a Process
How to Pipe Output from Grep to Cp
Difference Between Checkout and Export in Svn
Android Studio Error After ./Studio.Sh
Every Command Is Returning 'Bash: <Command>: Command Not Found...'
Bash Script; How to Use Vars and Funcs Defined After Command
How to Move All Files Including Hidden Files into Parent Directory via *