Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
293 lines (263 sloc) 18.3 KB
[alias]
# Commits: @=HEAD, -=last commit.
# N.B. # at end of func allows parsing $1 args.
# Helper functions:
headUpstream = rev-parse --abbrev-ref --symbolic-full-name @{u} # Upstream of current branch, e.g. origin/master.
headRemote = "!git rev-parse --abbrev-ref --symbolic-full-name @{u} | cut -d '/' -f 1" # e.g. origin.
headBranch = symbolic-ref --short HEAD # e.g. master.
remoteOrg = "!git remote get-url $1 | awk -F ':|/' '{print $(NF-1)}' #" # Github org for remote. `g remoteOrg up` -> gibfahn.
defaultBranch = "!git symbolic-ref --short refs/remotes/$1/HEAD | sed \"s|^$1/||\" #" # Default branch for remote. `g defaultBranch up` -> master
# Quote an alias you want to save here (quotes \ and ", and wraps in "! #" to handle args).
quote-string = "!read -r l; sed -E -e 's/([\\\"])/\\\\\\1/g' -e 's/(.*)/\"!\\1 #\"/' <<<\"$l\" #"
# Removes all branches and tags except "$1" (default oldmaster).
clean-fork = "!git ls-remote --heads --tags fork | awk '!/\\^\\{\\}/ && !/refs\\/heads\\/'\"${1:-oldmaster}\"'/ {print $NF}' | xargs -n ${2:-10} git push --delete fork && git remote prune fork #"
a = add # Add files to index.
ap = add -p # Adds files in hunks (only add some of the changes you made).
aa = add -A # Adds everything.
ama = am --abort # Bail out of an am (apply patch) session.
amc = am --continue # Include an empty commit as a patch.
ams = am --skip # Skip the current commit you're patching.
b = branch
ba = branch -a # Show all local and remote branches.
bd = branch -D # Delete branch.
# TODO(gib): Fix this to make it look nice (can also use git branch directly).
# Sorted list of branches.
bh = for-each-ref --sort=committerdate refs/heads/ --format='%(committerdate:short) %(color: 178)%(refname:short)' # Branch sistory.
brs = !git for-each-ref --sort=-committerdate refs/heads/ \
--format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset)|%(objectname:short)|%(color:green)%(committerdate:relative)%(color:reset)' \
| column -ts '|'
br = branch -r # Show remote branches only.
bdd = "!lastBranch=$(git headBranch); git checkout -; git branch -D $lastBranch" # Delete current branch.
bp = "!git fetch -p && git branch -vv | awk '/: gone]/{print $1}' | xargs -r git branch -d" # Delete orphaned local branches.
bP = "!git fetch -p && git branch -vv | awk '/: gone]/{print $1}' | xargs -r git branch -D" # Delete orphaned local branches!
bt = "!git branch -u $1/$(git headBranch) #" # g bt origin sets upstream to origin.
# I manually specify -S because gpgsign only works with Git 2.x. Also it
# means that test suites using `git commit` don't break.
ce = config --global --edit # Open this file with $VISUAL.
c = commit -S # Commit with gpg signing.
ca = commit -S -a # Commit all changed files with gpg.
cm = commit -S --amend # Amend the previous commit.
cmn = commit -S --amend --no-edit # Amend the previous commit but don't change the message.
can = commit -S --amend --no-edit -a # Add changed files and commit with the same message.
cn = clean -ffdx # Remove anything that's untracked (DANGER).
# Clean submodule directories that are no longer tracked.
cnm = "!git status --porcelain=v2 | awk '/^\\? / && !system(\"test -f \" $2 \"/.git\") { print $2 }' | xargs git clean -ffd #"
cl = clone --recursive --origin up # Always include submodules, set default remote to "up".
cp = cherry-pick # Apply commit hash(es) to current branch.
cpa = cherry-pick --abort # Bail out of cherry-pick.
cpc = cherry-pick --continue # Accept current changes and continue to next commit.
cpq = cherry-pick --quit # Only undo last commit (that failed) not all of them.
co = checkout # Change to a different commit or reset a file to a commit (e.g. `g co new-feature`).
cob = checkout --no-track -b # Create a new branch based on a different ref (e.g. `g cob new-feature up/master`).
com = checkout --recurse-submodules # Checkout and update submodules.
cop = checkout -p # Selectively undo some of the changes you made.
cot = checkout -t # g cot up/master means checkout master tracking the one in up.
d = diff HEAD # diff of staged and unstaged..
de = "!git diff HEAD --name-only $@ | xargs $VISUAL # " # Open files changed since last commit in editor.
dn = diff HEAD --name-only # diff of staged and unstaged file names.
ds = diff --staged # Diff of staged files (`git diff` for unstaged).
dt = difftool # Nicer way to view diffs in vim.
du = "!git diff $(git headUpstream)" # diff between working tree and upstream branch.
dus = "!git diff --staged $(git headUpstream)" # diff between working tree and upstream branch.
dun = "!git diff $(git headUpstream) --name-only" # diff between working tree and upstream branch file names.
f = fetch # Fetch one remote.
fa = fetch --all # Fetch from all the remotes.
fix = commit --fixup # g fix SHA means rebasing will attach to that SHA.
# Like commit --amend but for an arbitrary commit (`g fixup @~3.`).
fixup = "! hash=$(git rev-parse "$1") \
&& git commit --fixup=$hash ${@:2} \
&& EDITOR=true git rebase -i --autostash --autosquash $hash^ #"
# Create/update branch from Github PR, `g fp 657 origin` or `g fp` (Defaults: $1=headBranch, $2=upstreamRemote).
fp = "! b=${2:-$(git headRemote)}; b=${b:-up}; a=${1:-$(git headBranch)} \
&& git fetch -fu $b pull/$a/head:$a; \
git checkout $a \
&& git branch -u $(git symbolic-ref --short refs/remotes/$b/HEAD) #"
h = help
# `l` gives you history of current branch, `la` is all commits in repo, `las` is a shortlist of the important commits, `ll` shows you who and when.
l = log --graph --decorate --oneline # Graph log.
la = log --graph --decorate --oneline --all # Graph log of all commits.
las = log --graph --decorate --oneline --all --simplify-by-decoration # Graph log of tag/branch/labelled commits.
ll = log --color --graph --pretty=format:'%C(214)%h%C(reset)%C(196)%d%C(reset) %s %C(35)(%cr)%C(27) <%an>%C(reset)'
# Need to add other commands (and maybe switch to shortcuts as in https://junegunn.kr/, e.g. https://junegunn.kr/2016/07/fzf-git).
lp = "!git log --graph --color=always --format=\"%C(auto)%h%d %s %C(black)%C(bold)<%an> %cr%C(auto)\" \"$@\" \
| fzf --ansi -m --no-sort --reverse --tiebreak=index \
--bind=ctrl-s:toggle-sort \
--preview \"(grep -o '[a-f0-9]\\{7\\}' | head -1 | xargs -I % sh -c 'git show --color=always % | /usr/bin/less -R') <<< {}\" \
--bind \"ctrl-o:execute: (grep -o '[a-f0-9]\\{7\\}' | head -1 | xargs -I % sh -c 'git show --color=always % | LINES=0 less -R') <<< {}\" #"
# Escape < and > for github markdown, (useful for generating changelogs).
changelog = "! git log --pretty=format:'* %h - %s %n%w(76,4,4)%b%n' --abbrev-commit \"$@\" | perl -0 -p -e 's/(^|[^\\\\])([<>])/\\1\\\\\\2/g ; s/(\\s*\\n)+\\*/\\n\\n*/g' #"
ma = merge --abort
mb = "!git merge-base ${1:-master} ${2:-HEAD} ${@:2} #" # Get commit this branch forked from.
mc = "!echo \"$VISUAL\" | grep -iq vi && c='-c /\\(|||||||\\|=======\\|>>>>>>>\\|<<<<<<<\\)' || c=\"\"; git diff --name-only --diff-filter=U | xargs $VISUAL $c" # Open merge conflicts in editor.
mf = "!git merge --ff-only $@ \
&& git submodule update --init #" # Update branch from other commit (default upstream) as long as other commit has HEAD as an ancestor.
mt = mergetool # Alternative to `g mc`, `:h vimdiff` in nvim for more info (try `:dif[fupdate]`, `]c`, `do`, `dp`).
p = push # Push commits to a remote.
pf = push --force-with-lease # Better version of push -f.
pa = "!curl -L ${1%.patch}.patch | git am -S --whitespace=fix # " # Patch Github PR.
pap = "!curl -L ${1%.patch}.patch | git am -3 -S --whitespace=fix # " # Please patch it.
paw = "!curl -L ${1%.patch}.patch | git am -3 -S --whitespace=warn # " # Patch but don't fix whitespace.
pt = "!git push -u $1 $(git headBranch) #" # g pt origin sets branch to track up + pushes.
ra = remote add # Add new remote by url.
rb = rebase -S # Rebase and gpg sign.
rba = rebase --abort # Bail on the rebase session.
rbc = rebase --continue # Accept the current commit.
rbs = rebase --skip # Skip current commit you're rebasing on.
rhh = "!git reset --hard $(git headUpstream)" # Reset hard to the upstream commit.
rh = reset --hard # Reset hard (to HEAD by default).
ri = rebase -i -S --autosquash # Interactive rebase.
rim = "!git rebase -i -S --autosquash $(git merge-base ${1:-master} ${2:-HEAD} ${@:2}) # " # Rebase all commits since you forked the branch.
rii = "!git rebase -i -S --autosquash $(git headUpstream)" # Reset to upstream branch, not needed with merge.defaultToUpstream.
rp = rev-parse # Get the hash from a revision (`g rp @` and `g rp --short @` are often useful).
rr = remote rename # Change name of remote `g rr origin up`.
rs = remote set-url # Change URL of remote `g rs up hsg:dot`.
rsp = remote set-url --push # Change push URL of remote (`g rs up hhg:dot && g rsp up hsg:dot` to use https for fetch and ssh for push, which is faster).
rv = remote -v # Show remotes (with URLs).
s = status
ss = status --short --branch
sh = show
she = "!git show --pretty="" --name-only $@ | xargs $VISUAL #" # Open files changed in last commit in editor.
shde = "!{ git show --pretty="" --name-only; git diff HEAD --name-only; } | sort | uniq | xargs $VISUAL #" # Combines `g de` and `g she` files in editor.
shn = show --pretty="" --name-only # Show names of files changed only.
st = stash
stp = stash pop
std = stash drop
sm = submodule # For when you get bored of typing the word "submodule"
sma = submodule add # Add new submodules
smd = submodule deinit -f --all # Deinit submodules (for when updating fails).
sme = submodule foreach # Run a command in all submodules, e.g. `g sme git status`, can be used recursively.
smf = submodule update --init # Update to main repo upstream branch's submodule versions (make submodules match parent's HEADs).
# `g smh`: Like git rhh (above), but resets every submodule to upstream commit. Hopefully someone will upstream an easier way at some point.
smh = "!unset GIT_DIR; git cnm; while read sha pth && [[ -n $sha && -n $pth ]]; do git -C \"$pth\" reset --hard \"$sha\" || { git submodule deinit -f \"$pth\"; git submodule init \"$pth\"; }; done <<<\"$(git status --porcelain=v2 | awk '/^[12] ?? [^N]*/ { print $8 \" \" $NF }')\" #"
smhh = submodule foreach git smh # Recursive hard reset to parent's HEADS. Hopefully you never need smhhh.
smi = submodule update --init --recursive # Initialise submodules.
smr = submodule foreach git reset --hard # Hard reset all submodules to their HEAD.
sms = submodule sync --recursive # Make .git/config match .gitmodules.
smu = submodule update --remote # Update submodules to submodule repos latest versions (make submodules match submodule upstream HEADs).
# z is fuzzy log (fuzzy search through `git log $*`, za is the same with la (try g sh `g z`).
z = "!git l --color=always $* | grep -v '^\\.\\.\\.\\s\\+$' | fzf +s -m --ansi | sed 's/^\\W\\+\\(\\w\\+\\)\\s\\+.*/\\1/' #"
za = "!git la --color=always $* | grep -v '^\\.\\.\\.\\s\\+$' | fzf +s -m --ansi | sed 's/^\\W\\+\\(\\w\\+\\)\\s\\+.*/\\1/' #"
[apply]
whitespace = fix # Fix whitespace when applying patches.
# Color options: normal, black, red, green, yellow, blue, magenta, cyan, or white (or 0-255).
# Highlight options: bold, dim, ul (underline), blink, and reverse (swap fg and bg).
# Change the colours for `git branch`.
[color "branch"]
current = 33 # The branch you're currently on.
local = normal # Other normal branches.
remote = 180 # Local-tracking branches for your remotes.
upstream = 214 ul # No idea what this is (make it orange to find out).
plain = normal ul # No idea what this is (underline it to find out).
# Change colours for `git diff`.
[color "diff"]
meta = 249 # Header (diff --git a/file b/file).
frag = 8 # Line numbers (@@ -7,20 +7,20 @@).
func = 251 # The part of the changed file after frag.
context = 251 # Lines in the diff that haven't changed.
old = red bold # Removed lines (overwritten by diff-highlight).
new = green bold # Added lines (overwritten by diff-highlight).
commit = 178 # Commit hash in git show.
whitespace = normal reverse # Whitespace errors (trailing whitespace in the diff).
old = 160 # Deleted lines (defaults to red bold).
new = 40 # Added lines (defaults to green bold).
oldMoved = 161 # Line moved from here.
oldMovedAlternative = 161 ul # Alternative color to show difference between moved blocks.
newMoved = 42 # Line moved to here.
newMovedAlternative = 42 ul # Alternative color to show difference between moved blocks.
# Change colours for moved hunks in `git diff`.
[color "diff-highlight"] # See https://github.com/git/git/tree/master/contrib/diff-highlight
oldHighlight = reverse # Apply this to highlight word diff deletion.
oldReset = noreverse # Apply this to undo word diff deletion highlighting.
newHighlight = reverse # Apply this to highlight word diffs addition.
newReset = noreverse # Apply this to undo word diff addition highlighting.
# Change colours for `git status`.
[color "status"]
localBranch = 27 # Only used in status --short.
remoteBranch = 27 # Only used in status --short.
nobranch = red # IDK when this is used.
header = 8 # Standard git waffle.
branch = 27 # Current branch.
added = 35 # Files added to index (ready to commit).
changed = 172 # Files not added, but tracked by git.
untracked = 197 # Files git knows nothing about.
unmerged = 196 # Files that have conflicts in git rebase.
[commit]
# gpgsign = true # Always sign commits, available since Git 2.0.
# ^ is off because some people might not have gpg keys (and it breaks the npm test suite).
[core]
pager = "$([ -x ~/bin/diff-so-fancy ] && echo diff-so-fancy || echo cat) | less"
hooksPath = "~/.config/git/hooks" # Put global git hooks here.
[credential]
helper = osxkeychain # Store Git credentials in the macOS keychain.
[diff]
wsErrorHighlight = all # diff and show show whitespace errors.
renames = copies # Copies count as renames.
submodule = log # Show information about submodules in diffs and logs.
colorMoved = zebra # Highlight moved lines as oldMoved -> newMoved.
tool = vimdiff # Use nvim vimdiff to view diffs (`git difftool`).
[diff-so-fancy]
markEmptyLines = false # The red blobs are very distracting when only a newline has been added.
stripLeadingSymbols = false # Without `markEmptyLines` you need the +/- to show newline changes.
[fetch]
prune = true # Delete local tracking branches if remote is gone.
[format]
pretty = fuller # Shows author and committer.
[help]
autocorrect = 1 # Autocorrect nonexistant commands after 0.1s.
[filter "lfs"]
clean = git-lfs clean -- %f
smudge = git-lfs smudge -- %f
process = git-lfs filter-process
required = true
[log]
follow = true # Log tracks file move/rename.
[merge]
defaultToUpstream = true # Not set by default before Git 2.0, remove when possible.
conflictstyle = diff3 # Show common ancestor in diffs (initially confusing, but very helpful).
tool = vimdiff # Use vimdiff (actually neovim's vimdiff) to view and fix merge conflicts (instead of `g mc`).
[mergetool]
prompt = false # Don't confirm that I want to open the difftool every time.
[mergetool "vimdiff"]
cmd = nvim -d $BASE $LOCAL $REMOTE $MERGED -c '$wincmd w' -c 'wincmd J'
[pull]
rebase = true # pull = fetch + rebase, not fetch + merge.
[push]
default = simple # Only push the branch I'm on.
[rebase]
autosquash = true # Squash commits with autosquash! as commit message (see `git fix`).
[rerere]
enabled = true # Remember how I resolved the same merge conflict last time.
[submodule]
fetchJobs = 8 # Number of jobs to fetch when I submodule clone/update.
[stash]
showPatch = true # Show the actual diffs in `git stash show`.
[status]
showStash = true # Show the number of commits in the stash in `git status` output.
# Try `g cl hh:nodejs/node`.
[url "https://bitbucket.org/"]
insteadOf = bb:
[url "https://github.com/"]
insteadOf = hh: # Hub https.
[url "git@github.com:"]
insteadOf = hs: # Hub ssh.
[url "https://github.com/gibfahn/"]
insteadOf = hhg: # Hub https gibfahn.
[url "git@github.com:gibfahn/"]
insteadOf = hsg: # Hub ssh gibfahn.
[url "https://gist.github.com/"]
insteadOf = gist:
[url "https://gitlab.com/"]
insteadOf = lh: # Lab https.
[url "git@gitlab.com:"]
insteadOf = ls: # Lab ssh.
[url "https://gitlab.com/gib/"]
insteadOf = lhg: # Lab https gib.
[url "git@gitlab.com:gib/"]
insteadOf = lsg: # Lab ssh gib.
[user]
# Needs to match gpg signing email.
name = Gibson Fahnestock # REPLACEME
email = gibfahn@gmail.com # REPLACEME
# Work config for work repos.
[includeIf "gitdir:~/wrk/**"]
path = ~/.config/git/wrk-config