Skip to content

Instantly share code, notes, and snippets.

@siddontang
Created December 2, 2023 01:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save siddontang/5d62de34bea8e0feb84ad7922d695143 to your computer and use it in GitHub Desktop.
Save siddontang/5d62de34bea8e0feb84ad7922d695143 to your computer and use it in GitHub Desktop.
Diff two directories and output the differences
#!/bin/bash
# Check for the correct number of arguments
if [ "$#" -ne 3 ]; then
echo "Usage: $0 <directory1> <directory2> <output_directory>"
exit 1
fi
# Assign arguments to variables
DIR1="$1"
DIR2="$2"
OUTPUT_DIR="$3"
# Create output directory if it doesn't exist
mkdir -p "$OUTPUT_DIR"
# Function to create a safe filename from a full path
function create_safe_filename {
echo "$1" | sed "s|$DIR1/||; s|/|_|g; s|$DIR2/||"
}
# Function to handle unique directories
function handle_unique_directory {
UNIQUE_DIR_PATH="$1"
SAFE_DIR_NAME=$(create_safe_filename "$UNIQUE_DIR_PATH")
# Iterate over each file in the unique directory
find "$UNIQUE_DIR_PATH" -type f | while read -r file; do
# Generate output file name for each file in the unique directory
SAFE_FILE_NAME=$(create_safe_filename "$file")
OUTPUT_FILE="$OUTPUT_DIR/$SAFE_DIR_NAME.$SAFE_FILE_NAME.unique.diff"
# Create a diff file for the unique file
echo "Unique file in $UNIQUE_DIR_PATH: $file" > "$OUTPUT_FILE"
cat "$file" >> "$OUTPUT_FILE"
done
}
# Compare directories and get differing files and directories, excluding .git
diff -qr --exclude=".git" "$DIR1" "$DIR2" | while read -r line; do
if [[ "$line" == "Only in"* ]]; then
# Handle unique files and directories
# Extract the directory path and file/directory name
UNIQUE_PATH=$(echo "$line" | cut -d' ' -f3-)
UNIQUE_DIR=$(echo "$UNIQUE_PATH" | cut -d':' -f1)
UNIQUE_ITEM=$(echo "$UNIQUE_PATH" | cut -d':' -f2 | xargs)
# Check if it's a directory or file
if [ -d "$UNIQUE_DIR/$UNIQUE_ITEM" ]; then
# Handle unique directory
handle_unique_directory "$UNIQUE_DIR/$UNIQUE_ITEM"
elif [ -f "$UNIQUE_DIR/$UNIQUE_ITEM" ]; then
# Handle unique file
FULL_PATH="$UNIQUE_DIR/$UNIQUE_ITEM"
SAFE_OUTPUT_FILE=$(create_safe_filename "$FULL_PATH")
OUTPUT_PATH="$OUTPUT_DIR/$SAFE_OUTPUT_FILE.unique.file.diff"
# Copy the content of the unique file into the diff file
echo "Unique file: $FULL_PATH" > "$OUTPUT_PATH"
cat "$FULL_PATH" >> "$OUTPUT_PATH"
fi
elif [[ "$line" == "Files"* ]]; then
# Extract file paths
FILE1=$(echo "$line" | cut -d' ' -f2)
FILE2=$(echo "$line" | cut -d' ' -f4)
# Generate output file name based on FILE1's full path
SAFE_OUTPUT_FILE=$(create_safe_filename "$FILE1")
OUTPUT_PATH="$OUTPUT_DIR/$SAFE_OUTPUT_FILE.diff"
# Generate diff file
diff "$FILE1" "$FILE2" > "$OUTPUT_PATH"
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment