#!/usr/local/bin/perl $USAGE = q(USAGE: cvs-status [OPTIONS] [OTHERS] [FILES] SYNOPSIS: display cvs status one per line, and commands for diff/updates AUTHOR: GPL(C) Mohsin Ahmed, http://www.cs.albany.edu/~mosh OPTIONS: -/regex Show only matching lines. -v verbose, -v -v shows Up-to-date files also. -fsfile When NT cant pipe, do cvs status > sfile; cvs-status -fsfile; OTHERS pass thru to "cvs status OTHERS|". EXAMPLES: > cvs-status Show status of full tree. > cvs-status -l Status on current dir only. > cvs-status Makefile Calls "cvs status Makefile|" ); if( $0 =~ m/cvs-diff$/ ){ # If called as cvs-diff, do 'cvs-status -d'. unshift( @ARGV, "-d" ); } while( $_ = $ARGV[0], m/^-/ ){ shift; last if /^--$/; $do_diff++ , next if m/^-d/; $verbose++ , next if m/^-v/; ($sfile = $1), next if m/^-f(.+)/; ($pat = $1 ), next if m,^-/(.+),; die $USAGE if m/^-[h?]/; # warn "Unknown option '$_', use -h for help.\n", unshift(@ARGV,$_), last; } my( $cvsroot, $cvsdir ); my $shell = $ENV{'SHELL'} || $ENV{'shell'}; my( $usebackslash ) = ($shell =~ m,cmd,); $cvsroot = $ENV{CVSROOT}; if( -r "CVS/Repository" ){ $cvsdir = `cat CVS/Repository`; chomp $cvsdir; }else{ warn "No CVS/Repository, using CVSROOT=$cvsroot.\n"; $cvsdir = $cvsroot; } $cvsdir =~ s/^:local://; $cvsdir =~ s,\\,/,g; my $cmd = $sfile; unless( $cmd ){ $cmd = "cvs status @ARGV"; $cmd .= " 2> nul"; # unless $verbose; this hangs cvs on windows!!! $cmd .= "|"; } open( STATUS, $cmd) or die "cannot open '$cmd'\n"; print STDERR $cmd,"\n"; LINE: while( ){ chomp; if( m/^=======/ ){ # Reset all vars. $file = $fdir = $status = $wrev = $rrev = $wrev_org = $rrev_org = $sticky_tag = $sticky_date = $sticky_options = ''; next LINE; } if( m/revision:\s*(\S+)\s*(\S.*)$/ ){ my $number = $1; my $revdetails = $2; if( m/Working\srevision/ ){ $wrev = $wrev_org = $number; # 1.4 and 1.41 => 01.04, 01.41, for sorting. $wrev =~ s/\b\d\b/0$&/g; }elsif( m/Repository\srevision/ ){ $rrev = $rrev_org = $number; $rrev =~ s/\b\d\b/0$&/g; $fdir = $revdetails; $fdir =~ s,\\,/,g; $fdir =~ s,$cvsdir/,,; $fdir =~ s/,v$//; } next LINE; } if( m/File:/ ){ # eg. File: Makefile Status: Needs Patch if( m/File:\s*(\S+)\s*Status:\s*(.*)/ ){ $file = $1; $status = $2; next LINE; }elsif( m/File:\s*no file (\S+)\s*Status:\s*(.*)/ ){ $file = $1; $status = $2; next LINE; }else{ die "New stuff: $_"; } } if( m/Sticky/ ){ if( m/Sticky Tag:\s*(.*)/ ){ $sticky_tag = $1; $sticky_tag =~ s/\bbranch:\s*//i; next LINE; }elsif( m/Sticky Date:\s*(.*)/ ){ $sticky_date = $1; next LINE; }elsif( m/Sticky Options:\s*(.*)/ ){ $sticky_options = $1; $printit = 1; } } next unless $printit; $printit = 0; $fdir =~ s,/,\\,g if $usebackslash; $status =~ s/\bUp-to-date\b/uptodate/; my $line = sprintf "%-12s %-12s %-12s %-23s %s\n", $status, $wrev,$rrev, $sticky_tag, $fdir; next LINE if $pat && ($line !~ /$pat/); if( $status =~ m/Locally Modified/ ) { print $line; push @difflines, "cvs diff $fdir\n"; } elsif( $status =~ m/Needs Checkout/ ) { print $line; push @uplines, "cvs update $fdir\n"; push @difflines, "cvs diff -r $wrev_org -r $rrev_org $fdir\n"; } elsif( $status =~ m/Needs Patch/ ) { print $line; push @difflines, "cvs diff -r $wrev_org -r $rrev_org $fdir\n"; push @uplines, "cvs update $fdir\n"; } elsif( $status =~ m/Needs Merge/ ) { print $line; push @difflines, "cvs diff $fdir\n"; push @difflines, "cvs diff -r $rrev_org -r $wrev_org $fdir\n"; } else { print $line; } } close STATUS; print @uplines; print @difflines;