How to Roll Back Changes using Subversion

A question I’ve often gotten is “How do I roll back some changes I made in Subversion?” I’m the company expert in Subversion here at mediaRAIN (another one of my hats) so I thought I’d answer the question one more time.

Subversion is great as it allows you to track every change you’ve made and go back to a previous version if needed. Sometimes you only need to go back to an earlier revision temporarily (for example to tag the project at that point). But other times you (or that lousy co-worker who left on vacation yesterday!) have introduced bugs or committed something you shouldn’t have. Now you need to roll back the broken revision(s). Looking at TortoiseSVN’s menu or going through the list of command-line options you’ll see … gasp! … subversion forgot a roll-back feature! How could they do that?! Isn’t that one of the main reasons for using a versioning system like Subversion?

Never fear, Subversion can roll back changes made, it’s just not labeled “Roll Back” and it doesn’t quite undo those changes. See, it is Subversion’s job to track every revision of a document whether good or bad. What if you rolled back the lousy co-worker’s changes and after he gets back from holiday he shoots you to death with his flying-ninja gun because you destroyed all that code he worked on for days? Not good, Subversion needs to remember even the bad times.

So if Subversion won’t go back, it must go forward, and what you really need is the merge feature. Merge let’s you take a collective group of changes between two places (two separate files or two separate revisions, or both) and merge them into your working copy. Why doesn’t it just merge it into the head revision? Well, you’ve got to TEST it first of course! Merge is also used to get changes from a branch to the trunk and visa-versa, so we need to use it the right way for roll-backs.

Because Merge will “apply the differences between two sources to a working copy path.” (command line help `svn help merge`) it takes three parameters: the first source, the second source, and the working copy path. Since you are rolling back changes the first source and second source will be the same path but different revisions. Make sure to use the HEAD revision (or later revision) first and the starting of the bad-news revision second since you are rolling BACK and not forward. Then you’ll set the working copy path (if you’re using TortoiseSVN that will just be the folder you right-clicked on) to the corresponding folder in your working copy.

Command-line Example:

merge svn://domain.com/repo/trunk/folder/changedFile.txt@HEAD svn://domain.com/repo/trunk/folder/changedFile.txt@215 ./folder/changedFile.txt

When using TortoiseSVN you can hit that “Show Log” button to find the revision easily. Command-line users will have to find it first, remember it (yeah, painful ;), and then use it.

You’re not done yet. Now you’ve removed those changes made from your working copy you still need to test your code and the commit the files back to the repository. This will create a new revision that is now fixed, but leaves the broken one in the repo still in case you ever want to “roll back your roll back.”

26 Responses to “How to Roll Back Changes using Subversion”

  1. Stefan Says:

    To prevent your users from using the (sometimes) complicated merge dialog with TSVN:
    * show log
    * find the revision to roll back
    * right-click on that revision
    * choose “revert changes from this revision” from the context menu

  2. Jacob Wright Says:

    Nice one Stefan! I’m on Mac all the time now so I didn’t know that option. Tortoise is the one thing I really miss from Windows. [sigh…]

  3. Max Says:

    I’m using TortoiseSVN 1.4.8 w/ Subversion 1.4.6. When I right click on the Revision that I want to roll back I get:
    Show differences as unified diff
    Save revision to…
    Open
    Open with…
    Browse repository
    Create tag from revision
    Checkout…
    Edit author
    Edit log message
    Copy to clipboard
    Search log messages…

    Where is “Revert changes from this revision”???

  4. Lin Says:

    “Revert changes from this revision” is in version 1.5.2

  5. Amit Says:

    I have version 1.5.2 but I could not see “Revert changes from this revision”

  6. twobee Says:

    thanks you saved my life ;-)

  7. swo Says:

    Very nicely done. This has got to be one of the best explanations of subversion merge operations I have ever ran across. The author even gives the reader context *gasp*.

    Well done sir.

  8. bryce Says:

    I like you explinations. It help me with many problems given other developments. Many thanks for great assistance provided.

    Please continue doing this helps for many who are thanking you kindly.

    –Bryce

  9. Kat Says:

    Thank you for a great explanation. It is definitely memorable, especially when you refer to ninjas :)

  10. Tom Artoos Says:

    In T-SVN you can also use the merge dialog and use a revers merge. There you can specify the revs that contain the changes that need to be undone.

    Right-click your work folder and select Merge in the T-SVN context menu.

    Select the Merge a range of revision option
    In the dialog that is displayed:
    – Select the trunk in your repository
    – Enter the revision (or range of revs) that you want to undo.
    – Select the ‘Reverse merge’ option
    – Press OK and the changes from the selected revs will be removed in your working copy.

    To finalize the operation just commit your working copy to the repository again.

    Hopefully this is helpful.

    BTW: I’m using TortoiseSVN 1.6.1, Build 16129 – 32 Bit , 2009/04/10 08:14:05
    Subversion 1.6.1

  11. Cory House Says:

    Stefan’s post (the first) describes the easiest method I’m aware of, but note that if you don’t see the “revert changes from this revision” option in the context menu, it’s because you need to right click on your working copy file and select show log. If you navigate to showing the log any other way the option isn’t available.

  12. » Fun with Subversion Geek Mama Says:

    […] A frantic Google search on roll back and revert revealed that what  I needed to do is merge. Jacob Wright goes into detail in his blog How to Roll Back Changes Using Subversion. […]

  13. Mathias Says:

    SmartSVN is the way to go on a Mac.

  14. Janell Says:

    Thanks for posting this up on the web. Very helpful =D

  15. Justin Says:

    This helped me. Thanks for the arg details in the command-line example, specifically the revision syntax ( “@HEAD” and “@XXXX” ).

  16. scott Says:

    Thanks for the tips, but this didn’t work for me. Here’s the workaround I used that did work:

    1) Get the desired version. That’s not the head version.

    2) Copy the desired version outside of an svn managed local directory.

    3) Update to head revision.

    4) Delete all the bad files in the subfolder of the head version

    5) Commit it.

    4) Change the directory to the version in step 2, the non head version.

    5) Delete all the .svn directories and files in the non head version.

    6) Copy the non head version into the svn managedirectory.

    5) Add and commit the files to SVN.

    I know this is cloogy but I couldn’t get your directions to work.

  17. SVN Tortoise revert/Roll-back to older version « InfoFilled Says:

    […] Read more about it   […]

  18. Nathan Walther Says:

    Thanks for posting this. The reminder to use merge for a rollback was helpful to me.

    You can use the -c option on merge to simplify the arguments. For example to revert revision 215 you can:

    svn merge -c -215 .

    Assuming your current directory is your local workspace copy.

  19. OliCh Says:

    Thanks it really helped.
    I’ve tried other proposals but no one worked.

  20. Al Brown Says:

    Thanks. Worked like a charm!

  21. Jenny Says:

    This explanation makes no sense at all. Does this mean that there is no roll-back in subversion? Merge and rollback are not the same thing.

    If I made a bunch of changes and I wish to rollback to previously committed version, I would like these changes to be gone, not merged….so after performing this, I still need to manually edit the file?

    I am probably missing something here, but I just don’t see how this is useful. Merge and rollback are not the same thing….

  22. Jacob Wright Says:

    You are correct. There is no real rollback that makes subversion forget about the commits entirely. It will always remember every commit. The rollback here is to rollback your code to a previous version, but it creates a new commit with those reverse changes in it. You shouldn’t need to manually edit anything in the rollback. You are essentially letting subversion apply the changes you made in reverse to get back to where you were a few revisions ago, then you can commit these changes as a new revision going forward. I hope that makes sense.

  23. granadaCoder Says:

    I posted a windows .bat file at this URL:
    http://stackoverflow.com/questions/849382/svn-merge-with-revision-not-doing-what-i-expect/

    in regards to this question. I am using svn.exe 1.6.15.

    The scripts:
    1. Checks out the HEAD revision.
    2. Uses the merge argument to overlay an older revision over the HEAD revision (in your local working copy).
    3. Does a svn.exe status to show you the differences.
    4. PAUSE’s to give you a moment to consider what you are doing.
    5. COMMITs the local working copy to the repository.

    The biggest thing I was missing conceptually is that you “merge” an older revision ~~in your local working copy~~ then (if you’re happy) you commit that to the repository.

    As already discussed here, there is not a ROLLBACK function.

    You basically are allowed to set the HEAD revision to an older revision in the repository.

  24. Joshua Pinter Says:

    A quick way to do it locally is:

    svn merge -r HEAD:PREV .

    Make sure that you’ve done a svn update before so it knows what the correct HEAD is.

    Cheers,

    JP

  25. Arthur Says:

    I agree with Jenny. I’d like an option to simply overwrite my local files with a specific version from the repository.

    Sometimes I want to abort all my local edits on my working copy and revert (or rollback as she calls it) my local copy to the EXACT copy of a particular revision in the repository. I don’t want my new local copy to be a merge with that revision. I simply want to blow away my old local copy and retrieve a specific revision.

    Is the only way to do this by finding and deleting all the local files I want replaced and then check out fresh copies of the specific revision I want for them?

  26. Patrick Says:

    This seems like a design flaw to require every revision between B and A to be explicitly specified when you clearly just want A. It seems much less of a hassle to just show the log, select Save Revision To, and overwrite the local working copy of B with A, then commit it. Both these methods are unsatisfactory though since it has no built in information showing what revision you just rolled back to. You just have to hope that someone writes an appropriate and correct log message that contains the target revision number.