Below is a transcript that shows how long it took me to copy one directory to another using svn. All I wanted to do was copy the com subdirectory of the original/java/ directory into the customised/java/ directory. On a normal filesystem this could be achieved with cp original/java/com customised/java/.
Looking back over the transcript I see what went wrong. The problem occurred because the java subdirectory of customised was not already versioned. This must have lead to Subversion scheduling the addition of the java directory to customised in the repository. Why it then ignored the com directory and yet still continued to add it's contents to customised/java/ is anybody's guess.
So the standard Linux cp command doesn't map to the Subversion cp command - the Subversion command of:
svn cp original/java/com customised/java/
maps to the Linux command of:
cp original/java/com/* customised/java/
Anyway, here's the transcript. Following it is a description of what I did wrong (apart from not reading the documentation ;-)).
--- Start ---
bash$ ls customised original bash$ ls original/java com source bash$ ls customised/java --- 1. First attempt --- bash$ svn cp original/java/com customised/java/ A customised/java bash$ svn commit Adding code/customised/java Committed revision 61. bash$ ls customised/java steph --- Now I delete the contents of customised/java/ because it's wrong --- bash$ svn rm customised/java/* D customised/java/steph/file/CmsProject.java D customised/java/steph/file/CmsManager.java -- Snip -- bash$ svn commit Deleting code/customised/java/steph Committed revision 62. bash$ pwd /mnt/store/cal/svn/apps/cms/code --- 2. Try the copy again, with a slightly different syntax --- bash$ svn cp original/java customised/java A customised/java/java bash$ svn rm customised/java/java svn: Use --force to override this restriction svn: 'customised/java/java/source' is not under version control bash$ svn status ? customised/java/java/source A + customised/java/java bash$ svn rm customised/java/java --force D customised/java/java bash$ svn status bash$ ls customised original bash$ ls customised java bash$ ls customised/java bash$ ls original/java com source --- 3. Try again --- bash$ svn cp original/java customised svn: Destination 'customised/java' already exists --- 4. And again --- bash$ svn cp original/java/* customised/java/ copy (cp): Duplicate something in working copy or repository, remembering history. usage: copy SRC DST SRC and DST can each be either a working copy (WC) path or URL: WC -> WC: copy and schedule for addition (with history) WC -> URL: immediately commit a copy of WC to URL URL -> WC: check out URL into WC, schedule for addition URL -> URL: complete server-side copy; used to branch & tag Valid options: -m [--message] arg : specify commit message ARG -F [--file] arg : read data from file ARG -r [--revision] arg : ARG (some commands also take ARG1:ARG2 range) A revision argument can be one of: NUMBER revision number "{" DATE "}" revision at start of the date "HEAD" latest in repository "BASE" base rev of item's working copy "COMMITTED" last commit at or before BASE "PREV" revision just before COMMITTED -q [--quiet] : print as little as possible --username arg : specify a username ARG --password arg : specify a password ARG --no-auth-cache : do not cache authentication tokens --non-interactive : do no interactive prompting --force-log : force validity of log message source --editor-cmd arg : use ARG as external editor --encoding arg : treat value as being in charset encoding ARG --config-dir arg : read user configuration files from directory ARG --- 5. And again --- bash$ svn cp original/java/ customised/java/ A customised/java/java --- Bloody hell --- bash$ svn rm customised/java/* svn: Use --force to override this restriction svn: 'customised/java/java' has local modifications bash$ svn rm customised/java/* --force D customised/java/java bash$ svn commit --- 6. Finally --- bash$ svn cp original/java/com/ customised/java/ A customised/java/com bash$ svn commit Adding code/customised/java/com Committed revision 64. bash$ svn cp original/java/source/ customised/java/ A customised/java/source bash$ svn commit Adding code/customised/java/source Committed revision 65. bash$
--- end ---
Here's what must have happened on the copy attempts:
- Attempted to copy something into a local directory that wasn't versioned. Subversion does odd things - it versions java but copies the wrong files into it.
- Syntax was wrong because the java directory was now versioned. Hence, command behaved as expected.
- Copy of java failed because it's already versioned. Subversion doesn't do recursive copy as expected, but instead complains.
- Tried a wildcard character, which Subversion obviously doesn't support.
- Wondered if Subversion assumes you're referencing the contents of a directory if you preceed it with a slash. It doesn't.
- Finally, resorted to referencing contents of java one by one.
The lesson of this story? - the Subversion cp command is significantly less powerful than the Linux filesystem one and I shouldn't have assumed it wasn't.