Skip to content

Instantly share code, notes, and snippets.

@mej
Last active June 5, 2023 20:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mej/14b9534212a37d4cbee91880d12fa6fe to your computer and use it in GitHub Desktop.
Save mej/14b9534212a37d4cbee91880d12fa6fe to your computer and use it in GitHub Desktop.
mej's .gitconfig
### -*- Mode: conf-toml; fill-column: 80; comment-column: 40; \
### -*- comment-auto-fill-only-comments: t; tab-width: 4; \
### -*- eval: (auto-fill-mode 1); \
### -*- eval: (local-set-key "\C-i" 'indent-according-to-mode) -*-
################################################################################
# Git Configuration
#
# Michael Jennings <mej@eterm.org>
# 15 Mar 2013
#
# Evolved over time and cobbled together from innumerable sources.
#
################################################################################
### Global User (i.e., Identity) Settings
# Anyone grabbing and customizing this file will need to change ALL of these!
# And don't forget to use the *long* GPG key ID for safety.
[user]
name = Michael Jennings
#email = mej@kainx.org
#email = mej@eterm.org
email = mej@lanl.gov
signingkey = A95EBD0D160CA591
### Git Subcommand Aliases and JIT-Functions
# These are in sections by topic (roughly) and kept alphabetized within each
# section (roughly). (Occasionally my OCD-powered organizational and
# grammatical pedantry is superceded by functional similarity.)
#
# These should work as-is, though some do rely on content later in the file
# (e.g., the "hist" format for log output used by the "hist" alias). And
# references to my GPG key ID, obviously, won't work for you; otherwise, the
# vast majority of them should work just fine, either one-by-one or en masse.
[alias]
### Basics
bi = bisect
co = checkout # RCS, CVS, SVN...and less typing!
#cp = cherry-pick -x # "CherryPick" (w/hash by default)
c-p = cherry-pick # Alt. to above due to "cp" conflict
cpx = cherry-pick -x # "CherryPick-X" (log orig commit)
cpa = cherry-pick --abort # Abort the c-p seq and reset
cpc = cherry-pick --continue # Resume cherry-pick after conflict
cpq = cherry-pick --quit # Same as abort w/o reset
fa = fetch --all # "FetchAll," obviously.
ff = merge --ff-only # "FastForward" or DIE!
get = clone --recurse-submodules # This one is self-explanatory...
k = "!gitk --all &" # "git k" == "gitk" because typos.
sl = shortlog -e # "ShortLog" (with author e-mails)
stat = status
sw = switch
ustat = status -uno # Same as "stat" but skip untracked
fpush = push --force # Force-push for non-fast-forwards
npush = push --dry-run # "-n push" - don't send the objs!
tpush = push --tags # Tags aren't pushed by default...
ftpush = push --force --tags # Combine the 2 above
upush = push --set-upstream # Set push target as "upstream" repo
up = pull origin # Analogous to "cvs up" or "svn up"
### Clone-related aliases (in addition to "get" above)
cl = clone # ...duh...
clr = clone --recurse-submodules # Same as "get" but more obvious?
### Commit-related aliases
amend = commit --amend # Modify last commit (also see below)
ca = commit --amend -C HEAD # Amend, preserving log message
caa = commit -a --amend -C HEAD # "ca" but with auto-add/auto-rm
cae = commit --amend -c HEAD # Amend, edit previous log message
caae = commit -a --amend -c HEAD # "cae" but with auto-add/auto-rm
ci = commit # "CheckIn" (a la CVS, SVN)
nci = commit --dry-run # "NoCheckIn" (or, think "rsync -n")
cis = commit -S # "CheckInSigned" (user.signingkey)
sci = commit -S # "SignedCheckIn" (user.signingkey)
dco = commit --signoff # Commit with DCO (Signed-off-by:)
lsu = ls-files -u # "LS Unmerged" (conflicted) files
isync = add -A # "Index Sync" rm/adds (like mzsync)
addf = add -f # ADD+Force
fadd = addf # Force-ADD
addi = add -fi # ADD Interactively
iadd = addi # Interactive ADD
addp = add -fp # ADD Patch hunks (similar to -i)
padd = addp # Patch ADD
### Pushing and pulling
# Sync (pull-then-push) all shared branches or tags to remote(s)
# Origin: sync branches, sync tags, or force-push branches
sync = !git pull && git push origin : && :
tsync = !git pull && git push origin --tags && :
syncf = !git pull && git push origin +: && :
# Same as above but to both origin and "bb" (usually Bitbucket)
bbsync = !git pull && git push origin : && git push bb : && :
bbtsync = !git pull && git push origin --tags && git push bb --tags && :
bbsyncf = !git pull && git push origin +: && git push bb +: && :
# Push to all remotes ("t" for tags, "f" for force-push)
pushall = "!_gf() { for R in $(git remote) ; do test \"$R\" = \"upstream\" && continue ; echo \"=== git push $R $* ===\" ; git push \"$R\" \"$@\" ; done; }; _gf"
tpushall = "!_gf() { for R in $(git remote) ; do test \"$R\" = \"upstream\" && continue ; echo \"=== git push $R $* ===\" ; git push --tags \"$R\" \"$@\" ; done; }; _gf"
apushall = "!_gf() { for R in $(git remote) ; do test \"$R\" = \"upstream\" && continue ; echo \"=== git push $R $* ===\" ; git push \"$R\" \"refs/heads/*:refs/heads/*\" \"refs/tags/*:refs/tags/*\" \"$@\" ; done; }; _gf"
fpushall = "!_gf() { for R in $(git remote) ; do test \"$R\" = \"upstream\" && continue ; echo \"=== git push $R $* ===\" ; git push -f \"$R\" \"$@\" ; done; }; _gf"
ftpushall = "!_gf() { for R in $(git remote) ; do test \"$R\" = \"upstream\" && continue ; echo \"=== git push $R $* ===\" ; git push -f --tags \"$R\" \"$@\" ; done; }; _gf"
fapushall = "!_gf() { for R in $(git remote) ; do test \"$R\" = \"upstream\" && continue ; echo \"=== git push $R $* ===\" ; git push -f \"$R\" \"+refs/heads/*:refs/heads/*\" \"+refs/tags/*:refs/tags/*\" \"$@\" ; done; }; _gf"
### Dealing with remotes
re = remote # Just a shortcut
rea = remote add # REmote Add
real = remote add -f --tags # REmote Add, then Load (fetch)
rebr = remote set-branches # REmote set-BRanches
rebra = remote set-branches --add # ^- Same + Add
regu = remote get-url # REmote Get-Url
rels = remote -v # REmote LiSt
rels-stale = remote prune --dry-run # REmote LiSt STALE refs
relsps = remote prune --dry-run # ^- Same, but Prune Stale
remv = remote rename # REmote MoVe (rename)
rep = remote prune # REmote Prune
rerm = remote remove # REmote ReMove
res = remote show # REmote Show
resu = remote set-url # REmote Set-Url
reup = remote update # REmote UPdate
# More generic "do X for each remote"
foreach-remote = "!_gf() { for R in $(git remote) ; do test \"$R\" = \"upstream\" && continue ; REMOTE=\"$R\" ; echo \"=== git $* $R ===\" ; git \"$@\" \"$R\" ; done; }; _gf"
fere = "!_gf() { exec git foreach-remote \"$@\"; }; _gf"
### Branching and Tagging
br = branch # Just a shortcut
cob = checkout -b # Make+CheckOut Branch ("co -b")
brco = checkout --track # "cob" w/tracking setup (normal case)
brdesc = branch --edit-desc -- # Opens branch description in editor
brls = branch --list -vv # BRanch LiSting + 2*verbose
brlsa = branch -a --list -vv # "brls" for local+remote branches
brlsr = branch -r --list -vv # "brls" for remote branches only
brsetup = branch -u # BRanch SET UPstream
bru = branch -u # BR set Upstream (same, but shorter)
fbr = branch -f # Force BRanch (reset if exists)
mkbr = checkout -B # MaKe BRanch (br -f, then co)
mvbr = branch -m # MoVe BRanch (branch move/rename)
fmvbr = branch -M # "mvbr" even if new name exists
rmbr = branch -d # ReMove BRanch
frmbr = branch -D # "rmbr" even if not merged upstream
# CheckOut with Tracking or with Tracking + Branchname (either order)
cot = checkout -t
cobt = "!_gf() { exec git checkout -b \"${1}\" -t \"${@:2}\"; }; _gf"
cotb = "!_gf() { exec git checkout -t \"${1}\" -b \"${@:2}\"; }; _gf"
# Create developer or bugfix branches with "standard" naming
bdev = "!_gf() { exec git checkout -b \"$(id -un)/dev/${1}\" \"${@:2}\"; }; _gf"
bfix = "!_gf() { exec git checkout -b \"$(id -un)/fix/${1}\" \"${@:2}\"; }; _gf"
# These *should* do the exact same thing as the 2 above, but for now...
#devb = bdev
#fixb = bfix
devb = "!_gf() { exec git checkout -b \"dev/$(id -un)/${1}\" \"${@:2}\"; }; _gf"
fixb = "!_gf() { exec git checkout -b \"dev/$(id -un)/${1}\" \"${@:2}\"; }; _gf"
# brhist ("BRanch HISTory") is defined in "shortlog" section below
t = tag
tls = tag -l # Tag LiSting
tll = tag -n -l # Tag Long Listing (w/annotation)
tmv = tag -f # Tag MoVe (i.e., --force); not good!
trm = tag -d # Tag ReMove (delete)
atag = tag -af # "AnnotatedTAG" w/force to move
stag = tag -s # "SignedTAG"
# List tags showing commit hash, tag value, tag msg, commit msg for each
tags = for-each-ref --sort='-authordate' --sort='-*authordate' --format='%(if)%(*objectname)%(then)%(color:yellow)%(*objectname:short)%(color:reset) %(align:40,left)%(color:yellow bold)(tag:%(refname:short) %(subject))%(end)%(color:reset) %(align:80,left)%(*subject)%(end)%(else)%(align:80,left)%(color:yellow)%(objectname:short)%(color:reset) %(refname:short)%(end) %(align:80,left)%(subject)%(end)%(end)' refs/tags
### Generating/displaying non-historical diffs/diffstats
d = diff # Just a shortcut to "diff"
dw = diff --word-diff # Word-based diff
# "dc" shows the diff for a specific commit; "dcw" is word-based "dc"
dc = "!_gf() { git diff ${1}^..${1} \"${@:2}\"; }; _gf"
dcw = "!_gf() { git diff --color-words ${1}^..${1} \"${@:2}\"; }; _gf"
df = diff-files -p # Diff Files
dfw = diff-files -p --word-diff # Word-based "df"
di = diff -p --staged # Diff against index (def. HEAD)
diw = diff -p --staged --word-diff # Word-based "di"
diffstat = diff --stat # Generate diffstat output
dirstat = diff --dirstat # Generate dirstat output
ds = diff --stat --dirstat # Both of the above ("DiffStats")
dsp = diff -p --stat --dirstat # All of the above ("DiffStats w/Patch")
dt = diff-tree # Abbreviation for "diff-tree"
idiff = diff -p --staged # "IndexDiff" (same as "di")
# "CommitDIFF" or "ChangesetDIFF"
cdiff = "!_gf() { git diff ${1:-HEAD}^..${1:-HEAD} \"${@:2}\"; }; _gf"
# "Non-Colored DIFF" for creating patch files
ncdiff = "!_gf() { git diff --color=never \"$@\"; }; _gf"
### Working directory cleanup (to remove build products, etc.)
clear = clean -d # Nuke all untracked files & dirs
wipe = clean -xd # Nuke untracked+ignored files & dirs
nclean = clean -n # Dry-run of "clean"
cleann = clean -n # Because 2 Ns are better than one
nclear = clean -d -n # Dry-run of "clear"
nwipe = clean -xd -n # Dry-run of "wipe"
### Displaying commit history with diffs ("difflogs")
# "difflog" and its shorter form "dl" show commit log & diffs together
difflog = log -p --stat --pretty=difflog
dl = log -p --stat --pretty=difflog
# "dlbw" ("DiffLog BackWard") shows difflog in reverse (oldest first)
dlbw = log -p --stat --reverse --pretty=difflog
# "dlw" ("DiffLog Words") shows the difflog with word-based diffs
dlw = log -p --stat --color-words --pretty=difflog
# "dlwbw" simply combines the last 2 into 1
dlwbw = log -p --stat --color-words --reverse --pretty=difflog
last = log -p -1 HEAD # Show "difflog" for most recent commit
### External highlighting of Git diff output (requires `diff-highlight` script)
dhl = "!_gf() { export GIT_PAGER=\"${GIT_PAGER:-$(git config --get core.pager)}\" ; git \"$@\" | diff-highlight | ${GIT_PAGER} ; }; _gf"
# I do this constantly, so I made a quicker shortcut:
dhdl = "!_gf() { export GIT_PAGER=\"${GIT_PAGER:-$(git config --get core.pager)}\" ; git dl \"$@\" | diff-highlight | ${GIT_PAGER} ; }; _gf"
### Displaying commit history textually (see also "[pretty]" below)
# Commit history, 1 per line, with graph. "BackWard"/"Reverse" for oldest first.
hist = log --graph --decorate --format=hist
histbw = log --graph --decorate --format=hist --reverse
rhist = log --graph --decorate --format=hist --reverse
hista = log --graph --decorate --format=hist --all
histabw = log --graph --decorate --format=hist --all --reverse
rhista = log --graph --decorate --format=hist --all --reverse
# Different ways of spelling "log" with formats under "[pretty]"
l = log
la = log --graph --decorate --format=logall --all
ll = log --format=fuller
lla = log --format=fuller --all
ls = log --format=listing
lsa = log --format=listing --all
refhist = log -g --pretty=oneline # REFerence HISTory (reflog, def. HEAD)
### "shortlog" displays summaries, branches, release notes
slog = shortlog -e # "ShortLog" (with author e-mails)
# "RELeaseLOG" shows commits by author; for release notes, etc.
rellog = shortlog -en --format='* [%h] %s' -w'79,4,6'
mrlog = shortlog -en --pretty=mrlog -w'0,2,12'
# "BRanch HISTory" shows inter-branch deltas (symmetric differencing)
brhist = shortlog --cherry-mark --left-right --no-merges
headhist = shortlog --walk-reflogs # HEAD HISTory (from reflog)
histf = shortlog --cherry # "HISTory of Forks"
walkrl = shortlog --walk-reflogs # "WALK RefLogs"
who = shortlog -se # Summarize commit counts by author
# "RefLogGREP"
rlgrep = "!_gf() { git shortlog --walk-reflogs --grep-reflog=\"${1}\" \"${@:2}\"; }; _gf"
### Searching commit/delta history
# "Pickaxe" refers to searching for commits that change lines matching
# a given regexp (-G) or for commits that change the number of
# occurrences of a specified string (-S) or extended regexp
# (--pickaxe-regex -S). By default, the only diffs that are shown are
# for files that triggered the match, but --pickaxe-all shows the entire
# changeset. The aliases below use "pa" for "PickAxe" and "apa" for
# "AllPickAxe" (i.e., --pickaxe-all). "grep" (normal regex grep),
# "fgrep" (grep -F), and "egrep" (grep -E) are used as mnemonics for
# each of the behaviors described above, respectively, each with ("apa")
# and without ("pa") the --pickaxe-all flag. Do note, however, that the
# semantics are subtly different between "-S<regex> --pickaxe-regex" and
# "-G<regex>" as described in git-log(1) and gitdiffcore(7).
apaegrep = log -p --stat --pickaxe-all --pickaxe-regex -S
apafgrep = log -p --stat --pickaxe-all -S
apagrep = log -p --stat --pickaxe-all -G
paegrep = log -p --stat --pickaxe-regex -S
pafgrep = log -p --stat -S
pagrep = log -p --stat -G
pickaxe = log -p --stat -G
### Rewriting history by reordering, squashing, fixing, and/or undoing commits
histedit = rebase --interactive # Pretty self-explanatory, I think.
hreset = reset --hard # "HardRESET" is also pretty obvious.
sreset = reset --soft # "SoftRESET" is too...
ri = rebase --interactive # ...as is "RebaseInteractively."
unadd = reset -- # Reset by itself undoes "git add"
# Interactive un-add; if 1st arg isn't a path, must be a "<tree-ish>"
unaddi = "!_gf() { if [ -e \"${1}\" ]; then git reset -p -- \"$@\" ; else git reset -p \"${1}\" -- \"${@:2}\" ; fi; }; _gf"
# "UNdo CommIts" or "UNdoCIs" - Revert HEAD back to <commit> but leave changes staged in index.
#unci = reset --soft
unci = "!_gf() { if [ -n \"${1}\" -a -z \"${1//[0-9]}\" ]; then git reset --soft HEAD~${1} \"${@:2}\" ; else git reset --soft \"${@}\" ; fi; }; _gf"
# "ReMove CommIts"/"ReMoveCIs" - Revert HEAD and index back to <commit> but leave changes in working tree.
#rmci = reset --mixed
rmci = "!_gf() { if [ -n \"${1}\" -a -z \"${1//[0-9]}\" ]; then git reset --mixed HEAD~${1} \"${@:2}\" ; else git reset --mixed \"${@}\" ; fi; }; _gf"
# "ReWriteCommIts" or "ReWriteCIs" - refactor the last <num> commits
rwci = "!_gf() { local b=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) ; if [ -n \"${1}\" -a -z \"${1//[0-9]}\" ]; then git rebase -i HEAD~${1} HEAD \"${@:2}\" ; else git rebase -i \"${@}\" ; fi; }; _gf"
### Working with subtrees and submodules
# Subtree shortcut
st = subtree
sm = submodule
# Subtree add/update
sta = "!_gf() { git subtree add --prefix \"${2}\" \"${1}\" master --squash; }; _gf"
stu = "!_gf() { git subtree pull --prefix \"${2}\" \"${1}\" master --squash; }; _gf"
# Submodule add (TODO: Do "git add" for <name> and .gitmodules and "git commit")
#sma = "!_gf() { git submodule add \"$@\"; }; _gf"
sma = submodule add
smi = submodule init
smd = submodule deinit
smfe = submodule foreach
smsb = submodule set-branch
smsu = submodule set-url
smstat = submodule status
smsync = submodule sync --recursive
smup = submodule update --init --recursive --jobs 4
foreach-sm = submodule foreach
fesm = foreach-sm
### Assorted generalized goop
# No Color - Generic wrapper tool to disable color
nc = "!_gf() { export NEVER=never ; exec git -c color.pager=false --config-env=color.{advice,blame,branch,decorate,diff,grep,interactive,push,remote,showbranch,status,transport,ui}'=NEVER' \"$@\"; }; _gf"
[core]
abbrev = 8
# Normally "true" but need to be "false" on FAT, some NTFS
filemode = true
symlinks = true
# True uses native Win API whenever possible
ignorecygwinFStricks = true
# Should auto-set itself to true when needed, but ONLY at time
# of initialization or clone!
ignorecase = false
sharedrepository = group # Preserve group permissions
gitproxy = lanl-gitproxy-socat # Requires external script
pager = less -+S -FRXi -z-1
logAllRefUpdates = always
whitespace = blank-at-eol,space-before-tab,blank-at-eof,tabwidth=4
[branch]
# For *any* newly created branch, set it to rebase on update (i.e., pull)
autosetuprebase = always
[tag]
sort = -authordate
[commit]
# Always remove comment lines & extra whitespace, see git-commit(1)
cleanup = strip
# Includes HEAD..index diff in commit log message template
verbose = true
[fetch]
parallel = 4
prune = true
pruneTags = true
recurseSubmodules = true
[merge]
conflictstyle = diff3
log = true
# tool = diffuse
tool = meld
defaultToUpstream = true
[rebase]
autoSquash = true
autoStash = true
stat = true
[pull]
# Rebase local commits onto the fetched branch rather than merging
rebase = true
[push]
# Push the currently checked-out branch if none is specified
default = current
followTags = true
recurseSubmodules = check
### REuse REcorded REsolution
[rerere]
autoUpdate = true
enabled = true
[diff]
tool = meld
prompt = false
mnemonicprefix = true
dirstat = lines,cumulative,10
[stash]
showPatch = true
showStat = true
[clean]
# WARNING: This changes the "git clean" command to NOT require -f/--force!
requireForce = false
[status]
short = false
branch = true
aheadBehind = true
showStash = true
showUntrackedFiles = normal
submoduleSummary = true
[gc]
pruneExpire = 6.months.ago
reflogExpire = never
reflogExpireUnreachable = 3.months.ago
rerereResolved = 1.year.ago
rerereUnresolved = 9.months.ago
[grep]
lineNumber = true
patternType = perl
extendedRegexp = true
threads = 0
fallbackToNoIndex = true
[i18n]
# NOTE: Most users will want to use the default of UTF-8!
commitencoding = ISO-8859-1
logoutputencoding = ISO-8859-1
[submodule]
recurse = true
fetchJobs = 4
[interactive]
singlekey = true
[color]
status = always
diff = always
log = always
ui = auto
branch = auto
grep = always
decorate = always
interactive = auto
pager = true
showbranch = auto
[pretty]
# Text format for "git hist" alias - colorized 1-line history with graph
hist = tformat:%C(auto)%h%d <%ae> %s
# For "git la" ("LogAll") - Decorated commit history w/graph for HEAD+refs/*
logall = tformat:%C(auto)%h%Creset%C(auto)%d%Creset %s (%C(auto,cyan)%cr%Creset) by %C(auto,bold white)%aN%Creset
# For "git ls" ("LiSting") - One-line commit history only, no graph
listing = tformat:%C(auto)%h%Creset%C(auto)%d%Creset %s (%C(auto,cyan)%cr%Creset) by %C(auto,bold white)%aN%Creset
# Format for "git difflog" (or "dl") along with a few similar variations
# Shows detailed commit history with log messages and diffs
difflog = tformat:Commit: %C(auto)%h%Creset%C(auto)%d%Creset from %C(auto)%p%Creset%nAuthor: %C(auto,bold yellow)%aN <%aE>%Creset %C(auto,cyan)(%ad)%Creset%nCommit: %C(auto,bold yellow)%cN <%cE>%Creset %C(auto,cyan)(%cd)%Creset%n%n%C(auto,bold white)%w(76,4,4)%s%Creset%n%n%w(76,4,4)%b%n
mrlog = tformat:- [%h] %s
[format]
attach = true
##cc = mej@kainx.org
coverletter = true
##headers = "Organization: Los Alamos National Laboratory\n"
numbered = true
pretty = medium
signature =
signoff = true
subjectprefix = PATCH
suffix = .patch
thread = deep
to = mej@eterm.org
[sendemail]
smtpencryption = tls
smtpserver = smtp.gmail.com
smtpserverport = 587
smtpuser = mjennings@gmail.com
thread = false
confirm = auto
[tar]
umask = 0022
[help]
autocorrect = 20
[url "git+ssh://git@github.com/"]
insteadOf = gh:
[url "git+ssh://git@github.com/mej/"]
insteadOf = ghm:
[url "git+ssh://git@github.com/hpc/"]
insteadOf = ghpc:
[url "git+ssh://git@github.com/kraken-hpc/"]
insteadOf = ghk:
[url "git+ssh://git@bitbucket.org/"]
insteadOf = bb:
[url "git+ssh://git@bitbucket.org/mej0/"]
insteadOf = bbm:
[url "git+ssh://git@git.lanl.gov/"]
insteadOf = lgl:
[url "git+ssh://git@git.lanl.gov/mej/"]
insteadOf = lglm:
[url "git+ssh://git@git.hpc.lanl.gov:10122/"]
insteadOf = hgl:
[url "git+ssh://git@git.hpc.lanl.gov:10122/mej/"]
insteadOf = hglm:
[url "git+ssh://git@git.hpc.lanl.gov:10122/platforms/"]
insteadOf = hglp:
[url "git+ssh://git@cm.hpc.lanl.gov:10022/"]
insteadOf = cmgl:
[url "git+ssh://git@cm.hpc.lanl.gov:10022/mej/"]
insteadOf = cmglm:
[gui]
editor = emacs
[cola]
textwidth = 132
tabwidth = 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment