GNU Info

Info Node: (cvsbook.info)Getting Snapshots (Dates And Tagging)

(cvsbook.info)Getting Snapshots (Dates And Tagging)


Next: Acceptable Date Formats Prev: Avoiding Option Fatigue Up: Other Useful CVS Commands
Enter node , (file) or (file)node

Getting Snapshots (Dates And Tagging)
-------------------------------------

Let's return to the example of the program that's in a broken state when
a bug report comes in.  The developer suddenly needs access to the
entire project as it was at the time of the last release, even though
many files may have been changed since then, and each file's revision
number differs from the others.  It would be far too time-consuming to
look over the log messages, figure out what each file's individual
revision number was at the time of release, and then run update
(specifying a revision number with -r) on each one of them.  In medium-
to large-sized projects (tens to hundreds of files), such a process
would be too unwieldy to attempt.

CVS, therefore, provides a way to retrieve previous revisions of the
files in a project en masse.  In fact, it provides two ways: by date,
which selects the revisions based on the time that they were committed,
and by tag, which retrieves a previously marked "snapshot" of the
project.

Which method you use depends on the situation.  The date-based
retrievals are done by passing update the -D flag, which is similar to
-r but takes dates instead of revision numbers:

     floss$ cvs -q update -D "1999-04-19"
     U hello.c
     U a-subdir/subsubdir/fish.c
     U b-subdir/random.c
     floss$

With the -D option, update retrieves the highest revision of each file
as of the given date, and it will revert the files in the working copy
to prior revisions if necessary.

When you give the date, you can, and often should, include the time.
For example, the previous command ended up retrieving revision 1.1 of
everything (only three files showed changes, because all of the others
are still at revision 1.1 anyway).  Here's the status of hello.c to
prove it:

     floss$ cvs -Q status hello.c
     ===================================================================
     File: hello.c                 Status: Up-to-date
        Working revision:          1.1.1.1 Sat Apr 24 22:45:03 1999
        Repository revision:       1.1.1.1 /usr/local/cvs/myproj/hello.c,v
        Sticky Date:               99.04.19.05.00.00
     floss$

But a glance back at the log messages from earlier in this chapter shows
that revision 1.2 of hello.c was definitely committed on April 19,
1999.  So why did we now get revision 1.1 instead of 1.2?

The problem is that the date "1999-04-19" was interpreted as meaning
"the midnight that begins 1999-04-19" - that is, the very first instant
on that date.  This is probably not what you want.  The 1.2 commit took
place later in the day.  By qualifying the date more precisely, we can
retrieve revision 1.2:

     floss$ cvs -q update -D "1999-04-19 23:59:59"
     U hello.c
     U a-subdir/subsubdir/fish.c
     U b-subdir/random.c
     floss$ cvs status hello.c
     ===================================================================
     File: hello.c                 Status: Locally Modified
        Working revision:  1.2     Sat Apr 24 22:45:22 1999
        Repository revision:       1.2     /usr/local/cvs/myproj/hello.c,v
        Sticky Tag:                (none)
        Sticky Date:               99.04.20.04.59.59
        Sticky Options:    (none)
     floss$

We're almost there.  If you look closely at the date/time on the Sticky
Date line, it seems to indicate 4:59:59 A.M., not 11:59 as the command
requested (later we'll get to what the "sticky" means).  As you may have
guessed, the discrepancy is due to the difference between local time and
Universal Coordinated Time (also known as "Greenwich mean time").  The
repository always stores dates in Universal Time, but CVS on the client
side usually assumes the local system time zone.  In the case of -D,
this is rather unfortunate because you're probably most interested in
comparing against the repository time and don't care about the local
system's idea of time.  You can get around this by specifying the GMT
zone in the command:

     floss$ cvs -q update -D "1999-04-19 23:59:59 GMT"
     U hello.c
     floss$ cvs -q status hello.c
     ===================================================================
     File: hello.c                 Status: Up-to-date
        Working revision:  1.2     Sun Apr 25 22:38:53 1999
        Repository revision:       1.2     /usr/local/cvs/myproj/hello.c,v
        Sticky Tag:                (none)
        Sticky Date:               99.04.19.23.59.59
        Sticky Options:    (none)
     floss$

There - that brought the working copy back to the final commits from
April 19 (unless there were any commits during the last second of the
day, which there weren't).

What happens now if you run update?

     floss$ cvs update
     cvs update: Updating .
     cvs update: Updating a-subdir
     cvs update: Updating a-subdir/subsubdir
     cvs update: Updating b-subdir
     floss$

Nothing happens at all.  But you know that there are more recent
versions of at least three files.  Why aren't these included in your
working copy?

That's where the "sticky" comes in.  Updating ("downdating"?) with the
-D flag causes the working copy to be restricted permanently to that
date or before.  In CVS terminology, the working copy has a "sticky
date" set.  Once a working copy has acquired a sticky property, it stays
sticky until told otherwise.  Therefore, subsequent updates will not
automatically retrieve the most recent revision.  Instead, they'll stay
restricted to the sticky date.  Stickiness can be revealed by running
cvs status or by directly examining the CVS/Entries file:

     floss$ cvs -q update -D "1999-04-19 23:59:59 GMT"
     U hello.c
     floss$ cat CVS/Entries
     D/a-subdir////
     D/b-subdir////
     D/c-subdir////
     /README.txt/1.1.1.1/Sun Apr 18 18:18:22 1999//D99.04.19.23.59.59
     /hello.c/1.2/Sun Apr 25 23:07:29 1999//D99.04.19.23.59.59
     floss$

If you were to modify hello.c and then try to commit

     floss$ cvs update
     M hello.c
     floss$ cvs ci -m "trying to change the past"
     cvs commit: cannot commit with sticky date for file 'hello.c'
     cvs [commit aborted]: correct above errors first!
     floss$

CVS would not permit the commit to happen because that would be like
allowing you to go back and change the past.  CVS is all about record
keeping and, therefore, will not allow you to do that.

This does not mean CVS is unaware of all the revisions that have been
committed since that date, however.  You can still compare the
sticky-dated working copy against other revisions, including future
ones:

     floss$ cvs -q diff -c -r 1.5 hello.c
     Index: hello.c
     ===================================================================
     RCS file: /usr/local/cvs/myproj/hello.c,v
     retrieving revision 1.5
     diff -c -r1.5 hello.c
     *** hello.c   1999/04/24 22:09:27     1.5
     --- hello.c   1999/04/25 00:08:44
     ***************
     *** 3,9 ****
       void
       main ()
       {
         printf ("Hello, world!\n");
     -   printf ("between hello and goodbye\n");
         printf ("Goodbye, world!\n");
       }
     --- 3,9 --
       void
       main ()
       {
     +   /* this line was added to a downdated working copy */
         printf ("Hello, world!\n");
         printf ("Goodbye, world!\n");
       }

This diff reveals that, as of April 19, 1999, the between hello and
goodbye line had not yet been added.  It also shows the modification
that we made to the working copy (adding the comment shown in the
preceding code snippet).

You can remove a sticky date (or any sticky property) by updating with
the -A flag (-A stands for "reset", don't ask me why), which brings the
working copy back to the most recent revisions:

     floss$ cvs -q update -A
     U hello.c
     floss$ cvs status hello.c
     ===================================================================
     File: hello.c                 Status: Up-to-date
        Working revision:  1.5     Sun Apr 25 22:50:27 1999
        Repository revision:       1.5     /usr/local/cvs/myproj/hello.c,v
        Sticky Tag:                (none)
        Sticky Date:               (none)
        Sticky Options:    (none)
     floss$


automatically generated by info2www version 1.2.2.9