|
# ######################################################################################### |
|
# GIT AND BASH ALIASES DEFINITION IN A SINGLE FILE `.BASH_ALIASES` WITH GIT AUTO-COMPLETION |
|
# ######################################################################################### |
|
|
|
# All these git commands and bash aliases are tested on git version 2.17.1 on Linux Mint 19 |
|
|
|
# This compilation of aliases is an experiment. |
|
# On a daily basis, I use only a few of these aliases ¯\_(ツ)_/¯ |
|
|
|
# ********** |
|
# GIT CONFIG |
|
# ********** |
|
|
|
git config --global core.excludesFile '~/.gitignore_global' # set up a global .gitignore file (to avoid committing files like .DS_Store, Vim swp files, PHPStorm idea files, etc) |
|
git config --global tag.sort v:refname # version sort ordering |
|
git config --global push.default current # avoid fatal error on push: if the current branch has no upstream branch then it is created on push |
|
git config --global push.followTags 1 # push the commits and tags in one go |
|
git config --global rerere.enabled 1 # record and reuse previous conflicts resolutions |
|
git config --global help.autocorrect 1 # auto correct typos |
|
git config --global rebase.autosquash 1 # enable Git's autosquash feature by default |
|
git config --global pull.rebase 1 # rebase branches by default on pull (it's not a requirement :P) |
|
#git config --global core.autocrlf 1 # on Windows |
|
git config --global core.autocrlf input # on Linux and macOS |
|
git config --global color.status.untracked 'white red' # specific colors (white on red) for untracked files |
|
git config --global init.defaultBranch main |
|
|
|
# PHPSTORM |
|
# @see https://www.jetbrains.com/help/idea/working-with-the-ide-features-from-command-line.html |
|
# On linux : |
|
# 1. $ ln -s ~/path/to/PhpStorm-192.xxxx.xx/bin/phpstorm.sh /usr/local/bin/phpstorm |
|
# 2. $ phpstorm ==> launch phpstorm! |
|
|
|
git config --global diff.tool phpstorm # set the diff tool to show changes |
|
git config --global difftool.prompt 0 # disable prompt before each invocation of the diff tool |
|
git config --global difftool.phpstorm.cmd 'phpstorm diff "$LOCAL" "$REMOTE"' # PHPSTORM command to invoke to show changes |
|
git config --global difftool.phpstorm.trustExitCode 1 # exit difftool if PHPSTORM returns a non-zero exit status |
|
|
|
git config --global merge.tool phpstorm # set the merge tool to resolve merge conflicts |
|
git config --global mergetool.phpstorm.cmd 'phpstorm merge "$LOCAL" "$REMOTE" "$BASE" "$MERGED"' # PHPSTORM command to invoke to resolve merge conflicts |
|
git config --global mergetool.phpstorm.trustExitCode 1 # exit mergetool if PHPSTORM returns a non-zero exit status |
|
git config --global mergetool.keepBackup 0 # do not preserve *.orig files after merge conflict resolution @see https://stackoverflow.com/a/1251696/13480534 |
|
|
|
# *********** |
|
# GIT ALIASES |
|
# *********** |
|
|
|
#git config --global alias.<alias> '<action>' # <documentation> | <arguments>... |
|
|
|
# ------ |
|
# CONFIG |
|
# ------ |
|
|
|
git config --global alias.alias "!git config -l | grep 'alias\.' | sort | cut -d '.' -f 2" # list all git aliases |
|
git config --global alias.conf '!git config --list | sort' # list all sortered variables set in config file, along with their values |
|
|
|
# ------------------ |
|
# DIFF & MERGE TOOLS |
|
# ------------------ |
|
# @see previously the configuration with PHPSTORM |
|
|
|
git config --global alias.comparefile '!f() { git difftool $1 $2 -- $3; }; f' # compare a file across two branches | <branch_1> <branch_2> <file> |
|
git config --global alias.resolve 'mergetool' # run merge tool to resolve merge conflicts |
|
|
|
# -------------- |
|
# SIMPLE ALIASES |
|
# -------------- |
|
|
|
git config --global alias.a 'add' # simple 'add' alias |
|
git config --global alias.b 'branch' # simple 'branch' alias |
|
git config --global alias.ck 'checkout' # simple 'checkout' alias |
|
git config --global alias.cp 'cherry-pick' # simple 'cherry-pick' alias |
|
git config --global alias.d 'diff' # simple 'diff' alias |
|
git config --global alias.dt 'difftool' # simple 'difftool' alias |
|
git config --global alias.mt 'mergetool' # simple 'mergetool' alias |
|
git config --global alias.pl 'pull' # simple 'pull' alias |
|
git config --global alias.ps 'push' # simple 'push' alias |
|
git config --global alias.r 'reset' # simple 'reset' alias |
|
git config --global alias.s 'status -s' # simple 'status -s' alias |
|
git config --global alias.sub 'submodule' # simple 'submodule' alias |
|
|
|
# ---- |
|
# LOGS |
|
# ---- |
|
|
|
# show / list |
|
git config --global alias.last 'log -1 HEAD' # show last commit |
|
git config --global alias.count 'shortlog -sn' # number of commits per author |
|
git_log_graph="log --graph --oneline --decorate --date=short --pretty=format:'%C(yellow)%h %C(cyan)[%ar] %C(green)<%<(9,trunc)%aN>%C(auto)%d %C(reset)%s'" |
|
git config --global alias.l "$git_log_graph -12" # show the last 12 commit logs (graphical representation) |
|
git config --global alias.ll "$git_log_graph" # show all commit logs (graphical representation) |
|
git config --global alias.lmerges "$git_log_graph --merges" # show all merge logs (graphical representation) |
|
git config --global alias.ltags "!git $git_log_graph | grep 'tag:'" # show all tagged logs (graphical representation) |
|
git config --global alias.lfile "$git_log_graph --follow" # find commit logs for a specific file (graphical representation) | <file> |
|
git config --global alias.lfind "$git_log_graph --grep" # find commit messages that contains a specific text | <text> |
|
git config --global alias.lauthor "$git_log_graph --author" # find commit logs by author | <author> |
|
|
|
# ------ |
|
# SEARCH |
|
# ------ |
|
|
|
git config --global alias.find 'grep --break --heading --line-number' # displays all lines (per file) containing the searched text | <text> |
|
|
|
# -------- |
|
# BRANCHES |
|
# -------- |
|
|
|
# show / list |
|
git config --global alias.br '!git fetch --all && git branch -r' # get only remote branches |
|
git config --global alias.current 'rev-parse --abbrev-ref HEAD' # get the name of current branch |
|
git config --global alias.recent "!git branch --sort=-committerdate --format='%(HEAD) %(refname:short);%(committerdate:relative);%(authorname);%(subject)' | column -t -s ';'" |
|
# show all local branches ordered by recent commits |
|
# switch |
|
git config --global alias.previous 'checkout -' # quickly switch to the previous branch |
|
|
|
# create |
|
git config --global alias.copy 'checkout --track' # create local branch from remote branch | <remote_branch> |
|
git config --global alias.new 'checkout -b' # create and switch on new branch WITHOUT push new branch on origin | <new_branch> |
|
|
|
# rename |
|
git config --global alias.rename '!f() { \ |
|
[ -z "$2" ] && o=$(git current) || o=$1 && n=${2:-$1} \ |
|
&& git branch -m $@ && echo "Rename branch $o to $n" \ |
|
; }; f' # rename one local branch | [<old_branch>] <new_branch> |
|
git config --global alias.renameall '!f() { \ |
|
[ -z "$2" ] && o=$(git current) || o=$1 && n=${2:-$1} \ |
|
&& git branch -m $@ && git push origin -u $n && git push origin -d $o \ |
|
&& echo "Rename branch $o to $n (local & origin)" \ |
|
; }; f' # rename one local & remote branch (origin) | [<old_branch>] <new_branch> |
|
|
|
|
|
# delete |
|
git config --global alias.delete 'branch -d' # delete local branch | <branch>... |
|
git config --global alias.deletef 'branch -D' # forcefully delete local branch | <branch>... |
|
git config --global alias.deleter 'push --delete' # delete remote branch | <remote> <branch> |
|
git config --global alias.deleteall '!git branch -d $@ && git push --delete origin' # delete local and remote branches (origin) | <branch>... |
|
|
|
# cleaning |
|
grep_without_branches="grep -v '\*\|main\|dev\|staging'" |
|
git config --global alias.merged "!f() { git branch --merged \$1 | $grep_without_branches; }; f" # show local merged branches except HEAD, main, dev* & staging | [[<remote>/]<branch>] |
|
git config --global alias.no-merged "!f() { git branch --no-merged \$1 | $grep_without_branches; }; f" # show local not merged branches except HEAD, main, dev* & staging | [[<remote>/]<branch>] |
|
git config --global alias.delete-merged '!f() { \ |
|
echo -n "Do you want to delete all merged branches [yn]? " && exec </dev/tty && read r \ |
|
&& [ "$r" != "y" ] && echo "Cancelled!" || (echo "OK! Remove all" \ |
|
&& git merged $1 | xargs git branch -d) \ |
|
; }; f' # delete local merged branches except HEAD, main, dev* & staging | [[<remote>/]<branch>] |
|
git config --global alias.prunedr "fetch --prune --dry-run" # show references to remote branches that have been deleted in the remote |
|
git config --global alias.prune "fetch --prune" # prune references to remote branches that have been deleted in the remote |
|
|
|
# compare |
|
git config --global alias.compare '!f() { git diff $1..$2; }; f' # display the differences between two branches (with current by default) | <branch_1> [<branch_2>] |
|
|
|
# extract |
|
git config --global alias.grab '!f() { git checkout $1 -- $2; }; f' # grab just one file from another branch | <branch> <file> |
|
|
|
# ------- |
|
# CHANGES |
|
# ------- |
|
|
|
# add / index |
|
git config --global alias.all 'add --all' # add all changes (new, modified and deleted files - same as 'add .') |
|
git config --global alias.addn '!git add $(git ls-files --others --exclude-standard)' # add NEW files, without modified and deleted |
|
git config --global alias.addm '!git add $(git diff --name-only --diff-filter=M)' # add MODIFIED files, without new and deleted |
|
git config --global alias.addd '!git add $(git ls-files --deleted)' # add DELETED files, without new and modified |
|
git config --global alias.addnm 'add . --ignore-removal' # add NEW and MODIFIED files, without deleted |
|
git config --global alias.addmd 'add --update' # add MODIFIED and DELETED files, without new |
|
|
|
# show / list |
|
git config --global alias.dw 'diff -w --word-diff --color-words' # show changes (ignore whitespace / word diff / without [-...-]{+...+}) |
|
git config --global alias.ds 'diff --staged' # show changes staged for commit |
|
git config --global alias.dsw 'diff --staged -w --word-diff --color-words' # show changes staged for commit, like 'dw' |
|
|
|
# reset / clean / discard |
|
git config --global alias.discard 'checkout --' # discard changes made on a file | <file> |
|
git config --global alias.untrackeddr 'clean -f -d --dry-run' # show the list of all untracked changes to be removed |
|
git config --global alias.untracked 'clean -f -d' # remove all untracked changes |
|
git config --global alias.hard 'reset --hard' # discard any changes to tracked files, since last commit | [<hash>] |
|
git config --global alias.cleanup 'stash push -u -m "cleanup (safe)"' # remove all deleted, modified and untracked (new) files (more safe than 'clean -f -d') |
|
git config --global alias.cleanup-restore 'stash pop' # restore last 'cleanup' action (see 'git stash list' to find specific stash) |
|
|
|
# ------- |
|
# COMMITS |
|
# ------- |
|
|
|
# show / list |
|
git config --global alias.changelog '!f() { n=${1:-20}; git shortlog HEAD~$n..; }; f' # show the last 20 or 'n' commits grouped by author | [<n>] |
|
|
|
# create |
|
git config --global alias.c 'commit -m' # create commit with message | <msg> |
|
|
|
# amend / undo |
|
git config --global alias.amend 'commit --amend -m' # reword the previous commit message | <msg> |
|
git config --global alias.noedit 'commit --amend --no-edit' # modify previous commit without modifying the commit message |
|
git config --global alias.undo '!f() { git reset --soft HEAD~$1; }; f' # undo the last commit or the last 'n' commits, while keeping files changes | [<n>] |
|
|
|
# ---- |
|
# PULL |
|
# ---- |
|
|
|
#git config --global alias.plo 'pull origin' # ! Not effective - Auto-completion does not detect that the 'origin' remote is already indicated |
|
# and does not propose after the listing of the branches names. |
|
|
|
# ---- |
|
# PUSH |
|
# ---- |
|
|
|
# (trick: start with '!git push ...' for good branch completion) |
|
git config --global alias.psu '!git push -u' # push a new local branch to remote repository and track | <remote> <branch> |
|
git config --global alias.pushu '!git push -u' # push a new local branch to remote repository and track (same as 'git psu') | <remote> <branch> |
|
git config --global alias.psf '!git push --force-with-lease' # push force in safety mode | <remote> <branch> |
|
git config --global alias.pushf '!git push --force-with-lease' # push force in safety mode (same as 'git psf') | <remote> <branch> |
|
|
|
#git config --global alias.pso 'push origin' # ! Not effective - Auto-completion does not detect that the 'origin' remote is already indicated |
|
# and does not propose after the listing of the branches names. |
|
|
|
# --------- |
|
# SUBMODULE |
|
# --------- |
|
# (WIP & experimental!!!) - @see https://git-scm.com/book/en/v2/Git-Tools-Submodules |
|
|
|
# clone |
|
git config --global alias.sclone 'clone --recurse-submodules' # clone a repository, initialize and update each submodule | <clone_opts>... |
|
|
|
# diff |
|
git config --global alias.sdiff "!git diff && git submodule foreach 'git diff'" # nice unified diff of what is changed in your main project and all your subprojects as well |
|
#git config --global alias.sdiff 'diff --cached --submodule' # see that the submodule was updated and get a list of commits that were added to it |
|
|
|
# push / update |
|
git config --global alias.spush 'push --recurse-submodules=on-demand' # Git went into the submodules and pushed their before pushing the main project |
|
# If only one submodule push fails for some reason, the main project push will also fail |
|
git config --global alias.supdate 'submodule update --remote --merge' # update the checkout to the tracked branch (main by default) of the submodule repository | [<path>...] |
|
#git config --global alias.supdate 'submodule foreach git pull' # update all the submodules |
|
|
|
# config |
|
git config --global alias.strack '!f() { git config -f .gitmodules submodule.$1.branch $2; }; f' # set the default tracked branch of the submodule (for 'supdate') | <repository> <branch> |
|
git config --global alias.sconfig 'config -f .gitmodules' # read configuration from the file .gitmodules |
|
|
|
# ---- |
|
# TAGS |
|
# ---- |
|
# @see https://git-scm.com/book/en/v2/Git-Basics-Tagging |
|
|
|
# show / list |
|
git config --global alias.tlast 'describe --tags --abbrev=0' # show the most recent tag on the current branch |
|
|
|
# delete |
|
git config --global alias.tdelete 'tag -d' # delete local tag | <tag> |
|
git config --global alias.tdeleter '!f() { git push origin :refs/tags/$1; }; f' # delete remote tag | <tag> |
|
|
|
# ------- |
|
# ARCHIVE |
|
# ------- |
|
|
|
git config --global alias.zip '!f() { git archive $1 --format=zip --output=$1.zip; }; f' # archive branch | <branch> |
|
|
|
# ---- |
|
# GITK |
|
# ---- |
|
|
|
git config --global alias.visual '!gitk' # open git repository browser |
|
|
|
# ----- |
|
# STATS |
|
# ----- |
|
|
|
git config --global alias.contributors '!git log --format='%aN' | sort -u' # get the list of contributors for repository |
|
|
|
# -------------------------------------------- |
|
# GIT ALIASES - FORCE SPECIFIC AUTO-COMPLETION |
|
# -------------------------------------------- |
|
|
|
# Sometimes a complex Git alias can lose auto-completion of the correct Git command. |
|
# In this case, you need to specify the auto-completion you want. |
|
# @see https://coderwall.com/p/d2w7oa/auto-completion-within-complex-git-alias |
|
# |
|
# for 'x' alias, use 'function _git_x { _git_<command>; }' |
|
# for 'x-yz' alias, use 'function _git_x_yz { _git_<command>; }' |
|
# for 'x.yz' alias, no function available |
|
|
|
function _git_deleteall { _git_branch; } |
|
function _git_new { _git_branch; } |
|
function _git_rename { _git_branch; } |
|
function _git_renameall { _git_branch; } |
|
|
|
# ************ |
|
# BASH ALIASES |
|
# ************ |
|
|
|
alias reload='. ~/.bashrc' |
|
|
|
# BASH ALIASES WITH GIT AUTO-COMPLETION |
|
# |
|
# By default, Bash aliases don't benefit from Git auto-completion. |
|
# You need to specify the Git auto-completion you want. |
|
# @see https://stackoverflow.com/a/24665529/13480534 |
|
# |
|
# use '__git_complete <bash_alias> _git_<git_command>' |
|
# or '__git_complete <bash_alias> _git_<git_alias>' (_git_<git_alias> must be defined: see 'GIT ALIASES - FORCE SPECIFIC AUTO-COMPLETION') |
|
|
|
# avoid error "__git_complete: command not found" |
|
# @see https://stackoverflow.com/a/47496210/13480534 |
|
[ -f /usr/share/bash-completion/completions/git ] && . /usr/share/bash-completion/completions/git |
|
|
|
# @see https://stackoverflow.com/a/24665529 |
|
alias g='git'; __git_complete g __git_main |
|
alias gti='git'; __git_complete gti __git_main # because it could happen to anyone :P |
|
|
|
alias a='git a'; __git_complete a _git_add |
|
alias all='git all' |
|
alias addn='git addn' |
|
alias addd='git addd' |
|
alias addm='git addm' |
|
alias addnm='git addnm' |
|
alias addmd='git addmd' |
|
alias b='git b'; __git_complete b _git_branch |
|
alias br='git br'; __git_complete br _git_branch |
|
alias c='git c'; __git_complete c _git_commit |
|
alias ck='git ck'; __git_complete ck _git_checkout |
|
alias d='git d'; __git_complete d _git_diff |
|
alias dw='git dw' |
|
alias ds='git ds' |
|
alias dsw='git dsw' |
|
alias h='git hard' |
|
alias l='git l' # attention because the 'l' shortcut may already be in use (ex "alias l='ls -CF'") |
|
alias pull='git pull'; __git_complete pull _git_pull # ! not effective 'pull' auto-completion - 'git pull' is more efficient |
|
alias push='git push'; __git_complete push _git_push # ! not effective 'push' auto-completion - 'git push' is more efficient |
|
alias pushf='git pushf'; __git_complete pushf _git_push # ! not effective 'push' auto-completion - 'git push' is more efficient |
|
alias pushu='git pushu'; __git_complete pushu _git_push # ! not effective 'push' auto-completion - 'git push' is more efficient |
|
alias r='git r'; __git_complete r _git_reset |
|
alias recent='git recent' |
|
alias reflog='git reflog' |
|
alias s='git s'; __git_complete s _git_status |
|
|
|
alias current='git current' |
|
alias previous='git previous' |
|
alias develop='git ck develop' |
|
alias staging='git ck staging' |
|
alias main='git ck main' |
|
|
|
alias continue='git rebase --continue' |
|
alias abort='git rebase --abort' |
|
alias skip='git rebase --skip' |