Hi, I believe that this is bug in diffutils, but I am not entirely sure. The problem manifested itself while testing patchutils on Solaris. One of the tests was failing. Upon closer inspection the filterdiff (aka lsdiff) decides whether a give chunk is creating (or deleting) a file based on timestamp the chunk is having. It compares whether the timezone recorded equals to current timezone.
https://github.com/twaugh/patchutils/blob/master/src/filterdiff.c#L156 On Solaris patchutils correctly detect that there is no struct tm -> tm_gmtoff (HAVE_TM_GMTOFF). On line 1417 of nstrftime.c 1415 #if HAVE_TM_GMTOFF 1416 diff = tp->tm_gmtoff; 1417 #else 1418 if (!tz) 1419 diff = 0; 1420 else And since there is zero tz specified in context.c if (! (tm && nstrftime (buf, sizeof buf, time_format, tm, 0, nsec))) ^^^ The resulting chunk has zero timezone offset (on Solaris). Like here: $ TZ=EST+5 gdiff -urN dir.orig dir diff -urN dir.orig/a dir/a --- dir.orig/a 1969-12-31 19:00:00.000000000 +0000 <------ this file is missing +++ dir/a 2021-10-14 12:24:20.785102347 +0000 On Linux and after my fix on Solaris the result is --- dir.orig/a 1969-12-31 19:00:00.000000000 -0500 I am not entirely sure where is nstrftime.c coming from, so I'm reporting the issue here. I am also attaching patch I plan to use on Solaris. The patch and additional test works for me on diffutils 3.8 on both Linux and Solaris. Thanks for diffutils, I believe it's the most important tool for release engineer :) Cheers -- Vlad
Solaris does not support tm_gmtoff and diffutils in such case defaults to zero time offset no matter what timezone is being currently used. That manifests when creating patch with new and/or deleted files. $ TZ=EST+5 gdiff -urN dir.orig dir diff -urN dir.orig/a dir/a --- dir.orig/a 1969-12-31 19:00:00.000000000 +0000 <------ this file is missing +++ dir/a 2021-10-14 12:24:20.785102347 +0000 The correct line should be --- dir.orig/a 1969-12-31 19:00:00.000000000 -0500 This issue was found by failing patchutils test case. Patchutils detect new and/or deleted file by looking at the timestamp. It incorrectly assumes that this is not new file creation but rather modification of existing file. And it's test 'lsdiff2' fails. --- diffutils-3.8/lib/nstrftime.c +++ diffutils-3.8/lib/nstrftime.c @@ -1416,7 +1416,10 @@ #if HAVE_TM_GMTOFF diff = tp->tm_gmtoff; #else if (!tz) - diff = 0; + { + time_t now = time(0); + diff = timegm(localtime(&now)) - now; + } else { struct tm gtm; --- diffutils-3.8/tests/Makefile.am +++ diffutils-3.8/tests/Makefile.am @@ -22,7 +22,8 @@ stdin \ strcoll-0-names \ filename-quoting \ strip-trailing-cr \ - colors + colors \ + timezone XFAIL_TESTS = large-subopt --- diffutils-3.6/tests/timezone +++ diffutils-3.6/tests/timezone @@ -0,0 +1,20 @@ +#!/bin/sh + +. "${srcdir=.}/init.sh"; path_prepend_ ../src + +TZ=EST+5 +export TZ + +TZ_OFFSET=-0500 + +mkdir -p dir-empty dir +echo a > dir/a + +returns_ 0 diff -urN dir-empty dir > out || fail=1 +STRING=$( grep ^--- out ) +if [[ $STRING == *$TZ_OFFSET ]]; then + exit 0 +else + fail_ "The timezone should be $TZ_OFFSET, but it is $STRING" + exit 1 +fi