On 1/29/25 16:17, Simon Josefsson wrote:
I don't think sub-1s timestamps are useful in release tarballs. My
approach to avoid them right now is to hard code timestamps with 'tar
--mtime' to last git commit time.
This should work until the year 2242, albeit with some hassles with
HP/UX 'make'. (2242 is when ustar format stops working.)
However, I find it a bit annoying when a source file's last-modified
timestamp is that of the release, not of its last modification. This is
why for reproducible tarballs, the draft of the next tar manual suggests
using --clamp-mtime instead of just --mtime, using the following recipe.
(Admittedly this should all be easier.)
function get_commit_time() {
TZ=UTC0 git log -1 \
--format=tformat:%cd \
--date=format:%Y-%m-%dT%H:%M:%SZ \
"$@"
}
#
# Set each source file timestamp to that of its latest commit.
git ls-files | while read -r file; do
commit_time=$(get_commit_time "$file") &&
touch -md $commit_time "$file"
done
#
# Set timestamp of each directory under $FILES
# to the latest timestamp of any descendant.
find $FILES -depth -type d -exec sh -c \
'touch -r "$0/$(ls -At "$0" | head -n 1)" "$0"' \
{} ';'
#
# Create $ARCHIVE.tgz from $FILES, pretending that
# the modification time for each newer file
# is that of the most recent commit of any source file.
SOURCE_EPOCH=$(get_commit_time)
TARFLAGS="
--sort=name --format=posix
--pax-option=exthdr.name=%d/PaxHeaders/%f
--pax-option=delete=atime,delete=ctime
--clamp-mtime --mtime=$SOURCE_EPOCH
--numeric-owner --owner=0 --group=0
--mode=go+u,go-w
"
GZIPFLAGS="--no-name --best"
LC_ALL=C tar $TARFLAGS -cf - $FILES |
gzip $GZIPFLAGS > $ARCHIVE.tgz