Directory Diff & Sync Report Tool
Build a command-line tool in C that compares two directory trees and reports what's different: files that exist only on the left, only on the right, and files present in both but with different content. It works like a simplified diff -r and is useful for checking a backup against the original. It walks both trees with opendir and readdir, reads file metadata with stat, compares file contents byte by byte when sizes match, and prints a clear report. You'll practice recursion, dynamic memory in C (growing arrays, string building), sorting with qsort, and careful error handling with errno.
- Estimate
- ~12.5h
- Steps
- 7
- Completed by
- 0
- Proposed by
- codeseed.app
dirent.h · sys/stat.h
Project roadmap
- 01
Set up the program
~1hCreate dirdiff.c and a Makefile that builds with -Wall -Wextra -std=c11. The program takes two directory paths and exits with code 2 and a usage message if either is missing or isn't a directory. Exit codes: 0 when the trees are identical, 1 when differences are found, 2 for errors. Done when: make builds the program and bad arguments print the usage.
- 02
Walk a directory tree
~2.5hWrite a recursive function that walks a tree with opendir and readdir, skipping . and .., and collects each regular file's path relative to the root into a dynamic array that grows with realloc. Use lstat and skip symbolic links. Print a message with strerror(errno) for directories that can't be opened, and continue. Done when: the program prints every relative file path of a test tree.
- 03
Find added and removed files
~2hBuild the list for both trees and sort each with qsort and strcmp. Walk the two sorted lists together, like the merge step of merge sort, to find paths only on the left (removed), only on the right (added), and in both. Done when: with two test trees, the program lists exactly the removed and added files.
- 04
Compare files present in both
~2hFor each path found in both trees, compare the sizes from stat first; different sizes mean modified. If the sizes match, compare the contents in 4 KB blocks with fread and memcmp, stopping at the first difference. Done when: files that differ only in content are reported as modified, and identical files are not.
- 05
Print a clear report
~1.5hPrint the results grouped under Removed, Added and Modified, one path per line, with the size change for modified files (for example 1204 -> 1310 bytes), followed by a summary line with the three counts. Add a --quiet flag that prints only the summary. Done when: the report and the exit code are correct for identical and for different trees.
- 06
Exclude files by pattern
~1.5hAdd one or more --exclude PATTERN options that skip matching files and directories, using fnmatch from fnmatch.h, for example --exclude '*.tmp' --exclude .git. Excluded directories must not be walked at all. Done when: excluded files never appear in the report.
- 07
Test it and check memory
~2hWrite a shell script tests/run.sh that creates test trees (identical, added, removed and modified files, nested folders, an excluded file), runs the program, and checks the output and exit codes. Run it under valgrind --leak-check=full and fix any leaks. Done when: the script passes and valgrind reports no leaks.
Resources
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack