git: hash autocomplete

Is there any chance to configure git to autocomplete the hashes when pressing TAB?

Edit:

Please note that this question is not about autocomplete, but about hash autocomplete.
See my comment to VonC’s answer.

  • Expand git's autocomplete feature to plumbing commands
  • How do I enable auto-complete for a git-flow alias?
  • Git Auto-complete not working in bash
  • How do I get bash completion to work with aliases?
  • Homebrew’s `git` not using completion
  • YouCompleteMe can't autocomplete
  • Managing Go dependencies on git
  • Migrate SVN to git with cleanup
  • Does a Git a push configuration allow specifying the branch as well?
  • Why can't ssh establish “the authenticity of host” for Github?
  • Can Version Control Recognize Lines Being Transposed?
  • Git - checked out a file from a previous commit, did I lose the uncommitted work I had?
  • 4 Solutions collect form web for “git: hash autocomplete”

    If you have to consider all hashes from your repo, this is not likely because it wouldn’t scale well (if you have several hundreds of commits, tags, … each with their own hashes, this would quickly take a long time to list them all unless you have some caching system for this hash list)

    If you limit the hashes to a fairly recent list (on the current branch for instance), may be, but that won’t cover all use cases.

    You have here an example of git shell with different kind if tab expansion (in PowerShell), further enhanced here.
    Even if your environment has no use for PowerShell, that gives you an idea of “tab expansion” implementation.

    You can refer to a commit by only its first few characters: git will autocomplete internally:

    git checkout 9771
    

    Thus, you actually don’t have to enter the full hash!

    Sorry, I’m no bash expert. But I just tried to compile something like it for the csh family and this should be easy to transform into a bash completion script for those who know bash.

    The command line I’m using to get useful, recent commit hashes is similar to:

    (git branch | cut -c3-) ; (git branch | cut -c3- | xargs -ibranch git log -n 100 --pretty=format:%+H branch | sort -u)
    

    This line works for both: bash and csh.

    Basically it is the concatenation of the branch names:

    git branch | cut -c3-
    

    and the last (with n being 100) commit names (=full hash numbers)

    git branch | cut -c3- | xargs -ibranch git log -n 100 --pretty=format:%+H branch | sort -u
    

    The full autocompletion statement for csh is then like this

    #
    # tcsh completion for Git
    #
    # Taken from: https://gist.github.com/1663989
    # and from: https://gtirtha.wordpress.com/2010/05/14/git-autocomplete/
    # extended and merged them into what I (Ingo Schmiegel) like
    
    set _git_commands = (add am cherry-pick commit branch format-patch ls-files help remote merge pull push amend grep rebase reset revert bisect diff difftool blame log checkout fetch stash status wdiff config)
    set _git_aliase = `git config --get-regexp 'alias.*' | sed -e 's,alias.,,' | cut -d' ' -f1`
    
    complete git "p/1/($_git_commands $_git_aliase)/" \
      "n/help/($_git_commands $_git_aliase)/" \
      'n/add/`git status --porcelain|cut -c4-|xargs echo`/' \
      'n/br/`git branch|cut -c 3-`/' 'N/br/`git branch|cut -c 3-`/' \
      'n/branch/`git branch|cut -c 3-`/' 'N/branch/`git branch|cut -c 3-`/' \
      'n/cb/`git branch|cut -c 3-`/' \
      'n/cherry-pick/`(git branch|cut -c3-);(git branch|cut -c3-|xargs -ibranch git log -n 100 --pretty=format:%+h branch|sort -u)`/' \
      'n/co$/`git branch|cut -c 3-`/' \
      'n/config/(--global --get-regexp --list)/' \
      'n/diff/(--color-words --name-only)/' \
      'n/difftool/(--no-prompt --prompt --tool)/' \
      'n/fetch/`git remote`/' \
      'n/format-patch/`(echo --output-directory --stdout --signoff);(git branch|cut -c3-);(git branch|cut -c3-|xargs -ibranch git log -n 100 --pretty=format:%+h branch|sort -u)`/' \
      'n/log/`git branch|cut -c 3-|xargs echo -- --name-only --name-status --reverse --committer= --no-color --relative --ignore-space-change --ignore-space-at-eol --format=medium --format=full --format=fuller --color --decorate --oneline --summary`/' \
      'n/lg/`git branch|cut -c 3-|xargs echo -- --name-only --name-status --reverse --committer= --no-color --relative --ignore-space-change --ignore-space-at-eol --format=medium --format=full --format=fuller --color --decorate --oneline --summary`/' \
      'n/ls-files/(--cached --deleted --others --ignored --stage --unmerged --killed --modified --error-unmatch --exclude= --exclude-from= --exclude-standard --exclude-per-directory= --full-name --abbrev)/' \
      'n/merge/`git branch|cut -c 3-|xargs echo --no-commit --no-ff --ff-only --squash`/' \
      'N/merge/`git branch|cut -c 3-`/' \
      'n/pull/(--rebase --no-ff --squash)/' \
      'n/push/`git remote`/' 'N/push/`git branch|cut -c 3-`/' \
      'n/rebase/`git branch|cut -c 3-| xargs echo --continue --abort --onto --skip --interactive`/' \
      'N/rebase/`git branch|cut -c 3-`/' \
      'n/remote/(show add rm prune update)/' 'N/remote/`git remote`/' \
      'n/reset/(HEAD^)/' \
      'N/reset/(HEAD^)/' \
      'n/revert/`(echo --edit --no-edit --no-commit --mainline);(git branch|cut -c3-);(git branch|cut -c3-|xargs -ibranch git log -n 100 --pretty=format:%+h branch|sort -u)`/' \
      'n/stash/(apply list save pop clear show drop create branch)/' \
    

    Note that this does not automatically detect the start of a hash and then can autocomplete it. csh autocompletion is based on the context of the previous word(s). In this example I’m using the hash completion only for the git commands cherry-pick, format-patch, and revert commands.

    Under Linux you have git shell: dev-vcs/git-sh, dev-util/easygit. Moreover if you enable bash completion for git you will get autocomplete.

    Git Baby is a git and github fan, let's start git clone.