Subversion cp annoyance

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:

  1. 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.
  2. Syntax was wrong because the java directory was now versioned. Hence, command behaved as expected.
  3. Copy of java failed because it's already versioned. Subversion doesn't do recursive copy as expected, but instead complains.
  4. Tried a wildcard character, which Subversion obviously doesn't support.
  5. Wondered if Subversion assumes you're referencing the contents of a directory if you preceed it with a slash. It doesn't.
  6. 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.

Last modified: 30/03/2005 (most likely earlier as a site migration in 2006 reset some dates) Tags: (none)

This website is a personal resource. Nothing here is guaranteed correct or complete, so use at your own risk and try not to delete the Internet. -Stephan

Site Info

Privacy policy

Go to top