Using find in Subversion working copies

The POSIX find command is extremely convenient and powerful for searching out files and features of the filesystem. In combination with its -exec action it can make changes to many files based on nuanced characteristics. I can’t live without it.

However, it’s inconvenient to use find in Subversion working copies because of all the .svn folders. Find searches within all of them, and since they contain duplicates of the files in the working copy itself, things get cumbersome fast.

You can work around this by pruning .svn:

find . -name .svn -prune -o -print

but find’s -prune flag is pretty intricate and befuddles even the smartest administrators and developers from time-to-time, especially if you don’t understand the default action, -print.

To make this easier, I’ve written a shell function that automatically prunes “.svn” and anything found in the svn property “svn:ignore” in the target path. Feel free to use this if you find it convenient.

svnfind() {
	# find things in an svn working copy
	# excluding .svn dirs and anything
	# in the target directory's svn:ignores
	local ignores=()
	local IFS=$'\n'
	local path

	# GNU no-path compatibility
	case "$1" in
		-*) path=".";;
		*) path="$1"; shift;;

	set -f # turn off globbing temporarily
	local _ignores=( $(svn pg svn:ignore "$path") )
	for i in "${_ignores[@]}"; do
		ignores+=( -o -name "$i" )
	set +f

	# If find contains no "actions" other than -prune,
	# append the default action of -print
	local default="-print"
	for arg; do
		case "$arg" in
				unset default
	# $default must be unquoted here
	find "$path" \( -name .svn "${ignores[@]}" \) -prune -o "$@" $default