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.”
March 14th, 2008 at 2:07 am
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
March 15th, 2008 at 2:56 pm
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...]
April 17th, 2008 at 6:47 pm
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”???
August 4th, 2008 at 11:22 pm
“Revert changes from this revision” is in version 1.5.2
September 25th, 2008 at 11:37 am
I have version 1.5.2 but I could not see “Revert changes from this revision”
July 14th, 2009 at 10:19 am
thanks you saved my life ;-)
August 26th, 2009 at 12:01 pm
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.
October 20th, 2009 at 12:03 pm
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
October 22nd, 2009 at 4:35 pm
Thank you for a great explanation. It is definitely memorable, especially when you refer to ninjas :)
November 9th, 2009 at 5:47 am
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
November 23rd, 2009 at 5:22 pm
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.
December 9th, 2009 at 3:36 pm
[...] 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. [...]
January 6th, 2010 at 3:19 pm
SmartSVN is the way to go on a Mac.
February 9th, 2010 at 2:29 pm
Thanks for posting this up on the web. Very helpful =D
February 26th, 2010 at 10:19 am
This helped me. Thanks for the arg details in the command-line example, specifically the revision syntax ( “@HEAD” and “@XXXX” ).
June 29th, 2010 at 10:49 am
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.
October 5th, 2010 at 9:27 am
[...] Read more about it [...]
January 3rd, 2011 at 10:09 am
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.
January 5th, 2011 at 6:32 am
Thanks it really helped.
I’ve tried other proposals but no one worked.
January 14th, 2011 at 10:53 pm
Thanks. Worked like a charm!
August 3rd, 2011 at 5:39 pm
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….
August 26th, 2011 at 10:52 am
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.
August 31st, 2011 at 1:24 pm
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.
October 16th, 2011 at 4:19 pm
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
January 28th, 2012 at 11:43 am
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?