kohler / gifsicle

Create, manipulate, and optimize GIF images and animations
http://www.lcdf.org/gifsicle/
GNU General Public License v2.0
3.79k stars 241 forks source link

Do not touch file if not changed / preserve modification time #201

Open gwern opened 8 months ago

gwern commented 8 months ago

While attempting to optimize GIF videos in archives on my site, I noticed that the usual 'optimize if recently changed' choice of files was not working and the same GIF files were being modified each time; on closer inspection, the file contents were not changing, and only the modification time was changing. This triggered spurious re-optimizations and syncs and was increasingly becoming a problem.

gifsicle apparently will touch the file even if the new version is bit-for-bit identical and no CLI option like --force-write is specified. Example with an arbitrary GIF:

$ gifsicle --version
LCDF Gifsicle 1.92
Copyright (C) 1997-2019 Eddie Kohler
This is free software; see the source for copying conditions.
There is NO warranty, not even for merchantability or fitness for a
particular purpose.

$ wget --quiet http://www.theiling.de/00/aluminiumeimerchen-ffffff.gif; ls -l aluminiumeimerchen-ffffff.gif; md5sum aluminiumeimerchen-ffffff.gif; gifsicle --batch --colors=256 --optimize=3 aluminiumeimerchen-ffffff.gif; ls -l aluminiumeimerchen-ffffff.gif; md5sum aluminiumeimerchen-ffffff.gif; sleep 2m; gifsicle --batch --colors=256 --optimize=3 aluminiumeimerchen-ffffff.gif; ls -l aluminiumeimerchen-ffffff.gif; md5sum aluminiumeimerchen-ffffff.gif; alert

-rw------- 1 gwern gwern 6755 Jun  1  2011 aluminiumeimerchen-ffffff.gif
69ab80ea1c39d6a93f756002dff9ec39  aluminiumeimerchen-ffffff.gif

gifsicle:aluminiumeimerchen-ffffff.gif: warning: trivial adaptive palette (only 238 colors in source)

-rw------- 1 gwern gwern 6753 Mar 16 20:06 aluminiumeimerchen-ffffff.gif
c04355ba4cb446a706d6d2c54865d2c3  aluminiumeimerchen-ffffff.gif

gifsicle:aluminiumeimerchen-ffffff.gif: warning: trivial adaptive palette (only 238 colors in source)
-rw------- 1 gwern gwern 6753 Mar 16 20:08 aluminiumeimerchen-ffffff.gif
c04355ba4cb446a706d6d2c54865d2c3  aluminiumeimerchen-ffffff.gif

As expected, the GIF is slightly modified by the first gifsicle pass and the modification time is updated. The second time, it is the same size and bit-for-bit identical (as evidenced by the MD5 hash being the same c043...) but the file modification time has been incremented from 20:06 to 20:08. This touch behavior doesn't seem to be documented in the man page nor do I see any options which would disable it.

gifsicle should not write out unchanged files, thereby changing the file modification time, if the file has not been modified at that time: it is, after all, 'file modification time', not 'file non-modification time'. Falsifying the metadata of a file to indicate it has been modified at a time it has not, in fact, been modified, is a bug. (If this is desirable for some reason, it could be supported by adding an IO option like --force-write.)

kohler commented 8 months ago

This is a feature request, not a bug report. I’d welcome a patch to provide the behavior you want. However, it won’t be trivial.