Skip to content

F-i-f/tdiff

Repository files navigation

tdiff

Compare files inode attributes

Coverity: Coverity Scan Build Status

Features

Compare two file trees, showing any differences in their:

  • file size,
  • file block count (physical storage size),
  • owner user and group ids (uid & gid),
  • access, modification and inode change times,
  • hard link count, and sets of hard linked files,
  • extended attributes (if supported),
  • ACLs (if supported),
  • file system flags (BSD UFS, MacOSX).

Documentation

tdiff comes with an extensive manual page.

View or download the manual page as: [HTML], [PDF] or [ROFF].

Examples

Check that the two file trees rooted at directory1 and directory2 are exactly the same, including symbolic link targets if any, permissions, hard disk block usage, owner user or group ids, and if supported, flags, ACLs and extended attributes:

tdiff directory1 directory2

 

Same as previous example, but also check that the file modification times are the same:

tdiff -i directory1 directory2

 

Only report if any files are present in only one directory:

tdiff -0 --dirs directory1 directory2

 

Report only ownership (user or group id) differences, ignore any missing files:

tdiff -0 --uid --gid directory1 directory2

 

Report only group permission bits differences, ignore any missing files:

tdiff -0 --mode --mode-and 70 directory1 directory2

or:

tdiff -0 --mode --mode-or 7707 directory1 directory2

 

Report only sticky bits differences, ignore any missing files:

tdiff -0 --mode --mode-and 1000 directory1 directory2

or:

tdiff -0 --mode --mode-or 6777 directory1 directory2

 

Run cmp -l on every file of the same size in both trees:

tdiff -0 --exec cmp -l %1 %2 \; directory1 directory2

 

Run super-diff: diff files with diff -u and reports any other kind of differences in inode contents except for times:

tdiff --exec-always-diff directory1 directory2

or more tersely:

tdiff -W directory1 directory2

 

Same with file modification times:

tdiff -W --preset mtime directory1 directory2

or also:

tdiff -Wi directory1 directory2

License

tdiff is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see [http://www.gnu.org/licenses/].

Building from source

Requirements

  • C Compiler (eg. gcc)

  • Make (eg. GNU make)

  • libacl, optionally, for ACL support, if needed on your system.

  • autotools (autoconf, automake) is only required if building from the repository.

  • groff is optionally needed to generate the man page hard copies (HTML & PDF). It is only needed if you intend to update the manual page ROFF source.

From a release

Download the latest release from GitHub or the secondary mirror:

The source code release are signed with the GPG key ID 0x88D51582, available on your nearest GPG server or here.

You can also find all releases on the GitHub release page and on the secondary mirror.

When downloading from the GitHub release pages, be careful to download the source code from the link named with the full file name (tdiff-0.8.7.tar.gz), and not from the links marked Source code (zip) or Source code (tar.gz) as these are repository snapshots generated automatically by GitHub and require specialized tools to build (see Building from GitHub).

After downloading the sources, unpack and build with:

tar xvzf tdiff-0.8.7.tar.gz
cd tdiff-0.8.7
./configure
make
make check
make install
make install-pdf install-html # Optional

Alternately, you can create a RPM file by moving the source tar file and the included tdiff.spec in your rpm build directory and running:

rpmbuild -ba SPECS/tdiff.spec

From the GitHub repository

Clone the repository:

git clone https://github.com/F-i-f/tdiff.git
cd tdiff
autoreconf -i
./configure
make
make check
make install
make install-pdf install-html # Optional

Changelog

Version 0.8.7

January 30, 2024.

Bugs fixed:
  • Ignore trusted.SGI_ACL_DEFAULT default ACL (XFS-specific).
  • Do not update access time when comparing symbolic-link (system-dependent, Linux only).
Improvements:
  • Compare ACLs faster if acl_cmp() is available.
  • Improve test suite portability on *BSD.
  • Android build now defaults to statically linked executable.
  • Test suite skips some time and block related tests on problem platforms.

Version 0.8.6

May 20, 2022.

Bugs fixed:
  • Handle mallinfo2() and glibc 2.34.
  • Make getdents64 work on Linux again.

Version 0.8.5

November 1, 2019.

Bugs fixed:
  • Minor bug fixes terminal width handling.
  • Improvements in .spec cross-distribution compatibility.

Version 0.8.4

June 14, 2019.

New features:
  • A new -O/--follow-symlinks option has been implemented.
Bugs fixed:
  • Minor bug fixes in zsh completion.

Version 0.8.3

May 22, 2019.

Bugs fixed:
  • Fix rare file descriptor leak on directory enumeration failure.

  • Fix other inconsequential Coverity-detected errors.

Version 0.8.2

May 12, 2019.

Bugs fixed:
  • Fix missing xattr feature on Android.
Other changes:
  • Provide a build script for building all Android targets.

Version 0.8.1

May 7, 2019.

Bugs fixed:
  • tdiff could fail on Linux with O_NOATIME support when comparing files or reading directories not owned by the invoking user, when not running as root.
Other changes:
  • Specify better tdiff's behavior with regards to O_NOATIME.
  • Spec file now BuildRequires fakeroot.
  • Enhanced test suite / regressions.
  • Don't abort() on unexpected state, exit cleanly.
  • Fix nanosecond resolution detection in regressions.

Version 0.8

May 3, 2019.

New features:
  • The -e/--hardlinks option has been implemented: tdiff can now compare hard link sets between both directories and report which hard links are only in one of the directories.
User-visible changes:
  • Some options have been renamed for consistency with the stat(2) structure member names, and others to avoid non-standard options.

    Old option (before 0.8) New option (0.8 and later) Notes
    -r/-R -y/-Y atime check
    -o/-O/--owner/--no-owner -u/-U/--uid/--no-uid file user id
    --group/--no-group --gid/--no-gid file group id
    --nlinks --nlink hard link count
    -a/--all -6/--preset default default option state
    -A/--no-all -0/--preset none clear all comparison toggles
    -| -o file mode OR bit mask
    -& -a file mode AND bit mask
  • A lot of presets have been added, replacing the -a/--all and -A/--no-all options. They can be used numerically (-3) or by name (-p owner/--preset owner)

  • tdiff --version now reports the stat time granularity (seconds or microseconds).

  • A message is printed when a comparison is skipped or sub-trees are pruned because they cannot be read.

  • The README and NEWS files are now installed in $prefix/share/doc/tdiff.

  • HTML and PDF versions of the manual page can optionally be installed by running make install-html or make install-pdf.

Bugs fixed:
  • Fix compilation error on systems supporting st_xtimespec stat structure members.

  • tdiff's exit status was not always consistent with the documented behavior, this is now fixed.

  • Fix crash with the -x/--exec or -w/--exec-always command lines do not end with a semicolon.

Other changes:
  • Manual page improvements and updates.
  • Test suite (make check) improvements.
  • Zsh completion function improvements.
  • Lots of changes under the hood.

Version 0.7.2

April 30, 2019.

  • Fix crash when an unreadable directory is encountered.
  • Fix regression failures on odd systems.
  • Fix display overflow in --version.

Version 0.7.1

April 27, 2019.

  • Fixed rare bug where files could be skipped (and misreported as having no differences) if two files with the name inode number but with different device numbers were scanned within the second argument's sub-tree.

Version 0.7

April 26, 2019.

New features:

  • Bash and Zsh completion functions are now included.

  • A manual page is now included.

  • New -W --always-exec-diff option.

User-visible changes:

  • The (unimplemented) option -e / --hardlinks has been (temporarily) removed.

  • When reporting mode discrepancies (-m / --mode), if no mask is used with --mode-or or --mode-and, then masked values are not shown.

  • The -| / --mode-or and -& / --mode-and options now take their arguments as octal (no need to lead them with a zero to force octal parsing).

  • The -p / --no-mmap option has been removed.

  • Using the -v / --verbose option more than once now increases the logging level.

  • The -V / --version option now prints compiled in features (ACLs, xattrs, etc.)

  • The command specified in -w / --exec-always is not run anymore if both files to be compared are hard-links of each other.

  • Updated BSD / MacOSX flags.

Bugs fixed:

  • Fixed bug where paths could be wrongly displayed (when one of the arguments was / or ../ for example).

  • Change the inode cache hash function to DJB2 (performance).

  • Times could sometimes be compared incorrectly.

  • Compare symbolic links contents only when requested.

  • Crash fixed when the command line for -x / --exec or -w / --exec-always did not reference both %1 and %2.

Internal changes

  • Move to Git, git-aware build scripts.

  • Open files with O_NOATIME.

  • Factorize some autoconf code into macros.

  • Fix build errors when cross-compiling.

  • Support getdents64 on Linux.

  • Portability fixes for FreeBSD 12, MacOSX, Android, Solaris.

  • Add test suite.

  • Include RPM spec file.

Release 0.2

January 31, 2014.

  • First public release.

  • Now includes support for ACLs, extended attributes, and link count.

Credits

tdiff was written by Philippe Troin (F-i-f on GitHub).