[drupal-devel] Retaining CVS history over moves

Chris Johnson chris at tinpixel.com
Thu May 5 14:36:16 UTC 2005

Tom Dobes wrote:
> On 5/4/05, Chris Johnson <chris at tinpixel.com> wrote:

>>Umm, well, that's a function of how the move was done, not just CVS --
>>although I admit CVS doesn't make it as easy as one would like.  But
>>bluemarine could have been moved with all history intact.

> Really?  How?  Could you point me / us to some docs or write a quick
> how-to?  This has come up a couple of times, even just within the
> contrib repository when stuff was being rearranged.  I've read the CVS
> docs (quite a while ago), but I don't remember seeing anything about
> this type of ability.

It's in the "info" documentation for CVS as installed on FreeBSD systems, at 
least.  "info cvs" from the command line, then search for "moving 
directories".  Here is a cut-and-paste of some of the pages.  The "Normal way" 
loses the history.  The "Copying the history file" preservees the history. 
One needs to understand Unix filesystems and how CVS stores its revision 
history quite well to do this confidently, but it can be done.  I've done it 
half a dozen times or so with my employer's CVS repository.

File: cvs.info,  Node: Outside,  Next: Inside,  Up: Moving files

The Normal way to Rename

The normal way to move a file is to copy OLD to NEW, and then issue the
normal CVS commands to remove OLD from the repository, and add NEW to

      $ mv OLD NEW
      $ cvs remove OLD
      $ cvs add NEW
      $ cvs commit -m "Renamed OLD to NEW" OLD NEW

    This is the simplest way to move a file, it is not error-prone, and
it preserves the history of what was done.  Note that to access the
history of the file you must specify the old or the new name, depending
on what portion of the history you are accessing.  For example, `cvs
log OLD' will give the log up until the time of the rename.

    When NEW is committed its revision numbers will start again, usually
at 1.1, so if that bothers you, use the `-r rev' option to commit.  For
more information see *Note Assigning revisions::.

File: cvs.info,  Node: Inside,  Next: Rename by copying,  Prev: Outside,  Up: M\
oving files

Moving the history file

This method is more dangerous, since it involves moving files inside
the repository.  Read this entire section before trying it out!

      $ cd $CVSROOT/DIR
      $ mv OLD,v NEW,v


    * The log of changes is maintained intact.

    * The revision numbers are not affected.


    * Old releases cannot easily be fetched from the repository.  (The
      file will show up as NEW even in revisions from the time before it
      was renamed).

    * There is no log information of when the file was renamed.

    * Nasty things might happen if someone accesses the history file
      while you are moving it.  Make sure no one else runs any of the CVS
      commands while you move it.

File: cvs.info,  Node: Rename by copying,  Prev: Inside,  Up: Moving files

Copying the history file   <<<<<<<< This is probably what would be best.

This way also involves direct modifications to the repository.  It is
safe, but not without drawbacks.

      # Copy the RCS file inside the repository
      $ cd $CVSROOT/DIR
      $ cp OLD,v NEW,v
      # Remove the old file
      $ cd ~/DIR
      $ rm OLD
      $ cvs remove OLD
      $ cvs commit OLD
      # Remove all tags from NEW
      $ cvs update NEW
      $ cvs log NEW             # Remember the non-branch tag names
      $ cvs tag -d TAG1 NEW
      $ cvs tag -d TAG2 NEW

    By removing the tags you will be able to check out old revisions.


    * Checking out old revisions works correctly, as long as you use
      `-rTAG' and not `-DDATE' to retrieve the revisions.

    * The log of changes is maintained intact.

    * The revision numbers are not affected.


    * You cannot easily see the history of the file across the rename.

File: cvs.info,  Node: Moving directories,  Prev: Moving files,  Up: Adding and\

Moving and renaming directories

The normal way to rename or move a directory is to rename or move each
file within it as described in *Note Outside::.  Then check out with
the `-P' option, as described in *Note Removing directories::.

    If you really want to hack the repository to rename or delete a
directory in the repository, you can do it like this:

   1. Inform everyone who has a checked out copy of the directory that
      the directory will be renamed.  They should commit all their
      changes, and remove their working copies, before you take the
      steps below.

   2. Rename the directory inside the repository.

           $ cd $CVSROOT/PARENT-DIR
           $ mv OLD-DIR NEW-DIR

   3. Fix the CVS administrative files, if necessary (for instance if
      you renamed an entire module).

   4. Tell everyone that they can check out again and continue working.

    If someone had a working copy the CVS commands will cease to work
for him, until he removes the directory that disappeared inside the

    It is almost always better to move the files in the directory
instead of moving the directory.  If you move the directory you are
unlikely to be able to retrieve old releases correctly, since they
probably depend on the name of the directories.

More information about the drupal-devel mailing list