home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  

  Previous section   Next section

5.4 Comparing File Revisions

As your project develops, you sometimes need to compare a current revision with an old one, or compare two older revisions with each other. This usually happens when several developers are working on the same file and you need to know which changes were made to a file since you last worked on it.

The cvs diff command compares two revisions of a file and displays the differences. It uses a version of the GNU diff program internal to CVS; this code is also used when revisions are merged during cvs update.

The diff command and the similar rdiff command are also useful for creating patches to be installed by the GNU patch program.

cvs diff has the following syntax:

cvs [cvs-options] diff  [command_options] [filenames]

You can call cvs diff with filenames, directories, or module names. If you don't give a filename, the current working directory is the default.

Usually, you call cvs diff with at least one -r tag or -D date command option. If you invoke it with a single -r or -D parameter, CVS compares the current copy in the working directory with the version in the repository. For example, if you check out revision 1.6 of Makefile, edit the file, then run cvs diff -r 1.6 Makefile, diff displays the changes you made to Makefile since you checked it out.

If you invoke cvs diff with two -r or -D options, CVS compares the two revisions against each other. The command cvs diff -r 1.5 -r 1.7 Makefile displays the changes between revisions 1.5 and 1.7.

Example 5-14 shows a diff command that compares revisions 1.2 and 1.3 of the Makefile file, with the option to display a few lines of context around each change. The output starts with a header listing the filename, the repository copy of the file (listed as RCS file), the revisions to be retrieved, the diff options, and the times the revisions were committed.

diff then shows the sections that were changed. The diff in Example 5-14 shows the changes that occur when keywords are expanded, so the contents of the lines should help you understand the diff.

Example 5-14. Using cvs diff
bash-2.05a$ cvs diff -c -r 1.2 -r 1.3 Makefile
Index: Makefile
=  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =
RCS file: /var/lib/cvs/wizzard/Makefile,v
retrieving revision 1.2
retrieving revision 1.3
diff -c -r1.2 -r1.3
*** Makefile     1 Sep 2002 06:57:23 -0000     1.2
--- Makefile     12 Sep 2002 12:57:40 -0000    1.3
*** 2,10 ****
  # Makefile for the Wizzard project
  # First created by J Vesperman, 1 September 2002
! # Current revision $Revision: 1.3 $
  # On branch $Name:  $ (not expanded if this is the trunk)
! # Latest change by $Author: madd $ on $Date: 2003/07/07 21:52:50 $
  # Initial declarations
--- 2,10 ----
  # Makefile for the Wizzard project
  # First created by J Vesperman, 1 September 2002
! # Current revision $Revision: 1.3 $
  # On branch $Name:  $ (not expanded if this is the trunk)
! # Latest change by $Author: madd $ on $Date: 2003/07/07 21:52:50 $
  # Initial declarations
*** 34,39 ****
--- 33,41 ----
  # Log record for Makefile changes:
  # $Log: ch05.xml,v $
  # Revision 1.3  2003/07/07 21:52:50  madd
  # madd SC edits
  # Revision 1.2  2003/06/27 21:47:43  madd
  # madd R2 conversion edits
  # Revision 1.1  2003/06/26 22:22:10  madd
  # Initial revision
+ # Revision 1.3  2002/09/12 12:57:40  jenn
+ # Trying again with the wrappers..
+ #
  # Revision 1.2  2002/09/01 06:57:23  jenn
  # Initial code in the Makefile.

The first change occurs in the headers to the makefile, when the revision number and date are changed. These changes overwrite lines in the old revision, so the changed lines are denoted with an exclamation point (!) in the left column. The revision listed first in the parameter list is shown first, followed by the second revision.

The second change to the file is the new log message. This is only shown once, with plus marks (+) in the left column to show that the line was added.

Chapter 10 provides the full list of symbols and meanings for cvs diff.

In CVS 1.11.1 and later, you can also use cvs diff to generate files for patch.

The cvs rdiff command is a variant of cvs diff that can be used to create a patch file that can be installed using the standard GNU patch command. cvs rdiff is useful for publishing updates of programs. It does not require a sandbox but does require file, directory, or module name parameters. If cvs rdiff is used outside a sandbox, the repository path must be given with the -d CVS option or the CVSROOT environment variable. If cvs rdiff is used in a sandbox that connects to a repository other than the one you want to work from, the repository path must be given with the -d CVS option.

cvs rdiff has the following syntax:

cvs [cvs-options] rdiff  [command_options]   filenames

The filenames parameter can be one or more directories, filenames, or module names. Output from cvs rdiff is directed to stdout. If you intend to use the output as a patch file, you can redirect it to a file using the > shell operator. Example 5-15 shows how to make a patch for handheld.c that upgrades the file from revision 1.1 to the most current revision.

Example 5-15. Making a patch file
bash-2.05a$ cvs rdiff -r 1.1 -r HEAD wizzard/src/handheld.c  > patchfile

cvs diff and cvs rdiff take two types of options. The first are standard options that determine which revisions of which files are checked and which keyword mode is used. The second set of options determines the output format and affects how CVS compares the files. Chapter 10 provides the full list of options to cvs diff and cvs rdiff.

One of the most useful cvs diff (and cvs rdiff) options is -y, also available as --side-by-side. This option displays the differences between the files by showing the relevent lines beside each other. You will want to have a wide terminal window when using this option. Example 5-16 shows a side-by-side diff between the current revision of a file in the sandbox and the most recent revision in the repository.

Example 5-16. Displaying diff side-by-side
bash-2.05a$ cvs diff -y server.c
Index: server.c
=  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =
RCS file: /var/lib/cvs/wizzard/src/server.c,v
retrieving revision 1.1
diff --side-by-side -r1.1 server.c
/*                            /*
 * server.c                    * server.c 
 * Sep 13 2002                 * Sep 13 2002
 * Developer: Jenn Vesperman   * Developer: Jenn Vesperman 
 *                             * 
 * server code file            * server code file
 */                            */
                             > #include <iostream.h>
                             > int main (  ) {
                             >   cout << "Hello World\n";
                             >   return (0);
                             > }

  Previous section   Next section