58

You're using subversion and you accidentally checkin some code before it's ready. For example, I often: a) checkin some code, then b) edit a little, then c) hit up, enter to repeat the previous command which unfortunately was a checkin.

Is it possible to retract such an accidental checkin from the server with subversion?

Anto
  • 6,806
  • 8
  • 43
  • 65
moinudin
  • 134,091
  • 45
  • 190
  • 216
  • See [How do I revert an SVN commit?](http://stackoverflow.com/questions/13330011/how-do-i-revert-an-svn-commit) or [Delete all traces of a SVN commit](http://stackoverflow.com/questions/5566327/delete-all-traces-of-a-svn-commit) – Vadzim Jun 04 '16 at 12:11

11 Answers11

72

See the SVNBook, specifically the 'Undoing Changes' section, and reverse merging.

Another common use for svn merge is to roll back a change that has already been committed. Suppose you're working away happily on a working copy of /calc/trunk, and you discover that the change made way back in revision 303, which changed integer.c, is completely wrong. It never should have been committed. You can use svn merge to “undo” the change in your working copy, and then commit the local modification to the repository. All you need to do is to specify a reverse difference:

$ svn merge -r 303:302 http://svn.example.com/repos/calc/trunk

To clarify, your initial change will still be in the repository. But you've now retracted it in a later revision. i.e. the repository has captured all your changes (which is really what you want! Unless you've checked in a plaintext password or similar!)

Community
  • 1
  • 1
Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
19

NB: THIS PROBABLY WON'T WORK ON CURRENT VERSIONS OF SUBVERSION AND IS A BAD IDEA - but I've left it here for information

NB: Normally when you have checked in by mistake, you should just revert the commit - see the other answers to this question. However, if you want to know how to actually undo the effects of the commit and change the repository to be how it was before, there's some explanation below:

This isn't what you normally want, but if you really want to remove the actual committed version from the repository, then you can do a nasty rollback on the repository as follows (this assumes that $REV is set to the latest revision, which you are removing):

  • Backup your repository first as these changes may break it (and read the assumptions below)
  • Revert your local copy to the previous revision so it doesn't get confused (svn revert -r $((REV-1)))
  • In the repository, remove db/revs/$REV and db/revprops/$REV
  • In the repository, remove db/current and (for subversion 1.6 or greater) db/rep-cache.db, and run svnadmin recover .
  • (Possibly) adjust the permissions on db/rep-cache.db to prevent attempt to write a readonly database errors

This all assumes:

  • You're using a fsfs-based repository
  • Subversion release greater than 1.5.0 (otherwise you have to manually edit db/current and change the revision number rather than running svnadmin recover .)
  • No other subsequent revisions have been committed
  • You have write access to the filesystem of the repository
  • You aren't scared of somebody else trying to access it while you do the above

I've done it when a huge file was committed to a repository that I didn't want to stay in the history (and mirrors etc) forever; it's not in any way ideal or normal practice...

David Fraser
  • 6,475
  • 1
  • 40
  • 56
  • 1
    this is really the wrong approach! the answer below is right way to do this. – Martin Serrano Apr 18 '13 at 13:12
  • 4
    Hence the word *nasty* above! I gave the answer because the questioner asked about actually retracting the checkin; of course, committing the roll-back of a merge is normally what you want to do. Using a more intelligent version control system also makes these choices easier :) – David Fraser Apr 18 '13 at 15:36
  • Seriously, unless the commit is going to create a major burden on the repo, or the change just happened, the risk of damaging the repo is huge. – Julie in Austin Sep 05 '14 at 04:51
  • Absolutely. The question implied the change just happened, and I wouldn't recommend doing this unless you've accidentally committed confidential information like a password. And of course, using subversion is not something that I do very much nowadays when there are better alternatives :) – David Fraser Sep 05 '14 at 13:46
  • You should probably add that this could potentially cause permissions issues (ie `attempt to write a readonly database`) so the permissions on `db/rep-cache.db` must be set again. – wtf8_decode Jan 14 '15 at 12:07
  • @wtf8_decode - Added a note to that effect; I'm not going to test this so; feel free to edit if you have better instructions – David Fraser Jan 14 '15 at 12:32
  • 1
    This just happened to me and had to readjust its permissions via chmod. Other than that it works great and your writing is more than clear so no editing should be necessary. – wtf8_decode Jan 14 '15 at 12:59
  • 2
    -1 for repo corruption using this method. I agree that changing the repo in a way that loses data is sometimes necessary, and svn revert won't do. This process, however... we just tried it and it corrupted the repo (svnadmin: E200002: Serialized hash missing terminator). We found that, since we were just removing the latest revision, a svnadmin dump up to the penultimate revision followed by a svnadmin load into a fresh repo did exactly what we wanted and was thoroughly undestructive. – Dave Gregory Feb 20 '15 at 08:31
  • The instruction in the answer is destructive and should be NEVER used. – bahrep Mar 02 '15 at 09:49
  • This is also useful if you have a replicated repository setup and accidentally commit to the slave copy directly. That will break your svnsync and this is a very easy method to fix that instead of recreating the backup repository. +1 for exactly what I needed. – Chris Holt Sep 28 '16 at 21:56
  • This approach worked for me under svn 1.8.16 like a charm. – Irfy Feb 14 '17 at 08:03
14

WARNING: The accepted answer (by David Fraser) should work with an SVN 1.5 repository, but with SVN 1.6 you must also delete db/rep-cache.db before the next commit or you'll corrupt your repository and may not realize it until the next time you try a complete checkout. I've seen subsequent complete checkouts fail with a "Malformed representation header" error.

What is rep-cache.db, you may ask? The documentation on the FSFS layout says that you will lose "rep-sharing capabilities" if you delete this file; however, it will be recreated on your next commit. Representation sharing was added in 1.6.

Pete
  • 424
  • 4
  • 14
  • sorry, where is your answer?? – squashed.bugaboo Jul 09 '13 at 04:13
  • I now prefer to make a backup of the repository before each commit. That way, if I realize I've made a mistake, I can simply delete the whole repository and quickly restore it from of the of the backups @ a previous revision, without worrying about repository internals. An ounce of prevention… – Pete Nov 27 '13 at 23:03
  • Thanks, I've edited my answer to incorporate the above to reduce the risk of damage – David Fraser Aug 15 '14 at 18:14
12

Using TortoiseSVN, select Show log and locate the revision that you want to revert to. From the context menu, select Revert to this revision. This performs a reverse merge into your working copy, so you will have to commit your working copy to finish the operation.

See also How do we keep track of our working copy's branch? :-)

Community
  • 1
  • 1
Jamie Ide
  • 48,427
  • 16
  • 81
  • 117
6

If what you meant is, how do I cleanly remove the history of an accidental checkin: This is difficult.

svn does not allow you to undo anything since it saves revisions as changesets. However, there are some tools that let you do almost anything on a dump of a repository. You could:

  1. Dump your repo.

  2. Use svndumpfilter from the svn admin tools to get rid of the checkin.

  3. Put it back into the repo.

But this can completely ruin your repo, so never ever try to do this, unless you absolutely know what you are doing and have everything backed up.

mskfisher
  • 3,291
  • 4
  • 35
  • 48
AndreasT
  • 9,417
  • 11
  • 46
  • 60
2

You cannot remove the revision - several answers here seem to be totally misunderstanding what you want. But you can change the checkin message to indicate that it it was unintended. Checkins don't cost very much so having the odd extra one is no big deal.

  • This is wrong, and doesn't address the problem at all. Brian Agnew and David Fraser above have the better ideas. – Jim Dagg Jun 28 '13 at 13:17
1

It is sometimes necessary to edit the repo on the server, for example when you've accidentally committed a password that's hard to change. Here's a method I believe to be completely safe (the answer from @David Fraser caused repo corruption for me). NB this method will only remove revisions from the end of the repo so is most useful if you notice your mistake immediately.

  1. Inform all your users that the repo is going offline and that they'll need to create a new checkout from the server.
  2. Take the repo offline, take a backup copy and move the main repo to a safe location with a name like reponame_old.
  3. Dump your repo to a single-file representation, leaving the unwanted revisions off the end:
    • svnadmin dump -r 0:N > reponame.dump
    • e.g. svnadmin dump -r 0:6610 > reponame.dump will remove revs 6611 onwards
    • Note that the repodump file could be twice the size of your repo folder.
  4. Create a new repo to load these revisions into:
    • svnadmin create reponame
  5. Load the trimmed set of revisions into the new repo
    • svnadmin load reponame < reponame.dump
  6. Apply any necessary customisations to your new repo (e.g. hooks) and return it to service.
    • We're using VisualSVN server so had to restore the conf\VisualSVN-WinAuthz.ini file.
    • We also saw some odd behaviour until we rebooted the server, so VisualSVN may cache the repo state; YMMV with other hosting setups.
  7. Don't forget to either delete the backup with the secret data, or put it somewhere safe.
  8. Tell all the users to do a new svn checkout from the repo server.
Dave Gregory
  • 932
  • 7
  • 12
1

Yes, this is really what Subversion is for.

What you need to do is just replace your copy with previous revision in SVN repository.

There are several options:

  1. Replace with Revision.
  2. Replace with URL
  3. Latest from repository (but in your case, you already have the latest)
  4. Replace with Branch

But I strongly recommend you to do the following prior to replace your local copy:

  1. Do a 'Compare with Repository/ Revision / URL'.
  • That only changes the local copy. I want to retract the checkin from the server. – moinudin Apr 14 '09 at 14:07
  • If you really don't want to leave any history, you can always delete the whole repository and re-create it again. –  Apr 14 '09 at 14:12
0

I would doubt it. One of the main ideas of a source control is that a repository does not loose any history. You can't delete history. The best you can do is get an older version and overwrite the current one with that. But the history logs will still show your mistake.

(Offtopic: What kind of IDE are you using that does something like that?)

Vilx-
  • 104,512
  • 87
  • 279
  • 422
  • 1
    heh, using vim + separate shell for checkin – moinudin Apr 14 '09 at 14:12
  • Suggestion: use an IDE with integrated SVN support. Way easier. :) – Vilx- Apr 14 '09 at 14:22
  • **With great power comes great responsibility.** Another happy VIM and separate shell user here. I gladly take the occasional 'accident' like this for the power and speed that VIM and Bash provide. – dotancohen May 15 '17 at 09:56
  • This day and age I'm a staunch supporter of TortoiseGit. :) Even though Visual Studio does have a rudimentary Git support, it still doesn't come even close to what Tortoise can do. And, yes, I know - command line is even more powerful (still I prefer Tortoise for 99% of daily work). :) – Vilx- May 15 '17 at 16:40
0

you cannot retract the revision, the most you can do is revert back to prior revision and do another checkin.

Nuno Furtado
  • 4,548
  • 8
  • 37
  • 57
0

To comment on this as well: This is a series of commands that I did on a repository to revert it from revision 2 back to revision 1. You'd need to checkin at the end as well though.

Last login: Mon Apr 13 16:01:34 on ttys004
[wlynch@orange ~] cd /tmp
[wlynch@orange /tmp] svnadmin create foo
[wlynch@orange /tmp] svn co file:///tmp/foo foo-repo
Checked out revision 0.
[wlynch@orange /tmp] cd foo-repo/
[wlynch@orange foo-repo] ls
[wlynch@orange foo-repo] touch blah
[wlynch@orange foo-repo] touch repl
[wlynch@orange foo-repo] touch bar
[wlynch@orange foo-repo] svn add *
A         bar
A         blah
A         repl
[wlynch@orange foo-repo] svn ci
Adding         bar
Adding         blah
Adding         repl
Transmitting file data ...
Committed revision 1.
[wlynch@orange foo-repo] echo "hi" > bar
[wlynch@orange foo-repo] echo "oh no" > blah
[wlynch@orange foo-repo] svn ci
Sending        bar
Sending        blah
Transmitting file data ..
Committed revision 2.
[wlynch@orange older-foo] svn diff -r 1:2 file:///tmp/foo
Index: bar
===================================================================
--- bar (revision 1)
+++ bar (revision 2)
@@ -0,0 +1 @@
+hi
Index: blah
===================================================================
--- blah    (revision 1)
+++ blah    (revision 2)
@@ -0,0 +1 @@
+oh no

[wlynch@orange foo-repo] svn diff -r 1:2 file:///tmp/foo | patch -R
patching file bar
patching file blah    
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173