Skip to content

Instantly share code, notes, and snippets.

@MichaelChirico
Last active September 30, 2025 20:36
Show Gist options
  • Save MichaelChirico/2f5e578c3464ea584bd4a006563ecd94 to your computer and use it in GitHub Desktop.
Save MichaelChirico/2f5e578c3464ea584bd4a006563ecd94 to your computer and use it in GitHub Desktop.
Find range of SVN commits where a file matches a pattern
#!/bin/bash
# GENERATED BY GEMINI
# Configuration Variables
# The path to the file in the SVN repository
FILE_PATH="src/library/parallel/NAMESPACE"
# The pattern you are searching for (case-sensitive)
SEARCH_PATTERN="splitList"
# --- Script Logic ---
echo "--- SVN Commit Range Finder ---"
echo "File: $FILE_PATH"
echo "Pattern: $SEARCH_PATTERN"
echo ""
# Function to get the commit date (YYYY-MM-DD HH:MM:SS +/-TZ) for a given revision.
# It relies on the standard svn log output format.
get_commit_date() {
local rev=$1
# svn log -r REV --limit 1 fetches the specific log entry for the revision.
# We filter for the line starting with 'r' and extract the date/time fields (usually fields 5, 6, 7).
svn log -r "$rev" --limit 1 "$FILE_PATH" 2>/dev/null | \
grep -E '^r[0-9]+' | awk '{print $5, $6, $7}'
}
# 0. Check if the file is even under Subversion control (not just a local file).
SVN_STATUS=$(svn info "$FILE_PATH" 2>&1)
SVN_INFO_EXIT_CODE=$?
if [ "$SVN_INFO_EXIT_CODE" -ne 0 ]; then
echo "Error: The file '$FILE_PATH' is likely not under Subversion control at this path,"
echo " or you are not running this script from within an SVN working copy."
echo " svn info failed with: $(echo "$SVN_STATUS" | head -n 1)"
echo " Please ensure the file has been committed at least once and the path is correct."
exit 1
fi
# 1. Fetch all revision numbers that affected the file path.
# Using the fixed -r option.
REVS_LOG=$(svn log --quiet -r 1:HEAD "$FILE_PATH" 2>&1)
LOG_EXIT_CODE=$?
if [ "$LOG_EXIT_CODE" -ne 0 ]; then
echo "Error: svn log failed for '$FILE_PATH'."
echo " SVN reported: $REVS_LOG"
exit 1
fi
# Filter the log output to get revision numbers.
REVS=$(echo "$REVS_LOG" | grep -E '^r[0-9]+' | awk '{print $1}' | sed 's/r//g' | sort -n)
if [ -z "$REVS" ]; then
echo "Error: Could not find any history (commits) for file $FILE_PATH. It may be a newly added file awaiting its first commit."
exit 1
fi
FIRST_MATCH=""
LAST_MATCH=""
MATCH_COUNT=0
# 2. Iterate through relevant revisions and check the file content.
echo "Scanning $(echo $REVS | wc -w) historical revisions..."
for REV in $REVS; do
# Use svn cat -r to get the file content at this specific revision.
if svn cat -r $REV "$FILE_PATH" 2>/dev/null | grep -q "$SEARCH_PATTERN"; then
if [ -z "$FIRST_MATCH" ]; then
FIRST_MATCH=$REV
fi
LAST_MATCH=$REV
MATCH_COUNT=$((MATCH_COUNT + 1))
fi
done
# 3. Report the findings.
echo ""
if [ "$MATCH_COUNT" -gt 0 ]; then
# Fetch the dates for the boundary revisions
FIRST_DATE=$(get_commit_date $FIRST_MATCH)
LAST_DATE=$(get_commit_date $LAST_MATCH)
echo "SUCCESS: Found '$SEARCH_PATTERN' in $MATCH_COUNT unique revisions."
echo "The pattern was present in the overall commit range:"
echo " First Match: r$FIRST_MATCH ($FIRST_DATE)"
echo " Last Match: r$LAST_MATCH ($LAST_DATE)"
echo ""
echo "This means the line has existed (at least intermittently) since commit r$FIRST_MATCH up to r$LAST_MATCH."
else
echo "RESULT: Pattern '$SEARCH_PATTERN' was NOT found in any revision of $FILE_PATH."
fi
# To use this script:
# 1. Save it as svn-range-finder.sh
# 2. Make it executable: chmod +x svn-range-finder.sh
# 3. Run it from inside a working copy or a location with SVN access.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment