Someone in our team accidentally committed files containing a password to our repository. The password can't easily be changed.
Is there a way, with full admin permissions, to delete all traces of this commit? I'm not talking about a revert or delete, which would obviously keep the password in the file history.
To remove a file from a Subversion repository, change to the directory with its working copy and run the following command: svn delete file… Similarly, to remove a directory and all files that are in it, type: svn delete directory…
The simple answer is "no", because Subversion doesn't know how to resolve the case when you add a commit, someone else updates their checkout, and then you remove the commit from history. There might or might not be a complex answer involving surgery on the Subversion storage.
Using svn to delete a file from your working copy deletes your local copy of the file, but merely schedules it to be deleted from the repository. When you commit, the file is deleted in the repository. $ svn delete myfile D myfile $ svn commit -m "Deleted file 'myfile'." Deleting myfile Transmitting file data .
To undo a specific revision you can use the following command: $ svn merge -c -r3745 . In case you have other edited files in working directory, you can commit only the relevant files. Please note that undoing actually will mean you create a new revision with the negatives changes of last commit.
Yes, but it is not for the faint of heart. You have to use svnadmin dump
and svnadmin load
to recreate your repository.
If you choose to do this, the first step is to stop your users from committing, and make a backup of your repository. I also recommend walking through the steps on a copy of your repository; you can use rsync
to copy the entire repository directory into a temporary directory, and work from there.
For these instructions, I'm going to create a new repository in a temporary directory:
tmp, 502> svnadmin create example.repo tmp, 503> svn co file://`pwd`/example.repo example Checked out revision 0.
I created a file that contained four revisions, the 3rd of which needs to be deleted:
example, 536> svn log test.txt ------------------------------------------------------------------------ r4 | kgregory | 2011-04-06 08:46:59 -0400 (Wed, 06 Apr 2011) | 1 line post-bad commit ------------------------------------------------------------------------ r3 | kgregory | 2011-04-06 08:46:42 -0400 (Wed, 06 Apr 2011) | 1 line bad revision ------------------------------------------------------------------------ r2 | kgregory | 2011-04-06 08:46:28 -0400 (Wed, 06 Apr 2011) | 1 line good revision ------------------------------------------------------------------------ r1 | kgregory | 2011-04-06 08:46:02 -0400 (Wed, 06 Apr 2011) | 1 line initial revision ------------------------------------------------------------------------
So, we need to dump revisions both before and after the bad one, using the -r
flag to specify revision ranges. The --incremental
flag on the second dump is important, because it will tell the load command not to create a new file.
Note that I'm running these commands from the same directory that holds the repository.
svnadmin dump -r 1:2 example.repo/ > pred.svndump * Dumped revision 1. * Dumped revision 2. tmp, 552> svnadmin dump -r 4:4 --incremental example.repo/ > succ.svndump * Dumped revision 4.
Now move the original repository out of the way, and create an empty repository with the same name:
tmp, 540> mv example.repo example.repo.bak tmp, 541> svnadmin create example.repo
And import the contents of the dump files.
tmp, 569> svnadmin --quiet load example.repo < pred.svndump tmp, 570> svnadmin --quiet --ignore-uuid load example.repo < succ.svndump
Now tell everyone to delete their working directories and check out fresh. And you should see the following log:
example, 574> svn log test.txt ------------------------------------------------------------------------ r3 | kgregory | 2011-04-06 08:46:59 -0400 (Wed, 06 Apr 2011) | 1 line post-bad commit ------------------------------------------------------------------------ r2 | kgregory | 2011-04-06 08:46:28 -0400 (Wed, 06 Apr 2011) | 1 line good revision ------------------------------------------------------------------------ r1 | kgregory | 2011-04-06 08:46:02 -0400 (Wed, 06 Apr 2011) | 1 line initial revision ------------------------------------------------------------------------
There is one HUGE caveat: this process assumes that there haven't been any commits to the file since the bad commit (ie, the successor dump only contains changes to other files).
If that's not the case, you can still delete the revision, but it's a lot more work. You need to create a new check-in, containing a clean copy of the file along with any other files that were changed with it while bad. Then create multiple dumpfiles, excluding any revisions that contained the bad file.
Finally: I strongly suggest several dry runs. As you can see from the history numbers in my examples, I screwed up a few times. As I said at the beginning, it's easy to copy a Subversion repository into a temporary directory. And when you do that, you can keep trying until you get it right, then just copy the fixed repository back into place.
See the answer at the FAQ
There are special cases where you might want to destroy all evidence of a file or commit. (Perhaps somebody accidentally committed a confidential document.) This isn't so easy, because Subversion is deliberately designed to never lose information. Revisions are immutable trees which build upon one another. Removing a revision from history would cause a domino effect, creating chaos in all subsequent revisions and possibly invalidating all working copies.
The project has plans, however, to someday implement an svnadmin obliterate command which would accomplish the task of permanently deleting information. (See issue 516.)
In the meantime, your only recourse is to svnadmin dump your repository, then pipe the dumpfile through svndumpfilter (excluding the bad path) into an svnadmin load command. See chapter 5 of the Subversion book for details about this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With