Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete all traces of a SVN commit

Tags:

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.

like image 685
MasterScrat Avatar asked Apr 06 '11 12:04

MasterScrat


People also ask

How do I delete everything from svn?

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…

Does svn allow removing commits from history?

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.

How do I delete a file from a commit in svn?

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 .

How remove last commit in svn?

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.


2 Answers

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.

like image 98
kdgregory Avatar answered Sep 18 '22 12:09

kdgregory


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.

like image 39
Jeff Foster Avatar answered Sep 18 '22 12:09

Jeff Foster