I often use the find command to search through source code, delete files, whatever. Annoyingly, because Subversion stores duplicates of each file in its .svn/text-base/ directories my simple searches end up getting lots of duplicate results. For example, I want to recursively search for uint in multiple messages.h and messages.cpp files:
# find -name 'messages.*' -exec grep -Iw uint {} +
./messages.cpp: Log::verbose << "Discarding out of date message: id " << uint(olderMessage.id)
./messages.cpp: Log::verbose << "Added to send queue: " << *message << ": id " << uint(preparedMessage->id)
./messages.cpp: Log::error << "Received message with invalid SHA-1 hash: id " << uint(incomingMessage.id)
./messages.cpp: Log::verbose << "Received " << *message << ": id " << uint(incomingMessage.id)
./messages.cpp: Log::verbose << "Sent message: id " << uint(preparedMessage->id)
./messages.cpp: Log::verbose << "Discarding unsent message: id " << uint(preparedMessage->id)
./messages.cpp: for (uint i = 0; i < 10 && !_stopThreads; ++i) {
./.svn/text-base/messages.cpp.svn-base: Log::verbose << "Discarding out of date message: id " << uint(olderMessage.id)
./.svn/text-base/messages.cpp.svn-base: Log::verbose << "Added to send queue: " << *message << ": id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base: Log::error << "Received message with invalid SHA-1 hash: id " << uint(incomingMessage.id)
./.svn/text-base/messages.cpp.svn-base: Log::verbose << "Received " << *message << ": id " << uint(incomingMessage.id)
./.svn/text-base/messages.cpp.svn-base: Log::verbose << "Sent message: id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base: Log::verbose << "Discarding unsent message: id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base: for (uint i = 0; i < 10 && !_stopThreads; ++i) {
./virus/messages.cpp:void VsMessageProcessor::_progress(const string &fileName, uint scanCount)
./virus/messages.cpp:ProgressMessage::ProgressMessage(const string &fileName, uint scanCount)
./virus/messages.h: void _progress(const std::string &fileName, uint scanCount);
./virus/messages.h: ProgressMessage(const std::string &fileName, uint scanCount);
./virus/messages.h: uint _scanCount;
./virus/.svn/text-base/messages.cpp.svn-base:void VsMessageProcessor::_progress(const string &fileName, uint scanCount)
./virus/.svn/text-base/messages.cpp.svn-base:ProgressMessage::ProgressMessage(const string &fileName, uint scanCount)
./virus/.svn/text-base/messages.h.svn-base: void _progress(const std::string &fileName, uint scanCount);
./virus/.svn/text-base/messages.h.svn-base: ProgressMessage(const std::string &fileName, uint scanCount);
./virus/.svn/text-base/messages.h.svn-base: uint _scanCount;
How can I tell find to ignore the .svn directories?
Update: If you upgrade your SVN client to version 1.7 this is no longer an issue.
A key feature of the changes introduced in Subversion 1.7 is the centralization of working copy metadata storage into a single location. Instead of a
.svndirectory in every directory in the working copy, Subversion 1.7 working copies have just one.svndirectory—in the root of the working copy. This directory includes (among other things) an SQLite-backed database which contains all of the metadata Subversion needs for that working copy.
find ... -print0 | xargs -0 egrep ...instead offind ... -exec grep ...(does not forkgrepfor each file, but for a bunch of files at a time). Using this form you can also prune.svndirectories without using the-pruneoption of find, i.e.find ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...- vladr-execwith+doesn't forkgrepfor each file, while using it with;does. Using-execis actually more correct than usingxargs. Please notice that commands likelsdo something even if the argument list is empty, while commands likechmodgive an error if there is insufficient arguments. To see what I mean, just try the following command in a directory that does not have any shell script:find /path/to/dir -name '*.sh' -print0 | xargs -0 chmod 755. Compare with this one:find /path/to/dir -name '*.sh' -exec chmod 755 '{}' '+'. - Siu Ching Pong -Asuka Kenji-grep-ing out.svnis not a good idea too. Whilefindis specialized for handling file properties,grepdoes not. In your example, a file named '.svn.txt' will also be filtered by youregrepcommand. Although you can modify your regex to '^/\.svn$', it is still not a good practice to do so. The-prunepredicate offindworks perfectly for filtering a file (by filename, or creation timestamp, or whatever condition you supplied). It is just like even if you can kill a cockroach using a big sword doesn't mean it is the suggested way to do so :-). - Siu Ching Pong -Asuka Kenji-