Some Git sugar for your .bashrc
I'm one of those people that use Git command line quite a lot and have not really adopted any Git GUI clients. To make make life in the terminal more efficient I have added some sugar to my .bashrc
.
Make "g" an alias for "git"
alias g='git'
__git_complete g __git_main
The first line creates the alias g
for git
. Sadly tab completion stops working and the second line takes care of re-adding that. At the time of writing I'm running Git version 2.11.0 on macOS installed via Brew.
Branch Shortcuts
alias bm='git checkout master'
alias bd='git checkout develop'
alias bb='git checkout -'
alias b='git checkout'
__git_complete b _git_checkout
alias bn='git checkout -b'
__git_complete bn _git_checkout
function bs() {
local branch="$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')"
if [[ "${branch}" == "" ]] ; then
echo "No branch found!"
return 1
fi
echo "${branch}" > ~/savedbranch.txt
}
function bl() {
local branch="$(cat ~/savedbranch.txt)"
git checkout "${branch}"
}
Jumping between branches is so common I've added aliases that even allow me to omit the initial g
. The functions bs
and bl
stands for "branch save" and "branch load" and allow me to save a certain branch name that I can later on jump back to.
Gitty Git Aliases
# http://durdn.com/blog/2012/11/22/must-have-git-aliases-advanced-examples/
# Clone
git config --global alias.cl 'clone'
# Branch
git config --global alias.b 'branch'
git config --global alias.br 'branch'
git config --global alias.bdl 'branch --delete'
git config --global alias.bdr 'push origin --delete'
git config --global alias.bd '!f() { read -r -p "Delete the branch ${1} both locally and remotely? [y/N]" response; if [[ "${response}" =~ ^([yY][eE][sS]|[yY])$ ]]; then echo "... deleting local branch ${1} ..."; git branch --delete "${1}"; echo "... deleting remote branch ${1} ..."; git push origin --delete "${1}"; echo "... done."; else echo "aborted"; fi }; f'
# Check Out
git config --global alias.co 'checkout'
# Status
git config --global alias.s 'status'
git config --global alias.d 'diff'
# Add
git config --global alias.a 'add'
git config --global alias.aa 'add --all'
# Commit
git config --global alias.c 'commit'
git config --global alias.ci 'commit'
git config --global alias.ca 'commit --amend'
git config --global alias.cia 'commit --amend'
# Merge
git config --global alias.m 'merge'
# External Tools
git config --global alias.mt 'mergetool'
git config --global alias.dt 'difftool'
# Pull
# Pushing
git config --global alias.p 'push'
git config --global alias.pf 'push --force'
# Fetching
git config --global alias.f 'fetch'
git config --global alias.fa 'fetch --all'
# Reset
git config --global alias.r 'reset'
git config --global alias.r1 'reset HEAD^'
git config --global alias.r2 'reset HEAD^^'
git config --global alias.rh 'reset --hard'
git config --global alias.rh1 'reset HEAD^ --hard'
git config --global alias.rh2 'reset HEAD^^ --hard'
# Cherry Pick
git config --global alias.cp 'cherry-pick'
# Stash
git config --global alias.sl 'stash list'
git config --global alias.sa 'stash apply'
git config --global alias.ss 'stash save'
Of course you should throw in some regular "git git aliases" as well.
Bulk Actions on Many Repositories
# Buffer and Eachdir
buffer ()
{
local buffer="$(cat; echo 'x')"
printf '%s' "${buffer%x}"
}
eachdir ()
{
local cmd="${@}"
local directories=($(find . -mindepth 1 -maxdepth 1 -type d))
for directory in "${directories[@]}" ; do
local directory="${directory:2}"
{(cd "${directory}"; echo -e "\e[92m[ ${directory} ]\e[0m"; eval "${cmd}") 2>&1 | buffer &} 2>/dev/null
done
wait 2>/dev/null
}
Behold mein bulk action tool! Assume you wanted to git add everything in all repositories placed within the directory you are currently standing. This is how you would do it:
eachdir 'git add --all'
eachdir 'git commit -m "I made this same change to many repositories"'
eachdir 'git push'
And the beauty of it is that the work is done asynchronously.