2

I have a directory structure containing a bunch of config files for an application. The structure is maintained in Subversion, and then a few systems have that directory struture checked out. Developers make changes to the struture in the repository, and a script on the servers just runs an "svn update" periodically.

However, sometimes we have people who will inadvertently remove a .svn directory under one of the directories, or stick a file in that doesn't belong. I do what I can to cut off the hands of the procedural unfaithful, but I'd still prefer for my update script to be able to gracefully (well, automatically) handle these changes.

So, what I need is a way to delete files which are not in subversion, and a way to go ahead and stomp on a local directory which is in the way of something in the repository. So, warnings like

Fetching external item into '/path/to/a/dir'
svn: warning: '/path/to/a/dir' is not a working copy

and

Fetching external item into '/path/to/another/dir'
svn: warning: Failed to add directory '/path/to/another/dir': an unversioned directory of the same name already exists

should be automatically resolved.

I'm concerned that I'll have to either parse the svn status output in a script, or use the svn C API and write my own "cleanup" program to make this work (and yes, it has to work this way; rsync / tar+scp, and whatever else aren't options for a variety of reasons). But if anyone has a solution (or partial solution) which takes care of the issue, I'd appreciate hearing about it. :)

dannysauer
  • 3,793
  • 1
  • 23
  • 30

2 Answers2

0

How about

rm -rf $project
svn checkout svn+ssh://server/usr/local/svn/repos/$project
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • I've also used `svn update --accept theirs-full project`, but it assumes the presence of a sane `.svn` directory, and I don't know if it deletes untracked files. – ikegami Apr 12 '12 at 22:21
  • While the removal will technically work, it lacks a certain elegance. :) The main issue with that is that in this situation is that it takes a while to check the directory out again (it contains around 110K files). I'd like this solution to be targeted enough that it can fix only what's broken, so as to not adversely impact the use of sections of the repository which are *not* broken. – dannysauer Apr 13 '12 at 13:07
  • Actually, it's extremely elegant as it handles broken `.svn` directories in one clear line of code. The alternative would be a hot mess. How can one possibly validate the `.svn` directory? – ikegami Apr 13 '12 at 16:06
  • It's extremely simple, but consider how you'd feel if someone referred to you as "elegant" v/s if someone called you "simple". They're different. ;) Say Joe accidentally deletes three files from his homedir. It'd be simple to wipe the drives and rebuild the whole system from backup. As far as "how do you validate a .svn directory", you run svn status on the directory containing it. If the .svn directory is broken, svn status will complain. :) – dannysauer Apr 14 '12 at 04:10
  • Then only run `rm` if `status` complains. – ikegami Apr 14 '12 at 09:54
  • As for your comment about "simple", it's a fallacy. Simple refers to lack of complexity when talking about code. That's a good thing. Simple refers to lack of intelligence when talking about people. That's a bad thing. – ikegami Apr 14 '12 at 09:54
  • I didn't say "smash it with the biggest hammer possible at the first sign of trouble" wasn't simple; I said it wasn't elegant. Though, I'd argue that there's not a whole lot of computational intelligence in those four characters, so it's a more apt metaphor than you're giving credit for. ;) In any event, I wrote a 26-line perl script to solve the problem, rather than checking out all 702MB and 178214 files in the repository over a WAN link to several geographically-distributed mirrors. :) Maybe someone in a different situation will prefer the rm route, though; thanks for taking the time. – dannysauer Apr 15 '12 at 03:21
  • Also, congrats on 28.8K reputation. The "I remember when" in me finds that incredibly entertaining. :) – dannysauer Apr 15 '12 at 03:24
0

I wrote a perl script to first run svn cleanup to handle any locks, and then parse the --xml output of svn status, removing anything which has a bad status (except for externals, which are a little more complicated)

Then I found this: http://svn.apache.org/repos/asf/subversion/trunk/contrib/client-side/svn-clean Even though this doesn't do everything I want, I'll probably discard the bulk of my code and just enhance this a little. My XML parsing is not as pretty as it could be, and I'm sure this is somewhat faster than launching a system command (which matters on a very large repository and a command which is run every five minutes).

I ultimately found that script in the answer to this question - Automatically remove Subversion unversioned files - hidden among all the suggestions to use Tortoise SVN.

Community
  • 1
  • 1
dannysauer
  • 3,793
  • 1
  • 23
  • 30
  • ...and, after a while, what I ended up doing was writing a python script using the svn API directly (not pysvn) to duplicate changes to a filesystem based on the post-commit and post-revprop-change hooks in the repo. Right now I just do a scheduled export every 6 hours to handle unauthorized changes, but I'm writing a filesystem monitor (inotify via pyinotify) to catch any non-hook-generated changes to the filesystem. Any other detected filesystem change will generate an alert and replace whatever changed with a copy from svn. Details eventually at http://blog.dannysauer.com/?tag=subversion – dannysauer May 15 '14 at 18:02