This web site uses cookies. By staying on this web site, you accept the use of cookies.

Ever wanted to search the whole subversion repository?

Did you ever remember that you coded something exactly the way you need it now but don't know the project name anymore? - Was it this one? (check out project, click through the files) No... wait, perhaps this one? (check out project, click through the files) No... *sigh*

 

At least for Subversion users the following script is a solution - you can narrow your search by regex concerning file path and content, but then search in all projects of the whole repository. Have fun with it!

#!/bin/sh
#
# svn-grep.sh <CONTENT_SEARCH_EXPRESSION> [<PATH_SEARCH_EXPRESSION>]
#             - both arguments are regular expressions for egrep
#             - the second argument is optional
#             - branches and tags excluded, only searches in trunk
#
# example: ./svn-grep.sh "sun\.misc\.Unsafe" "\.java\$"
#

if [ "x$1" == "x" ]; then
	echo "no content search expression - cancelled"
	exit 1
fi

# local access is much faster, so use it if you can:
BASEURL="file:///opt/svn-repo/projects"
#BASEURL="https://svn.mydomain.com/projects"

SEARCH=$1
NAMEEXCLUDE="\(/tags/\|/branches/\|/\$\)"
NAMESEARCH='.'

if [ "x$2" != "x" ]; then
	NAMESEARCH="$2"
fi

echo ""
echo "starting a search in $BASEURL for $SEARCH in files with a path like $NAMESEARCH"
echo ""
echo "step 1/2: collecting all paths to be considered (can take some time)..."
TEMPFILE=$(mktemp /tmp/svn-grep.XXXXXXXXXX)
svn ls -R "$BASEURL" | grep -v -e "$NAMEEXCLUDE" | grep -e "$NAMESEARCH" >$TEMPFILE &
SVN_LS_PID=$!
while ps -p $SVN_LS_PID >/dev/null; do
	sleep 1
	TEMPFILE_LINES=$(cat $TEMPFILE | wc -l)
	echo -ne  "\r [ found $TEMPFILE_LINES candidates ] "
done
TEMPFILE_LINES=$(cat $TEMPFILE | wc -l)
echo -e "\rstep 1/2 finished, found $TEMPFILE_LINES candidates"
echo ""

echo "step 2/2: search through the contents of all candidates"
echo "-----------------------------------------"
i=0

cat $TEMPFILE | while read file;
do
	result=$(svn cat "$BASEURL/$file" | grep -e $SEARCH)
	i=$(($i+1))
	if [ -n "$result" ]; then
		echo -e "\r$file"
	else
		percent=$(bc <<<"scale=1; 100*$i/$TEMPFILE_LINES")
		if [ $(($i%50)) == 0 ]; then
			echo -ne "\r [ ${percent} % ] "
		fi
	fi
done

echo -e "\r-----------------------------------------"
echo "step 2/2 finished"

rm $TEMPFILE