views:

400

answers:

3

My situation is that a bunch of files are checked into svn which are very annoying to have under source control (specifically a log4j.properties file), and I would like to remove them from version control. I already know how to remove a file from svn version control in my own local working copy, as in this question and this one, but that's not exactly what I'm looking for.

The problem is that once I remove the file with svn rm --keep-local, when every other user pulls from the repository their local copies of log4j.properties will disappear and their environments will crash. What I want to do is remove the file from version control in the repository, but also make it so that when everyone else pulls from the repository it will be as though they had used --keep-local on their own machines, so that the existing copy of their log4j.properties file sticks around but becomes unversioned.

Is this even possible to do? I suspect it's a feature that svn just doesn't have.

+2  A: 

What I usually do in similar situations is to rename the repository copy of log4j.properties to log4j.properties.template or log4j.properties.default, and I add log4j.properties to the svn:ignore list. Then every user has to copy that file to log4j.properties in their working copy. To make it a little more friendly, you can put a check in your build script that prints out a reminder message if it doesn't find the local copy.

Don Kirkby
We actually have something very similar for a lot of these files, and part of spinning up a fresh environment involves copying these files. But I don't want to have to make everyone copy the files I'm removing from svn all over again.
Tim Gilbert
@Tim: sometimes growing requires a bit of pain.
Chris Lively
However, the build script idea is intriguing - I suppose I could write a script that automatically copied the sample files over the actual ones if they didn't exist, and then just go for it and nuked the existing copies out of the repository. But that's a different question...
Tim Gilbert
+3  A: 

If you really have a lot of such files, you can kill two birds with one stone by using a svndumpfilter operation. The idea is to make a dump of the repository on the server, filter out files you don't want to keep, and load the result in a new repository. Then you put the new one instead of the old one.

This has to be done with care, when users don't access the repository obviously. But it will actually remove the files (interesting when they are big) instead of keeping them in the history. As a side-effect, the next time a user does an update, these files will be ignored as if they were never in the repository. We had to do that a few times to remove binaries that didn't have their place there.

Link to the related documentation.

Simple example (the command offers more flexibility of course):

svnadmin create repos_new
svnadmin dump repos | svndumpfilter exclude trunk/log4j.properties | svnadmin load repos_new

Since it touches to the repository on the server, I want to emphasize again that you should take precautions (keep your old repository). For not-so-annoying files the method proposed by Don is less drastic and preferable.

To avoid this kind of situation, you can set the corresponding svn:ignore properties in the directories, you can also encourage people to use global ignores (they have to be set on each client unfortunately), or even use the hook-scripts to preemptively refuse categories of files.

RedGlyph
Good gravy. This seems like a lot of work, and dangerous to boot (besides which I don't have shell access to the repository). But it does seem like a solution.
Tim Gilbert
The amount of work is mainly telling which files to exclude, you can do that in several steps as better explained in the link. Good news is you won't actually touch the original repository, in the worst case you will just have to recreate the new one. Move the original elsewhere, rename the new one as the original, verify that everything is fine and you're done :-)
RedGlyph
+1  A: 

The secret is to make sure it's on the ignore list before you commit the delete. If you do it in that order, the delete won't propagate to others' working copies.

We're still using svn 1.4 so the --keep-local option isn't available. But you can achieve the same thing by deleting it using a server path and a -m commit message.

So in my example I accidentally committed a directory called nbproject. That is where developer project setting for the IDE we use (NetBeans). I didn't want to delete that from everyone's working copies or they'd lose all their settings! But this did the trick. Starting from the parent directory:

$ cd trunk
$ svn propedit svn:ignore .

brings up $EDITOR

add nbproject on its own line and save

$ svn commit -m 'Ignore nbproject'
$ svn rm https://.../trunk/nbproject -m 'Remove nbproject from svn'
Colin Kelley