# hg version: 3.9.1
[ui]
askusername = True
verbose = False
ignore = ~/.hgignore
editor = vim
interface = curses
## To go back to using conflict markers, uncomment this line.
merge = internal:merge
mergemarkers = detailed
[web]
# allow_push = *
push_ssl = False
stripes=4
[phases]
publish = False
[diff]
git = True
nobinary = True
showfunc = True
[extensions]
rebase =
hgext.extdiff =
hgext.histedit =
color =
churn =
debugshell = $HOME/lib/mercurial-main/contrib/debugshell.py
evolve = $HOME/lib/hg-evolve/hgext3rd/evolve
guestrepo = $HOME/dotfiles/hg/guestrepo/guestrepo
hggit = $HOME/lib/hggit/hggit
## Don't enable this by default. If you really want to clean your
## directory, use `hg --config 'extensions.purge=' clean`
# purge =
pager =
prompt = $HOME/dotfiles/hg/hg-prompt/prompt.py
progress =
record =
share =
shelve =
whenfile = $HOME/dotfiles/hg/whenfile.py
[pager]
pager = LESS='FRX' less
ignore = version, update, serve, record
## Commands that I added to the default set: help, heads
attend = annotate, cat, diff, export, l, log, slog, gitlog,
filelog, qdiff, help, heads, mine, vlog, tags
quiet = True
[merge-patterns]
**.ipynb = nbdime
# The typical usage pattern for the webtool is like this::
# > hg merge <other branch>
# merging ***.ipynb
# 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
# use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
# > hg resolve --tool nbdimeweb
[extdiff]
cmd.extdiff = meld
cmd.nbdime = hg-nbdiff
cmd.nbdimeweb = hg-nbdiffweb
opts.nbdime = --log-level ERROR
[merge-tools]
kdiff3.args=--L1 base --L2 local --L3 other $base $local $other -o $output
nbdime.priority = 2
nbdime.premerge = False
nbdime.executable = hg-nbmerge
nbdime.args = $base $local $other $output
nbdimeweb.priority = 1
nbdimeweb.premerge = False
nbdimeweb.executable = hg-nbmergeweb
nbdimeweb.args = --log-level ERROR $base $local $other $output
nbdimeweb.gui = True
[alias]
# First, the various flavours of logging aliases
slog = log --graph --template slog
l = slog
vlog = log --graph --template vlog
testlog = log --graph --template '{label("log.branch", ifeq(branch, "default", "", branch))}'
gitlog = log --graph --template '\
{ifcontains("tip", tags, "\n\n")} \
{label("changeset.{true_phase}", node|short)} \
git:{gitnode|short} \
{maybe_branch}\
{maybe_bookmarks}\
{maybe_tags}\
-- \
{label("grep.user", author|person)} -- \
{label("log.date", date(date, "%Y-%m-%d %H:%m"))}\n\
_ {label("log.desc", desc|firstline)}'
# A log with changed files. Each file is on its own line and preceded by
# the rev number, to facilitate grepping.
filelog = log --removed --graph --template '\
{ifcontains("tip", tags, "\n\n")} \
{label("log.branch", branch)} -- {label("grep.user", author|emailuser)} -- \
{label("log.date", date|shortdate)} -- {rev}:{node|short}\n\
{label("log.desc", desc)}\n\
{file_dels % "del {rev}: {file}\n"}\
{file_copies % "chg {rev}: {filecopy}\n"}\
{file_adds % "add {rev}: {file}\n"}\
{file_mods % "mod {rev}: {file}\n"}\
\n'
# Then, all the other aliases, sorted alphabetically.
bm = bookmark
ci = commit -i
cim = commit -m
commmit = commit
# hg explicitmerge
# ----------------
#
# Given a history like this:
# o feature
# |
# o
# |
# o master
# |
# ~
# It is desirable to be able to explicitly merge the feature into master:
# o merge feature into master
# |\
# | o feature
# | |
# | o
# |/
# o master
# |
# ~
# Mercurial normally doesn't allow that, and expects you to just move the
# master bookmark forward (a 'fast forward merge'). Let's create an explicit
# merge commit, instead.
explicitmerge = ! \
incoming=$(echo $HG_ARGS | sed 's/.*explicitmerge //'); \
# Abort if the current commit and the incoming one are on diverged branches
if /usr/bin/test \
$( \
$HG log -r "($incoming and descendants(.)) or ($incoming and ancestors(.))" \
--template 'x' \
) != 'x' \
; then \
echo "The current commit and $incoming are on different branches"; \
echo "Use an ordinary merge."; \
exit 1; \
fi; \
# Merge the incoming into the current commit
$HG debugsetparents . $incoming \
# Use the code as present in the more recent parent.
$HG revert --all -r "last(sort($incoming or ., date))" \
# Commit the result
$HG commit
# Quickly get a feature's log
f = !$HG slog -r "feature($(echo $HG_ARGS| sed 's/^f //'))"
github = clone git+ssh://git@github.com:$1.git
# The pre-push.outgoing fails with `hg push -B mybookmark`, which is often used
# with git repos. `hg gitpush -B mybookmark` does its own, manual, outgoing
# call. Only problem is that it doesn't automatically find the target repo.
gitpush = !$HG outgoing --graph; $HG $(echo $HG_ARGS | sed 's/gitpush/push/') --config 'hooks.pre-push.outgoing='
# Example invocation:
# hg git-delete-remote default/bad-branch
gitremotedelete = ! \
if echo "$HG_ARGS" | grep '/'; then
remote=`echo $HG_ARGS | sed 's_/.*__' | sed 's_.* __'`;
branch=`echo $HG_ARGS | sed 's_.*/__'`;
remote_url=$($HG paths $remote | sed 's_^git+ssh://__');
git_dir=$($HG root)/.hg/git;
echo "# Deleting remote branch"
git --git-dir=$git_dir push $remote_url :$branch;
echo "# Deleting local ref to remote branch"
git --git-dir=$git_dir branch -rd $remote/$branch;
echo "# Deleting local branch"
git --git-dir=$git_dir branch -D $branch
echo "Don't forget to run "'`'"hg bookmark -d $branch"'`'
else
echo 'Usage:' &&
echo ' hg gitremotedelete <remote>/<branchname>' &&
exit 1
fi
heads = heads --template '{branch} : {rev}\n'
headss = !$HG heads --template '{branch} : {rev} : {node|short}\n' | sort | column -s: -t
# Imagine the `convert` extension (for the `convert` command) is not enabled
# This does not work: `hg help convert`
# This works, but is long: `hg help --config extensions.convert= convert`
# So, `helpext` to the rescue
#
# Usage:
# hg helpext [EXTENSION] [ARGS]
# hg helpext convert convert # Help on the `convert` command
# hg helpext convert -e convert # Help on the `convert` extension
#
# A single arg is interpreted both as extension and as topic:
# hg helpext convert # Help on the `convert` command
helpext = ! \
extension=$(echo "$HG_ARGS" | sed 's/^\(helpext\|exthelp\) //' | sed 's/ .*//');
topic=$(echo "$HG_ARGS" | sed 's/^\(helpext\|exthelp\) //' | sed 's/^[a-z]* //');
$HG help --config extensions.${extension}= $topic
exthelp = helpext
lstatus = ! \
args="$( \
echo "$HG_ARGS" | \
sed 's/\(^lstatus\|^lstatu\|^lstatu\|^lstat\|^lsta\|^lst\) \?//' | \
sed 's/^$/./' \
)";
hg status --verbose --config 'commands.status.relative=True' $args
# Show commits made by me
mine = slog -r 'mine()'
# Quickly create a new test commit. E.g. commit 3 will create a file `f3`. This
# is nice when you want to quickly create some history in a test repository.
# The naming guideline comes from here:
# https://www.mercurial-scm.org/wiki/WritingTests#A_naming_scheme_for_test_elements
newcommit = !
# new rev number: current tip commit + 1
oldrev=$($HG id --hidden -r 'last(sort(head(), "rev"))' --num 2> /dev/null || echo "-1")
rev=$(echo $oldrev + 1 | bc);
touch f$rev;
chg add f$rev;
chg commit -m $rev;
relist = resolve -l
remark = resolve -m
reunmark = resolve -u
personal = !
echo '[ui]' >> $(hg root)/.hg/hgrc;
echo 'username = Sietse Brouwer <sbbrouwer@gmail.com>' >> $(hg root)/.hg/hgrc
praise = blame --quiet --user --date --number
# Short aliases, because pu is {push,pull}
p = push
f = pull # fetch
# Open the repository's hgrc file, or else the user hgrc
rc = !$HG config --local 2> /dev/null || $HG config --edit
# Summarize status
s = !$HG diff; $HG status --verbose
sta = status --all --verbose
stash = !echo 'You meant `hg shelve`'
show = !\
revision=$(echo $HG_ARGS | sed 's/show\( -r\)\? \?//');
if /usr/bin/test x${revision}x = xx; then
$HG log -pr .;
$HG slog -r 'family(.) or (descendants(.) and head()) or tip';
else
$HG log -pr $revision;
$HG slog -r "family($revision) or (descendants(.) and head()) or tip";
fi
tagdate = log -r 'tag()' --template '\
{label("log.date", date|shortdate)} -- {rev} -- {label("log.tag", tags)}'
tagdates = tagdate
toecho = !
name=$(basename $(hg root))
remote="ssh://echo//home/sietse/hg/$name"
$HG clone . $remote &&
echo "[paths]" &&
echo "echo = $remote"
# hg versions:
# Place multiple versions of file in directory, for easy comparison when
# resolving conflicts.
# * file -- the file, possibly half-merged already
# * file.local -- file as it is in the receiving (current) branch
# * file.other -- file as it is in the donating (merged) branch
# * file.base -- file as it is in the first common ancestor
versions = !
f=${HG_ARGS#versions }
p1=$($HG id --id -r 'p1()')
p2=$($HG id --id -r 'p2()')
$HG cat -r $p1 $f > $f.local &&
echo $f.local;
$HG cat -r $p2 $f > $f.other &&
echo $f.other;
$HG cat -r "ancestor($p1, $p2)" $f > $f.base &&
echo $f.base
wip = log --graph -r wip --style wip
work = !
echo '[ui]' >> $(hg root)/.hg/hgrc;
echo 'username = Sietse Brouwer <s.brouwer@anchormen.nl>' >> $(hg root)/.hg/hgrc
structure = slog -r structure
[hooks]
# After pulling, show a graph of the changes that came in.
pre-pull.incoming = $HG id -n -r tip > $($HG root)/.hg/tip-pre-pull
post-pull.incoming = OLDTIP=$(cat $($HG root)/.hg/tip-pre-pull) &&
$HG slog --pager=none -r "rev($OLDTIP):tip - rev($OLDTIP)"
# Show graph of outgoing changes before pushing
pre-push.outgoing = $HG outgoing --graph `echo ${HG_ARGS#push} | sed 's/--new-branch//'`
# Abort commits that introduce trailing whitespace.
# pretxncommit.whitespace = python:$HOME/dotfiles/hg/hooks/whitespace.py:hook
post-init.username = echo '[hg personal / hg work]'
post-clone.username = echo '[hg personal / hg work]'
# Before running extdiff, print the id of each revision
pre-extdiff.rev_ids = \
$HG id -nibtB -r "$(echo $HG_ARGS | sed 's/.* -r \(.*\) -r \(.*\)/\1/')"; \
$HG id -nibtB -r "$(echo $HG_ARGS | sed 's/.* -r \(.*\) -r \(.*\)/\2/')";
[revsetalias]
wip = (parents(not public()) or not public() or . or head()) and not closed()
family($1) = $1 or parents($1) or children($1)
feature($1) = _firstancestors($1) and not _firstancestors(master)
feat($1) = feature($1)
mine() = user("Brouwer")
# pp1 is 'first parents', like p1 is 'first parent';
# compare pp 'pages' and p 'page'.
pp1($1) = _firstancestors($1)
structure_heads = master or not(ancestors(master))
structure = structure_heads or ancestor(structure_heads)
# In hg-git repos, remote branch pointers are represented as tags of the form
# `default/...` or `origin/...`; so let's find all tags containing `/`.
git_public() = ancestors(tag('re:/'))
gitupstream() = tag('re:/')
gitdraft() = not(git_public())
# branches or tags or localtags or bookmarks or ...
isnamed = named("re:.*")
[templatealias]
# phase detection that is robust to hg-git repos
true_phase = ifcontains(rev, revset("git_public()"), "public", "{phase}")
# This is what the maybe_x templates do: if x exists, print x followed by a
# space. If it doesn't, print neither the x nor the space.
maybe_bisect = '\
{label("bisect.{bisect}", bisect)}\
{ifeq(bisect, "", "", " ")}'
maybe_branch = '\
{label("log.branch", ifeq(branch, "default", "", branch))}\
{ifeq(branch, "default", "", " ")}'
maybe_bookmarks = '\
{label("log.bookmark", bookmarks)}\
{ifeq(bookmarks, "", "", " ")}'
maybe_tags = '\
{label("log.tag", tags)}\
{ifeq(tags, "", "", " ")}'
[templates]
# The two blank lines atop the tip revision: I have a fat prompt. When I exit a
# pager like `less`, the top two lines scroll off the screen, which is annoying
# when you want to copy the tip's node id.
# * two blank lines at the top
# * graph-friendly underscores
# * narrow: two lines
# * hg hashes
# The first line should have TWO spaces before the backslash!
# Otherwise the first and second lines won't align.
slog = '\
{ifcontains("tip", tags, "\n\n")} \
{label("changeset.{true_phase}", rev)} \
{maybe_branch}\
{maybe_bookmarks}\
{maybe_tags}\
-- \
{label("grep.user", author|person)} -- \
{label("log.date", date(date, "%Y-%m-%d %H:%m"))} -- \
{label("changeset.{true_phase}", node|short)}\n\
_ {label("log.desc", desc|firstline)}'
# Like slog, but with the full description
vlog = '\
{ifcontains("tip", tags, "\n\n")} \
{label("changeset.{true_phase}", rev)} \
{maybe_branch}\
{maybe_bookmarks}\
{maybe_tags}\
-- \
{label("grep.user", author|person)} -- \
{label("log.date", date|shortdate)} -- \
{label("changeset.{true_phase}", node|short)}\n\
_ {label("log.desc", desc)}'
# Computing the implicit bisect status of every changeset is an expensive
# operation, so let's segregate that in a separate log-style command.
bisectlog = '\
{ifcontains("tip", tags, "\n\n")} \
{maybe_bisect}\
{label("changeset.{true_phase}", rev)} \
{maybe_branch}\
{maybe_bookmarks}\
{maybe_tags}\
-- \
{label("grep.user", author|person)} -- \
{label("log.date", date|shortdate)} -- \
{label("changeset.{true_phase}", node|short)}\n\
_ {label("log.desc", desc|firstline)}'
[color]
mode = terminfo
#Custom colours
color.orange=202
color.lightyellow=191
color.darkorange=220
color.brightyellow=226
#Colours for each label
log.author=cyan
log.branch=green
log.summary=white
log.desc=yellow
log.bookmark=cyan bold
log.tag=green bold
log.graph=blue
log.date=red
changeset.public=
changeset.secret=blue bold
changeset.draft=yellow bold
# Colours for bisect statuses
bisect.good = green
bisect.bad = red
bisect.skipped = blue
bisect.untested = orange
bisect.ignored = cyan
desc.here=bold blue_background
[committemplate]
# FIXME: show previous commit messages
# {revset('parents(%d)', rev) % '{desc|firstline}\n'}
changeset = {desc}\n\n
HG: Enter commit message. Lines beginning with 'HG:' are removed.
HG: {extramsg}
HG: --
HG: user: {author}\n{ifeq(p2rev, "-1", "",
"HG: branch merge\n")
}HG: branch '{branch}'\n{if(activebookmark,
"HG: bookmark '{activebookmark}'\n") }{subrepos %
"HG: subrepo {subrepo}\n" }{file_adds %
"HG: added {file}\n" }{file_mods %
"HG: changed {file}\n" }{file_dels %
"HG: removed {file}\n" }{if(files, "",
"HG: no files changed\n")}
HG: ------------------------ >8 ------------------------
HG: Do not touch the line above.
HG: Everything below will be removed.
{diff()}
[hostfingerprints]
github.com = a0:c4:a7:46:00:ed:a7:2d:c0:be:cb:9a:8c:b6:07:ca:58:ee:74:5e
bitbucket.org = 3f:d3:c5:17:23:3c:cd:f5:2d:17:76:06:93:7e:ee:97:42:21:14:aa
[experimental]
copytrace = heuristics
# Include private settings
# ========================
%include ~/dotfiles/secrets/hgrc
%include ~/.hgrc-local