I accidentally committed too many files to an SVN repository and changed some things I didn't mean to. (Sigh.) In order to revert them to their prior state, the best I could come up with was
svn rm l3toks.dtx
svn copy -r 854 svn+ssh://<repository URL>/l3toks.dtx ./l3toks.dtx
Jeez! Is there no better way? Why can't I just write something like this:
svn revert -r 854 l3toks.dtx
Okay, I'm only using v1.4.4, but I skimmed over the changes list for the 1.5 branch and I couldn't see anything directly related to this. Did I miss anything?
Edit: I guess I wasn't clear enough. I don't think I want to reverse merge, because then I'll lose the changes that I did want to make! Say that fileA
and fileB
were both modified but I only wanted to commit fileA
; accidentally typing
svn commit -m "small change"
commits both files, and now I want to roll back fileB
. Reverse merging makes this task no easier (as far as I can tell) than the steps I outlined above.
Check out "undoing changes" section of the svn book
sorry to use up some space on just a reiteration of the previously given answer - but this is something I always end up in trouble with.
Let's say I've updated the local files to the latest revision, which is 854. Then, I'd want to get an older revision - the version of the file from few revision earlier, say revision 851.
Copy would work:
svn copy -r 851 svn+ssh://<repository URL>/l3toks.dtx ./l3toks.dtx
.. however, I can't be bothered grepping for the repo URL :)
Update seemingly might work:
svn up -r 851 ./l3toks.dtx
... however, it also marks the local copy as "freshly checked out", or rather "same as online revision" (i.e. in Tortoise/RabbitVCS you get a green OK checkmark) - which means you cannot do svn ci -m "rolled back to r 851"
: simply because the local subversion
executable won't notice any local changes, and won't be bothered to upload anything to the online repository.
And, as already answered, reverse merge works - but in this case, one shouldn't rely on shortcut syntax; but specifically state:
svn merge -r HEAD:851 l3toks.dtx
--- Reverse-merging r854 through r852 into 'l3toks.dtx':
U l3toks.dtx
I must admit - I would never understand the sentence "Reverse-merging r854 through r852 into file" to mean "Just got r851 of your file, and overwritten whatever you had previously locally - and it is marked as different from latest online revision, so you can check it back in online as a new 'rollback' revision", but I guess (and hope :) ) that is what it does :)
After this, one can use svn diff
for a quick make-sure if we got the right revision back locally; and also, the file will be marked with a red exclamation mark in Tortoise/RabbitVCS (that is, different from latest committed version), and so svn ci -m "rolled back to r 851"
can run this time.
Also, note that if you, finally, change your mind after reverse merging (i.e. you anyways want to keep working on the latest, HEAD revision, here 854 - after you have rolled back to 851 locally, but haven't yet committed the rollback), you shouldn't use svn up
, because it will simply say that it is already "At revision 854"; use instead svn revert --recursive .
or similar...
Cheers!
Ref: How to Roll Back Changes using Subversion - Jacob Wright – Flex, AIR, PHP, etc.
EDIT: ... and apparently, the exactly same effect as svn merge -r HEAD:851 l3toks.dtx
, can be achieved with:
svn export -r 851 l3toks.dtx
A l3toks.dtx
Export complete.
--force
to overwrite directories. Just remember it will overwrite any changes.
svn export
- am I missing something or is that just not implemented in these GUIs?
I recently had to revert to a particular revision to debug an older build and this worked like magic:
svn up -r 3340 (or what ever your desired revision number)
I had to resolve all conflicts using "tc" option as I did not care about local changes (checked in everything I cared about prior to reverting)
To get back to head revision was simple too:
svn up
What you're looking for is called a "reverse merge". You should consult the docs regarding the merge function in the SVN book (as luapyad, or more precisely the first commenter on that post, points out). If you're using Tortoise, you can also just go into the log view and right-click and choose "revert changes from this revision" on the one where you made the mistake.
Reverse merge is exactly what you want (see luapyad's answer). Just apply the merge to the erroneously-commited file instead of the entire directory.
If you only want to undo the last checkin, you can use the following
svn merge -r head:prev l3toks.dtx
That way, you don't have to hunt for the current and previous version numbers.
svn merge will merge revisions, not revert them. i.e. if you have some addition in your HEAD version then merge that with a previous revision, then the change will persist.
I use svn cat then redirect it into the file:
svn cat -r 851 l3toks.dtx > l3toks.dtx
Then you have the 851 content in that file and can check it back in.
If you use the Eclipse IDE with the SVN plugin you can do as follows:
Right-click the files that you want to revert (or the folder they were contained in, if you deleted them by mistake and you want to add them back) Select "Team > Switch" Choose the "Revision" radion button, and enter the revision number you'd like to revert to. Click OK Go to the Synchronize perspective Select all the files you want to revert Right-click on the selection and do "Override and Commit..."
This will revert the files to the revision that you want. Just keep in mind that SVN will see the changes as a new commit. That is, the change gets a new revision number, and there is no link between the old revision and the new one. You should specify in the commit comments that you are reverting those files to a specific revision.
Success story sharing
svn merge -c -854 my.file
, and then dosvn diff
, it seems to show one revision before 854 (that is, 853); only when I dosvm merge -c 854 myfile
(without the-
), it looks like myfile is reverted to rev 854. Thanks again, cheers!