[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
`cvsdo diff'
From: |
Tom Tromey |
Subject: |
`cvsdo diff' |
Date: |
01 Jul 2001 13:12:24 -0600 |
Sorry for the cross post. I think this is of interest to both
projects. I'm trying to make it possible to use both utilities at
once.
The appended patch (made with Alexandre's "cvsdiff" :-) changes the
cvsutils `cvsdiff' to `cvsdo diff', which seems more natural to me.
It also adds a few TODO items for `cvsdo diff'.
Tom
Index: ChangeLog
from Tom Tromey <address@hidden>
* README: Document `cvsdo diff'.
* Makefile.am (plscripts): Removed cvsdiff.
(plscripts_src): Removed cvsdiff.pl.
* cvsdiff.pl: Removed.
* cvsdo.pl (Main): Handle `diff'. Anchor command-matching regular
expression.
(offline_diff): New function. Taken from cvsdiff.pl `Main'
(offline_diff): Modified to handle files on command line.
(handle_added, handle_removed, handle_modified, diff_print,
warning): From cvsdiff.pl.
Use `Time::Local'.
Index: Makefile.am
===================================================================
RCS file: /usr/local/cvs/cvsutils/Makefile.am,v
retrieving revision 1.5
diff -u -r1.5 Makefile.am
--- Makefile.am 2001/05/16 19:08:49 1.5
+++ Makefile.am 2001/07/01 18:51:08
@@ -5,8 +5,8 @@
shscripts = cvsco cvsdiscard cvspurge cvstrim cvsrmadm
shscripts_src = cvsco.sh cvsdiscard.sh cvspurge.sh cvstrim.sh cvsrmadm.sh
-plscripts = cvsu cvsdo cvsdiff cvschroot
-plscripts_src = cvsu.pl cvsdo.pl cvsdiff.pl cvschroot.pl
+plscripts = cvsu cvsdo cvschroot
+plscripts_src = cvsu.pl cvsdo.pl cvschroot.pl
bin_SCRIPTS = $(shscripts) $(plscripts)
CLEANFILES = $(bin_SCRIPTS)
Index: README
===================================================================
RCS file: /usr/local/cvs/cvsutils/README,v
retrieving revision 1.14
diff -u -r1.14 README
--- README 2001/05/16 19:08:49 1.14
+++ README 2001/07/01 18:51:08
@@ -97,23 +97,6 @@
Note that the backups for modified files are removed. cvstrim relies
- cvsdiff
-
-cvsdiff is an offline "cvs diff"
- "cvsdiff" tries to locate the backup copies of the modified files. If they
-can be found, cvsdiff compares them with the current version using "diff"
- Only those backup copies are used, that have the modification date equal
-the date listed in CVS/Entries for the modified file
- "cvsdiff" patches the diff output to make it more robust to apply.
-An exception is made for files named "ChangeLog" - in this case "diff" will
-be instructed to omit all context lines, so that the patch can be applied
-even if other changes have been written to the ChangeLog.
- Also the added files are handled properly. The header of the "diff" output
-is patched in such way, that at least GNU patch will create a new file when
-the resulting patch is applied and remove that file when the patch is
-reverted
-
-
cvschroot
cvschroot makes it possible to change CVS/Root in all subdirectories to
@@ -134,8 +117,23 @@
cvsdo
-cvsdo simulates some of the CVS commands (currently add and remove) without
-any access to the CVS server.
+cvsdo simulates some of the CVS commands (currently add, remove, and
+diff) without any access to the CVS server.
You can now create diffs with "cvs diff -N", and all removed and added
files will be mentioned there as such, even if you only have read-only
access to the repository
+
+"cvsdo diff" is an offline "cvs diff"
+ "cvsdo diff" tries to locate the backup copies of the modified
+files. If they can be found, cvsdiff compares them with the current
+version using "diff"
+ Only those backup copies are used, that have the modification date equal
+the date listed in CVS/Entries for the modified file
+ "cvsdo diff" patches the diff output to make it more robust to apply.
+An exception is made for files named "ChangeLog" - in this case "diff" will
+be instructed to omit all context lines, so that the patch can be applied
+even if other changes have been written to the ChangeLog.
+ Also the added files are handled properly. The header of the "diff" output
+is patched in such way, that at least GNU patch will create a new file when
+the resulting patch is applied and remove that file when the patch is
+reverted
Index: TODO
===================================================================
RCS file: /usr/local/cvs/cvsutils/TODO,v
retrieving revision 1.24
diff -u -r1.24 TODO
--- TODO 2000/06/24 00:03:49 1.24
+++ TODO 2001/07/01 18:51:08
@@ -11,3 +11,5 @@
cvsdep - "cvsdo touch Makefile.in" and other dependent stuff
"cvsdo prune" offline prune empty directories
cvsdiff - handle "cvs remove"d files properly
+"cvsdo diff" - read .cvsrc for diff options; handle diff options
+ from command line; handle files for diffing on command line
Index: cvsdo.pl
===================================================================
RCS file: /usr/local/cvs/cvsutils/cvsdo.pl,v
retrieving revision 1.2
diff -u -r1.2 cvsdo.pl
--- cvsdo.pl 2000/06/23 22:50:07 1.2
+++ cvsdo.pl 2001/07/01 18:51:08
@@ -4,6 +4,7 @@
# CVS repositories
require 5.004;
+use Time::Local;
use Getopt::Long;
use strict;
@@ -30,10 +31,14 @@
my $command = shift (@ARGV);
- if ( $want_ver || !$command || ($command !~ /(add|remove)/) ) {
+ if ( $want_ver || !$command || ($command !~ /^(add|remove|diff)$/) ) {
usage();
}
+ if ($command eq 'diff') {
+ offline_diff (@ARGV);
+ return;
+ }
if ( $#ARGV < 0 ) {
error ("No files specified\n");
}
@@ -123,6 +128,150 @@
( unlink $file || error ("Cannot delete file $file\n") );
}
+sub offline_diff
+{
+ my (@files) = @_;
+
+ if (scalar @files > 0) {
+ error ("`cvsdo diff' takes no arguments");
+ }
+
+ open(CVSADM, "cvsu --ignore --types AMRO |") ||
+ error ("Cannot read output of cvsu: $!");
+
+ while (<CVSADM>) {
+ chomp;
+ if ($_ !~ m{^([AMRO]) (.*)$}) {
+ error ("Unrecognized output from cvsu");
+ }
+ my $type = $1;
+ my $file = $2;
+ if ($type eq "A") {
+ handle_added ($file);
+ }
+ elsif ($type eq "R") {
+ handle_removed ($file);
+ }
+ else {
+ handle_modified ($file);
+ }
+ }
+}
+
+# Handle added files
+sub handle_added
+{
+ my $file = shift(@_);
+ open(DIFFOUT, "diff -u -L /dev/null -L $file /dev/null $file |") ||
+ error ("Cannot read output of diff: $!");
+ diff_print ("Index: $file");
+ while (<DIFFOUT>) {
+ diff_print ($_);
+ }
+}
+
+# Handle removed files
+sub handle_removed
+{
+ my $file = shift(@_);
+ # FIXME: scan for backup copies, as in handle_modified()
+ # Any ideas about how to make `patch' erase that file?
+ diff_print ("File $file should be removed!\n");
+}
+
+# Handle modified files
+sub handle_modified
+{
+ my $file = shift(@_);
+ # split into directory and file name
+ $file =~ m{^((.*/)?)([^/]+)};
+ my $short_file = $3;
+ my $dir = $1;
+ my %months = (
+ "Jan" => 0,
+ "Feb" => 1,
+ "Mar" => 2,
+ "Apr" => 3,
+ "May" => 4,
+ "Jun" => 5,
+ "Jul" => 6,
+ "Aug" => 7,
+ "Sep" => 8,
+ "Oct" => 9,
+ "Nov" => 10,
+ "Dec" => 11
+ );
+
+ # Lookup the original timestamp in CVS/Entries
+ open (ENTRIES, "< ${dir}CVS/Entries")
+ || error ("couldn't open ${dir}CVS/Entries: $!");
+ my $date_str;
+ while (<ENTRIES>) {
+ if ( m{^/$short_file/[^/]*/([^/]+)/} ) {
+ $date_str = $1;
+ last;
+ }
+ }
+ unless (defined $date_str) {
+ error ("$file is not listed in ${dir}CVS/Entries");
+ }
+ close (ENTRIES);
+
+ unless ($date_str =~ m{^(...) (...) (..) (..):(..):(..) (....)$}) {
+ error ("Invalid timestamp for $file: $date_str");
+ }
+
+ my $basetime = timegm($6, $5, $4, $3, $months{$2}, $7 - 1900);
+
+ # Scan the directory for similar files
+ my $backup_file;
+ opendir (DIR, $dir eq "" ? "." : $dir) ||
+ error ("Cannot open directory $dir: $!");
+ foreach (readdir (DIR)) {
+ m{$short_file} || next;;
+ my $candidate = $dir . $_;
+ stat ($candidate) || next;
+ if ($basetime == (stat _) [9]) {
+ $backup_file = $candidate;
+ last;
+ }
+ }
+ closedir (DIR);
+
+ unless (defined $backup_file) {
+ warning ("Backup file for $file not found");
+ return;
+ }
+
+ my $diff_opts = "-u";
+ if ($short_file eq "ChangeLog") {
+ $diff_opts = "-u1";
+ }
+
+ open(DIFFOUT,
+ "diff $diff_opts -L $file -L $file $backup_file $file |") ||
+ error ("Cannot read output of diff: $!");
+ diff_print ("Index: $file");
+ while (<DIFFOUT>) {
+ diff_print ($_);
+ }
+}
+
+# print message and make sure that it ends with a UNIX-style newline
+sub diff_print
+{
+ my $msg = shift(@_);
+ chomp $msg;
+ print $msg . "\012";
+}
+
+# print a warning message
+# newline is added at the end
+sub warning
+{
+ print STDERR "cvsdiff: WARNING: " . shift(@_) . "\n";
+}
+
# print message and exit (like "die", but without raising an exception)
sub error
{
@@ -140,7 +289,8 @@
" add Add a new file\n" .
" -f | --force Don't check whether the file exists\n" .
" remove Remove a file\n" .
- " -f | --force Delete existing files\n";
+ " -f | --force Delete existing files\n" .
+ " diff Print diffs for files\n";
exit 1;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- `cvsdo diff',
Tom Tromey <=