info-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Comparison of two repositories?


From: Mark D. Baushke
Subject: Re: Comparison of two repositories?
Date: Wed, 10 Sep 2003 09:55:33 -0700

Stephen Biggs <address@hidden> writes:

> Is there any easy way to do a full diff of two checked out trees from
> different repositories?

Using GNU diffutils, the 'diff -x CVS -r dir1 dir2' with and optional -c
for contex or -u for unified style diffs is how I typically do this kind
of comparison.

The '-x CVS' option tells GNU diff to exclude any CVS directories from
the comparison.

If you have lots of RCS keywords turned on, then you may wish to write a
quick script that goes thru your diff output an elides any hunks that
only contain differences in RCS keyword expansions. Feel free to adapt
the 'norcshunks' script included after my .signature for the purpose.

> The way I am doing it now is to export both trees (with -kk) so I don't
> have the CVS directories and then do a command line diff between the two
> local trees.
>
> What I would like to do is to be able to act upon the actual CVS
> sandboxes, but then the CVS directories and the info tags mess up the
> compare.

You can tell the GNU diffutils 'diff' program to exclude the CVS
directories, otherwise you will need to generate the list of files
to compare using find or something.

> Does anybody know of any simple scripts written for just this purpose?

Well, the attached is a script that elides a few RCS keywords from a raw
diff generated by  commands something like this:

    diff -x CVS -rup tree1 tree2 | ./norcshunks > my.diff
    diff -x CVS -rc2p tree1 tree2 | ./norcshunks > my.diff
    cvs diff -up | ./norcshunks > my.diff
    cvs diff -c2p -rsome-tag | ./norcshunks > my.diff

Your mileage may vary if you have different RCS keywords. Also, the
$Log$ keyword will not be properly hanlded by this script.

        Enjoy!
        -- Mark

            --------------- start norcshunks ---------------
: # use perl -*-Perl-*-
eval 'exec perl -S $0 ${1+"$@"}'
    if 0;

########################################################################
# Perl script to strip some RCS keywords from a context or unified diff.
#
# Copyright (c) 2003, Mark D. Baushke <address@hidden>
# All rights reserved.
#
# Permission is granted to copy and/or distribute this file, with or
# without modifications, provided this notice is preserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
########################################################################

use strict;
use warnings;

# GNU Diffutils -c (context) diff marker starts with 15 asterisk characters
# adding the -p option may add trailing text.
my $cdelim = '^' . '\*' x 15;                     # Context delimiter
my $udelim = 'address@hidden@\s[-+,0-9]+\s[-+,address@hidden@'; # Unified 
delimiter
my $sep = '';
my $hunk = '';
while (<>) {
    # Context diffs || Unified diffs
    if (/$cdelim/ || /$udelim/) {
        check_hunk();
        $hunk = '';
        $sep = $_;
    } elsif (($hunk ne '') &&
             (/^Index:/         # Common to directory diffs
              || /^$cdelim/     # Context diff hunk marker
              || /^$udelim/)) { # Unified diff marker
        check_hunk();
        $hunk = $_;
        $sep = '';
    } else {
        $hunk .= $_;
    }
    check_hunk() if (eof());
}

exit 0;

# Check each hunk to see if it has a change other than a trivial
# keyword expansion.
sub check_hunk {
    # Unified Diffs?
    my $unified = ($sep =~ /$udelim/) ? 1 : 0;

    # Context Diffs?
    my $context = ($sep =~ /$cdelim/) ? 1 : 0;

    # If there are no understood hunks, just print the block
    # and return.
    if ($context == 0 && $unified == 0) {
        print $sep, $hunk;
        return;
    }

    # Break the hunk into multiple lines and see if there is
    # anything in this hunk other than a keyword expansion.
    # Discard all context-only lines first.
    my @lines = grep($_ !~ /^\s/, split(/\n/, $hunk));

    # Remove all of the RCS/CVS keywords we want supressed.
    if ($unified) {
        @lines = grep($_ !~ /^[-+!].*\$(Id|Source|FreeBSD):.*\$/, @lines);
    } else {
        @lines = grep($_ !~ /^[-+!]\s.*\$(Id|Source|FreeBSD):.*\$/, @lines);

        # Remove the Context line markers if this is a context diff.
        @lines = grep($_ !~ /^[-*]{3}\s[,0-9]+\s[-*]{3}/, @lines);
    }

    # If there are any lines remaining, then the user will want to
    # see this entire hunk. Otherwise, we may silently drop this hunk.
    print($sep, $hunk) if (scalar(@lines) > 0);
}
__END__
            --------------- end norcshunks ---------------




reply via email to

[Prev in Thread] Current Thread [Next in Thread]