views:

273

answers:

2

I have a large application in a production environment that I'm trying to move under version control. So, I created a new repo and imported the app, minus various directories and files that shouldn't be under version control. Now, I need to make the installed copy a checkout (but still retain the extra files). At this point, in a recent version of SVN, I'd simply do a checkout over top the existing directory using the --force option. But sadly, I have an ancient version of SVN, from before when the --force option was added (and can't yet upgrade... long story).

So, I checked out the app to another directory, and want to simply copy all of the .svn directories into the original directory, thus turning the original into a checkout whilst leaving alone the extra files. Now, maybe I'm just having a rough day and missing something that's in plain site, but I can't seem to be able to figure this out. Here are the approaches I've tried so far:

1) Use rsync: I can't seem to hit the right combination of include and exclude directives to recursively capture all the .svn directories but nothing else.

2) Use cp: I can't figure out a good way to have it hit all the .svn directories across and down through the whole app.

3) Use find with -exec cp: I'm running into trouble with the leading part of the pathnames of the found files messing up the destination paths. I can exclude it using -printf '%P', but that doesn't seem to go into the {} replacement for exec.

4) Use find with xargs to cp: I'm running into trouble with find sending over child directories before sending their parents. Unfortunately, find does not have a --breadth option.

Any thoughts out there?

Other info:

  • bash 3.0.0.14
  • rsync 2.6.3 p28
  • cp 5.2.1
  • svn 1.3.2
A: 

(5) Can't you just make a checkout to a different directory, then copy the extra files to that directory, verify that everything's fine before switching to running the app from the new directory?

middus
Unfortunately, this is not really a good option because the list of extra files is continuously changing as the app runs.
mr. w
A: 

Use tar and find to capture the .svn dirs in a clean checkout, then untar into your app.

cd /tmp/
svn co XXX
cd XXX
find . -name .svn -print0 | tar cf /tmp/XXX.tar -T - --null
cd /to/your/app/
tar xf /tmp/XXX.tar

Edit: switched find/tar command to use NUL terminator for robustness in the face of filenames containing spaces. Original command was:

tar cf /tmp/XXX.tar $(find . -name .svn)
bstpierre
Wow, I wasn't aware of the $(...) syntax - I assume that's a bash feature.This seems to work except for one problem: it misses files/directories that appear to the shell as multiple tokens (such as those with spaces in the name). How can I modify the tar...find command to handle these names?Example file name: "6 - the foo"Output:$ tar -cf ~/testsvn.tar \'$(find . -name .svn)\'tar: './6: Cannot stat: No such file or directorytar: -: Cannot stat: No such file or directorytar: the: Cannot stat: No such file or directorytar: foo: Cannot stat: No such file or directory
mr. w
Sorry for the mess of a comment - can't figure out how to force line breaks in comments.
mr. w
Yes, $(...) is a bash feature. Spaces in filenames are yucky. You probably want to instead use something like "find . -name .svn -print0 | tar cf /tmp/XXX.tar -T - --null". The -print0 tells find to use NUL separator characters instead of newline. The -T- tells tar to read filenames from stdin, and --null tells tar to use NUL separator characters instead of newlines.
bstpierre
Perfect! I started to attempt just that, but I couldn't figure out how to get tar to read from stdin. (Turns out that the use of hyphen for that purpose is not mentioned in the man page. In fact, 'stdin' is not mentioned at all.)Anyway, thanks a ton! That's exactly what I needed - it worked like a charm.
mr. w
Use of hyphen to refer to stdin/stdout is a fairly common feature for tools like tar.
bstpierre