#!/bin/bash list_branches() { git for-each-ref refs/heads --format="%(refname:short)" } list_tracked() { git ls-tree HEAD | grep blob | awk '{print $4}'; git ls-tree HEAD | grep tree | awk '{print $4"/"}'; } list_untracked() { git ls-files --exclude-standard --other --directory --no-empty-directory } list_modified() { git ls-files --modified } list_staged() { git diff --name-only --relative --cached } list_tags() { git tag } list_remotes() { git remote } _get_complete() { # Available variables: # COMP_LINE COMP_POINT COMP_KEY COMP_TYPE COMP_WORDS COMP_CWORD # $1 : name of command whose arguments are being completed # $2 : the word being completed # $3 : the word preceding the word being completed case ${COMP_CWORD} in 1) commands="+ - = ! @ # ? ^ \ clone fetch push remote \ add rm ignore stage unstage reset commit uncommit branch rmbranch tag untag \ branches status diff log review \ squash subrepo submodule" COMPREPLY=( $(compgen -W "${commands}" "$2") ) ;; 2) compopt -o nospace #case "$3" in case "${COMP_WORDS[1]}" in # '@' | branch | rmbranch | fetch) COMPREPLY=( $(compgen -W "$(list_branches)" "$2") ) ;; # '=' | stage | reset) COMPREPLY=( $(compgen -W "$(list_modified)" "$2") ) ;; # unstage) COMPREPLY=( $(compgen -W "$(list_staged)" "$2") ) ;; # '-' | rm) COMPREPLY=( $(compgen -W "$(list_tracked)" "$2") ) ;; # diff) COMPREPLY=( $(compgen -W "$(list_tracked)" -W "STAGE" -W "HEAD" "$2") ) ;; # '+' | add | ignore) compopt -o nospace COMPREPLY=( $(compgen -W "$(list_untracked)" "$2") ) ;; esac ;; 3) case "${COMP_WORDS[COMP_CWORD-2]}" in diff) compopt -o nospace COMPREPLY=( $(compgen -W "$(list_tracked)" "$2") ) ;; esac ;; *) COMPREPLY=() ;; esac } complete -F _get_complete g