Creating recreatable tar.gz from SVN

by

I was searching for an equivalent of git-archive for creating a bit identical version of the tar.gz each time I run it. I couldn't find anything like that and svn export .. && tar cvfz .. will result in different hash sums for different people/time it gets started. This has different reasons:

  • no time of folders are set when using svn export

  • umask can be different on different systems

  • tar saves group/users

  • gzip saves the original file name

  • gzip saves the timestamp

The solution I came up with is a little bit hacky but works fine for me

#! /bin/sh
set -e
if [ "$1" = "" ] || [ "$2" = "" ]; then
      echo "Usage: $0 REPO TARGET"
      exit 1
fi
umask 000
REPO="$1"
RELEASENAME="$2"
MANIFEST="`mktemp -t`"
trap "rm -rf \"${RELEASENAME}\"; rm -f \"${MANIFEST}\"" 0
rm -rf "${RELEASENAME}"*
svn export "${REPO}" "${RELEASENAME}"
find "${RELEASENAME}" -type f |sed 's/^\.*\/*//'|sort > "$MANIFEST"
tar cf "${RELEASENAME}".tar --owner 0 --group 0 --numeric-owner --no-recursion --files-from "$MANIFEST"
gzip -n -m -f "${RELEASENAME}".tar
md5sum -b "${RELEASENAME}".tar.gz > "${RELEASENAME}".tar.gz.md5
sha1sum -b "${RELEASENAME}".tar.gz > "${RELEASENAME}".tar.gz.sha1
gpg -a --detach-sign --comment "Verify with \`gpg --verify '${RELEASENAME}.tar.gz.asc' '${RELEASENAME}.tar.gz'\`" "${RELEASENAME}".tar.gz

To create a tarball from B.A.T.M.A.N. subversion tag directory, I can simply invoke svntag2release https://downloads.open-mesh.org/svn/batman/tags/batman-0.3/ batman-0.3 and everytime I get a bit identical tar.gz :)