---
name: "File::DirCompare"
section: "3pm"
platform: "linux"
package: "libfile-dircompare-perl"
version: "0.7-2"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/File::DirCompare"
---

# File::DirCompare(3pm)

Perl module to compare two directories using callbacks.

## NAME

File::DirCompare - Perl module to compare two directories using callbacks.

## SYNOPSIS

```
  use File::DirCompare;
  # Simple diff -r --brief replacement
  use File::Basename;
  File::DirCompare->compare($dir1, $dir2, sub {
    my ($a, $b) = @_;
    if (! $b) {
      printf "Only in %s: %s\n", dirname($a), basename($a);
    } elsif (! $a) {
      printf "Only in %s: %s\n", dirname($b), basename($b);
    } else {
      print "Files $a and $b differ\n";
    }
  });
  # Version-control like Deleted/Added/Modified listing
  my (@listing, @modified);     # use closure to collect results
  File::DirCompare->compare('old_tree', 'new_tree', sub {
    my ($a, $b) = @_;
    if (! $b) {
      push @listing, "D   $a";
    } elsif (! $a) {
      push @listing, "A   $b";
    } else {
      if (-f $a && -f $b) {
        push @listing, "M   $b";
        push @modified, $b;
      } else {
        # One file, one directory - treat as delete + add
        push @listing, "D   $a";
        push @listing, "A   $b";
      }
    }
  });
```

## DESCRIPTION

File::DirCompare is a perl module to compare two directories using a callback, invoked for all files that are 'different' between the two directories, and for any files that exist only in one or other directory ('unique' files).

File::DirCompare has a single public *compare()* method, with the following signature:

```
  File::DirCompare->compare($dir1, $dir2, $sub, $opts);
```

The first three arguments are required - `$dir1` and `$dir2` are paths to the two directories to be compared, and `$sub` is the subroutine reference called for all unique or different files. `$opts` is an  optional hashref of options - see OPTIONS below.

The provided subroutine is called for all unique files, and for  every pair of 'different' files encountered, with the following  signature:

```
  $sub->($file1, $file2)
```

where `$file1` and `$file2` are the paths to the two files. For 'unique' files i.e. where a file exists in only one directory, the subroutine  is called with the other argument 'undef' i.e. for:

```
  $sub->($file1, undef)
  $sub->(undef, $file2)
```

the first indicates `$file1` exists only in the first directory given ($dir1), and the second indicates `$file2` exists only in the second  directory given ($dir2).

### OPTIONS

The following optional arguments are supported, passed in using a  hash reference after the three required arguments to *compare()* e.g.

```
  File::DirCompare->compare($dir1, $dir2, $sub, {
    cmp             => $cmp_sub,
    ignore_cmp      => 1,
    ignore_unique   => 1,
    matches         => $matches_sub,
  });
```

- cmp

  By default, two files are regarded as different if their contents do  not match (tested with File::Compare::compare). That default behaviour can be overridden by providing a 'cmp' subroutine to do the file comparison, returning zero if the two files are equal, and non-zero if not.

  E.g. to compare using modification times instead of file contents:

  ```
    File::DirCompare->compare($dir1, $dir2, $sub, {
      cmp => sub { -M $_[0] <=> -M $_[1] },
    });
  ```

- ignore\_cmp

  If you want to see *all* corresponding files, not just 'different' ones, set the 'ignore\_cmp' flag to tell File::DirCompare to skip its  file comparison checks i.e.

  ```
    File::DirCompare->compare($dir1, $dir2, $sub,
      { ignore_cmp => 1 });
  ```

- ignore\_unique

  If you want to ignore files that only exist in one of the two  directories, set the 'ignore\_unique' flag i.e.

  ```
    File::DirCompare->compare($dir1, $dir2, $sub,
      { ignore_unique => 1 });
  ```

- matches

  Subroutine to be called for file pairs that *match*, with the following signature:

  ```
    $sub->($file1, $file2)
  ```

  These pairs are ordinarily ignored (unless `"ignore_cmp"` is set).

## SEE ALSO

File::Dircmp, which provides similar functionality (and whose  directory walking code I've adapted for this module), but a simpler reporting-only interface, something like the first example in the  SYNOPSIS above.

## AUTHOR AND CREDITS

Gavin Carr \<gavin@openfusion.com.au\>

Thanks to Robin Barker for a bug report and fix for glob problems with whitespace.

## COPYRIGHT AND LICENSE

Copyright 2006-2012 by Gavin Carr \<gavin@openfusion.com.au\>.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
