How do I return to an older version of our code in Subversion?
Asked Answered
H

14

526

I'm working on a project with a friend and I want to return to an older version of our code and set it to be the current. How do I do it?

I'm using "anksvn" on vs08.

I have the version that I want on my PC, but the commit is failing; The message that I get is "commit is failed, file or directory is out of date."

I also have the subversion client on my PC.

Hypolimnion answered 2/5, 2009 at 8:35 Comment(0)
L
842

Basically you need to "merge backwards" - apply a diff between the current and previous version to the current version (so you end up with a working copy looking like the old version) and then commit again. So for example to go from revision 150 (current) back to revision 140:

svn update
svn merge -r 150:140 .
svn commit -m "Rolled back to r140"

The Subversion Red Book has a good section about this.

Lorrainelorrayne answered 2/5, 2009 at 8:38 Comment(16)
but the merge is not override my changes and the new revision.Hypolimnion
Which changes? Any changes you don't want in your working copy can just be removed with svn revert. Committed changes will be 'undone' by this merge.Lorrainelorrayne
If you are using TortoiseSVN, right-click the file select Merge, then Merge a Range of Revisions. In the log box type in 140-150 and click the Reverse Checkbox. After that, commit as usual. This will perform the same operation as Jon's example.Fatling
If they do not want to revert the entire commit this approach could lead to subtree mergeinfo which should be avoided as per svnbook.red-bean.com/en/1.7/svn.branchmerge.advanced.html. In this case I would go with Bill's answer.Downwind
With eclipse and subclipse, you can right-click on your project, Team/Show History, then select then revisions you want to "undo" and with another right-click select "Revert changes from Selected Revisions".Dumbwaiter
To revert from head revision you can also write svn merge -r HEAD:140.Bonis
@DavGarcia's TortoiseSVN instructions weren't right for me, at least not to revert all the files in a revision (using TortoiseSVN 1.8.8). Right click on the folder, select TortoisSVN->Show log. Pick the revision(s) that you want to revert, right click as say "Revert changes from this revision". Commit the changes.Sylphid
So after the above commit svn commit -m "Rolled back to r140" the revision number would be 151?Alcmene
@inckka: Yes, I believe so.Lorrainelorrayne
saved my countless hours and this got all the history that I deleted. Thank you very muchSomehow
I will remind people to check your svn status and compile/unit test/smoke test before you commit. And in comments, do your best to explain why you are rolling back.Brisesoleil
does the merge would bring tons of conflicts ?Oblast
@JasonHuang: It shouldn't do, because it's just rolling back diffs.Lorrainelorrayne
Pay attention to the dot(.) at the end of the merge commandRhodarhodamine
After execution command "svn merge -r 150:140", I used "svn info --show-item revision" and found it shows still 150. Shouldn't it be 140?Peba
@StanHuangatTaiwan: I'm afraid it's now been many years (probably over a decade) since I've used subversion. I suggest you ask a new question with a complete set of commands and output to repro the issue.Lorrainelorrayne
T
184

You can only commit new changes at the head of the subversion history.

The reason you can't do anything directly with the good copy you have on your PC, is that its .svn folders know that it is code from the past, so requires an update before any commit.

Find the good revision number and revert

  1. Find the revision number of the old copy you want.

    Get your current revision with:

    svn info --show-item revision
    # or
    svn log
    

    Or to check older versions of your project, use:

    svn update -r <earlier_revision_number>
    

    until you find the right revision number.

  2. Note down the good revision number (assuming 123 for examples below).

  3. Update to the latest revision:

    svn update
    
  4. Undo all the changes between the revision you want and the latest version:

    svn merge -r HEAD:123 .
    svn commit -m "Reverted to revision 123"
    

    (the same as Jon Skeet's answer above.)

If you can't find the revision number

If you can't find the old copy, and you just want to commit the files currently on your PC:

  1. Make a copy of your good version (but without any .svn folders):

    cd ..
    rsync -ai --exclude=.svn  project/  project-good/
    
  2. Now make sure you have the latest version:

    cd project
    svn update
    # or make a fresh checkout
    svn checkout <url>
    
  3. Copy your good version over the top of the working copy.

    This command will copy, and also delete any files from the working tree that aren't in your good copy, but it won't affect the existing .svn folders.

    cd ..
    rsync -ai --exclude=.svn --delete  project-good/  project/
    

    If you don't have rsync, you can use cp -a but you will also need to delete any unwanted files manually.

  4. You should be able to commit what you have now.

    cd project
    svn commit -m "Reverted to good copy"
    
Territoriality answered 2/5, 2009 at 9:43 Comment(5)
svn doesn't interpret it as a modification, I can't commit that.Abdullah
I guess this answer was upvoted by people who couldn't find their revision number, or who appreciated the leading explanation. I have updated the answer now to include both approaches.Territoriality
svn commit -m "Reverted to good copy" , you are missing -mBarnes
@SalimShamim Thanks, it's been missing for 12 years.Territoriality
on step 4 of the first case (where i have revision number) when running svn merge -r HEAD:revnumber i get "merge source required"Huoh
U
35

Just use this line

svn update -r yourOldRevesion

You can know your current revision by using:

svn info

Underpants answered 27/3, 2013 at 13:21 Comment(2)
This does not solve the problem. Instead, this produces the state the asker was in at the time of asking their question.Tajuanatak
If you've been unfortunate enough to follow this advice, run: "svn resolve --accept working -R ."Pyrrha
C
28

The standard way of using merge to undo the entire check-in works great, if that's what you want to do. Sometimes, though, all you want to do is revert a single file. There's no legitimate way to do that, but there is a hack:

  1. Find the version that you want using svn log.
  2. Use svn's export subcommand:

    svn export http://url-to-your-file@123 /tmp/filename

(Where 123 is the revision number for a good version of the file.) Then either move or copy that single file to overwrite the old one. Check in the modified file and you are done.

Chaffin answered 2/7, 2009 at 20:39 Comment(2)
Using Tortoise-svn I can right-click on a single file and merge it. There should be a way to do this using svn as well?Diatribe
svn cat -r 123 path-in-your-working-copy > path-in-your-working-copyUnfurl
F
9

A bit more old-school

svn diff -r 150:140 > ../r140.patch
patch -p0 < ../r140.patch

then the usual

svn diff
svn commit
Firework answered 2/9, 2013 at 10:53 Comment(0)
S
5

I think this is most suited:

Do the merging backward, for instance, if the committed code contains the revision from rev 5612 to 5616, just merge it backwards. It works in my end.

For instance:

svn merge -r 5616:5612 https://<your_svn_repository>/

It would contain a merged code back to former revision, then you could commit it.

Scarcity answered 13/4, 2013 at 7:42 Comment(0)
M
4

This is what I did and worked for me.

I want to undo the changes in multiple commits that I did for certain times and want to go to the previous commit point.

  1. Go to Team -> Show History.
  2. Right-click on the or range of revisions you want to ignore.
  3. Select the "Revert changes" option.

This will run a reverse merge, undoing the changes in your working copy.

Just review the code and commit.

Magnuson answered 28/2, 2014 at 20:8 Comment(0)
P
3

There are a lot of dangerous answers on this page. Note that since SVN version 1.6, doing an update -r can cause tree conflicts, which rapidly escalates into a potentially data losing kafkeresque nightmare where you're googling for information on tree conflicts.

The correct way to revert to a version is:

svn merge -r HEAD:12345 .

Where 12345 is the version number. Don't forget the dot.

Pyrrha answered 12/4, 2019 at 16:11 Comment(0)
S
2

Right-click on the highest hierarchy you want to revert >> Revert or Revert to Revision

Scrutable answered 2/5, 2009 at 8:40 Comment(0)
H
2

Most of the previous answers have been using a reverse merge, and that's usually the right answer. However, there's one situation (which just happened to me) where it's not.

I accidentally changed a file with Unix line endings to DOS line endings when making a small change, and committed it. This is easily undone, either by changing the line endings and committing again, or by a reverse merge, but it has the effect of making svn blame list my edit as the source of every line of the file. (Interestingly, TortoiseSVN on Windows doesn't get affected by this; only the command line svn blame.)

If you want to maintain the history as reported by svn blame, I think you need to do the following:

  • Delete the file and commit.
  • In the repository, copy the previous good copy of the file into the head, and commit.
  • Restore any edits that you do want to keep.

The deletion is a little scary, but remember you always have the file saved in the repository, so restoring it is not a big deal. Here's some code to illustrate the steps. Assume that xxx is the revision number of the last good copy.

svn rm svn+ssh://path/to/file
svn copy svn+ssh://path/to/file@xxx svn+ssh://path/to -m"Restore good copy"
svn update
<restore the edits>
svn commit -m"Restore edits"

Note that for a copy in the repository, the destination needs to be a directory, not a filename.

Himself answered 24/5, 2017 at 12:48 Comment(0)
W
0

Sync to the older version and commit it. This should do the trick.

Here's also an explanation of undoing changes.

Whim answered 2/5, 2009 at 8:38 Comment(0)
M
0

Right click the project > Replace With > Revision or URL > Select the specific revision you want to revert.

Now commit the local update code version to the repository. This will revert the code base to the specific revision.

Mispronounce answered 6/9, 2016 at 13:11 Comment(0)
M
0

Jon Skeet's answer is pretty much the solution in a nutshell, however if you are like me, you might want an explanation. The Subversion manual calls this a

Cherry-Pick Merge

From the man pages.

  1. This form is called a 'cherry-pick' merge: '-r N:M' refers to the difference in the history of the source branch between revisions N and M.

    A 'reverse range' can be used to undo changes. For example, when source and target refer to the same branch, a previously committed revision can be 'undone'. In a reverse range, N is greater than M in '-r N:M', or the '-c' option is used with a negative number: '-c -M' is equivalent to '-r M:'. Undoing changes like this is also known as performing a 'reverse merge'.


  • If the source is a file, then differences are applied to that file (useful for reverse-merging earlier changes). Otherwise, if the source is a directory, then the target defaults to '.'.

    In normal usage the working copy should be up to date, at a single revision, with no local modifications and no switched subtrees.

Example:

svn merge -r 2983:289 path/to/file

This will replace the local copy[2983] (which, according to the quote above, should be in sync with the server--your responsibility) with the revision 289 from the server. The change happens locally, which means if you have a clean checkout, then the changes can be inspected before committing them.

Mollee answered 23/5, 2018 at 11:9 Comment(0)
C
-1

The following has worked for me.

I had a lot of local changes and needed to discard those in the local copy and checkout the last stable version in SVN.

  1. Check the status of all files, including the ignored files.

  2. Grep all the lines to get the newly added and ignored files.

  3. Replace those with //.

  4. and rm -rf all the lines.

    svn status --no-ignore | grep '^[?I]' |  sed "s/^[?I] //" | xargs -I{} rm -rf "{}"
    
Coppinger answered 24/3, 2014 at 11:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.