Subversion bulk move

The version control system Subversion comes with a handy function to copy or move an already versioned file from one place in the repository to another: The command svn move.

This is particularly good (and superior over, for example, CVS which is unable to do so) because the version history of the file is kept, and also the copy on the server is done lazily, meaning just because the file was copied there won’t be a second physical copy created on the server (yet, until you write to it).

A drawback of the command, though, is that it is only possible to move one single file or directory at a time. If you have a lot of files to be moved, this can get very tedious.

However, if the files you want to cover have something to be distinguished by, you may try the following (which I blog here mainly so I can get back later when I have forgotten the syntax again ;) ):

find . -name "06*" -maxdepth 1 -exec svn mv "{}" 2006/ \;

Note that I am filtering by name here (everything starting with 06), with a maximum tree depth of 1 (to avoid pulling in the .svn folder) and I am moving the respective files into the (recently created) subfolder 2006/. Also note that the the -exec flag of the find command wants to be terminated by a semicolon, but since that is a reserved character for the Bash shell, you need to escape it. This is something I trip over every time.

Anyway, I hope this helps.



8 Responses to “Subversion bulk move”

  1. Ah, that -exec flag is handy. I’ve found myself on numerous occasions just using find (or ls) piped through a “perl -ne” construct (or awk) to build actual Bash command strings and then pipe that through /bin/sh. Which works well, but is slightly icky. The good thing is without the last pipe to /bin/sh you can do dry runs to make sure it does what the doctor ordered.

  2. You could also do the move on your local copy, for more than one file at a time, and then commit them all at once… can’t you?

  3. Yes, but that will get rid of the file history (i.e. the commit log).

  4. Alex: This command actually works on the working copy, so you can still commit all the moves in one go. Unfortunately the svn mv command doesn’t accept a list of files to move, so it has to be called for each file and directory separately. GUI tools usually don’t have this limitation, but if you’re stuck with the command line client, that line is definitely a keeper.

    Now if only SVN supported “true” renames, instead of simulating a file move with copy & delete :-(

  5. using linux looks like great fun.
    with TortoiseSVN, i just drag and drop. no need to remember complicated commands.

  6. Tsahi: I wasn’t using Linux.

    Also, obviously using a GUI tool is always a possibility, but of course I didn’t say anything to the contrary in the article.

    At last, the “find” command I was showing exemplarily here can be modified to satisfy much more complicated requirements than “filename starts with abc”, so that it makes more sense. An example would be a distinction by file creation date, file size, or a combination of them.

  7. So what about following small snippet?

    for i in 06* ; do svn mv $i 2006/ ; done

  8. Except for that you need quotes, that should work :) However, the find command will allow you to do more complex filtering than that.

Leave a Reply