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


Reply via email to