Skip to content

Instantly share code, notes, and snippets.

@mwhite
Last active April 1, 2024 15:06
Show Gist options
  • Save mwhite/6887990 to your computer and use it in GitHub Desktop.
Save mwhite/6887990 to your computer and use it in GitHub Desktop.
The Ultimate Git Alias Setup

The Ultimate Git Alias Setup

If you use git on the command-line, you'll eventually find yourself wanting aliases for your most commonly-used commands. It's incredibly useful to be able to explore your repos with only a few keystrokes that eventually get hardcoded into muscle memory.

Some people don't add aliases because they don't want to have to adjust to not having them on a remote server. Personally, I find that having aliases doesn't mean I that forget the underlying commands, and aliases provide such a massive improvement to my workflow that it would be crazy not to have them.

The simplest way to add an alias for a specific git command is to use a standard bash alias.

# .bashrc

alias s="git status -s"

The disadvantage of this is that it isn't integrated with git's own alias system, which lets you define git commands or external shell commands that you call with git <alias>. This has some nice advantages:

  • integration with git's default bash completion for subcommand arguments
  • ability to store your git aliases separately from your bash aliases
  • ability to see all your aliases and their corresponding commands using git config

If you add the following code to your .bashrc on a system with the default git bash completion scripts installed, it will automatically create completion-aware g<alias> bash aliases for each of your git aliases.

if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
    . /etc/bash_completion                                                                                                                                                                
fi


function_exists() {
    declare -f -F $1 > /dev/null
    return $?
}

for al in `__git_aliases`; do
    alias g$al="git $al"
    
    complete_func=_git_$(__git_aliased_command $al)
    function_exists $complete_fnc && __git_complete g$al $complete_func
done

The main downside to this approach is that it will make your terminal take a little longer to load.

My aliases

Here are the aliases I use constantly in my workflow. I'm lazy about remembering many other aliases that I've decided I should be using, which this setup is great for because I can always list them all using gla.

[alias]
    # one-line log
    l = log --pretty=format:"%C(yellow)%h\\ %ad%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate --date=short

    a = add
    ap = add -p
    c = commit --verbose
    ca = commit -a --verbose
    cm = commit -m
    cam = commit -a -m
    m = commit --amend --verbose
    
    d = diff
    ds = diff --stat
    dc = diff --cached

    s = status -s
    co = checkout
    cob = checkout -b
    # list branches sorted by last modified
    b = "!git for-each-ref --sort='-authordate' --format='%(authordate)%09%(objectname:short)%09%(refname)' refs/heads | sed -e 's-refs/heads/--'"

    # list aliases
    la = "!git config -l | grep alias | cut -c 7-"

See Must Have Git Aliases for more.

@NotSoShaby
Copy link

I copy the exact function:

if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
    . /etc/bash_completion
fi


function_exists() {
    declare -f -F $1 > /dev/null
    return $?
}

for al in `__git_aliases`; do
    alias g$al="git $al"

    complete_func=_git_$(__git_aliased_command $al)
    function_exists $complete_fnc && __git_complete g$al $complete_func
done

to my .zshrc file, and I get:
parse error near \n'`
in the line where this function ends (the last lkine, where the 'end' is).

Any ideas what im doing wrong?

@dasong
Copy link

dasong commented Feb 5, 2019

As of git 2.18.0, __git_aliases has been replace with git --list-cmds=alias

@dlopezdev
Copy link

If anyone wants this solution for Windows, the following works for me on Windows 10 64-bits with Git for Windows v2.21.0 with optional Unix tools installed (standard installation location):

if [ -f "C:\Program Files\Git\etc\bash_completion" ] && ! shopt -oq posix; then
    . "C:\Program Files\Git\etc\bash_completion"                                                                                                                                                                
fi

function_exists() {
    declare -f -F $1 > /dev/null
    return $?
}

for al in `git --list-cmds=alias`; do
    alias g$al="git $al"
    
    complete_func=_git_$(__git_aliased_command $al)
    function_exists $complete_fnc && __git_complete g$al $complete_func
done

Also, just FYI, the .bashrc file should be located in C:\Users\<username>\.bashrc

@aasutossh
Copy link

I am getting

__git_aliased_command: command not found
__git_complete: command not found

on bash.
Any ideas?

@astropanic
Copy link

astropanic commented Mar 3, 2020

git config --global alias.col 'checkout @{-1}'

Check out the last branch you were on

git checkout -

just works

@dlopezdev
Copy link

I am getting

__git_aliased_command: command not found
__git_complete: command not found

on bash.
Any ideas?

A bit late with the reply, but try to check if regular git autocompletion works. Otherwise you might need to do this:
https://stackoverflow.com/questions/36795816/git-auto-complete-not-working-in-bash

I had the same error in Debian, did sudo apt-get install git bash-completion and then aliases worked. Just make sure you are using the updated script since, as explained by @dasong, __git_aliases no longer exists.

@nicolas-t
Copy link

Using git --list-cmds=alias instead of __git_aliases fixed it for me.
Related commit :
git/git@3301d36

@SangamSwadiK
Copy link

Thanks!

@robertcatgithub
Copy link

because I can always list them all using gla.

you mean "git la" ?

@korthout
Copy link

For those looking to use this on zsh:

for al in `git --list-cmds=alias`; do
    alias g$al="git $al"
done

@jtunhag
Copy link

jtunhag commented Dec 12, 2023

The completion function for cherry-pick is _git_cherry_pick (not _git_cherry-pick), so there needs to be a replacement like

aliased_command=$(__git_aliased_command $al)
complete_func="_git_${aliased_command/-/_}"

to handle such commands as well.

@ABD-01
Copy link

ABD-01 commented Jan 10, 2024

[alias]
	fb = !sh -c \"git branch -a | grep -v remotes | grep $1\"
	cb = !sh -c \"git branch -a | grep -v remotes | grep $1 | head -n 1 | xargs git checkout\"

To find a branch, mostly my work involves jumping to branch based on issue no.
so for branch: falcon/ABD-01/2972-TCP-socket-initialization-failed where 2972 is issue no. so I just do:

gfb 2972  ## I find the branch else I create it

Reference: https://stackoverflow.com/a/11388904

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment