# -*- mode: conf -*- # Copyright (C) 2010-2022 Sean Whitton # # This file is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or (at # your option) any later version. # # This file is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this file. If not, see . [DEFAULT] git_update = git pull-safe "$@" # Avoid trying to push to read-only remotes. # Sometimes will want to redefine for a repository to include --no-tags. git_push = git push-all "$@" # Look for branches with unpushed commits in only the main working tree, but # look for loose commits on a possibly-detached HEAD in all working trees. # Thus, we assume that for each linked working tree registered with myrepos, # its main working tree is also registered (we don't assume the converse). git_status = git status --short "$@" ||: if [ ! -h .git -a -d .git ]; then git --no-pager log HEAD --branches --not --remotes \ --simplify-by-decoration --decorate --oneline ||: git --no-pager stash list else git --no-pager log HEAD --not --branches --remotes \ --simplify-by-decoration --decorate --oneline ||: fi # Custom actions to be configured repository-by-repository. sync = : autoci = : git_isclean = git is-clean git_clean = git clean -xdff # There is no 'mr stow' to help avoid accidentally stowing repos that aren't # intended ever to be stowed. Can type 'hstow stow .' for an initial stow. lib = when_stowed () { if [ -e "$HOME/.STOW/$(echo "$MR_REPO" | tr / _)" ]; then hstow "$MR_ACTION" "$MR_REPO" fi } adopt = when_stowed unstow = when_stowed restow = when_stowed # Repack git-remote-gcrypt origin remotes. # Useful to avoid surprise repacks; see git-remote-gcrypt README.rst. git_repack = git config --get remote.origin.gcrypt-id >/dev/null || exit 0 if ! git is-clean; then echo >&2 must commit first; exit 1 elif [ -n "$(git for-each-ref \ --no-contains=origin/master refs/heads/master)" ]; then git pull origin master fi # Ensure that there is something to push, else no repack will occur. [ -n "$(git for-each-ref \ --contains=master refs/remotes/origin/master)" ] \ && git push -f origin origin/master~1:master GCRYPT_FULL_REPACK=yes git push origin master lib = if [ -n "$USER" ]; then whoami="$USER" elif [ -n "$LOGNAME" ]; then whoami="$LOGNAME" else # Cut off any Windows machine name. whoami="$(whoami)"; whoami="${whoami##*\\}" fi # Ensure it's a short hostname, not an FQDN. hostname="$(hostname)"; hostname="${hostname%%.*}" win32() { test "$(perl -e 'print $^O')" = msys } # This function is from joeyh's myrepos config. 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@melete } mine() { workstation || on spwhitton@athena } # git_worktree_checkout () { local repo=$1; shift local i=0 while [ $((i += 1)) -lt $# ]; do set -- "$@" "$1"; shift done local committish=$1; shift git -C "$repo" worktree add "$@" "$MR_REPO" "$committish" } git_worktree_skip () { case "$MR_ACTION" in checkout) eval "set -- $(mr config "$MR_REPO" checkout)" [ "$1" = git_worktree_checkout -a ! -d "$2" ] && return 0 ;; # Avoid fetching from remotes over and over again. update) return 0 ;; esac return 1 } #################################################################### [src/dotfiles] checkout = git clone https://git.spwhitton.name/dotfiles # We have a script to update master, and all other branches should be checked # out and committed to on only a single host, so no need to update them here, # and they'll always be rebaseable. update = git dotfiles-update-master # Update from master on a host that has its own branch. pull = git dotfiles-update-master; git co "$hostname" && git rebase master # Attempt to ensure tip of master is signed before attempting to push. pre_push = if git diff-index --quiet --cached HEAD \ && ! git verify-commit-spw master; then [ "$(git rev-parse --abbrev-ref HEAD)" = master ] || git co master git commit -S --amend --no-edit if git rev-parse -q --verify refs/heads/"$hostname" >/dev/null; then git co "$hostname" git rebase master fi fi fixups = bstraph [lib/priv] checkout = git clone athenag:libpriv.git priv update = git annex sync --content cloud origin push = git annex sync --content cloud origin sync = mr autoci && git annex sync --no-commit --content cloud origin pre_status = git update-index -q --refresh \ .passwddb.pet .labbook.gpg .gnupg/pubring.kbx fixups = chmod 600 \ .passwddb.pet .gnupg/*.kbx .gnupg/private-keys-v1.d/*.key .ssh/id_* hstow restow ~/lib/priv # We used to --export-ownertrust, but now we just manually maintain this # file, import it here, and don't set ownertrust values interactively. command -v gpg >/dev/null && gpg --import-ownertrust ~/lib/priv/otrust.lst skip = lazy post_checkout = cd priv git annex init git annex enableremote cloud git annex group . backup # Delete any pubring.kbx created by INSINUATE-DOTFILES Consfigurator # property / 'insinuate-dotfiles' shell script: don't want to adopt it. rm -f ~/.gnupg/pubring.kbx autoci = hstow stow ~/lib/priv # to perform adoptions git annex add .passwddb.pet .labbook.gpg .gnupg/pubring.kbx git commit -a -m \ "auto passwddb, pubring and labbook commit on $(hostname -s)" ||: pre_update = mr autoci [src/athpriv] checkout = git clone demeterp:athpriv pre_update = on athena || git annex sync origin athenah pre_push = on athena || git annex sync --content origin athenah post_update = hstow restow ~/src/athpriv post_checkout = hstow stow ~/src/athpriv # Deal with phantom modifications because git-annex couldn't update the index. # Avoid calling git-update-index(1) on other score files (including those # we've already called it on since the last commit) so as to avoid continually # annexing intermediate versions of score files. pre_status = git status -s -- News/*.SCORE News/*.ADAPT \ | perl -MGit=unquote_path,command \ -wlne'/^ M / and push @up, unquote_path $'"'"'; END { @up and command qw(update-index -q --refresh), @up }' skip = ! mine post_checkout = cd athpriv git annex init on athena || git remote add athenah athenah:src/athpriv git annex group . backup autoci = git annex add News/* git commit News -m"auto commit of Gnus score files" ||: fixups = # Drop score files unused by master or origin/master for a week. [ "$MR_ACTION" = checkout -o "$MR_ACTION" = update ] || git fetch origin git annex unused \ --used-refspec="+refs/heads/master:+refs/remotes/origin/master" \ | perl -wlne'BEGIN { $w = time - 7*24*60*60 } /^\s+(\d+)\s+/ and $t = `git log -1 --format="%ct" --no-textconv -S"$'"'"'" -- News` and $t < $w and print $1' | xargs git annex dropunused --force #################################################################### [doc] checkout = git clone demeterp:doc doc update = git pull --rebase=false --no-edit "$@" autoci = doccheckin pre_update = win32 || doccheckin sync = doccheckin && git pull --no-edit && git push # Set mtimes to last commit, for Howm; doing so only in post_checkout, and not # fixups, should be sufficient for summary buffer ordering purposes. post_checkout = git utime skip = ! mine [src/wiki] checkout = git clone demeter:wiki skip = ! mine [lib/realloc] checkout = git clone demeterp:realloc skip = ! mine #################################################################### [lib/radicale] checkout = git clone demeterp:radicale radicale skip = ! on spwhitton@athena [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 ] #################################################################### [lib/annex] checkout = git clone athenag:annex.git annex post_checkout = cd annex git annex init git annex enableremote athena rsyncurl=athena:local/rsync/annex update = git annex sync --no-content origin push = git annex sync --content origin athena skip = lazy [annex] checkout = git clone athenag:annex19.git annex post_checkout = cd annex; git annex init; git annex enableremote cloud update = git annex sync --no-content origin push = git annex sync --content cloud origin skip = lazy [lib/wikiannex] checkout = git clone demeter:wikiannex post_checkout = cd wikiannex; git annex init update = git annex sync --no-content push = git annex sync --content fixups = ! on demeter || git annex adjust --hide-missing --unlock skip = lazy [lib/podcasts] checkout = git clone demeterp:podcasts post_checkout = cd podcasts; git annex init update = ./update-and-sync push = git annex --no-content sync skip = lazy [lib/athena-apt] checkout = git clone demeter:athena-apt post_checkout = cd athena-apt git annex init --version=7 git annex enableremote demeter rsyncurl=demeter:/srv/www/debian git annex get . update = git annex sync --no-content skip = lazy push = git annex add git annex unlock db git annex sync --content demeter git annex sync origin ssh demeter find /srv/www/debian -type f -exec chmod 644 '{}' + ssh demeter find /srv/www/debian -type d -exec chmod 755 '{}' + # The git-diff-files(1) call in ~/src/dotfiles/bin/git-is-clean fails in v7 # git-annex repos with unlocked empty files, which this repo often has: empty # Packages files. isclean = output="$(git annex status)" test -z "$output" || ( echo "$output"; exit 1 ) #################################################################### # "master" branch: just for installing changes to upstream master # # "$(hostname -s)" branch: # # Rebased onto a branch from sv.gnu.org, usually master. It has # # - bug fixes, reversions etc., (cleaned up versions of) which have not # yet made it onto sv.gnu.org's master, but which are required for my # own usage, on this machine or in general # # - WIP patches of my own -- this branch is used for my own development # work, at least where that doesn't require long-lived feature # branches, or when we are rebasing onto master but need to commit to # emacs-NN and they're too different to cherry-pick across, etc.. # # A key advantage of using these development builds is that references to # files in *Help* buffers will be to ~/src/emacs/primary, not to somewhere # owned by root. Another reason for having a branch for localhost is to # keep track of what upstream commit we want to be running on this host, # and which upstream branch we want to rebase onto, e.g. emacs-29 # vs. master, or some feature branch we want to test here. # # This branch doesn't usually need to be pushed anywhere, but if we do # need to push it somewhere for backup purposes, we execute # # % git config branch."$(hostname -s)".pushRemote demeter # # and then 'mr push' will force push it to demeter. # # "athena/unstable" branch: # # Merges from sv.gnu.org's master branch or the latest emacs-NN release # branch, only. .deb packages produced from this branch are available from # . There are two purposes: # # - providing byte-compiled Lisp /usr/share/emacs-snapshot/site-lisp/elpa # to builds from the "$(hostname -s)" branch # # - direct use on machines other than my development laptop where I want # something more current than the stable release of Emacs but not with # my current WIP. # # Updated only when new fixes, features or reversions on sv.gnu.org's # master branch or the latest emacs-NN branch are wanted on machines other # than my development laptop. To do that, first "melete" is updated using # "mr pull", and then I run that build for a day or so. Then # # % cd ~/src/deb/emacs-snapshot # % debian/merge-snapshot # % dgit sbuild --no-run-lintian # % cp ../emacs-snapshot_29~git202*amd64.deb ~/local/develacc/tmp # % sudo virsh start develacc.melete.silentflame.com # % cd /ssh:root@develacc:/home/spwhitton/tmp # % apt-get install ./emacs-snapshot_29~git202*amd64.deb # % rm emacs-snapshot_29~git202*amd64.deb # % cd //ssh:develacc:src/dotfiles # % mr up # # C-i s develacc RET # $ /opt/emacs-snapshot/bin/emacs -nw --debug-init # # % cd ~//src/deb/emacs-snapshot # % sudo virsh destroy develacc.melete.silentflame.com # % reprepro-rebuilder --release # if develacc test was successful # # If need to back out before reprepro-rebuilder: # % cd ~//src/deb/emacs-snapshot # % git reset --hard demeter/athena/unstable # # It is important to test local installability of the new .deb, probably # in develacc or a sid chroot, before adding to demeter-apt, because # running the rebased "melete" branch doesn't detect any byte compilation # issues against my current selection of elpa-* packages. # # "athena/CODENAME-bpo" branch: # # Backported from athena/unstable. Automatically updated by # reprepro-rebuilder when updating athena/unstable as described above. # # See also bin/emacsclient wrapper script in dotfiles.git. # This worktree: usually the master branch, sometimes some feature branch. [src/emacs/trunk] checkout = git clone https://git.savannah.gnu.org/git/emacs.git trunk post_clean = ./autogen.sh autoconf post_checkout = cd trunk git remote add -f demeter demeter:emacs ||: git -c fetch.fsckObjects=false \ remote add -f debian https://salsa.debian.org/rlb/deb-emacs.git/ ||: ./autogen.sh all skip = lazy # This worktree: either a detached HEAD or the "$hostname" branch. [src/emacs/primary] checkout = git_worktree_checkout "$HOME/src/emacs/trunk" \ -b "$hostname" --no-track \ "$(if [ -n "$(git -C $HOME/src/emacs/trunk \ for-each-ref '[r]efs/remotes/demeter/'"$hostname")" ] then echo demeter/"$hostname"; else echo master; fi)" post_clean = ./autogen.sh autoconf post_checkout = cd primary; ./autogen.sh autoconf # We don't have the "$(hostname -s)" branch's upstream set to origin/master to # avoid accidentally pushing personal commits to Savannah (push.default cannot # help here). So for convenient updates of "$(hostname -s)" to its conceptual # upstream, we have this definition. "pull" not "update" because we want to # update from upstream deliberately, not as part of automated updates. pull = branch="${1:-$(git reflog $hostname -1 --pretty='%gs' \ --grep-reflog='^pull --rebase --autostash origin' \ | awk '{print $5}')}" if [ -n "$branch" ]; then git co "$hostname" git pull --rebase --autostash origin "$branch" else echo >&2 "Don't know what to pull; try 'mr pull BRANCH'."; exit 1 fi skip = lazy || git_worktree_skip [src/emacs/release] checkout = git_worktree_checkout "$HOME/src/emacs/trunk" \ -b emacs-29 origin/emacs-29 post_clean = ./autogen.sh autoconf post_checkout = cd release; ./autogen.sh autoconf skip = lazy || git_worktree_skip # src/deb/ contains repos/worktrees used only, or almost only, for packaging # work, and not for working upstream. [src/deb/emacs-snapshot] checkout = git_worktree_checkout "$HOME/src/emacs/trunk" \ -b athena/unstable demeter/athena/unstable skip = ! workstation || git_worktree_skip [src/deb/emacs] checkout = git_worktree_checkout "$HOME/src/emacs/trunk" \ -b deb/emacs/d/sid/master debian/deb/emacs/d/sid/master skip = ! workstation || git_worktree_skip [src/deb/emacs-non-dfsg] checkout = git_worktree_checkout "$HOME/src/emacs/trunk" \ -b deb/emacs-non-dfsg/d/sid/master debian/deb/emacs-non-dfsg/d/sid/master skip = ! workstation || git_worktree_skip #################################################################### [src/elpa] checkout = git clone https://git.savannah.gnu.org/git/emacs/elpa.git post_checkout = cd elpa && make setup skip = lazy [src/nongnu-elpa] checkout = git clone https://git.savannah.gnu.org/git/emacs/nongnu.git nongnu-elpa post_checkout = cd elpa && make skip = lazy [src/org-mode] checkout = git clone https://git.savannah.gnu.org/git/emacs/org-mode.git skip = lazy #################################################################### [src/dgit] checkout = git clone salsa:dgit-team/dgit post_checkout = cd dgit git remote add -f demeter demeter:dgit ||: dgit setup-new-tree skip = lazy [src/p5-Git-Annex] checkout = git clone demeter:p5-Git-Annex post_checkout = cd p5-Git-Annex git remote \ add -f salsa salsa:perl-team/modules/packages/libgit-annex-perl ||: git branch --track debian salsa/master skip = lazy [src/p5-API-GitForge] checkout = git clone demeter:p5-API-GitForge post_checkout = cd p5-API-GitForge git remote \ add -f salsa salsa:perl-team/modules/packages/libapi-gitforge-perl ||: git branch --track debian salsa/master skip = lazy [src/notmuch] checkout = git clone https://git.notmuchmail.org/git/notmuch skip = lazy [src/linux] checkout = git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git skip = lazy [src/sbcl] checkout = git -c fetch.fsckobjects=false clone https://git.code.sf.net/p/sbcl/sbcl skip = lazy