Last active
September 30, 2025 20:36
-
-
Save MichaelChirico/2f5e578c3464ea584bd4a006563ecd94 to your computer and use it in GitHub Desktop.
Find range of SVN commits where a file matches a pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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