The other day I was on Stack Overflow and ran into a question I could readily answer.

Imagine we have a repository “my_repository” with theses files :

  • my_repository/file01 (revision 105)
  • my_repository/file02 (revision 110)
  • my_repository/file03 (revision 125)
  • my_repository/folder01/file01 (revision 100)
  • etc…etc…

I would like to save this state. So if I do a svn update my_repository, I could backup to my previous state with all different file states easily.

Is it possible ?

It is! Although in the first place it’s an unusual use case. Usually a group of files are dependent on each other and would need to be synchronized together.

First steps

I knew a branch was needed but that’s not the whole story. He has a potentially long list of file/revision pairs that need tracking. His followup comment suggests that he simply add files to a new unversioned directory in their desired states, then add this directory to his repository. This route will get the files in the right states, but the files’ histories will be cut off. I hate doing stuff like that, but there is a way around.

Creating a branch from a working copy

The svn book explains this quite well. If you customize your working copy through update -rARG, switch URL manipulations, you can copy this state to a branch and retain your history.

Example

I created a test repository and the structure from the question, and made some revisions on the files. For my example, I want to create a branch with the following properties:

  • example_repo/file01@4
  • example_repo/file02@3
  • example_repo/file03@1
  • example_repo/folder01/file01@5

(Don’t know about @-notation in svn paths? Read up on peg revisions. They’re not terribly relevant for my example so I’ll omit them from now on)

Now that I know what I want, it’s trivial to update those items to the desired revisions. For example:

$ svn update ./file01 -r 4

Once I have everything setup the way I want, create the branch:

$ svn copy . file:///path/to/example_repo/result_branch

That’s it! It’s a less common use of the svn copy command, summarized here. The benefit over the other method is that history is preserved:

$ svn log -v ./file01 | less

------------------------------------------------------------------------
r6 | chris | 2012-11-04 22:50:11 -0800 (Sun, 04 Nov 2012) | 3 lines
Changed paths:
   A /result_branch (from /:5)

Copying for example!


------------------------------------------------------------------------
r4 | chris | 2012-11-04 22:10:51 -0800 (Sun, 04 Nov 2012) | 1 line
Changed paths:
   M /file01

Revision\!
------------------------------------------------------------------------
r2 | chris | 2012-11-04 22:00:25 -0800 (Sun, 04 Nov 2012) | 1 line
Changed paths:
   M /file01

Revision\!

Without this method, none of this history is available on your files. Hope this helps!