Best way to recursively ignore a file or directory pattern in SVN without globally ignoring
Many times temporary files are created as the result of a compilation or opening of a project file. I want SVN to ignore (not version) these files where they are created without having to globally ignore them since different programs/processes may create them elsewhere and they could require versioning (same extension different file type). What's the best way to do this using Bash and SVN? Is the following bash script I created sufficient?
# Recursively find, remove, and set svn:ignore on files or folders.
# For safety, you must perform an svn status and an svn commit yourself.
#
# $1 is the pattern to ignore
# $2 is the starting directory (optional)
# $3 is a flag to remove the ignored files locally (optional)
#
# Example: recursive_svn_ignore "*.bak" . --remove
#
recursive_svn_ignore ()
{
cd "$2";
svn info > /dev/null 2>&1;
if [ "$?" -ne "0" ]; then
echo "Skipping `pwd` because it is not under version control.";
return 1;
fi;
# Check if pattern matches
ls -l $1 > /dev/null 2>&1;
if [ "$?" = "0" ]; then
for f in "$1"; do
if [ "$3" = "--remove" ]; then
# Remove file from working directory and repository
svn rm --force -q $f;
else
# Remove file from repository only
svn rm --force --keep-local $f;
fi;
done
echo "Adding "$1" in `pwd` to svn:ignore list";
svn propget svn:ignor开发者_StackOverflow社区e . > svnignore.tempfile;
echo "$1" >> svnignore.tempfile;
svn propset -q svn:ignore -F svnignore.tempfile .;
rm svnignore.tempfile;
fi;
# Recurse
for d in *
do
if [ -d "$d" ]; then
( recursive_svn_ignore "$1" "$d" )
fi;
done
}
As suggested by @david-van-brink, using find
simplifies things a lot by eliminating the recursion. This is what I have come up with.
#!/bin/bash
# Recursively find and set svn:ignore on files or folders.
# If the file was already version it will be removed from the repository
# and keep the local copy (can be overridden).
# This does not perform the final commit so you can review the changes
# using svn status.
#
# $1 pattern to ignore
# $2 remove the ignored files locally as well (optional)
#
# Example: find_svn_ignore "*.bak" . --remove
#
for a in `find . -name $1`
do
svn info ${a%/*} > /dev/null 2>&1;
if [ "$?" -ne "0" ]; then
echo "Skipping ${a%/*} because it is not under version control.";
continue;
fi;
echo "Ignoring ${a##*/} in ${a%/*}";
svn propget svn:ignore ${a%/*} > svnignore.tempfile;
echo "$1" >> svnignore.tempfile;
svn propset -q svn:ignore -F svnignore.tempfile ${a%/*};
rm svnignore.tempfile;
if [ "$2" = "--remove" ]; then
# Remove file from working directory and repository
svn rm --force -q ${a##*/};
else
# Remove file from repository only
svn rm --force --keep-local ${a##*/};
fi;
done
Using "find" might be nicer. Something like:
for a in `find . -name '*.bak'`
do
echo something $a
echo something else to $a
done
Or pass in the pattern as an argument to the function. Replace my "echo somethings" with your work-logic. It just avoids the actual recursion, to use "find" this way.
Of course, really you should adjust your flow to generate files somewhere else, or at least in just one "output" folder, for tidiness, wherever possible, so you're not needing to ignore an ever-growing list of files.
But yeah, some tools aren't so tidy as we'd like, alas.
Maybe there is something else you can do.
Why not simply ban files with certain suffixes from being placed into your Subversion repository?
I have a hook script that does just that. You give it a glob pattern or regular expression, and if a file is being added to the repository with a name that match that glob pattern or regular expression, the commit won't happen. The developer is given an error message, and must delete the added file before the commit will go through.
This does several things:
- Developers will add the ignore pattern themselves.
- They will start moving built objects into other directories
- They make sure their clean functions in their build scripts really clean up all the garbage the compile creates.
Otherwise, you'll have to keep running your script over and over. And somewhere along the line, some developer is going to check in something that they shouldn't have been, and it will be your fault because you took upon yourself to prevent this from happening.
精彩评论