[user]
; Don't try to guess `user.name` and `user.email`.
useConfigOnly = true
[include]
path = ~/.gitconfig-user
[core]
; If the `LESS` environment variable is unset, Git (naively) prepends
; `LESS=FRX` to the shell expression given in `pager` (or it's
; default). `X` disables sending termcap (alternate screen)
; initialization and deinitialization strings to the terminal, which
; disables mouse scrolling and makes long text scroll past previous
; context.
; pager = LESS=FR less
pager = diff-highlight | LESS=FR less
; TODO: E.g. `attributesFile` defaults to
; `$XDG_CONFIG_HOME/git/attributes`. Maybe this is a better place to
; put these?
hooksPath = ~/.githooks
excludesFile = ~/.gitignore
attributesFile = ~/.gitattributes
; Print paths verbatim (e.g. UTF-8).
quotePath = false
; Disable newline conversion (mangling). This relies on editors *also*
; not doing any conversions or else you will get huge useless diffs.
; Also be aware of text files copied verbatim from somewhere else such
; as the internet. The Git default of having only LF in commits (autocrlf = false), but sometimes .
; autocrlf = input
; If we re-enable conversion (see above), reject on failed roundtrip.
safecrlf = true
; [pager]
; ; As suggested in `contrib/diff-highlight/README`, except as explained
; ; in `core.pager` above.
; log = diff-highlight | less -+X
; show = diff-highlight | less -+X
; diff = diff-highlight | less -+X
[interactive]
; TODO: It is untested if this is needed or happens by virtue of
; `core.pager`. Also untested if it has any ill effects.
diffFilter = diff-highlight
[init]
templateDir = ~/.gittemplate
defaultBranch = master
; defaultBranch = main
[remote]
pushDefault = origin
[push]
default = current ; This obviates `git push --set-upstream`.
; In the past, `current` was commented out and we used `upstream`
; instead, unsure why.
; default = upstream
recurseSubmodules = check
autoSetupRemote = true ; Git 2.37
[branch]
autoSetupMerge = always
autoSetupRebase = always
[fetch]
prune = true
pruneTags = true
[rebase]
autoSquash = true
autoStash = true
rebaseMerges = true
updateRefs = true
missingCommitsCheck = error
instructionFormat = %s%nexec GIT_COMMITTER_DATE='%ci' GIT_AUTHOR_DATE='%ai' git commit --amend --no-edit --reset-author
[pull]
rebase = merges
[merge]
ff = false
autoStash = true
conflictStyle = diff3
; TODO: `zdiff3` removes edge common lines but is too new?
; conflictStyle = zdiff3
[am]
threeWay = true
[rerere]
enabled = true
[diff]
renames = copies
algorithm = histogram
[url "ssh://git@"]
pushInsteadOf = https://
[protocol]
allow = never
[protocol "file"]
allow = always
[protocol "ssh"]
allow = always
[protocol "https"]
allow = always
[transfer]
fsckObjects = true
[fsck]
zeroPaddedFilemode = warn
badTimezone = warn
[receive "fsck"]
zeroPaddedFilemode = warn
badTimezone = warn
[fetch "fsck"]
zeroPaddedFilemode = warn
badTimezone = warn
[notes]
rewriteRef = refs/notes/commits
[format]
notes = true
[status]
showStash = true
submoduleSummary = true
[log]
; abbrevCommit = true
decorate = short
[log]
date = relative
[blame]
date = relative
[log]
graphColors = \
BrightRed, \
BrightGreen, \
BrightYellow, \
BrightBlue, \
BrightMagenta, \
BrightCyan
[diff]
wsErrorHighlight = all
colorMoved = zebra
colorMovedWS = ignore-space-change
[color "diff"]
; TODO: Harmonize with `vimdiff`?
; TODO: Use `dim` and remove `Bright`? Terminal support?
commit = BrightYellow
meta = BrightBlue
frag = Blue
func = Blue
context = BrightWhite
contextBold = BrightWhite reverse
contextDimmed = White reverse
old = BrightRed
oldBold = BrightRed reverse
oldDimmed = Red reverse
new = BrightGreen
newBold = BrightGreen reverse
newDimmed = Green reverse
oldMoved = BrightMagenta
oldMovedDimmed = BrightMagenta
oldMovedAlternative = Magenta
oldMovedAlternativeDimmed = Magenta
newMoved = BrightCyan
newMovedDimmed = BrightCyan
newMovedAlternative = Cyan
newMovedAlternativeDimmed = Cyan
whitespace = BrightRed reverse
[color "diff-highlight"]
; TODO: Harmonize with `vimdiff`?
oldNormal = BrightRed
newNormal = BrightGreen
oldHighlight = BrightRed Red
newHighlight = BrightGreen Green
[blame]
; coloring = repeatedLines
coloring = highlightRecent
[color "blame"]
; repeatedLines = White
highlightRecent = \
245, 2 years ago, \
246, 1 year ago, \
247, 6 months ago, \
248, 3 months ago, \
249, 1 months ago, \
250, 2 weeks ago, \
251, 1 weeks ago, \
252, 5 days ago, \
253, 2 days ago, \
254, 1 days ago, \
255
[absorb]
; https://github.com/tummychow/git-absorb
maxStack = 100
; [instaweb]
; ; TODO: There seems to be bugs with both `local` and `python` in
; ; `git-instaweb`! Look at, fix, and sumbit patches for them.
; local = true
; httpd = python
[pretty]
compact = tformat:%C(BrightYellow)%h%C(auto) %C(BrightWhite)%s%C(auto)%d
columnars = tformat:%C(BrightYellow)%h%x20%C(BrightMagenta)%>(13,trunc)%ar%x20%C(BrightBlue)%<(15,trunc)%aN%x20%C(BrightWhite)%s%C(auto)%d
columnart = tformat:%C(BrightYellow)%h%x09%C(BrightMagenta)%>(1 )%ar%x09%C(BrightBlue)%<(1 )%aN%x09%C(BrightWhite)%s%C(auto)%d
patch = format:%C(BrightYellow)commit %h%C(auto)%d%n%C(BrightYellow)Author: %aN <%aE>%n%C(BrightYellow)Date: %ad%n%n%C(Yellow)%s%n
[alias]
; All.
; TODO: `eval` the supplied command (if any), so that one can use pipes
; and other shell features? That would require one to type `git all git
; <git-command>` (i.e. repeat `git` twice) for Git commands though.
; Actually, borrow an idea from git aliases themselves? If the command
; starts with `!` then strip it and do `eval "$@"`, otherwise do `git
; "$@"`?
all = "!f() { : ; \
[ -t 1 ] && tty=true; \
git config --get-colorbool color.all && color_all=always; \
git config --get-colorbool color.ui && color_ui=always; \
find -L . -type d -name '*.git' -prune \
| sed 's#^\\./\\|/\\.git$##g' \
| LC_ALL=C sort \
| awk '{ \
for (parent in parents) \
if (index($0, parent \"/\") == 1) \
next; \
parents[$0]; \
print; \
}' \
| { \
if [ $# -eq 0 ]; \
then \
if [ \"$tty\" ]; \
then \
tree -n --fromfile; \
else \
cat; \
fi; \
else \
if [ $color_all ]; \
then \
get_color() { git -C \"$path\" config --get-color \"$@\"; }; \
color_reset=$(get_color '' reset); \
color_all_header=$(get_color color.all.header \"BrightWhite White\"); \
fi; \
while read -r path; \
do \
output=$(git -C \"$path\" -c color.ui=$color_ui \"$@\" 2>&1); \
[ \"$output\" ] || continue; \
printf '%s# %s%s\\n%s\\n\\n' \
\"$color_all_header\" \
\"$path\" \
\"$color_reset\" \
\"$output\"; \
done; \
fi; \
} \
| eval \"LESS=${LESS-FRX} $(git var GIT_PAGER)\"; \
}; f"
; Tree.
; This could have been basically `git ls-files | tree --fromfile` but
; `--fromfile` doesn't look at the filesystem at all and misses
; permission bits for coloring. Instead, we use `tree`'s `-P` and `-I`
; even though they can only match on file basenames, so this solution
; is quite brittle. Also, `git ls-files` quotes "unusual" charactes,
; even with `git -c core.quotePath=false`. The only way around that is
; to pass `-z` but of course that uses null separators, which shell
; command substitution doesn't handle. So to convert the nulls to
; newlines we have to thread the return code out through extra file
; descriptors as a string.. Unix is elegant, right? Yes, I know about
; `-o pipefail`, that POSIX is too new for me :) It mostly works.
; Actually, fuck it, it turns out `tree`'s `-P` and `-I` are not
; anchored, even though they support `*` but no anchoring mechanism, so
; we get even more false positives than expected, so we do without the
; absolutely correct coloring for now.
tree = "!f() { : git ls-files ; \
git config --get-colorbool color.tree && color_tree=always; \
files=\"$( \
((( \
(git ls-files -z \"$@\"; echo $? >&3) | sed 's/\\x00/\\n/g' >&4 \
) 3>&1) | exit $(cat)) 4>&1 \
)\" || return; \
printf '%s\\n' \"$files\" \
| tree -a -n ${color_tree+-C} --fromfile; \
return; \
dirs=\"$( \
printf '%s\\n' \"$files\" \
| sed -n 's#\\([^/]\\+\\)/.*#\\1#p' \
| sort -u \
| paste -sd '|' \
)\"; \
pattern=\"$( \
printf '%s\\n' \"$files\" \
| sed 's#/#\\n#g' \
| sort -u \
| paste -sd '|' \
)\"; \
ignore=\"$( \
find . \\! -name '.' -type d -prune \
| sed 's#^./##' \
| grep -Ev \"$dirs\" \
| paste -sd '|' \
)\"; \
tree -a -n ${color_tree+-C} \
--matchdirs \
--prune \
-P \"$pattern\" \
-I \"$ignore\"; \
}; f"
; Clone user repo
; `git clone-user-repo */$user/$repo` =>
; `git clone */$user/$repo $user/repo`
clone-user-repo ="!f() { : git clone ; \
url() { shift $(($#-1)); echo \"$1\"; }; \
url=\"$(url \"$@\")\"; \
url=\"${url%/}\"; \
repo=\"${url##*/}\"; \
user=\"${url%/*}\"; \
user=\"${user##*/}\"; \
git clone \"$@\" \"$user/$repo\"; \
}; f"
; Users.
users = "!f() { : git log ; \
git log --pretty=full \"$@\" \
| sed -n 's/^\\(Author\\|Commit\\): \\(.*\\)/\\2/p' \
| LC_ALL=C sort -u; \
}; f"
; Browse.
browse ="!f() { : ; \
[ $# != 0 ] || set -- $(git remote); \
for remote in \"$@\"; \
do \
url=\"$(git remote get-url \"$remote\")\"; \
printf '%s: %s\\n' \"$remote\" \"$url\"; \
{ [ $(command -v xdg-open) ] && xdg-open \"$url\"; } || \
{ [ $(command -v open) ] && open \"$url\"; } || \
{ [ $(command -v start) ] && start \"$url\"; } || \
true; \
done; \
}; f"
; Refdiff.
refdiff = "!f() { : git diff ; \
git config --get-colorbool color.diff && color_diff=always; \
git reflog --pretty='format:%h: %gs' \
| awk -F': ' '$2~/(commit|rebase).*\\((amend|finish)\\)/{print $1}' \
| while read -r ref; \
do \
git -c color.diff=$color_diff show --no-patch $ref; \
echo; \
git -c color.diff=$color_diff diff \"$@\" $ref HEAD; \
echo; \
done \
| eval \"LESS=${LESS-FRX} $(git var GIT_PAGER)\"; \
}; f"
; Reset user.
reset-user = "!f() { : git filter-branch ; \
name=\"$1\"; shift; \
email=\"$1\"; shift; \
git filter-branch --env-filter \" \
GIT_AUTHOR_NAME=\\\"$name\\\"; \
GIT_AUTHOR_EMAIL=\\\"$email\\\"; \
GIT_COMMITTER_NAME=\\\"$name\\\"; \
GIT_COMMITTER_EMAIL=\\\"$email\\\"; \
GIT_COMMITTER_DATE=\\\"\\$GIT_AUTHOR_DATE\\\"; \
\" \"$@\" ; \
}; f"
; Reset date.
reset-date = "!f() { : git filter-branch ; \
git filter-branch --env-filter ' \
sleep 1; \
date=\"$(date --iso-8601=s)\"; \
GIT_AUTHOR_DATE=\"$date\"; \
GIT_COMMITTER_DATE=\"$date\"; \
' \"$@\" ; \
}; f"
; Log.
; TODO: Add `--no-merges` and `--merges` (or `--first-parent`) aliases?
; They fit well with the workflow of my personal projects.
; TODO: If would be cool to add like a `=> ${u}` to the decoration to
; also show the tracking branch if any.
; TODO: Add `--shortstat` info?
; <https://til.codeinthehole.com/posts/how-to-add-commit-sizes-to-git-log-output/>
; TODO: Can we do nicer (Unicode) graphs?
; - <https://github.com/rbong/vim-flog/issues/49>
l = "!f() { : git log ; \
git config --get-colorbool color.diff && color_diff=always; \
git -c color.diff=$color_diff log --graph --pretty=columnart \"$@\" \
| sed -E 's/^([^\\t]+\\t[^\\t,]+)(,.+)? ago(.*\\t.*)$/\\1\\3/' \
| sed -E 's/^(.*) +(.*[0-9a-f]{7}.*\\t)/\\1\\t\\2/' \
| sed -E 's/ *$//' \
| column -t -o ' ' -s \"$(printf '\\t')\" \
| eval \"LESS=${LESS-FRX} $(git var GIT_PAGER)\"; \
}; f"
lb = log --topo-order --graph --pretty=compact --simplify-by-decoration ; `git-show-tree` from `git-extras` is similar.
ls = log --topo-order --graph --pretty=compact
ll = log --topo-order --graph --pretty=columnars
lp = log --topo-order --patch --pretty=patch --find-copies-harder --irreversible-delete
lpw = lp --color-words='[_[:alnum:]]+|[^[:space:]]'
lpww = lp --color-words='.'
la = l --all
lba = lb --all
lsa = ls --all
lla = ll --all
lpa = lp --all
lpwa = lpw --all
lpwwa = lpww --all
; Status.
s = status
ss = status --short
sb = status --short --branch
sa = s --ignored
ssa = ss --ignored
sba = sb --ignored
; Diff.
d = diff --find-copies-harder --irreversible-delete
du = diff --find-copies-harder --irreversible-delete @{upstream}
dp = diff --find-copies-harder --irreversible-delete @{push}
dc = d --cached
duc = du --cached
dpc = dp --cached
dw = d --color-words='[_[:alnum:]]+|[^[:space:]]'
duw = du --color-words='[_[:alnum:]]+|[^[:space:]]'
dpw = dp --color-words='[_[:alnum:]]+|[^[:space:]]'
dcw = dc --color-words='[_[:alnum:]]+|[^[:space:]]'
ducw = duc --color-words='[_[:alnum:]]+|[^[:space:]]'
dpcw = dpc --color-words='[_[:alnum:]]+|[^[:space:]]'
dww = d --color-words='.'
duww = du --color-words='.'
dpww = dp --color-words='.'
dcww = dc --color-words='.'
ducww = duc --color-words='.'
dpcww = dpc --color-words='.'
; Add.
au = add -u
aa = add -A
; Commit.
c = commit
ca = commit --amend
; Rebase.
ri = rebase -i --rebase-merges
ro = rebase -i --rebase-merges --root
rr = rebase --continue
; Fetch.
f = fetch
; Push.
p = push
pf = push --force-with-lease
; Clean ignored files (requires either `-f`, `-i` or `-n`).
x = clean -Xd
; Contains.
; contains = name-rev --name-only
contains = tag --contains
; contains = branch --contains
; contains = describe --contains