tags:

views:

121

answers:

3

How could I use find unix utility to find all working copies on the machine? For example, I can use find / -name .svn -type d command, but it outputs all redundant results (a lot of subfolders), while I need only parent directory of working copy to be shown.

There is related question, but it does not really help in my case: http://stackoverflow.com/questions/1242364/

+5  A: 

Update 3 - sorted output of find to ensure .svn comes before hidden files. still might fail for checked-in hidden directories.


Perl can remove the nested paths for you:

find -s . -ipath *.svn | perl -lne's!/\.svn$!!i;$a&&/^$a/||print$a=$_'

In human, this says: for each svn path, ignoring the /.svn part, if the current path is a child of the last path I printed, don't print it.

example: for the directory structure:

$ find .
.
./1
./1/.svn
./1/1
./1/1/.svn
./2
./2/.svn
./3

this yields

./1
./2
Alex Brown
nope. it does not work as supposed. child directories are still shown
altern
can you please give me some example input that fails to work correctly?
Alex Brown
@Alex Brown: I got list of folders as the result ./REL_1.0/archive/pubupdate ./REL_1.0/archive ./REL_1.0/meta ./REL_1.0/backend ./REL_1.0/doc ./REL_1.0/src ./REL_1.0while only REL_1.0 folder is the parent svn repository
altern
Looks like when you run `find` it is returning the results *depth-first*. Are you sure you aren't accidentally adding a `-d` or `-depth` option to find (which would have this effect)? If you can't see it on the command-line, check your `alias`es (run `alias`) and see if `find` has been aliased to `find -d`
Alex Brown
No, find is ok: no aliases or -d flags
altern
okay, I see what's happening - it's not depth first, it only looks like that after you prune `.svn`. let's put the sort back in - add a -s option to find. This will mean that `./REL_1.0/archive/.svn` comes before `/REL_1.0/archive/pubupdate` (and hence `/REL_1.0/archive/pubupdate/.svn`)
Alex Brown
+1  A: 

maybe something like this?

#!/bin/bash
if [ -d "$1/.svn" ]; then
        echo $1
else
        for d in $1/*
        do
                if [ -d "$d" ]; then
                        ( $0 $d )
                fi;
        done
fi;

name it, for example - find_svn.sh, make it executable, and call like ./find_svn.sh /var/www (may need some tweaking to normalize directory name(s), strip trailing slash.. but works for me in this form, when called on some dir without trailing slash).

parserr
A: 

if you have GNU find/sort

find /path -type f -name ".svn*" -printf "%h\n"  | sort -u
ghostdog74