#!/usr/bin/perl # Written by: Wayne Davison # Freely redistributable. # This script has been modified to use the helper scripts cvs-status and # git-cvs-push instead of having that code included in this script. To # snag the helpers, see: http://opencoder.net/repos/ use strict; use warnings; my($action) = $0 =~ m{(?:^|/)(\w\w)$}; die "Run this script using a two-letter action link (ad, ci, di, lo, pu, st, up).\n" unless defined $action; my($type, $level) = find_repo_indicator(); die "Unable to figure out this directory's repo setup.\n" unless $type; my $func = \&{join '_', $type, $action}; $func->($level); die "Failed to run command: $!\n"; sub CVS_ad { exec qw( cvs add ), @ARGV; } sub svn_ad { exec qw( svn add ), @ARGV; } sub git_ad { exec qw( git add ), @ARGV; } sub bzr_ad { exec qw( bzr add ), @ARGV; } sub hg_ad { exec qw( hg add ), @ARGV; } sub CVS_ci { exec qw( cvs ci ), @ARGV; } sub svn_ci { exec qw( svn ci ), @ARGV; } sub git_ci { push @ARGV, '-a' if !@ARGV || (@ARGV == 2 && $ARGV[0] eq '-m'); pop @ARGV if @ARGV && $ARGV[-1] eq '-i'; exec qw( git commit ), @ARGV; } sub bzr_ci { exec qw( bzr commit ), @ARGV; } sub hg_ci { exec qw( hg ci ), @ARGV; } sub CVS_di { &run_with_pager( qw( cvs diff ), @ARGV ); } sub svn_di { &run_with_pager( qw( svn diff --no-diff-deleted ), @ARGV ); } sub git_di { exec qw( git diff ), @ARGV; } sub bzr_di { &run_with_pager( qw( bzr diff ), @ARGV ); } sub hg_di { &run_with_pager( qw( hg diff ), @ARGV ); } sub CVS_lo { &run_with_pager( qw( cvs log ), @ARGV ); } sub svn_lo { &run_with_pager( qw( svn log ), @ARGV ); } sub git_lo { my($level) = @_; if (-d "$level/.git/svn" && @ARGV && $ARGV[0] eq '-s') { shift @ARGV; exec qw( git svn log ), @ARGV; } else { if (@ARGV && $ARGV[0] eq '-v') { $ARGV[0] = '--name-status'; } exec qw( git log ), @ARGV; } } sub bzr_lo { &run_with_pager( qw( bzr log ), @ARGV ); } sub hg_lo { &run_with_pager( qw( hg log ), @ARGV ); } sub CVS_pu { die "This is a cvs repository.\n"; } sub svn_pu { die "This is an svn repository.\n"; } sub git_pu { my($level) = @_; if (-d "$level/.git/svn") { exec qw( git svn dcommit ), @ARGV; } elsif (-d "$level/.git/cvs") { exec qw( git-cvs-push ), $level, @ARGV; } else { exec qw( git push ), @ARGV; } } sub bzr_pu { exec qw( bzr push ), @ARGV; } sub hg_pu { exec qw( hg push ), @ARGV; } sub CVS_st { exec qw( cvs-status ), @ARGV; } sub svn_st { exec qw( svn st ), @ARGV; } sub git_st { system qw( git status ); exit; # We want a 0 exit, which git status frequently doesn't return. } sub bzr_st { exec qw( bzr st ), @ARGV; } sub hg_st { exec qw( hg st ), @ARGV; } sub CVS_up { my @opts = qw( -q ); if (@ARGV && $ARGV[0] eq '-n') { push @opts, '-n'; shift @ARGV; } exec 'cvs', @opts, qw( up -d -P ), @ARGV; } sub svn_up { exec qw( svn up ), @ARGV; } sub git_up { my($level) = @_; if (-d "$level/.git/svn") { exec qw( git svn rebase ), @ARGV; } else { exec qw( git pull --rebase ), @ARGV; } } sub bzr_up { exec qw( bzr pull ), @ARGV; } sub hg_up { exec qw( hg pull -u ), @ARGV; } sub find_repo_indicator { my $dir = shift || '.'; my $fn; my $inode = (stat($dir))[1]; while (1) { if (opendir(DP, $dir)) { while (defined($fn = readdir(DP))) { last if $fn =~ /^(CVS|\.svn|\.git|\.bzr|\.hg)$/; } closedir(DP); } last if defined $fn; $dir = "../$dir"; my $parent_inode = (stat($dir))[1]; return '' if $inode == $parent_inode; $inode = $parent_inode; } $fn =~ s/^\.//; ($fn, $dir); } sub run_with_pager { exec @_ unless -t STDOUT; # You should have -F in your less options for this to work nicely. # e.g. export LESS='mqeFisz-2XR' my $pager = $ENV{PAGER} || 'less'; open IN, '-|', @_ or die $!; open OUT, '|-', $pager or die $!; print OUT ; close OUT; close IN; exit; }