diffdir
is a Bash script for comparing files in two directories. It helps identify differences between the contents of two directories, including all files and subdirectories.
If you want to compare two directories, you can use:
diff -r <source_directory> <destination_directory>
That's fine, but what if you want to ignore a .env.local
file and a local.json
file in the destination directory?
diff -r <source_directory> <destination_directory> | grep -v -E "\.env\.local$|local\.json$"
The problem with this approach is that if there are no .env.local or local.json files, you'll get an exit code 1 because grep can't find them. If there are such files, the exit code will be 0, even if the directories are completely different. In many scripting scenarios, the exit code is essential for determining whether the directories differ.
Alternatively, you can use rsync, but it also has an exit code issue. rsync will always return exit code 0:
rsync -n -r -v --exclude='*.env.local' <source_directory> <destination_directory>
In both cases (diff+grep and rsync), you could theoretically count lines with | wc -l
, but that’s not a clean solution.
With diffdir
, you can simply do this:
diffdir <source_directory> <destination_directory> --ignore-files "^/\.env\.local$|^/local\.json$"
...and you'll get the expected exit code!
You face the same problem with the exit code when you want to ignore extra files and directories in the destination directory. See more Examples.
Clone the repository from GitHub:
git clone https://github.com/doppelar0n/diffdir.git
cd diffdir
Copy the program to /usr/local/bin/ to make it globally available:
sudo cp diffdir /usr/local/bin/
Run the script with the following parameters:
./diffdir <source_directory> <destination_directory> [OPTIONS]
--fast-fail
: Enable fast fail. If a difference is found, the script exits immediately. Helpful for scripts.--find-type <string>
: Specify the types to find in the directory. The default isfd
(files and directories).--ignore-dest-extras
: Ignore extra files or subdirectories in the destination directory.--ignore-files <regex>
: Ignore files or paths matching this regex pattern.-h
,--help
: Display help message.
To compare the contents of two directories:
./diffdir /path/to/source_directory /path/to/destination_directory
Ignore all .img
files:
./diffdir /path/to/source_directory /path/to/destination_directory --ignore-files "\.img$"
Ignore all .png
and .jpeg
files:
./diffdir /path/to/source_directory /path/to/destination_directory --ignore-files "\.png$|\.jpeg$"
Ignore all .env.local
and local.json
files in root directory:
diffdir <source_directory> <destination_directory> --ignore-files "^/\.env\.local$|^/local\.json$"
Ignore all .env.local
and local.json
files in all sub directory:
diffdir <source_directory> <destination_directory> --ignore-files "/\.env\.local$|/local\.json$"
Ignore all files that ends with .env.local
or local.json
in all sub directory:
diffdir <source_directory> <destination_directory> --ignore-files "\.env\.local$|local\.json$"
Ignore any path containing abc
. This will ignore abc
in both source and destination directories, but only in sub-paths:
./diffdir /abc/path/to/source_directory /abc/path/to/destination_directory --ignore-files ".*abc.*"
Ignore all files and subdirectories that exist only in the destination directory:
./diffdir /path/to/source_directory /path/to/destination_directory --ignore-dest-extras
diffdir
uses the find
command to locate all files and directories. If you want to ignore all empty directories, you can specify the find type to only include files (f), thus ignoring empty folders:
./diffdir /path/to/source_directory /path/to/destination_directory --find-type f
If differences between files or directories are found, the script outputs a corresponding message and exits with a non-zero exit code.
Run test with:
docker run -it -v "$PWD:/code" bats/bats:latest /code/test
This project is licensed under the MIT License. See the LICENSE file for more information.