Title: Subversion: The Magic of Merging
Author: Alex Kirk
Published: October 12, 2006

---

# Subversion: The Magic of Merging

October 12, 2006

When programming professionally, [Subversion](http://subversion.tigris.org/) is 
a must-have. Same for system administration: it’s quite a good idea to keep your
configuration files (e.g in Linux the whole /etc/ directory) as a Subversion checkout.

So the goal of Subversion (or any other [Source Control system](http://en.wikipedia.org/wiki/Source_control))
is to allow you to do something Apple will introduce with it’s new Leopard operating
system: [Time Machine](http://www.apple.com/macosx/leopard/timemachine.html). Go
back in time (and restore a version of a file as it was on day x).

Using Subversion on a daily basis is quite easy. Just check in (svn ci) your changes
after you have completed a certain task. When you work collaboratively, and someone
else has committed some changes, you do a svn up and the changes of the others are
applied to your codebase.

That’s all you basically need. But how can you go back in time now?

So you poke around a bit and find that svn up has a parameter -r which let’s you
put your checkout to the state in which it was at a certain revision.

Let’s suppose we know that something was ok on monday and is not today. So let’s
use the command from above to see what it looks like.
 ` ~/project/trunk$ svn up-
r {2006-10-09} app.php U app.php  Voila, there it is. Now we choose to use that 
code now and throw away all changes that have been committed since. We modify the
file a bit and do a check in:  ~/project/trunk$ svn ci -m "revert to monday" app.
php Sending app.php svn: Commit failed (details follow): svn: Your file or directory'
app.php' is probably out-of-date svn: The version resource does not correspond to
the resource within the transaction. Either the requested version resource is out
of date (needs to be updated), or the requested version resource is newer than the
transaction root (restart the commit).  Uh.. ok. So you probably you know that error
message already. It is also returned when you want to check something in on a file
that has been changed by someone else since your last svn up.

When you check something into a subversion repository, one of the basic rules is
that the file you want to commit is “up to date”, i.e. the revision number of your
local file (updated by svn up) equals the number in the repository (on the server).

Ok, so, let’s update our checkout so we can re-run the check in.
 ` ~/project/trunk
$ svn up G app.php  So you discover the changes that happened since have been re-
inserted to that file again. Maybe Subversion has alerted you of a conflict, because
you changed some lines that have been modified since monday also.

Great! Basically we are back to where we started.

Let’s not resign here, but rather use the appropriate command: svn merge. That command
is mostly known for merging changes from one branch of development to another. But
it can also help you to go back in time.

The parameters of svn merge are to specify a revision range, which changes to be
merged, and a source — what part of the subversion repository should be searched
for the changes.

Usually one would find this command used in a way like:
 ` ~/project/trunk$ svn 
merge -r 15:26 ../branches/first_release/ G app.php  So with two revisions specified
you define a range of changes which should be merged into the current checkout. 
Ok so how would us help this here?

You can also specify revisions _backwards_, to go back in time. So to undo the command
form before you can write:
 ` ~/project/trunk$ svn merge -r 26:15 ../branches/first_release/
G app.php

To put it simple, Subversion generates a diff file behind the scenes that incorporates
the changes between the given revisions. Then the changes are merged with the files
in the same way the patch command (Linux, Unix, OS X, …) does it. When going back
in time, the parameter -R is used which applies the patch in the reverse direction.
Voila.

So as a final solution this leaves us with:
 ` ~/project/trunk$ svn merge -r head:{
2006-10-09} . U app.php ~/project/trunk$ svn ci -m "revert to monday" app.php Sending
app.php Transmitting file data . Committed revision 27.

For further questions, the [Subversion FAQ](http://subversion.tigris.org/faq.html)
is a good starting point when you know exactly what you want (i.e. the correct terminology).(
For example _reverting_ does not mean to go back to a previous version of the file,
but rather to remove the changes you did locally).

There is the [subversion book](http://svnbook.red-bean.com/) (also published by 
[O’Reilly](http://www.oreilly.com/catalog/0596004486/)), of which the [Guided Tour](http://svnbook.red-bean.com/nightly/en/svn.tour.html)
is a good starting point.

The process I described above as a trial and error is also described in that book
at [Undoing changes](http://svnbook.red-bean.com/nightly/en/svn.branchmerge.commonuses.html#svn.branchmerge.commonuses.undo).

Also [OSCON: Subversion Best Practices](http://bradchoate.com/weblog/2006/07/27/oscon-subversion-best-practices),
a transcript of a talk given by the subversion creators (Ben Collins-Sussman and
Brian W. Fitzpatrick) by Brad Choate has some good tips.

Have fun :)

subversion, merge, revert, time machine

[Code](https://alex.kirk.at/category/code/)

Read this next

[phpBB ajaxified](https://alex.kirk.at/2006/09/25/phpbb-ajaxified/)

### Leave a Reply 󠀁[Cancel reply](https://alex.kirk.at/2006/10/12/subversion-the-magic-of-merging-2/?output_format=md#respond)󠁿

Only people in [my network](https://alex.kirk.at/friends/) can comment.

This site uses Akismet to reduce spam. [Learn how your comment data is processed.](https://akismet.com/privacy/)