#!/bin/bash # Generate a diff of framework files against the upstream version this # project is based on. Useful for contributing changes back to diachron. # # Usage: # ./diff-upstream.sh # diff against .diachron-version # ./diff-upstream.sh # diff against a specific ref # ./diff-upstream.sh --stat # show changed files only set -eu set -o pipefail IFS=$'\n\t' DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" stat_only=false ref="" for arg in "$@"; do case "$arg" in --stat) stat_only=true ;; *) ref="$arg" ;; esac done if [ -z "$ref" ]; then if [ ! -f "$DIR/.diachron-version" ]; then echo "Error: .diachron-version not found and no ref specified." >&2 echo "Usage: $0 [--stat] []" >&2 exit 1 fi ref=$(cat "$DIR/.diachron-version") fi cached_repo="$HOME/.cache/diachron/v1/repositories/diachron.git" if [ ! -d "$cached_repo" ]; then echo "Error: cached repository not found at $cached_repo" >&2 echo "Run ./update-cached-repository.sh first." >&2 exit 1 fi # Update cached repo "$DIR/update-cached-repository.sh" # Verify ref exists if ! git -C "$cached_repo" rev-parse --verify "$ref^{commit}" >/dev/null 2>&1; then echo "Error: ref '$ref' not found in cached repository." >&2 exit 1 fi # Read file-list files=() while IFS= read -r line; do [[ "$line" =~ ^[[:space:]]*# ]] && continue [[ -z "$line" ]] && continue files+=("$line") done < "$DIR/file-list" # Check out upstream into a temp directory tmpdir=$(mktemp -d) cleanup() { rm -rf "$tmpdir"; } trap cleanup EXIT git clone --quiet "$cached_repo" "$tmpdir/upstream" git -C "$tmpdir/upstream" checkout --quiet "$ref" # Generate diff if $stat_only; then diff -rq "$tmpdir/upstream" "$DIR" \ --no-dereference \ 2>/dev/null \ | grep -v '^\.' \ || true # Simpler: just list files that differ for f in "${files[@]}"; do # Skip directories [ -d "$DIR/$f" ] && continue upstream="$tmpdir/upstream/$f" local="$DIR/$f" if [ ! -f "$upstream" ] && [ -f "$local" ]; then echo "added: $f" elif [ -f "$upstream" ] && [ ! -f "$local" ]; then echo "removed: $f" elif [ -f "$upstream" ] && [ -f "$local" ]; then if ! diff -q "$upstream" "$local" >/dev/null 2>&1; then echo "modified: $f" fi fi done else for f in "${files[@]}"; do [ -d "$DIR/$f" ] && continue upstream="$tmpdir/upstream/$f" local="$DIR/$f" if [ ! -f "$upstream" ] && [ -f "$local" ]; then diff -u /dev/null "$local" \ --label "a/$f" --label "b/$f" \ || true elif [ -f "$upstream" ] && [ ! -f "$local" ]; then diff -u "$upstream" /dev/null \ --label "a/$f" --label "b/$f" \ || true elif [ -f "$upstream" ] && [ -f "$local" ]; then diff -u "$upstream" "$local" \ --label "a/$f" --label "b/$f" \ || true fi done fi