Creating recreatable tar.gz from SVN


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
umask 000
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 batman-0.3` and everytime I get a bit identical tar.gz :)