# -*- mode: conf -*- # --- global settings [DEFAULT] git_gc = git gc "$@" # Just a single job for now because otherwise sometimes hangs due to # SSH connection sharing. jobs = 1 # actions to be configured per repository git_sync = : git_rebase = : git_autoci = : # In general, I don't want merge commits to be made en masse by mr git_update = git remote update; git pull --ff-only "$@" # `mr -ms status` is a great way to check for unpushed branches and # unchecked in files, but what about checking only for the latter? git_isclean = ( # 1st line: check HEAD versus index # 2nd line: index versus working tree # 3rd line: untracked files git diff-index --quiet --cached HEAD && \ git diff-files --quiet && \ test -z "$(git status --porcelain)" ) || (git status --porcelain && exit 1) # --- Adam Spiers' plugin for managing dotfile symlinks with mr include = if [ -e ~/lib/mr/stow ]; then cat ~/lib/mr/stow # If the stow mr library gets included on Windows then we'll get errors on # e.g. mr update because mr'll try to call stow but it's not installed. # This second if clause will find the library on Windows, so check for # that. We can't do this with my win32 command because inside include= is # a subshell that can't access stuff defined in mr config lib= directives. elif [ -e ~/src/dotfiles/lib/mr/stow -a ! "$(perl -e 'print $^O')" = "msys" ]; then cat ~/src/dotfiles/lib/mr/stow elif [ -e ~/local/lib/stow ]; then cat ~/local/lib/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 = fast() { test "${MR_FAST}" = "true" } win32() { test "$(perl -e 'print $^O')" = "msys" } if win32; then hostname=$(hostname) else hostname=$(hostname -s) fi whoami="$(whoami)" # cut off the machine name from whoami on Windows if win32; then whoami=${whoami##*\\} fi 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 } mine() { on swhitton@artemis || on swhitton@zephyr || on swhitton@athena } workstation() { on swhitton@artemis || on swhitton@zephyr } gcrypt() { which git-remote-gcrypt >/dev/null 2>/dev/null } # --- standard procedures lib = # Make a lot of dirs that stow will symlink dotfiles into. If we # don't make these dirs, stow will just symlink the whole dir # which means that various temporary files that programs dump into # the dirs will end up part of the dotfiles repo. Further, more # than one repo might try to stow files in the dir and this can # only succeed if the dirs already exist. homedir_mkdirs() { ( cd $HOME mkdir -p \ .emacs.d \ tmp \ src \ lib \ .ssh \ .gnupg \ .duply \ .config/xfce4/xfconf/xfce-perchannel-xml \ .config/autostart \ .config/Thunar \ .irssi \ .cabal \ .xmonad \ .recoll \ .caff/gnupghome \ local/mutt \ local/mpd \ local/anacron/spool \ local/src \ local/bin \ local/big \ local/lib \ local/pub touch local/big/.duplicity-ignore src/.mrconfig [ -L "src/build-area" ] || ln -s -T /tmp/debuild src/build-area ) } # GTK and others insist on replacing the symlink to its bookmarks # file with the actual file even if the bookmarks in that file # don't change (XFCE only replaces symlinks to its config files if # its changed them). Fix this situation in the simplest case to # avoid mr restow giving an error. Don't try anything fancy if # the files are different; let the restow command give an error # and the user fix it. fix_overwritten_symlink () { local file=$1 if ! win32; then if ! [ -L $HOME/$file ]; then # file in home directory is not a link if diff -q $HOME/src/dotfiles/$file ~/$file 2>&1 >/dev/null; then rm $HOME/$file fi fi fi } # For the case where the updated file overwrites the symlink (this # is for ~/src/priv which is not checked out on win32 so skip that # check) fix_overwritten_symlink_aggressive () { local file=$1 if [ ! -L "$HOME/$file" \ -a "$HOME/$file" -nt "$HOME/src/priv/$file" ]; then mv "$HOME/$file" "$HOME/src/priv/$file" fi } # TODO: have a variable "unstowable" listing the files in a repo that # should be fixed by the above code, and incorporate into mr stow # library. Similarly set MR_NAME as a variable or something (should # work on that library) # --- primary dotfiles repository [src/dotfiles] checkout = git clone https://git.spwhitton.name/dotfiles.git dotfiles stowable = true update = # always make a go of updating master branch="$(git rev-parse --abbrev-ref HEAD)" git checkout master git pull --ff-only git checkout $branch push = # always make a go of pushing master git push origin master 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 -s)" ]; then git rebase master # fallback case: if we're on another branch but a host branch exists elif git branch | grep -q "^ $hostname$"; then git checkout $hostname git rebase master fi fixups = # we don't want git doing any automated merges of master, or other # intermediate branches. mr is configured not to do this (see # redefinition of git_update at top of this file) but I often run # git pull in this repo myself git config branch.master.rebase true git config branch.autosetuprebase always # stow won't overwrite a real ~/.mrconfig with a symlink to the # version in my dotfiles repository. Cannot just delete .mrconfig # before a stow, because then mr can't tell stow what to do. So # just do it with manual fixup and have stow ignore this file. # Name is different to avoid mr trying to chain load it at any # point. Similarly for .stow-global-ignore # TODO rm ~/.mrconfig using pre_stow? But then running mr from within ~/src/dotfiles might go wrong.. Or boostrap script writes ~/.mrconfig including ~/src/dotfiles/home-mrconfig if ! win32; then ln -sf $HOME/src/dotfiles/home-mrconfig $HOME/.mrconfig ln -sf $HOME/src/dotfiles/.stow-global-ignore $HOME homedir_mkdirs # set up auth info folder: the "|| true" is because if the # folder is empty the final recursive chmod will fail mkdir -p $HOME/local/auth && chmod 700 $HOME/local/auth && chmod -R 600 $HOME/local/auth/* 2>/dev/null || true touch $HOME/local/big/.duplicity-ignore touch $HOME/.ssh/known_hosts chmod 600 $HOME/.msmtprc # use absolute path because maybe we only just stowed so this # shell doesn't have $PATH setup by .shenv $HOME/bin/loadcron || true $HOME/bin/loadsshkeys || true $HOME/bin/mkcabalc else # win32 cd ~/src/dotfiles/bin cmd "/C win32setup.bat" fi # set up Emacs packages $HOME/.emacs.d/pkg/subtrees.sh # clean-ups so that initial stow will be successful pre_stow = homedir_mkdirs $HOME/src/dotfiles/bin/unskel pre_unstow = fix_overwritten_symlink .gtk-bookmarks; fix_overwritten_symlink .config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml pre_restow = fix_overwritten_symlink .gtk-bookmarks; fix_overwritten_symlink .config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml pre_update = fix_overwritten_symlink .gtk-bookmarks; fix_overwritten_symlink .config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml # --- private dotfiles repositories [src/priv] checkout = git clone gcrypt::athenap:priv priv stowable = true # this repository can't be checked out until we install # git-remote-gcrypt. And thanks to gcrypt being slow, skip if I run # via fmr. skip = (! gcrypt) || (! workstation) || fast fixups = chmod 600 .passwddb.pet .s3ql/authinfo2 .gnupg/*.gpg 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 autoci = git add .passwddb.pet .labbook.gpg git commit -a -m "auto passwddb 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 pre_unstow = fix_overwritten_symlink_aggressive .gnupg/pubring.gpg; fix_overwritten_symlink_aggressive .gnupg/secring.gpg; fix_overwritten_symlink_aggressive .gnupg/trustdb.gpg; pre_restow = fix_overwritten_symlink_aggressive .gnupg/pubring.gpg; fix_overwritten_symlink_aggressive .gnupg/secring.gpg; fix_overwritten_symlink_aggressive .gnupg/trustdb.gpg; pre_update = fix_overwritten_symlink_aggressive .gnupg/pubring.gpg; fix_overwritten_symlink_aggressive .gnupg/secring.gpg; fix_overwritten_symlink_aggressive .gnupg/trustdb.gpg; [src/athpriv] checkout = git clone athenap:athpriv athpriv stowable = true skip = ! mine # rss2email insists on replacing the symlink to its config file with a # real file. Fix this situation in the simplest case to avoid mr # restow giving an error pre_unstow = fix_overwritten_symlink .config/rss2email.cfg pre_restow = fix_overwritten_symlink .config/rss2email.cfg pre_update = fix_overwritten_symlink .config/rss2email.cfg # since priv repo also stows into ~/.gnupg, make the dir first pre_stow = homedir_mkdirs # --- hosts configuration [src/propellor] checkout = git clone athena:propellor propellor --branch spwconf post_checkout = cd propellor git remote add -f upstream github:joeyh/propellor.git which cabal && cabal sandbox init || true # from echo >.dir-locals.el """ ((nil . ((indent-tabs-mode . t) (tab-width . 8) (fill-column . 80))) ;; Warn about spaces used for indentation: (haskell-mode . ((eval . (highlight-regexp \"^ *\"))))) """ 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 git config propellor.spin-branch spwconf git config propellor.forbid-dirty-spin true # --- personal website source [src/wiki] checkout = git clone https://git.spwhitton.name/wiki skip = ! mine # --- primary git annex # TODO: consider using /usr/share/mr/git-annex helper to simplify this # configuration (override its update definition to avoid --content) # (and isclean defn can be generalised) [lib/annex] checkout = git clone athenap:annex post_checkout = git remote rm origin git annex init git annex enableremote origin gitrepo=athenap:annex skip = (! workstation) || fast update = git annex sync origin push = git annex sync --content origin 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 # set upstream so that mr can tell when I need to push git branch -u origin/master master git branch -u origin/git-annex git-annex sync = git annex sync origin # --- personal website big files annex [lib/wikiannex] checkout = git clone athena:wikiannex.git status = git annex status # direct mode on athena, so status won't work post_checkout = git annex init if [ "$(hostname -s)" = "athena" ]; then git annex direct fi 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 pull in direct mode skip = ! mine # --- git annex for university stuff [lib/dionysus] checkout = git clone athenah:lib/dionysus post_checkout = git annex init git annex direct status = git annex status update = git annex sync athena push = git annex sync --content athena sync = git annex sync --content isclean = test -z $(git annex status) # setup not yet solidified skip = lazy # --- git annex for use with rtorrent [lib/rt] checkout = git clone gcrypt::athenap:rt post_checkout = git annex init status = git annex status --fast update = git annex sync origin push = git annex sync 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 git config remote.origin.annex-ignore true 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 skip = (! workstation) || fast # --- source code repositories registered to their own mr config file [src] # Chain load unless we invoked mr via fmr alias. chain = ! [ "${MR_FAST}" = "true" ] # Always skip, since this is a dummy repository entry in order to # chainload. skip = ! [ "$MR_ACTION" = "stowable" ] # --- 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 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 = if win32; then cmd "/C doccheckin.bat" && git pull && git push else doccheckin && git pull && git push fi # --- 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 = ! on faeroes # --- my offline e-mail (& machine's postfix queue) [.fmail] sync = movemail update = mbsync --quiet fastmail push = movemail # Don't do anything if I don't use mbsync on this machine, or I # didn't run one of the sync or update commands. skip = ! [ -d "$HOME/.fmail" ] || ! ( [ "$MR_ACTION" = "stowable" ] || [ "$MR_ACTION" = "push" ] || [ "$MR_ACTION" = "sync" ] || [ "$MR_ACTION" = "update" ] )