bashgitbash-completion

How to create a custom command that has an argument that tab completes to a git branch in bash?


The first positional argument to git switch can be a branch, e.g. git switch <branch> and it tab completes nicely.

  1. How can I make my own command with an argument that can tab complete into a git branch?

    For git banana [--optional-option] <branch> to tab complete, it does not seem to be enough to bash builtin complete -F as that would not necessarily include "banana". And also I want to amend the completions for git, not overwrite it.

  2. Does git have some subcommand or shell functions to help with this?

    I found __gitcomp but not sure how to use it

    • together with an alias
    • specifically to trigger for the 1st positional argument

Solution

  • The standard bash-completion module shipped with Git automatically determines all available subcommands (see [1]). If you make an alias.banana, bash-completion will recognize it. If you create a git-banana script in your usual $PATH, Git itself will recognize it as a subcommand, and so will bash-completion.

    For each subcommand, the bash-completion script (see [2]) checks whether a function named _git_<subcommand> is defined in the shell (not necessarily in the file but in the "live" environment). The same file has plenty of examples – you'll want to look at the definition of _git_switch, which uses __git_complete_refs to suggest completions.

    ~/.bashrc
    _git_banana() { __git_complete_refs --mode=heads }

    (Specifically for aliases, if a specific _git_<name> function does not exist, then bash-completion will actually look up the alias and will apply completion of whichever "real" Git subcommand the alias points to.)


    [1] See __git_compute_all_commands in /usr/share/bash-completion/completions/git, which uses git --list-cmds=main,others,alias,nohelpers

    [2] See __git_complete_command in the same file.