: #-*- Perl -*- eval 'exec perl -w -S $0 ${1+"$@"}' # Portability kludge if 0; ### cvs-merge-diff --- Show the diff between various versions of a file ## Copyright (C) 2001 Ben Wing. ## Author: Ben Wing ## Maintainer: Ben Wing ## Current Version: 1.0, April 6, 2001 ## This file is part of XEmacs. ## XEmacs 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. ## XEmacs 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. ## You should have received a copy of the GNU General Public License ## along with XEmacs; see the file COPYING. If not, write to the Free ## Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ## 02111-1307, USA. use strict; (my $myName = $0) =~ s@.*/@@; my $usage=" Usage: $myName SPEC SPEC FILE Shows the diff between different versions of a file, after a merge. SPEC is one of Z, A, B, C, or D, according to the following diagram: Ancestor's Parent (Z) | | | | Ancestor (A) | \\ | \\ | \\ | \\ | \\ | \\ | \\ | \\ Pre-Merge (B) Repository (C) (in this ws) Change | / | / | / | / | / Post-Merge (D) (needs fixup) "; die $usage if $#ARGV != 2 || grep (/^-h/, @ARGV); my $spec1 = shift; my $spec2 = shift; my $file = shift; die $usage unless $spec1 =~ /^[zabcd]$/i and $spec2 =~ /^[zabcd]$/i; my ($filez, $filea, $fileb, $filec, $filed); my $cvsstatus; # To find the various versions: # B = look for files named .#FILE(.[0-9]+)+ and take the most recent one. # (#### this could fail in pathological cases but seems the most reliable # test.) # A = Extract the revision specified in the file found for B. # Z = derived from A. # C = `Working revision: ...' in cvs status. # D = current file. if ($spec1 =~ /c/i || $spec2 =~ /c/i) { ($filec) = (`cvs status $file` =~ /Working revision:\s*([0-9.]+)$/m); } sub sort_dot_pound_files { -M $a <=> -M $b; } if ($spec1 =~ /[baz]/i || $spec2 =~ /[baz]/i) { opendir DIR, "."; my @files = grep /^\.\#$file(.[0-9]+)+/, readdir DIR; closedir DIR; @files = sort sort_dot_pound_files @files; $fileb = $files[0]; ($filea = $fileb) =~ s/^\.\#$file.//; ($filez = $filea) =~ s/(\d+)$/$1-1/e; if ($filez =~ /\.0$/) { $filez =~ s/\.\d+\.\d+$//; } } sub getfile { return $filea if ($_[0] =~ /a/i); return $fileb if ($_[0] =~ /b/i); return $filec if ($_[0] =~ /c/i); return $file if ($_[0] =~ /d/i); return $filez if ($_[0] =~ /z/i); die "Bad arg $_[0] to getfile()"; } my $file1 = getfile ($spec1); my $file2 = getfile ($spec2); my $spec1_is_rev = $spec1 =~ /[azc]/i ? 1 : 0; my $spec2_is_rev = $spec2 =~ /[azc]/i ? 1 : 0; # print "file1: $file1\n"; # print "file2: $file2\n"; if ($spec1_is_rev && $spec2_is_rev) { # We are diffing two repository revisions. system "cvs diff -r $file1 -r $file2 $file"; } elsif (!$spec1_is_rev && !$spec2_is_rev) { # We are diffing two real files. system "diff -u $file1 $file2"; } else { # We are diffing a repository revision and a real file. Fetch the # repository revision. my $tmpfile = "/tmp/$file.$$"; if ($spec1_is_rev) { system "cvs update -p -r $file1 $file > $tmpfile"; system "diff -u $tmpfile $file2"; system "rm $tmpfile"; } else { system "cvs update -p -r $file2 $file > $tmpfile"; system "diff -u $file1 $tmpfile"; system "rm $tmpfile"; } }