views:

287

answers:

3

What is the easiest way to run a command in each subfolder of a path? In this case I have to run svn cleanup for every directory in my repository.

+1  A: 

svn cleanup automatically recurses into subdirectories. I'm not sure why you would need to recurse manually for that particular command.

Greg Hewgill
In the root folder:>svn cleanupsvn: In directory 'main\create_course'svn: Error processing command 'committed' in 'main\create_course'svn: Working copy 'main' lockedsvn: run 'svn cleanup' to remove locks (type 'svn help cleanup' for details)when i go into the problematic folder and do an svn cleanup there first, then i get further when doing the main svn cleanup. :S
Pacifika
Interesting, sounds like a bug in cleanup. I wonder if that's specific to the Windows implementation.
Greg Hewgill
Greg: I had similar issues numerous times. Sometimes svn just seems to destroy half of its working copy and the easiest fix is to re-checkout. Although most of the cases I recently encountered were faults in SVNKit; with 64-bit Subclipse you have not much choice there :/
Joey
+3  A: 

for command is what you are looking for. In order to read about the exact syntax type for /?

For example, in order to print the names of all sub directories in the current directory. You can use the command:

for /d /r %i in (*.*) do @echo %i

The echo %i part is the part you must change to suit your case.

Can
This has the unfortunate side-effect of doing a pre-order traversal of the directory tree. So the top-level cleanup will fail before the lower-level ones are attempted, which means you have to tun that line several times before resolving the problem.
Joey
A: 

I have found that in such cases it is much easier to just delete the working copy and re-checkout. If you have local changes, then copy the changed files elsewhere first.

But Can's answer might work in your case, unless SVN has greater problems. Though you probably have to run it several times since it would begin at the root folder which would still have problems, then. You'd need some kind of post-order traversal in that case which can't be done with for /r but which can ensure that you would start with the lowest directories in the hierarchy to clean up.

You'd also need to exclude SVN's statekeeping directories .svn:

for /r /d %i in (*) do if NOT %i==.svn svn cleanup %i

As for the post-order traversal, you can build a little batch:

@echo off
call :recurse "."
goto :eof

:recurse
pushd %1
if not %~1==.svn (
    for /d %%i in (*) do call :recurse "%%i"
    echo svn cleanup %~1
)
popd
goto :eof

On the following tree:

a
├───.svn
├───a1
│   └───.svn
└───a2
    └───.svn
b
├───.svn
├───b1
│   ├───.svn
│   ├───b11
│   │   └───.svn
│   └───b12
│       └───.svn
└───b2

This yields the following output:

svn cleanup "a1"
svn cleanup "a2"
svn cleanup "a"
svn cleanup "b11"
svn cleanup "b12"
svn cleanup "b1"
svn cleanup "b2"
svn cleanup "b"
svn cleanup "."

which, as you can see, makes sure that the lowest directories are processed first and the .svn directories are skipped. Remove the echo if you want to use it. This could resolve your problem. Maybe.

Joey