Skip to content

Instantly share code, notes, and snippets.

@mej
Last active June 25, 2025 23:21
Show Gist options
  • Select an option

  • Save mej/14b9534212a37d4cbee91880d12fa6fe to your computer and use it in GitHub Desktop.

Select an option

Save mej/14b9534212a37d4cbee91880d12fa6fe to your computer and use it in GitHub Desktop.
mej's .gitconfig
### -*- Mode: conf-toml; fill-column: 80; comment-auto-fill-only-comments: t; tab-width: 4; eval: (local-set-key "\C-i" 'indent-according-to-mode) -*-
################################################################################
# Git Configuration
#
# Michael Jennings <[email protected]>
# 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 = [email protected]
#email = [email protected]
email = [email protected]
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 # "Fetch All," obviously.
fap = fa -p # "Fetch All and Prune"
fat = fa --tags # "Fetch All Tags"
fatp = fa -Pt # "Fetch All Tags and Prune" CAUTION!
faa = fap -P # "Fetch All and prune All the things!"
ff = merge --ff-only # "FastForward" or DIE!
noff = merge --no-ff # NO FastForward, even if possible
mc = merge --no-ff --log # Force a "MergeCommit" (like GitHub)
up = pull origin # Analogous to "cvs up" or "svn up"
pullup = pull upstream # PULL the latest UPstream code
get = clone --recurse-submodules # This one is self-explanatory...
sl = shortlog -e # "ShortLog" (with author e-mails)
stat = status
ustat = status -uno # Same as "stat" but skip untracked
fstat = ustat --ignored=no --ignore-submodules=all # Fast STAT
fast = fstat # Going for "fast stat" even FASTer
sw = switch # "co" old & busted, "SW" new hotness
swc = switch -c # Same as "cob"/"co -b" but switchier
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
# The particulars of staging and unstaging are easy to forget or mistype,
# so aliases to the rescue!
stage = add
pstage = addi # Partial STAGE (i.e., interactively)
unstage = restore -S # -S/--staged restores HEAD -> index
# Use refspecs, without or with the leading '+', to push branches+tags
apush = "!set -x;_gf() { git push $(git remote show) refs/heads/*:refs/heads/* refs/tags/*:refs/tags/*; }; _gf"
fapush = '!_gf() { git push $(git remote show) +refs/heads/*:refs/heads/* +refs/tags/*:refs/tags/* "$@"; }; _gf'
# Basics - Simple Stuff
vvar = '!_gf() { if test $# -eq 0; then exec git var -l; else exec git var "$@"; fi; }; _gf'
### Extra-short shortcuts
a = add
b = branch
c = config
d = diff
f = fetch
g = grep
h = help
i = init
#j =
k = "!gitk --all &" # "git k" == "gitk" because typos.
l = log
m = merge
#n =
#o =
p = push
q = quiltimport
r = rebase
s = fstat
t = tag
#u =
#v = # Need something a bit more clever here because `git-var` isn't.
v = vvar
w = worktree
###############################################################################################################################
### Configuration data access
c-e = config --edit
c-g = config --get
c-s = config --set
c-u = config --unset
c-ua = config --unset-all
# I think these are safe, but comment out if not.
ce = config --edit
cg = config --get
cs = config --set
cu = config --unset
cua = config --unset-all
# Everything else...
c-a = config --add
c-ga = config --get-all
c-gb = config --get-colorbool
c-gc = config --get-color
c-gcb = c-gb
c-gr = config --get-regexp
c-gu = config --get-urlmatch
c-mv = config --rename-section
c-rm = config --remove-section
c-ls = config --list
c-lsv = config --list --show-origin --show-scope
c-lsz = config --list --null
c-lsn = config --list --name-only
###############################################################################################################################
### Cloning and Committing
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 @ # Amend, preserving log message
caa = commit -a --amend -C @ # "ca" but with auto-add/auto-rm
cae = commit --amend -c @ # Amend, edit previous log message
caae = commit -a --amend -c @ # "cae" but with auto-add/auto-rm
ci = commit # "CheckIn" (a la CVS, SVN)
cia = commit -a # "ci" with automatic "git add"
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 (item #5 in "add -i")
padd = addp # Patch ADD
###############################################################################################################################
### Porcelains
# These aliases, not unlike their common command-line option, are mainly
# for purposes of automation, either in scripts or in one-liners.
porcstat = status --porcelain # Parsable file/dir states
statporc = porcstat
po-stat = porcstat
po-s = porcstat
procstat = porcstat # Common typos for the win!
# One more of these, because reasons.
sss = status --porcelain # Status for Scripts & Stuff
###############################################################################################################################
### 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 +: && :
###############################################################################################################################
### 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
relss = remote prune --dry-run # REmote LiSt STALE refs
relsf = remotes-fetch # REmote LiSt, Fetch-able only
relsp = remotes-push # REmote LiSt, Push-able only
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
resup = remote set-url --push # REmote Set-Url for Push
reup = remote update # REmote UPdate
# Shortcuts for some of the `remotes-*` multi-remote ops (below)
re-f = remotes-fetch
re-p = remotes-push
### FIXME: Prefer `re`* aliases? mdo = remotes-do-a-few # Multi-remote DO
redaf = remotes-do-a-few
red1 = remotes-do-one
redl = remotes-do-list
re-do1 = remotes-do-one
re-doaf = remotes-do-a-few
# See above for the implementation
foreach-remote = remotes-do-all
fere = foreach-remote
### FIXME: Should some portion of these move into Bash/mejsh? Some of these are a wee bit gnarly as one-liners....
### Utility functions for running commands on remote(s)
# remotes-fetch returns a list of remotes that are fetch-able (should be all of them...); conditional is currently ":" (true always).
remotes-fetch = "!_gf() { local C L R U; while read R U C; do if test "$C" = '(push)'; then continue; elif : ; then echo "$R"; : L+=" $R"; fi; done < <(git remote -v); }; _gf"
# remotes-push returns a list of remotes that are push-able; at present, that means it's not named "upstream" and the URL isn't `no_push`.
remotes-push = "!_gf() { local C L R U; while read R U C; do if test "$C" = '(fetch)' -o "$R" = 'upstream' -o "$U" = 'no_push' ; then continue; else echo "$R"; fi; done < <(git remote -v); }; _gf"
# remotes-do-one executes a single command on a single remote, after some checking and decorating.
remotes-do-one = "!_gf() { local C=\"$1\" R=\"$2\"; shift 2 ; printf '\\e[5;100m[===]\\e[0m \\e[1;97;40m[ %s ]\\e[0m \\e[5;100m[===]\\e[0m\\n' \"git $C${1:+ $*}: $R\" ; exec git $C $R \"$@\"; }; _gf"
# remotes-do-list takes a whitespace-delimited list of remotes as $1 and the command to be run as $2, then everything else.
remotes-do-list = "!_gf() { local R S=\"$1\" C=\"$2\"; shift 2; for R in $S ; do git remotes-do-one \"$C\" \"$R\" \"$@\"; done; }; _gf"
# remotes-do-a-few pulls args off the command line until it hits `--` or an empty string;
# then it calls remotes-do-list with all those initial args stuffed into a single arg ("$1")
remotes-do-a-few = "!_gf() { local C=\"$1\" L=''; shift; while test -n \"$1\" -a \"$1\" != \"--\"; do L=\"$L $1\"; shift; done; exec git remotes-do-list \"${L:1}\" \"$C\" \"${@:2}\"; }; _gf"
# remotes-do-all just invokes `git remotes-do-list` and inserts a list of all remotes' names as the 1st argument
remotes-do-all = "!_gf() { exec git remotes-do-list \"$(git remotes-fetch)\" \"$@\"; }; _gf"
# remotes-do-all-push is identical to "do-all" except that only remotes with "push" URLs are included
remotes-do-all-push = "!_gf() { exec git remotes-do-list \"$(git remotes-push)\" \"$@\"; }; _gf"
# These use "remotes-do-a-few" rather than "remotes-do-list" just because.
remotes-moo-all = "!_gf() { exec git remotes-do-a-few $(git remotes-fetch) -- \"$@\"; }; _gf"
remotes-moo-push-all = "!_gf() { exec git remotes-do-a-few $(git remotes-push) -- \"$@\"; }; _gf"
# Push with different settings to one or more remotes (or all remotes); "t" means tags, "f" means to force-push)
pushall = remotes-do-all-push push
tpushall = remotes-do-all-push tpush
apushall = remotes-do-all-push apush
fpushall = remotes-do-all-push fpush
ftpushall = remotes-do-all-push ftpush
fapushall = remotes-do-all-push fapush
npushall = remotes-do-all-push npush
# The commands above do all push-able remotes; these next 4 take a user-supplied list of remotes as arguments terminated by an
# argument of either `--` or `''`. "t"/"f" same as above; "m" means "multi-remote;" "n" means "dry-run" (usually `-n` flag).
mpush = remotes-do-a-few push # Multi-remote PUSH
mnpush = remotes-do-a-few npush # Multi-remote NPUSH (i.e., a dry-run push)
fmpush = remotes-do-a-few fpush # Multi-remote FPUSH
fmnpush = remotes-do-a-few fnpush # Multi-remote FNPUSH (dry-run for a forced push)
# Push shortcuts specific to NHC
ppush = push ghp
pfpush = fpush ghp
lpush = push lanl
lfpush = fpush lanl
lppush = remotes-do-a-few push ghp lanl --
lpfpush = remotes-do-a-few fpush ghp lanl --
###############################################################################################################################
### Branching and Tagging
br = branch # Just a shortcut
cob = checkout -b # Make+CheckOut Branch ("co -b")
#swc = switch -c # Equivalent with switch (set above)
swC = switch -C # Same as "cob"/"swc" but forced
brco = checkout --track # "cob" w/tracking setup (normal case)
brdesc = branch --edit-desc -- # Opens branch description in editor
brget = branch --show-current # BRanch GET name
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)
fcob = checkout -B # Force-COB (like forcing "cob" above)
brmv = branch -m # BRanch MoVe (branch move/rename)
fbrmv = branch -M # "brmv" even if new name exists
brrm = branch -d # BRanch ReMove
fbrrm = branch -D # "brrm" even if not merged upstream
# The following 5 aliases break standard ordering and are thus deprecated.
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 \"fix/$(id -un)/${1}\" \"${@:2}\"; }; _gf"
# brhist ("BRanch HISTory") is defined in "shortlog" section below
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)(%(align:15,left)"%(refname:short)" %(end)%(align:25,left)"%(subject)")%(end)%(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
# Previous (tag subjects not aligned): 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
###############################################################################################################################
### Diffs and Patches
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:-HEAD}^..${1:-HEAD} \"${@:2}\"; }; _gf"
dcw = "!_gf() { git diff --color-words ${1:-HEAD}^..${1:-HEAD} \"${@:2}\"; }; _gf"
# Same as the previous 2 for those (me) with pre-existing muscle memory
cdiff = dc
cwdiff = dcw
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
dds = dirstat --stat # Both of the above ("Dir+DiffStats")
dsp = dds -p # All of the above ("DDS w/Patch")
idiff = diff -p --staged # "IndexDiff" (same as "di")
ncdiff = diff --color=never # "Non-Colored DIFF" for patch creation
dnc = ncdiff # Alternative ("Diff w/No Color")
ncidiff = nc idiff # "No-Color" idiff
dinc = nc idiff # "DI" from above but with No Color.
dcnc = nc cdiff # "DC" from above with No Color
dcwnc = nc cwdiff # "DCW" from above with No Color
### Patch Generation
# Usage: git gp "pkgname-version" "Reason for patch" [ other-args ]
gp = "!_gf() { local DS=\"$(date \"+%Y%m%d\")\" N=\"${1:-$(basename ${PWD})}\" PN R=\"${2:+${2// /_}}\"; R=\"${R:-wip-${DS}}\"; PN=\"${N,,}${R:+-${R,,}}\"; git dnc \"${@:3}\" > \"${PN}.patch\"; diff-highlight \"${PN}.patch\" 2>/dev/null; }; _gf"
# gp = "!~/bin/git-gp"
### Archive generation (tar up anything in `git status` output)
ad-delta = "!_gf() { awk '{print $2}' < <(git status --porcelain); }; _gf"
archdiff = "!_gf() { exec tar --one-file-system --xattrs --acls --selinux -Hpax -Pachpv -f \"$@\" -T <(git ad-delta); }; _gf"
diffarch = archdiff
archd = archdiff
darch = archdiff
### Some other diff-based aliases
df = diff-files -p # Diff Files
dfw = diff-files -p --word-diff # Word-based "df"
dt = diff-tree # Abbreviation for "diff-tree"
### Diff Highlighting
# Uses external `diff-highlight` script, originally from Git, that highlights smaller, more specific changes
dhl = "!_gf() { export GIT_PAGER=\"${GIT_PAGER:-$(git config --get core.pager)}\" ; git \"${1:-diff}\" \"${@:2}\" | 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"
#dhd = "!_gf() { export GIT_PAGER=\"${GIT_PAGER:-$(git config --get core.pager)}\" ; git diff --color=never \"$@\" | diff-highlight | ${GIT_PAGER} ; }; _gf"
dhdl = dhl dl # Diff-Highlight DiffLog
dhll = dhl dllast # "dllast" with highlighting
### Non-repository Diff Variants
# All these are mainly just adding `fs` to the beginning
fsd = diff --no-index # FileSystem-only Diff
fsdw = fsd --color-words # FSD Word-based
fsdnc = fsd --color=never # FSD with No Color
###############################################################################################################################
### History and Logs
# 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
ha = hista
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]"
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)
### Displaying commit history with diffs ("difflogs")
# "difflog" and its shorter form "dl" show commit log & diffs together
difflog = log -p --stat --pretty=difflog
dl = difflog
# "dlbw" ("DiffLog BackWard") shows difflog in reverse (oldest first)
dlbw = difflog --reverse
# "dlw" ("DiffLog Words") shows the difflog with word-based diffs
dlw = difflog --color-words
# "dlwbw" simply combines the last 2 into 1
dlwbw = dlw --reverse
last = log -p -1 @ # "dl" for latest commit only (@ = HEAD)
dllast = dl -1 @ # "dl" for latest commit only (@ = 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"
###############################################################################################################################
### Restore
# `git-restore` is a relatively new Git subcommand used for snarfing content from some other source
# into the working tree or the index
# Pulls content into the worktree by default (or with -W) or index (-S)
rest = restore # RESTore worktree from another source
irest = restore -S # Index RESTore (--staged)
trest = restore -W # workTree RESTore (--worktree)
itrest = restore -SW # Both of the above simultaneously
# Same 4 aliases, this time with a different source specified (-s/--source)
rests = restore -s # RESTore worktree from Source
irests = restore -Ss # Index RESTore from Source
trests = restore -Ws # workTree RESTore from Source
itrests = restore -SWs # Both of the above simultaneously
arrest = restore -W . # All-Repo RESTore from HEAD
###############################################################################################################################
### Clean
# Working directory cleanup (to remove build products, etc.) aliases below distinguish among 3 "tiers" of tidying:
# - "git clean" uses the `git-clean` defaults, so it only removes untracked files throughout the tree
# - "git clear" goes a step further, recursing *into* untracked directories to remove their contents (and them)
# - "git wipe" is the harshest of the 3, removing ignored files and dirs as well as untracked ones
# Be careful, especially with `git wipe`; removed items cannot be recovered. Consider doing a dry-run first (`nclean`,
# `nclear`, and `nwipe`) to review what would be removed, or use interactive mode (`iclean`/`iclear`/`iwipe`) to refine your
# selection by hand (and no action will be taken until you're done).
#
# NOTE: By default, `git-clean` will not remove anything unless the `-f`/`--force` flag is given. This has always seemed
# kinda silly to me -- why would you be running `git clean` if you didn't want it to clean?! -- so that behavior is
# disabled in the `[clean]` section below, so don't rely on that safety net unless you restore it yourself!!
#
clear = clean -d # Nuke all untracked files & dirs
wipe = clean -xd # Nuke untracked+ignored files & dirs
nclean = clean -n # Dry-run of "clean"
nclear = clear -n # Dry-run of "clear"
nwipe = wipe -n # Dry-run of "wipe"
iclean = clean -i # Interactive "clean"
iclear = clear -i # Interactive "clear"
iwipe = wipe -i # Interactive "wipe"
cleanig = clean -X # Clean *only* ignored files/dirs
igclean = cleanig
ncleanig = cleanig -n # Dry-run of "cleanig"
ignclean = ncleanig
# These should be easy to remember too...because dry cleaning...it's punny!
dryclean = clean -n # These should be self-explanatory
dryclear = clear -n
drywipe = wipe -n
# Even punnier! "dry" -> "dri" for -i/--interactive!
driclean = clean -in # These should be self-explanatory
driclear = clear -in
driwipe = wipe -in
###############################################################################################################################
### 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...
rbi = rebase --interactive # ...as is "ReBaseInteractively."
# Actions taken *during* a rebase
rba = rebase --abort # ReBase Abort
rbc = rebase --continue # ReBase Continue
rbe = rebase --edit-todo
rbp = rebase --show-current-patch
rbq = rebase --quit # ReBase Quit
rbs = rebase --skip # ReBase Skip
# FIXME: Rename section to Merging and Rebasing, and clean this up.
mra = merge --abort # MeRge Abort
mrc = merge --continue # MeRge Continue
mrq = merge --quit # MeRge Quit (abort without reset)
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 exec git reset -p -- \"$@\" ; else exec git reset -p \"${1}\" -- \"${@:2}\" ; fi; }; _gf"
# Back up HEAD for the current branch by some number of commits
backout = "!_gf() { if [ -n \"${1}\" -a -z \"${1//[0-9]}\" ]; then exec git reset --hard HEAD~${1} \"${@:2}\" ; else exec git reset --hard \"${@}\" ; fi; }; _gf"
bk = backout
# "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 exec git reset --soft HEAD~${1} \"${@:2}\" ; else exec 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 exec git reset --mixed HEAD~${1} \"${@:2}\" ; else exec git reset --mixed \"${@}\" ; fi; }; _gf"
# "ReWriteCommIts" or "ReWriteCIs" - refactor the last <num> commits (`@` == `HEAD`)
rwci = "!_gf() { local b=$(git rev-parse --abbrev-ref @ 2>/dev/null) ; if [ -n \"${1}\" -a -z \"${1//[0-9]}\" ]; then exec git rbi @~${1} @ \"${@:2}\" ; else exec git rbi \"${@}\" ; fi; }; _gf"
###############################################################################################################################
### Worktrees, Subtrees, and Submodules
# Abbreviated aliases for common git-worktree tasks
wt = worktree
wta = worktree add
wtalk = worktree add --lock
wtal = wtalk
wtls = worktree list
wtlsv = worktree list -v
wtlsp = worktree list --porcelain
wtlsz = worktree list --porcelain -z
wtmv = worktree move
wtp = worktree prune
wtrm = worktree remove
wtrep = worktree repair
wtfix = wtrep
wtfsck = wtrep
wtlk = worktree lock
wtulk = worktree unlock
wtconfig = config --worktree
wtcfg = wtconfig
wtconf = wtconfig
### Working with subtrees and submodules
# Base shortcuts
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"
# Stash if needed, then fetch refs, fetch tags, fast-forward merge, and if stash was done, pop stashed changes. If something
# goes wrong, launch a clean Bash shell with no fancy prompts, no history, and a custom prompt for making repairs.
sync-up = "!_gf() { local -i RC=0 STASH_POP=0; if test -n \"$(git status -uno --porcelain --ignore-submodules=all)\"; then STASH_POP=1; git stash; fi; git fetch --all --recurse-submodules=yes && git fetch --all --tags && git merge --ff; RC=$?; if (( STASH_POP && !RC )); then git stash pop; RC=$?; fi; return ${RC}; }; _gf"
sup = sync-up
# Basically equivalent to "sync-up" above but includes some special handling for the Bash history file.
sync-up-home = "!_gf() { local STASH_POP=0 ; if test -n \"$(git status -uno --porcelain --ignore-submodules=all)\" ; then STASH_POP=1 ; git stash ; fi ; git fetch --all --recurse-submodules=yes && git fetch --all --tags && git merge --ff ; test $STASH_POP -eq 1 && (git stash pop || (git restore \"$(readlink -f \"${HISTFILE}\")\" && git stash pop || /bin/bash --noprofile --rcfile <( echo 'export GIT_PS1= PS1=\"[no-hist-sync] \\u@\\h \\w ${PCHAR:->}> \" PROMPT_COMMAND= HISTFILE=' ) -i); }; _gf"
shup = sync-up-home
# Switch to a local tracking branch and sync it up with the corresponding remote's equivalent branch (e.g., "dev" <- "origin/dev").
# The remote-tracking branch in the local repo is updated via "fetch," after which the local branch gets fast-forwarded to match.
sync-tracking-branch = "!_gf() { local OB='' SP='' TB=\"${1}\"; local -i RC=0 STASH_POP=0; OB=\"$(git rev-parse --abbrev-ref 2>/dev/null)\"; SP=\"$(git status -uno --porcelain --ignore-submodules=all)\"; STASH_POP=$(( ${#SP} > 0 ? 1 : 0 )); (( STASH_POP )) && git stash; git switch "${TB}" && git fetch --all --recurse-submodules=yes && git fetch --all --tags && git merge --ff; RC=$?; if (( STASH_POP && !RC )); then git stash pop; RC=$?; fi; if (( RC != 0 )); then /bin/bash --noprofile --rcfile <( echo 'export GIT_PS1= PS1=\"[no-hist-sync] \\u@\\h \\w ${PCHAR:->}> \" PROMPT_COMMAND= HISTFILE=' ) -i; RC=$?; fi; return ${RC}; }; _gf"
#ffb ### FIXME: WTF was this going to be, "fetch fuckinbranch" or something??!
tbsync = sync-tracking-branch
###############################################################################################################################
### Configuration for git-core, git-branch, etc.
[core]
abbrev = 8
# These are normally "true" but must be "false" on FAT, some NTFS, et al.
filemode = true
symlinks = true
#protectNTFS = true # Would this be good or bad??
# 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
# "Alternative" line-ending settings for non-UNIX platforms...maybe?
#eol = crlf
#autoCRLF = true
#safeCRLF = true
# Git-native permissions control; use only 1 of the values shown
#sharedrepository = group/true | all/world/everybody | umask/false | 0nnn
[branch]
# For *any* newly created branch, set it to rebase on update (i.e., pull)
autosetuprebase = always
sort = -authordate
[checkout]
guess = true
defaultRemote = origin
[clean]
# WARNING: This changes the "git clean" command to NOT require -f/--force!
requireForce = false
[commit]
# Always remove comment lines & extra whitespace, see git-commit(1)
cleanup = strip
# Includes HEAD..index diff in commit log message template
verbose = true
[diff]
tool = meld
prompt = false
mnemonicprefix = true
dirstat = lines,cumulative,10
[fetch]
parallel = 4
prune = true
pruneTags = false
recurseSubmodules = 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
[merge]
conflictstyle = diff3
log = true
# tool = diffuse
tool = meld
defaultToUpstream = 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
[rebase]
autoSquash = true
autoStash = true
stat = true
### REuse REcorded REsolution
[rerere]
autoUpdate = true
enabled = true
[stash]
showPatch = true
showStat = true
[status]
short = false
branch = true
aheadBehind = true
showStash = true
showUntrackedFiles = normal
submoduleSummary = true
[submodule]
recurse = true
fetchJobs = 4
[tag]
sort = -authordate
[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%C(reset)[%C(auto,cyan)%as%C(auto)]%d %C(auto,bold white)<%ae>%C(reset) %C(auto)%s%C(reset)
# 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 = [email protected]
coverletter = true
##headers = "Organization: Los Alamos National Laboratory\n"
numbered = true
pretty = medium
signature =
signoff = true
subjectprefix = PATCH
suffix = .patch
thread = deep
to = [email protected]
[sendemail]
smtpencryption = tls
smtpserver = smtp.gmail.com
smtpserverport = 587
smtpuser = [email protected]
thread = false
confirm = auto
[tar]
umask = 0022
[help]
autocorrect = 20
[url "git+ssh://[email protected]/"]
insteadOf = gh:
[url "git+ssh://[email protected]/mej/"]
insteadOf = ghm:
[url "git+ssh://[email protected]/hpc/"]
insteadOf = ghpc:
[url "git+ssh://[email protected]/kraken-hpc/"]
insteadOf = ghk:
[url "git+ssh://[email protected]/"]
insteadOf = bb:
[url "git+ssh://[email protected]/mej0/"]
insteadOf = bbm:
[url "git+ssh://[email protected]/"]
insteadOf = lgl:
[url "git+ssh://[email protected]/mej/"]
insteadOf = lglm:
[url "git+ssh://[email protected]:10122/"]
insteadOf = hgl:
[url "git+ssh://[email protected]:10122/mej/"]
insteadOf = hglm:
[url "git+ssh://[email protected]:10122/platforms/"]
insteadOf = hglp:
[url "git+ssh://[email protected]:10022/"]
insteadOf = cmgl:
[url "git+ssh://[email protected]:10022/mej/"]
insteadOf = cmglm:
[gui]
editor = emacs-w32 --no-desktop
[cola]
textwidth = 132
tabwidth = 4
[remote "origin"]
tagOpt = --tags
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment