--- /dev/null
+#!/bin/bash
+#
+# To start tracking a file,
+# cp ~/.screenrc dot/screenrc
+#
+# To sort out symlinks when things are clean
+# infra/makelinks install
+
+set -e -o posix -o pipefail
+
+badusage () {
+ echo >&2 "usage: $0 [-n|-v] list|setup|import|clean"
+ exit 18
+}
+
+real_act=''
+
+while true; do
+ if [ $# = 0 ]; then break; fi
+ case "$1" in
+ -n) real_act=log_only ;;
+ -v) real_act=with_log ;;
+ -*) badusage ;;
+ *) break ;;
+ esac
+ shift
+done
+
+case "$#.$1" in
+1.list|1.setup|1.import|1.clean) ;;
+*) badusage ;;
+esac
+
+mode=$1; shift
+
+dots=$( find dot -type f -name '[0-9a-zA-Z]*[0-9a-zA-Z]' )
+
+basepath=$(pwd)
+basepath=${basepath#$HOME/}
+
+estatus=0
+
+show () {
+ printf "%s\n" "$1"
+}
+
+good () {
+ if [ $mode = list ]; then
+ show "good: $dot: $1"
+ fi
+}
+
+bad () {
+ estatus=16
+ show "bad: $dot: $1" >&2
+}
+
+needs () {
+ if [ $mode = $1 ]; then
+ act=$real_act
+ else
+ show "needs $1: $prhome: $2"
+ act=:
+ fi
+}
+
+log_only () {
+ echo "x $*"
+}
+
+with_log () {
+ log_only "$@"
+ "$@"
+}
+
+for dot in $dots; do
+ underhome=".${dot#dot/}"
+ inhome="$HOME/$underhome"
+ prhome="~/$underhome"
+ if [ "$inhome" -ef "$dot" ]; then
+ good "already symlinked here"
+ elif [ -h "$inhome" ]; then
+ bad "wrong symlink target"
+ elif ! [ -e "$inhome" ]; then
+ needs setup "absent here"
+ $act ln -s "$basepath/$dot" "$inhome"
+ elif [ -f "$inhome" ] && cmp -s "$dot" "$inhome"; then
+ needs setup "identical here but not yet symlinked"
+ $act rm -f "$inhome"~
+ $act ln -s "$basepath/$dot" "$inhome"~
+ $act mv -f "$inhome"~ "$inhome"
+ else
+ needs import "modified here"
+ $act rm -f "$dot"~
+ $act cp "$inhome" "$dot"~
+ $act mv -f "$dot"~ "$dot"
+ fi
+done
+
+brokens=$(
+ cd $HOME
+ find -L .[0-9a-zA-Z]* -xdev -type l -lname "$basepath/dot/*"
+)
+for underhome in $brokens; do
+ inhome="$HOME/$underhome"
+ prhome="~/$underhome"
+ needs clean "symlink to removed file in dot/"
+ $act rm -f "$inhome"
+done