Last active
July 21, 2022 11:45
-
-
Save benoitzohar/b5841a2aaef6a2fbecc5d7fc161cecd7 to your computer and use it in GitHub Desktop.
Git helpers for bash/zsh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# GIT | |
# | |
alias gs='git status' | |
alias gd='git diff' | |
alias gp='git pull --rebase --autostash' | |
alias gl='git log --pretty=format:"%h | %an | %s (%ar)"' | |
alias gcl='git checkout -'; | |
alias gst='git stash --include-untracked' | |
alias gsta='git stash apply' | |
alias gmain='gc main && gp && yarn' | |
# checkout any branch | |
function gc() { | |
if [ $# -eq 0 ] | |
then | |
branch=$(git for-each-ref --color --sort=-committerdate \ | |
refs/heads/ \ | |
--format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) | (%(color:green)%(committerdate:relative)%(color:reset)) %(color:bold)%(authorname)%(color:reset) - %(contents:subject)' | \ | |
fzf --ansi | \ | |
cut -f2 -d'*' | \ | |
cut -f1 -d'|' | \ | |
xargs) | |
if [ ! -z "$branch" ] ; then | |
git checkout "$branch" | |
fi | |
else | |
git checkout $1; | |
fi | |
} | |
# checkout with auto stash | |
function gcas() { | |
gst; | |
gc $1; | |
gsta; | |
} | |
# create branch based on current branch or passed branch | |
function gb() { | |
if [ $# -eq 0 ] | |
then | |
echo "Usage: gb name-of-the-branch-to-create"; | |
else | |
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD); | |
git checkout -b $1 "$BRANCH_NAME" | |
fi | |
} | |
# add interactive | |
function ga() { | |
git add -p && git add -i; | |
} | |
# commit with message | |
function gcm() { | |
if [ $# -eq 0 ] | |
then | |
echo "missing param: message, usage: gcm 'this is an amazing commit'" | |
else | |
git commit -m "$1" | |
fi | |
} | |
git_exit_if_necessary() { | |
if [[ $GFORCE ]] | |
then | |
return 0 | |
fi | |
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD); | |
if [ "$BRANCH_NAME" = "master" ] || [ "$BRANCH_NAME" = "main" ] | |
then | |
OTHER_COMMITERS=$(git shortlog --summary --numbered --email | grep -iF -v 'zohar') | |
if [ ! -z "$OTHER_COMMITERS" ] | |
then | |
echo "⚠️ You are on $BRANCH_NAME branch, but you have other commiters." | |
echo "Use GFORCE=1 inline, or 'gforce' once if you want to override this check." | |
echo "Do you want to continue? (y/N)" | |
REPLY="" | |
vared -p "Continue? " -c REPLY | |
echo # (optional) move to a new line | |
if [[ ! $REPLY =~ ^[Yy]$ ]] | |
then | |
return 1 | |
fi | |
fi | |
fi | |
return 0 | |
} | |
git_get_default_branch() { | |
git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@' | |
} | |
# set GFORCE to 1 | |
function gforce() { | |
export GFORCE=1; | |
} | |
# amend last commit | |
function gfix() { | |
git_exit_if_necessary || return; | |
ga && git commit --amend --no-edit && gpsf; | |
} | |
# amend last commit and change its message | |
function gfixm() { | |
git_exit_if_necessary || return; | |
ga && git commit --amend && gpsf; | |
} | |
# Git push | |
function gps() { | |
git_exit_if_necessary || return; | |
git push -u origin $BRANCH_NAME; | |
} | |
# Force git push | |
function gpsf() { | |
git_exit_if_necessary || return; | |
git push -u origin $BRANCH_NAME --force-with-lease; | |
} | |
# git reset hard | |
function grh() { | |
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD); | |
git reset --hard origin/$BRANCH_NAME; | |
} | |
# Git add + commit + push | |
function gacp() { | |
git_exit_if_necessary || return; | |
ga && gcm "$1" && gps; | |
} | |
# Git checkout + add + commit + push | |
# creates branch name from commit message | |
# you can replay this same command, if the branch has already been created | |
# it will ignore the new branch and just add + commit + push | |
function gcacp() { | |
BRANCH_NAME="${1//\[co\]/co/}" | |
BRANCH_NAME="${BRANCH_NAME//\[CO\]/co/}" | |
BRANCH_NAME="${BRANCH_NAME//[\W _]/-}" | |
BRANCH_NAME="${BRANCH_NAME//\/-//}" | |
BRANCH_NAME="${BRANCH_NAME//\'/}" | |
BRANCH_NAME=$(echo "$BRANCH_NAME" | tr '[:upper:]' '[:lower:]'); | |
CURRENT_BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD); | |
if [ "$BRANCH_NAME" = "$CURRENT_BRANCH_NAME" ] | |
then | |
ga && gcm "$1" && gps; | |
else | |
gb "$BRANCH_NAME" && ga && gcm "$1" && gps; | |
fi | |
} | |
# rebase current branch from origin/(master|main) or from origin/specified-branch | |
function grb() { | |
git_exit_if_necessary || return; | |
git fetch; | |
if [ $# -eq 0 ] | |
then | |
git rebase origin/$(git_get_default_branch); | |
else | |
git rebase origin/$1; | |
fi | |
} | |
# continue rebase | |
function grbc() { | |
git rebase --continue; | |
} | |
# open PR for current branch in browser | |
function gpr() { | |
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD); | |
open $(hub pr list --format='%U' -h $BRANCH_NAME); | |
} | |
function gf() { | |
if [ $# -eq 0 ] | |
then | |
echo "missing param: search, usage: gf 'pok'" | |
else | |
git log -S "$1" --reverse --source --all | |
fi | |
} | |
function git-remove-branch() { | |
while true; do | |
BRANCH_NAME=`git branch --sort=-committerdate | fzf --reverse` | |
if [ -z $BRANCH_NAME ] | |
then | |
break; | |
else | |
git branch -D ${BRANCH_NAME##*( )}; | |
fi | |
done | |
} | |
function git-remove-branches() { | |
git branch -D $(printf "%s\n" $(git branch) | grep "$1") | |
} | |
function git-remove-already-merged-branches() { | |
git branch -d `git branch --merged | grep -v '^*' | grep -v 'master' | grep -v 'main' | tr -d '\n'` | |
} | |
function ghelp() { | |
echo "gs: git status"; | |
echo "gl: git log"; | |
echo "gd: git diff"; | |
echo "gp: git pull (rebase with autostash)"; | |
echo "gc: git checkout branch with fuzzy search of local branches (needs fzf)"; | |
echo "gc [branch]: checkout branch"; | |
echo "gb [branch]: create branch based on current branch or passed branch"; | |
echo "gcl: git checkout -"; | |
echo "gb [branch]: create new branch from current and check it out"; | |
echo "ga: git add interactive"; | |
echo "gcm [message]: git commit with message"; | |
echo "gfix: add, amend last commit & force push"; | |
echo "gfixm: add, amend last commit with new message & force push"; | |
echo "gps: git push"; | |
echo "gpsf: git push force"; | |
echo "gacp [message]: add, commit & push"; | |
echo "gcacp [message]: create branch base with message, add, commit, push"; | |
echo "grb: rebase current branch from origin/master"; | |
echo "grbc: continue rebase"; | |
echo "grb [branch]: rebase current branch from origin/BRANCH"; | |
echo "grh: git reset --hard origin/CURRENT_BRANCH" | |
echo "gpr: open PR in browser"; | |
echo "git-remove-branch: remove branches based on fuzzy search (needs fzf)"; | |
echo "git-remove-branches [search]: remove all branch containing search"; | |
echo "git-remove-already-merged-branches: remove all already merged branches"; | |
echo "gforce: allow to commit/push to master or main without warning for the entire session"; | |
echo "gst: git stash"; | |
echo "gsta: git stash apply"; | |
echo "gf [string]: git find first commit to introduce string"; | |
echo "gmain: checkout main and pull latest" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ℹ️ If you use this, make sure to replace
zohar
by your last name/github handle!