# -*- mode: conf -*- [DEFAULT] # --- global settings # avoid hangs due to SSH connection sharing jobs = 1 # custom actions to be configured repository-by-repository, that do # nothing by default git_sync = : git_rebase = : git_autoci = : # avoid pushing non-matching branches, while trying to avoid errors # from trying to push to read-only remotes git_push = git push-all # find dirty working directories, i.e., uncommitted changes, untracked # files and stashes git_isclean = git is-clean # --- Plugin for dgit repos # actually shipped with upstream mr, but use an include command that # will always work include = cat ~/src/dotfiles/lib/mr/dgit # --- git-svn # include = [ -e "/usr/share/mr/git-svn" ] && cat /usr/share/mr/git-svn # --- Sensible pulls # Redefine git_update to avoid an unconditional `git pull`, which can # result in unwanted merge commits all over $HOME (this has to come # after we include the dgit lib, which also redefines git_update) git_update = git pull-safe # --- Adam Spiers' plugin for managing dotfile symlinks with mr # actually shipped with upstream mr, but use an include command that # will always work include = # stow is not available on Windows if [ -e "$HOME/src/dotfiles/lib/mr/stow" ] \ && ! [ "$(perl -e 'print $^O')" = "msys" ]; then cat "$HOME/src/dotfiles/lib/mr/stow" fi # --- joeyh's code for specifying what machine we're on for repo skip # --- tests, plus my code for detecting Git-on-Windows lib = win32() { test "$(perl -e 'print $^O')" = "msys" } # if win32; then hostname=$(hostname) else hostname=$(hostname -s) fi # whoami="$(whoami)" # cut off the machine name on Windows win32 && whoami=${whoami##*\\} # on() { for host in $@; do if [ "${host%@*}" != "${host#*@}" ]; then if [ "$whoami" != "${host%@*}" ]; then continue fi host="${host#*@}" fi if [ "$hostname" = "$host" ]; then return 0 fi done return 1 } workstation() { on swhitton@zephyr spwhitton@hephaestus spwhitton@melete } mine() { workstation || on spwhitton@athena } # tucson() { # on artemis shortgeese athena hephaestus iris melete # } # --- run a command on athena in a sane environment # lib = # athena_cmd () { # # here we rely on the fact that ssh already passes argument # # through `/bin/sh -c' (note use of single-quotes in this # # function) # ssh athena 'cd $HOME/'"$1"' && . $HOME/.shenv && '"$2" # } # --- standard procedures lib = homedir_mkdirs() { ( cd $HOME mkdir -p \ .ssh \ tmp \ src \ lib \ mnt \ # lib/athena \ lib/backup \ local/mutt \ # local/anacron/spool \ local/src \ local/bin \ local/big \ local/lib \ local/log \ local/pub \ local/tmp \ local/auth \ local/info chmod 700 local/auth # [ -L "src/build-area" ] || ln -s -T /tmp/debuild src/build-area [ -e "Downloads" ] || ln -s tmp Downloads # clean up after additions to .stow-local-ignore find bin lib/aid lib/perl5 lib/hooks \ -type l 2>/dev/null | while read -r link; do if readlink "$link" | grep --quiet "^[../]*/.STOW/"; then rm "$link" fi done # cleanup some old dirs if they're empty find \ bin \ lib/aid \ lib/perl5 \ lib/hooks \ lib/athena \ local/anacron/spool \ -type d -empty -delete 2>/dev/null ||: ) } # specify files that should automatically be adopted because # programs convert them from symlinks to regular files. Arguments # to this function should be paths relative to the stow target # (usually $HOME) always_adopt () { for f in $@; do if ! [ -L "$STOW_TARGET/$f" ]; then # ignore errors; if it doesn't work, the user will # have to fix up manually mv 2>/dev/null "$STOW_TARGET/$f" "$MR_REPO/$f" || true fi done } # export plain text Org agenda in post_ hooks of ~/doc repo (not currently used) export_org_agenda () { if on athena; then emacs --batch -l ~/.emacs.d/init.el -eval '(org-batch-agenda "a")' 2>/dev/null \ >~/local/priv/agenda.txt else emacs --batch -l ~/.emacs.d/init.el -eval '(org-batch-agenda "a")' 2>/dev/null \ | ssh athena "cat >/home/spwhitton/local/priv/agenda.txt" fi } # --- primary dotfiles repository # TODO we need to unstow before switching branches, and stow # afterwards, or else do some sort of automatic cleanup of dangling # symlinks before a restow, so a broken situation is easy to fix? # Also see kill-broken-stowed-symlink() in .bashrc. # # Note that the scan is expensive. So actually we probably don't want # the cleanup to happen automatically. Also, it should exclude # lib/annex, src/*/ (but not src/) because I don't stow files into # those dirs. # # Maybe just run it as part of sysmaint # # Hmm. Situation is not as bad as I thought. stow manages to clean # up quite a few of the symlinks. So running it as part of sysmaint # seems like a sufficient fix [src/dotfiles] checkout = git clone https://git.spwhitton.name/dotfiles.git dotfiles stowable = true # we have a script to update master, and all other branches should # only be checked out and committed to on a single host update = git dotfiles-update-master push = git push origin master # use `git dotfiles-rebase` instead # rebase = # # usual rebasing pattern. Per dotfiles repo policy (excluding # # win32 case), the branch being rebased will always be rebaseable # # on master, since it is only checked out and committed to on this # # host # branch="$(git rev-parse --abbrev-ref HEAD)" # hostname="$(hostname -s)" # if [ "$branch" = "win32" -o "$branch" = "$hostname" -o "$branch" = "develacc-$hostname" ]; then # git rebase master # fi fixups = # Use a rebase workflow as I'm the only committer git config pull.rebase true # Pushing and pulling are always done explicitly for head in $(git for-each-ref --format='%(refname)' refs/heads/); do branch=$(echo "$head" | cut -d/ -f3) git branch --unset-upstream "$branch" 2>/dev/null || true done git config push.default nothing # this is just for M-x magit-status git config remote.pushDefault origin # if win32; then ( cd ~/src/dotfiles/bin && cmd "/C win32setup.bat" ) else $HOME/src/dotfiles/bin/normalise-mrconfig # homedir_mkdirs chmod -Rf u+rwX,go= $HOME/local/auth/* || true fi # eventually move the following three lines from fixups to post_checkout install-git-hooks dotfiles git config commit.gpgsign true git config user.signingkey 8DC2487E51ABDD90B5C4753F0F56D0553B6D411B # clean-ups so that initial stow will be successful pre_stow = homedir_mkdirs $HOME/src/dotfiles/bin/unskel # these will often end up created, e.g. by insinuate-dotfiles script rm -f $HOME/.gnupg/{gpg.conf,gpg-agent.conf,dirmngr.conf,.gpg-v21-migrated} # this file frequently gets desymlinked pre_unstow_append = always_adopt .config/mimeapps.list pre_restow_append = always_adopt .config/mimeapps.list pre_stow_append = always_adopt .config/mimeapps.list pre_update_append = always_adopt .config/mimeapps.list # --- private dotfiles repositories [lib/priv] checkout = git clone athenag:libpriv.git priv update = git annex sync --content cloud origin push = git annex sync --content cloud origin stowable = true skip = lazy post_checkout = cd priv git annex init git annex enableremote cloud git annex group . backup fixups = chmod 600 .passwddb.pet \ .gnupg/*.kbx \ .gnupg/private-keys-v1.d/*.key \ .ssh/id_* git config push.default nothing git config remote.origin.gcrypt-publish-participants true git config remote.origin.gcrypt-participants 0x0F56D0553B6D411B git config annex.startupscan false git config annex.autocommit true # needed for `git annex sync` git config remote.origin.annex-ignore true git config unpushed-tags.ignore true git config annex.gitaddtoannex false # see README git config annex.addunlocked true # see README git config mrrepo.review-unused false autoci = git annex add .passwddb.pet .labbook.gpg .gnupg/pubring.kbx git commit -a -m \ "auto passwddb, pubring and labbook commit on $(hostname -s)" || true pre_update = mr autoci # since dotfiles repo also stows into ~/.gnupg, and athpriv repo stows # into ~/.duply, make the dirs first pre_stow = homedir_mkdirs post_stow = load-trustdb [src/athpriv] checkout = git clone athenap:athpriv athpriv stowable = true skip = ! mine # since priv repo also stows into ~/.duply, make the dir first pre_stow = homedir_mkdirs # r2e always desymlinks this file pre_stow_append = always_adopt .config/rss2email.cfg pre_unstow_append = always_adopt .config/rss2email.cfg pre_restow_append = always_adopt .config/rss2email.cfg pre_update_append = always_adopt .config/rss2email.cfg # --- hosts configuration [src/propellor] checkout = git clone athena:propellor propellor --branch spw3conf post_checkout = cd propellor # get new release tags for merging into 'spw3conf' and 'debian' branches git remote add -f upstream https://git.joeyh.name/git/propellor.git # This hook sets up .dir-locals.el to make it easier to follow # Propellor's coding style. We have to use a hook because # .dir-locals.el and the cabal sandbox must be nuked when working # with dgit on the 'debian' branch install-git-hooks propellor echo ".dir-locals.el" >>.git/info/exclude fixups = # check that the link isn't already in place before making the link # because otherwise we get an infinite loop of links that breaks propellor [ -L ~/.propellor ] || ln -sf ~/src/propellor ~/.propellor # my preferences when using propellor for configuring my own machines git config propellor.spin-branch spw3conf git config propellor.forbid-dirty-spin true git config --local sendemail.to "Joey Hess " skip = ! workstation # --- personal website source [src/wiki] checkout = git clone athena:wiki skip = ! mine # --- misc. source repos with special config (e.g. installation of git # --- hooks) [src/dgit] checkout = git clone salsa:dgit-team/dgit post_checkout = cd dgit git remote add -f athena athena:dgit dgit setup-new-tree install-git-hooks dgit skip = lazy # [src/ublock-origin] # checkout = git clone 'https://anonscm.debian.org/git/pkg-mozext/ublock-origin.git' 'ublock-origin' # # beta, rc and alpha tags get deleted by upstream so there will very # # often be unpushed tags # push = git push-all --no-tags # skip = lazy [src/grml-live] checkout = git clone athena:grml-live -b spw/std post_checkout = cd grml-live git remote add -f upstream github:grml/grml-live fixups = git config commit.gpgsign true skip = lazy [src/mailscripts] checkout = git clone 'athena:mailscripts' 'mailscripts' post_checkout = cd mailscripts install-git-hooks mailscripts git config branch.buster-bpo.signOffOptional true dgit fetch buster-backports; dgit fetch sid skip = ! workstation [src/p5-Git-Annex] checkout = git clone athena:p5-Git-Annex p5-Git-Annex post_checkout = cd p5-Git-Annex install-git-hooks p5-Git-Annex git remote add -f salsa salsa:perl-team/modules/packages/libgit-annex-perl git branch --track debian salsa/master git config branch.debian.signOffOptional true git config branch.buster-bpo.signOffOptional true skip = lazy [src/p5-API-GitForge] checkout = git clone athena:p5-API-GitForge p5-API-GitForge post_checkout = cd p5-API-GitForge install-git-hooks p5-API-GitForge git remote add -f salsa salsa:perl-team/modules/packages/libapi-gitforge-perl git branch --track debian salsa/master git config branch.debian.signOffOptional true skip = lazy [src/org-d20] checkout = git clone 'athena:org-d20' 'org-d20' post_checkout = cd org-d20 install-git-hooks org-d20 skip = lazy [src/haskell-tab-indent] checkout = git clone 'athena:haskell-tab-indent' 'haskell-tab-indent' post_checkout = cd haskell-tab-indent install-git-hooks haskell-tab-indent skip = lazy [src/git-remote-gcrypt] checkout = git clone 'athena:git-remote-gcrypt' 'git-remote-gcrypt' post_checkout = cd git-remote-gcrypt install-git-hooks git-remote-gcrypt skip = ! workstation [src/pandoc-citeproc-preamble] checkout = git clone 'athena:pandoc-citeproc-preamble' 'pandoc-citeproc-preamble' post_checkout = cd pandoc-citeproc-preamble install-git-hooks pandoc-citeproc-preamble skip = lazy [src/cl/consfigurator] checkout = git clone 'athenap:consfigurator' 'consfigurator' post_checkout = cd git-remote-gcrypt install-git-hooks consfigurator skip = lazy [src/notmuch] checkout = git clone 'https://git.notmuchmail.org/git/notmuch' 'notmuch' fixups = git config --local sendemail.to notmuch@notmuchmail.org skip = lazy [src/linux] checkout = git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux skip = lazy [src/sbcl] checkout = git -c fetch.fsckobjects=false clone https://git.code.sf.net/p/sbcl/sbcl skip = lazy # --- radicale collections [lib/radicale] checkout = git clone athenap:radicale radicale skip = ! on spwhitton@athena # could use /usr/share/mr/git-annex helper to simplify the following # configuration of annexes (overriding its update definition to avoid # --content) but probably not flexible enough for all that's going on # in the below # --- primary git annex [lib/annex] checkout = git clone athenag:annex.git annex post_checkout = cd annex git annex init git annex enableremote athena rsyncurl=athena:/srv/rsync/annex skip = ! workstation update = git annex sync --no-content origin # disabled because required yubikey # sync = git annex sync --no-content origin push = git annex sync --content origin athena fixups = git config push.default matching git config remote.origin.gcrypt-publish-participants true git config remote.origin.gcrypt-participants 0x0F56D0553B6D411B # git config gcrypt.publish-participants true # git config gcrypt.participants 0x0F56D0553B6D411B git config annex.startupscan false git config annex.autocommit true # needed for `git annex sync` git config remote.origin.annex-ignore true git config unpushed-tags.ignore true [annex] checkout = git clone athenag:annex19.git annex update = git annex sync --no-content origin push = git annex sync --content cloud origin skip = lazy post_checkout = cd annex git annex init git annex enableremote cloud fixups = git config push.default nothing git config remote.origin.gcrypt-publish-participants true git config remote.origin.gcrypt-participants 0x0F56D0553B6D411B git config annex.startupscan false git config annex.autocommit true # needed for `git annex sync` git config remote.origin.annex-ignore true git config unpushed-tags.ignore true # --- personal website big files annex [lib/wikiannex] checkout = git clone athena:wikiannex.git # this repo uses direct mode on athena, so status won't work status = git annex status post_checkout = cd wikiannex git annex init git config remote.origin.annex-ignore false # ^ the git-annex-init sets this wrong # if workstation; then # git remote add bkupsd /media/${USER}/bkupsd/git/athena/wikiannex.git # git remote add m3 /media/${USER}/m3/git/athena/wikiannex.git # fi update = git annex sync --no-content # no pull in direct mode push = git annex sync --content skip = lazy fixups = git config unpushed-tags.ignore true if [ "$(hostname -s)" = "athena" ]; then git annex adjust --hide-missing --unlock fi # --- git annex for university stuff [lib/dionysus] checkout = git clone athenap:dionysus post_checkout = cd dionysus git annex init on athena || git remote add athena athenah:lib/dionysus status = git annex status update = git annex sync --no-content push = git annex sync --content sync = sync-for-dionysus # origin remote is just for keeping a backup copy of metadata. athena # remote, in $HOME on athena, contains a copy of content. At present, # origin remote only updated by sysmaint script (run weekly) fixups = git config push.default matching git config annex.startupscan false git config annex.autocommit true # needed for ga sync git config annex.addunlocked true # for simplicity with existing workflows git config remote.origin.annex-ignore true git config mrrepo.review-unused false git config unpushed-tags.ignore true skip = lazy # --- git annex for podcasts # [lib/podcasts] # checkout = git clone athenap:podcasts # post_checkout = # cd podcasts # git annex init # status = git annex status # update = git annex --no-content sync # push = git annex --no-content sync # # origin remote is just for keeping a backup copy of metadata. athena # # remote, in $HOME on athena, contains a copy of content. At present, # # origin remote only updated by sysmaint script (run weekly) # fixups = # git config push.default matching # git config annex.startupscan false # git config annex.autocommit true # needed for ga sync # git config remote.origin.annex-ignore true # skip = ! workstation # --- git annex for use with rtorrent # [lib/rt] # checkout = git clone athenag:rt.git rt # post_checkout = # cd rt # git annex init # if [ -d "$(hostname -s)" ]; then # mkdir -p $HOME/local/rt # cd $HOME/local/rt # touch .duplicity-ignore # mkdir -p session incomplete # if ! [ -e "complete" ]; then # ln -s $HOME/lib/rt/complete complete # fi # if ! [ -e "watch" ]; then # ln -s $HOME/lib/rt/$(hostname -s) watch # fi # fi # status = git annex status --fast # update = git annex sync --no-content origin # push = git annex sync --no-content origin # autoci = (git annex add . && git commit -m "auto commit on $(hostname -s)") || true # fixups = # git config push.default matching # # git config gcrypt.publish-participants true # git config remote.origin.gcrypt-publish-participants true # git config remote.origin.gcrypt-participants 0x0F56D0553B6D411B # git config annex.startupscan false # git config annex.autocommit true # needed for `git annex sync` # git config remote.origin.annex-ignore true # git config unpushed-tags.ignore true # skip = lazy # pre_update = mr autoci # --- git annex for athena's apt repository [lib/athena-apt] checkout = git clone athena:athena-apt athena-apt post_checkout = cd athena-apt git annex init --version=7 git annex enableremote athena git annex get . skip = lazy update = git annex sync --no-content push = git annex add git annex unlock db git annex sync --content athena git annex sync origin ssh athena find /srv/www/debian -type f -exec chmod 644 '{}' + ssh athena find /srv/www/debian -type d -exec chmod 755 '{}' + fixups = git config push.default matching git config annex.startupscan false git config annex.autocommit true # needed for `git annex sync` git config remote.origin.annex-ignore true git config annex.thin true git config annex.addunlocked true git config mrrepo.review-unused false git config remote.athena.annex-tracking-branch master # The git-diff-files(1) call in ~/bin/git-is-clean fails in v7 # git-annex repos with unlocked empty files, which this repo often # has: empty Packages files. So can't use that script in this repo isclean = output="$(git annex status)" test -z "$output" || ( echo $output && exit 1 ) [lib/realloc] checkout = git clone athenap:realloc realloc skip = ! mine [lib/nmbug-spw] checkout = nmbug-spw clone athenap:nmbug-spw update = nmbug-spw pull push = nmbug-spw push status = nmbug-spw status | grep -v "^U\s" || true # `nmbug status` does not catch committed but unpushed changes git --no-pager log --branches \ --not --remotes \ --simplify-by-decoration --decorate --oneline log = nmbug-spw log commit = nmbug-spw commit # Should be safe to commit a small number of local changes. We're # trying to avoid: # - wiping out git because db contains no spw:: tags (`nmbug # checkout` needed) # - doing any committing when there are known remote changes. autoci = nmbug-spw status | perl -ne'/^.[a-z]\s/ || $. > 500 and exit 1' \ && nmbug-spw commit skip = ! [ -e "$HOME/local/auth/fmailsyncpass" ] # --- my personal documents. Override my global update command back # --- to the myrepos default so that git automatically pulls and # --- merges. Skipped on non-local hosts [doc] checkout = git clone athenap:doc doc update = git pull "$@" skip = ! mine # set file modification times to last commit for deft.el # (commented out because no longer using deft) #fixups = git-utime # before pulling, automatically commit in the same way that my cron job does pre_update = win32 || doccheckin # ... and let me do it manually autoci = doccheckin || true # quick syncs sync = doccheckin && git pull && git push # --- static websites on web host boxes [public_html] clone = git clone https://git.spwhitton.name/sageweb public_html skip = ! on spwhitton@sage [html] clone = git clone https://git.spwhitton.name/sdfweb html skip = ! [ "$(domainname)" = "SDF" ] # --- my offline e-mail (& machine's postfix queue) [.fmail] checkout = mkdir ~/.fmail movemymail sync = movemymail update = movemymail push = movemymail status = : clean = : commit = : record = : fetch = : diff = : log = : grep = : autoci = : isclean = : skip = ! [ -e "$HOME/local/auth/fmailsyncpass" ] # this is slower than other repos for which sync is defined, so have # it go last order = 12