]> git.vpit.fr Git - perl/modules/rgit.git/blob - bin/rgit
Stop looking for repositories inside repositories
[perl/modules/rgit.git] / bin / rgit
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Carp qw/croak/;
7 use Config qw/%Config/;
8 use Cwd qw/cwd/;
9 use File::Spec::Functions qw/catfile path/;
10
11 use App::Rgit;
12 use App::Rgit::Utils qw/:levels/;
13 use App::Rgit::Policy;
14
15 our $VERSION;
16 BEGIN {
17  $VERSION = '0.06';
18 }
19
20 my %opts;
21 my $cmd;
22
23 BEGIN {
24  @ARGV = grep {
25   defined $cmd ? $_
26                : ( /^-([DIKV]+)$/ ? do { $opts{$_} = 1 for split //, $1; () }
27                                   : do { $cmd = $_ unless /^-/; $_ } )
28  } @ARGV;
29  $cmd = ' ' unless defined $cmd;
30 }
31
32 my $policy;
33
34 if (-t && $opts{I}) {
35  $policy = 'Interactive';
36 } elsif ($opts{K}) {
37  $policy = 'Keep';
38 }
39 $policy = eval { App::Rgit::Policy->new(name => $policy) };
40 if (not defined $policy) {
41  print STDERR $@ if $@;
42  $policy = App::Rgit::Policy->new(name => 'Default');
43 }
44
45 setpgrp 0, 0 if $Config{d_setpgrp};
46
47 my $git = $ENV{GIT_EXEC_PATH};
48 unless (defined $git) {
49  for (path) {
50   my $g = catfile $_, 'git';
51   if (-x $g) {
52    $git = $g;
53    last;
54   }
55  }
56 }
57 croak "Couldn't find any valid git executable" unless defined $git;
58
59 my $root = $ENV{GIT_DIR};
60 $root = cwd unless defined $root;
61
62 my $ar = App::Rgit->new(
63  git    => $git,
64  root   => $root,
65  cmd    => $cmd,
66  args   => \@ARGV,
67  policy => $policy,
68  debug  => $opts{D} ? INFO : WARN,
69 );
70
71 print STDOUT "rgit $VERSION\n" if $opts{V};
72
73 exit $ar->run;
74
75 __END__
76
77 =head1 NAME
78
79 rgit - Recursively execute a command on all the git repositories in a directory tree.
80
81 =head1 VERSION
82
83 Version 0.06
84
85 =head1 SYNOPSIS
86
87     rgit [-K|-I|-D|-V] [GIT_OPTIONS] COMMAND [COMMAND_ARGS]
88
89 =head1 DESCRIPTION
90
91 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<GIT_DIR> environment variable) for all git repositories, sort this list by the repository path, C<chdir> into each of them, and executes the specified git command.
92 For efficiency reasons, repositories located inside another repository won't be searched for.
93
94 Moreover, those formats are substituted in the arguments before running the command :
95
96 =over 4
97
98 =item *
99
100 C<%n> with the current repository name.
101
102 =item *
103
104 C<%g> with the relative path (based from the root directory) to the current repository.
105
106 =item *
107
108 C<%G> with the absolute path to the current repository.
109
110 =item *
111
112 C<%w> with the relative path (based from the root directory) to the current repository's working directory.
113
114 =item *
115
116 C<%W> with the absolute path to the current repository's working directory.
117
118 =item *
119
120 C<%b> with a "bareified" relative path, i.e. C<%g> if this is a bare repository, and C<%w.git> otherwise.
121
122 =item *
123
124 C<%B> with an absolute version of the "bareified" path.
125
126 =item *
127
128 C<%R> with the absolute path to the root directory.
129
130 =item *
131
132 C<%%> with a bare C<%>.
133
134 =back
135
136 There are actually a few commands that are only executed once in the root directory : C<daemon>, C<gui>, C<help>, C<init> and C<version>.
137 For any of those, no format substitution is done.
138
139 You can specify which C<git> executable to use with the C<GIT_EXEC_PATH> environment variable.
140
141 =head1 COMMAND LINE SWITCHES
142
143 C<rgit> takes its options as the capital switches that comes before the git command.
144 It's possible to bundle them together.
145 They are removed from the argument list before calling C<git>.
146
147 =over 4
148
149 =item *
150
151 C<-K>
152
153 Keep processing on error.
154 The default policy is to stop whenever an error occured.
155
156 =item *
157
158 C<-I>
159
160 Enables interactive mode when the standard input is a tty.
161 Requires L<Term::ReadKey> to be installed.
162 This lets you choose interactively what to do when one of the commands returns a non-zero status.
163
164 =item *
165
166 C<-D>
167
168 Outputs diagnostics.
169
170 =item *
171
172 C<-V>
173
174 Outputs the version.
175
176 =back
177
178 =head1 EXAMPLES
179
180 Execute C<git gc> on all the repositories below the current directory :
181
182     rgit gc
183
184 Tag all the repositories with their name :
185
186     rgit tag %n
187
188 Add a remote to all repositories in "/foo/bar" to their bare counterpart in C<qux> on F<host> :
189
190     GIT_DIR="/foo/bar" rgit remote add host git://host/qux/%b
191
192 =head1 DEPENDENCIES
193
194 The core modules L<Carp>, L<Config>, L<Cwd>, L<Exporter>, L<File::Find>, L<File::Spec::Functions> and L<POSIX>.
195
196 =head1 AUTHOR
197
198 Vincent Pit, C<< <perl at profvince.com> >>, L<http://profvince.com>.
199    
200 You can contact me by mail or on C<irc.perl.org> (vincent).
201
202 =head1 BUGS
203
204 Please report any bugs or feature requests to C<bug-rgit at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=rgit>.  I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
205
206 =head1 SUPPORT
207
208 You can find documentation for this module with the perldoc command.
209
210     perldoc rgit
211
212 Tests code coverage report is available at L<http://www.profvince.com/perl/cover/rgit>.
213
214 =head1 COPYRIGHT & LICENSE
215
216 Copyright 2008-2009 Vincent Pit, all rights reserved.
217
218 This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
219
220 =cut