回滚或将整个 svn 存储库恢复到较早的版本

我搞砸了我的 SVN 存储库,现在需要将整个存储库从修订版28恢复到24,并且不想处理差异或冲突。有没有一种快速简单的方法可以做到这一点?在使用 merge 命令之前,我已经能够恢复单个文件了——但是在这个例子中,它希望将修订版28中的所有文件都添加回存储库,而我真正想做的只是删除它们。

我在 linux 机器上使用命令行(bash)。

谢谢

剪辑

谢谢你的帮忙,我修好了:

svnadmin create /svnroot/<repo>.fixed
svnadmin dump -r 1:24 /svnroot/<repo> --incremental > dump.svn
svnadmin load /svnroot/<repo>.fixed < dump.svn

然后将旧的回购放在备份位置,并将 repo.fix 移动到回购。

再次感谢!

85281 次浏览

You can do a new checkout of a particular revision. http://svnbook.red-bean.com/en/1.1/re04.html

svn co path/to/my/repo -r 24

A "reverse" merge may be what you need. See "undoing changes" section of svn book.

E.g. svn merge -r 28:24 [path to svn]

I hate to say this, but that is a situation where I've found myself using backups of my svn repository.

Can you copy files of a certain revision to a new directory within the repository?

Check out svnadmin dump/load. It creates a text file with every version of your files. It may be possible to delete everything above/below a certain point and re-import it.

See for instance Migrating Repository Data Elsewhere

here is how I would start to do it. Brutal, yes, but its the only thing guaranteed to completely ignore collisions and keep revisions history intact.

  cd /scratchdir
svn co -r good svn://repository
cd /hosed_project
svn up -r HEAD
cat >> /tmp/cp.sh
ORIG=$1
TARG=$( echo $ORIG | sed 's/\/scratchdir\///' );
cp $ORIG /hosed_project/$TARG;
^D
chmod u+x /tmp/cp.sh
find /scratchdir -not -wholename "*/.svn*" -exec /tmp/cp.sh {} \;

Note, this is not the "normal" way IMO, the normal way is to create a branch from an old version, and then merge that branch back in to the head. ( at least, that's how It used to work )

Edit: the above code is untested, do NOT run it verbatim

If you really want to completely remove files from the repository, you need to do an svndump into a file, filter out the revs and/or file paths you don't want, make a new repo, and svnload the filtered dump into the new repository. You'll want to carefully read the SVN book section on repository maintenance before you do any of this, and make sure you don't remove the existing repo until you're sure the new one has the stuff you want.

I'm not entirely sure if this work as I haven't used it in a live production yet, but I just now tried on a test repository (I copied one of my production ones) and it seems to work.

When you're in your repository, use the following command:

svn update -r 24 trunk

Where 24 is the revision number, and trunk is the file/folder you'd like to update (or restore, in this case) to said revision number.

In my test, several files were updated and (re-)added, and after doing a commit I did not receive any warnings whatsoever. I then modified a file with some dummy text and tried yet another commit, and only said file popped up on the modified list. So it seems to work rather well!

Again, I didn't use this before in live productions, so if I'm wrong please advice. I'd love to know if this is the way to go, too, because I can see myself needing this in the (near) future.

-Dave

If the folder structure of your application hasn't changed, checkout the old revision and replace the .svn folders from the latest revision into the checked out old revision. Now you can commit the "older" version.

If you really need to wipe 'evidence' that the files ever existed, you need to do the svndump/svnload actions described above.

In a 'normal' situation, where you made a mistake, you need to use reverse merge. This make sure that undoing the changes after r24 can also be reverted, diffed, etc.

The command below should work to undo your changes (you need to commit the result of the merge to reflect the merge in the repository)

svn merge -r 28:24

If you have access to the SVN server, you can just edit path/db/current, put the old revision number you want to revert to (here: 24) there, and remove no longer needed revision files (i.e. 25, 26, 27, 28) from path/db/revs/0/. At least this worked for me today, after I had accidentally removed a directory in the repository.

If you do not avail admin rights then you cannot obliterate any old revisions BUT you can still hide them extremely well with just one amazingly simple "svn copy" command (nickf and JesperE already mentioned this but in a rather cryptic way)

svn delete protocol://svnserver/some/resource
svn copy protocol://svnserver/some/resource@24 protocol://svnserver/some/resource

And that's it, revisions 25 to 28 have completely disappeared from svn log. It's not a hack at all, it is a safe and (barely...) documented feature.

If "resource" is a directory then you must strip it from the last URL:

svn copy protocol://svnserver/some/directory@24 protocol://svnserver/some/

(otherwise you would copy it inside itself)

Example:
Rev 100 all is working great
Rev 101 somebody really corrupted the dir structure and / or merged in bad changes, etc.
Rev 102 You delete /trunk
Rev 103 You copy /trunk@100 to HEAD
You now have a /trunk that reflects only Rev 100 and 103. Not 101 or 102.


svn del svn://[RepoName]/trunk -m "removing issue in HEAD"
svn copy svn://[RepoName]/trunk@100 svn://[RepoName]/trunk -m "Copy of correct revision of trunk to HEAD"

Could you svn del the topmost directories, then svn copy them:

svn copy svnurl@version svnurl

For anyone using TortoiseSVN, the solution is simple:

  • view change log
  • right-click the revision you want to roll back to...
  • ...select "Revert to this revision"
  • commit your changes

This method preserves the version history (i.e. all of the revisions that you reverted).