#!/usr/bin/perl use strict; use warnings; use Carp qw/croak/; use Config qw/%Config/; use Cwd qw/cwd/; use File::Spec::Functions qw/catfile path/; use App::Rgit; use App::Rgit::Utils qw/:levels/; use App::Rgit::Policy; our $VERSION; BEGIN { $VERSION = '0.06'; } my %opts; my $cmd; BEGIN { @ARGV = grep { defined $cmd ? $_ : ( /^-([DIKV]+)$/ ? do { $opts{$_} = 1 for split //, $1; () } : do { $cmd = $_ unless /^-/; $_ } ) } @ARGV; $cmd = ' ' unless defined $cmd; } my $policy; if (-t && $opts{I}) { $policy = 'Interactive'; } elsif ($opts{K}) { $policy = 'Keep'; } $policy = eval { App::Rgit::Policy->new(policy => $policy) }; if (not defined $policy) { print STDERR $@ if $@; $policy = App::Rgit::Policy->new(policy => 'Default'); } setpgrp 0, 0 if $Config{d_setpgrp}; my $git = $ENV{GIT_EXEC_PATH}; unless (defined $git) { for (path) { my $g = catfile $_, 'git'; if (-x $g) { $git = $g; last; } } } croak "Couldn't find any valid git executable" unless defined $git; my $root = $ENV{GIT_DIR}; $root = cwd unless defined $root; my $ar = App::Rgit->new( git => $git, root => $root, cmd => $cmd, args => \@ARGV, policy => $policy, debug => $opts{D} ? INFO : WARN, ); print STDOUT "rgit $VERSION\n" if $opts{V}; exit $ar->run; __END__ =head1 NAME rgit - Recursively execute a command on all the git repositories in a directory tree. =head1 VERSION Version 0.06 =head1 SYNOPSIS rgit [-K|-I|-D|-V] [GIT_OPTIONS] COMMAND [COMMAND_ARGS] =head1 DESCRIPTION This utility recursively searches in a root directory (which may be the current working directory or - if it has been set - the directory given by the C environment variable) for all git repositories, sort this list by the repository path, C into each of them, and executes the specified git command. For efficiency reasons, repositories located inside another repository won't be searched for. Moreover, those formats are substituted in the arguments before running the command : =over 4 =item * C<%n> with the current repository name. =item * C<%g> with the relative path (based from the root directory) to the current repository. =item * C<%G> with the absolute path to the current repository. =item * C<%w> with the relative path (based from the root directory) to the current repository's working directory. =item * C<%W> with the absolute path to the current repository's working directory. =item * C<%b> with a "bareified" relative path, i.e. C<%g> if this is a bare repository, and C<%w.git> otherwise. =item * C<%B> with an absolute version of the "bareified" path. =item * C<%R> with the absolute path to the root directory. =item * C<%%> with a bare C<%>. =back There are actually a few commands that are only executed once in the root directory : C, C, C, C and C. For any of those, no format substitution is done. You can specify which C executable to use with the C environment variable. =head1 COMMAND LINE SWITCHES C takes its options as the capital switches that comes before the git command. It's possible to bundle them together. They are removed from the argument list before calling C. =over 4 =item * C<-K> Keep processing on error. The default policy is to stop whenever an error occured. =item * C<-I> Enables interactive mode when the standard input is a tty. Requires L to be installed. This lets you choose interactively what to do when one of the commands returns a non-zero status. =item * C<-D> Outputs diagnostics. =item * C<-V> Outputs the version. =back =head1 EXAMPLES Execute C on all the repositories below the current directory : rgit gc Tag all the repositories with their name : rgit tag %n Add a remote to all repositories in "/foo/bar" to their bare counterpart in C on F : GIT_DIR="/foo/bar" rgit remote add host git://host/qux/%b =head1 DEPENDENCIES The core modules L, L, L, L, L, L and L. =head1 AUTHOR Vincent Pit, C<< >>, L. You can contact me by mail or on C (vincent). =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. =head1 SUPPORT You can find documentation for this module with the perldoc command. perldoc rgit Tests code coverage report is available at L. =head1 COPYRIGHT & LICENSE Copyright 2008-2009 Vincent Pit, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut