Git Recipes
This page contains a whole lot of Git commands that I personally used in the past to keep as a track record for future use.
Navigating history
git log ; git lg
git checkout ca55e77e
git checkout master
git checkout HEAD^3
git checkout "HEAD@{1 month ago}"
git checkout :/Commit message
Branching
git checkout -b develop # creates new branch develop and does checkout of develop
git merge feature/awesomeness # merges the branch "feature/awesomeness" into the current branch
git branch -d feature/bullshit # deletes local branch "feature/bullshit"
git push origin :feature/bullshit # deletes remote branch "feature/bullshit" from the "origin" remote
Stash
Getting a single file from a stash…
git checkout stash@{0} -- «filename»
Stash all files including untracked files…
git stash -u
Save a stash with a specific message…
git stash apply -m "My stash with ABC"
Comitting
Add specific lines of a file to the commit interactively.
git add -p «filenames»
Commit the staged changes.
git commit -m "your commit message"
Bisect
Trace buggy commit with git bisect…
Manual
git bisect reset # only needed after a bisect
git bisect start
git bisect good «revision»
git bisect bad «revision»
# git will checkout the next revision to check
git bisect (good | bad)
Automated
git bisect start
git bisect good «revision»
git bisect bad «revision»
git bisect «run/path/to/decision/script args…»
Filter Branch
Fix committer/author
#!/bin/sh
git filter-branch -f --env-filter'
n=$GIT_AUTHOR_NAME
m=$GIT_AUTHOR_EMAIL
case ${GIT_AUTHOR_NAME} in
"Marco Franssen") n="Marco Franssen" ; m="[email protected]" ;;
"Marco Franssen [email protected]") n="Marco Franssen" ; m="[email protected]" ;;
esac
export GIT_AUTHOR_NAME="$n"
export GIT_AUTHOR_EMAIL="$m"
export GIT_COMMITTER_NAME="$n"
export GIT_COMMITTER_EMAIL="$m"
' HEAD
Remove filter-branch backup
git update-ref -d refs/original/refs/heads/master
Move commits to new Repository
These examples assume you are already on the branch you want to cherry-pick these commits into.
git remote add oldrepo https://github.com/path/to/oldrepo
git fetch oldrepo
Take a specific subset of commits
git cherry-pick --strategy recursive --strategy-option theirs «oldestCommitHash»^..«latestCommitHash»
Take all commits involved in a specific merge commit
git cherry-pick --strategy recursive --strategy-option theirs «mergeCommitHash»^..«mergeCommitHash»
Handle deleted files and conflicts
As you are cherry-picking your target branch might not have all files. You might end up in some conflicts that you will have to handle.
git mergetool
# either c/m or d based on if you want to keep or delete the files
git cherry-pick --continue
Git config
[alias]
bw = blame -w -M
c = commit
commend = commit --amend --no-edit
cc = commit --all --amend --no-edit
ca = commit --all
co = checkout
cb = "!f() { git co `git log --until=\"$*\" -1 --format=%h`; } ; f"
s = status --short
d = diff
dc = diff --cached --word-diff=color
dw = diff --word-diff=color
l = log
a = add
addnw = !sh -c 'git diff -U0 -w --no-color --ignore-blank-lines "$@" | git apply --cached --ignore-whitespace --unidiff-zero -'
af = add -f
p = push
dt = difftool
mt = mergetool
ss = show -1 --format=%B--stat
sw = show -1 --format=%B--stat --word-diff=color
whatis = show -s --pretty='tformat:%h (%s, %ad)' --date=short
whatadded = log --diff-filter=A
deleted = log --diff-filter=D --summary
lg = log --graph --pretty=format:'%Cred%h%Creset %C(yellow)%an%d%Creset %s [%N] %Cgreen(%ar)%Creset' --date=relative
lgd = log --graph --pretty=format:'%Cred%h%Creset %C(yellow)%an%d%Creset %s [%N] %Cgreen(%ar)%Creset' --date=default
lgm = log --graph --pretty=format:'%Cred%h%Creset %C(yellow)%an%d%Creset %s [%N] %Cgreen(%ar)%Creset' --date=relative --author=AUTHOR_EMAIL
abbr = "!sh -c 'git rev-list --all | grep ^$1 | while read commit; do git --no-pager log -n1 --pretty=format:\"%H %ci %an %s%n\" $commit; done' -"
refeature = "!f() { git co develop && git pull && git co $1 && git pull && git rebase develop; } ; f"
ffmerge = "!f() { git refeature $1 && git co develop && git merge $1; } ; f"
clearbranch = "!f() { git branch -d $1 && git push origin :$1; } ; f"
please = push --force-with-lease
undo = restore
unstage = restore --staged
wip = for-each-ref --sort='authordate:iso8601' --format='%(color:green)%(authordate:relative)%09%(color:reset)%(refname:short)' refs/heads
[color]
ui = always
[core]
pager = less -x1,5
fileMode = true
editor = vim
autocrlf = false
[push]
default = current
[branch]
autosetuprebase = remote
[merge]
tool = vimdiff
guitool = gvimdiff
conflictstyle = diff3
[mergetool]
prompt = false
[diff]
tool = vimdiff
guitool = gvimdiff
[difftool]
prompt = false
[commit]
gpgSign = true
[tag]
forceSignAnnotated = true
[includeIf "gitdir:~/code/priv/**/*"]
path = "~/.gitconfig-private"
[init]
defaultBranch = main