Version Control with Subversion - Common Use-Cases - Resurrecting Deleted Items
Resurrecting Deleted Items
The great thing about version control systems is that
information is never lost. Even when you delete a file or
directory, it may be gone from the HEAD
revision, but the object still exists in earlier revisions.
One of the most common questions new users ask is, “How
do I get my old file or directory back?”.
The first step is to define exactly
which
item you're trying to resurrect.
Here's a useful metaphor: you can think of every object in the
repository as existing in a sort of two-dimensional coordinate
system. The first coordinate is a particular revision tree,
and the second coordinate is a path within that tree. So
every version of your file or directory can be defined by a
specific coordinate pair.
Subversion has no Attic directory
like CVS does,
[11]
so you need to use
svn
log
to discover the exact coordinate pair you wish
to resurrect. A good strategy is to run
svn log
--verbose
in a directory which used to contain your
deleted item. The --verbose option shows a
list of all changed items in each revision; all you need to do
is find the revision in which you deleted the file or
directory. You can do this visually, or by using another tool
to examine the log output (via
grep
, or
perhaps via an incremental search in an editor).
$ cd parent-dir
$ svn log --verbose
…
------------------------------------------------------------------------
r808 | joe | 2003-12-26 14:29:40 -0600 (Fri, 26 Dec 2003) | 3 lines
Changed paths:
D /calc/trunk/real.c
M /calc/trunk/integer.c
Added fast fourier transform functions to integer.c.
Removed real.c because code now in double.c.
…
In the example, we're assuming that you're looking for a
deleted file real.c . By looking through
the logs of a parent directory, you've spotted that this file
was deleted in revision 808. Therefore, the last version of
the file to exist was in the revision right before that.
Conclusion: you want to resurrect the path
/calc/trunk/real.c from revision
807.
That was the hard part—the research. Now that you
know what you want to restore, you have two different
choices.
One option is to use
svn merge
to apply
revision 808 “in reverse”. (We've already
discussed how to undo changes, see
the section called “Undoing Changes”.) This would have the effect of
re-adding real.c as a local modification.
The file would be scheduled for addition, and after a commit,
the file would again exist in HEAD .
In this particular example, however, this is probably not
the best strategy. Reverse-applying revision 808 would not
only schedule real.c for addition, but
the log message indicates that it would also undo certain
changes to integer.c , which you don't
want. Certainly, you could reverse-merge revision 808 and
then
svn revert
the local modifications to
integer.c , but this technique doesn't
scale well. What if there were 90 files changed in revision
808?
A second, more targeted strategy is not to use
svn merge
at all, but rather the
svn copy
command. Simply copy the exact
revision and path “coordinate pair” from the
repository to your working copy:
$ svn copy --revision 807 \
https://svn.example.com/repos/calc/trunk/real.c ./real.c
$ svn status
A + real.c
$ svn commit -m "Resurrected real.c from revision 807, /calc/trunk/real.c."
Adding real.c
Transmitting file data .
Committed revision 1390.
The plus sign in the status output indicates that the item
isn't merely scheduled for addition, but scheduled for
addition “with history”. Subversion remembers
where it was copied from. In the future, running
svn
log
on this file will traverse back through the
file's resurrection and through all the history it had prior
to revision 807. In other words, this new
real.c isn't really new; it's a direct
descendant of the original, deleted file.
Although our example shows us resurrecting a file, note
that these same techniques work just as well for resurrecting
deleted directories.
[an error occurred while processing this directive]
|