]> git.ipfire.org Git - thirdparty/git.git/blame - perl/Git.pm
git-svn, perl/Git.pm: add central method for prompting passwords
[thirdparty/git.git] / perl / Git.pm
CommitLineData
b1edc53d
PB
1=head1 NAME
2
3Git - Perl interface to the Git version control system
4
5=cut
6
7
8package Git;
9
d48b2841 10use 5.008;
b1edc53d
PB
11use strict;
12
13
14BEGIN {
15
16our ($VERSION, @ISA, @EXPORT, @EXPORT_OK);
17
18# Totally unstable API.
19$VERSION = '0.01';
20
21
22=head1 SYNOPSIS
23
24 use Git;
25
26 my $version = Git::command_oneline('version');
27
8b9150e3
PB
28 git_cmd_try { Git::command_noisy('update-server-info') }
29 '%s failed w/ code %d';
b1edc53d
PB
30
31 my $repo = Git->repository (Directory => '/srv/git/cogito.git');
32
33
34 my @revs = $repo->command('rev-list', '--since=last monday', '--all');
35
d79850e1 36 my ($fh, $c) = $repo->command_output_pipe('rev-list', '--since=last monday', '--all');
b1edc53d 37 my $lastrev = <$fh>; chomp $lastrev;
8b9150e3 38 $repo->command_close_pipe($fh, $c);
b1edc53d 39
d43ba468
PB
40 my $lastrev = $repo->command_oneline( [ 'rev-list', '--all' ],
41 STDERR => 0 );
b1edc53d 42
7182530d
AR
43 my $sha1 = $repo->hash_and_insert_object('file.txt');
44 my $tempfile = tempfile();
45 my $size = $repo->cat_blob($sha1, $tempfile);
46
b1edc53d
PB
47=cut
48
49
50require Exporter;
51
52@ISA = qw(Exporter);
53
8b9150e3 54@EXPORT = qw(git_cmd_try);
b1edc53d
PB
55
56# Methods which can be called as standalone functions as well:
d79850e1
PB
57@EXPORT_OK = qw(command command_oneline command_noisy
58 command_output_pipe command_input_pipe command_close_pipe
d1a29af9 59 command_bidi_pipe command_close_bidi_pipe
89a56bfb 60 version exec_path html_path hash_object git_cmd_try
38ecf3a3 61 remote_refs prompt
836ff95d 62 temp_acquire temp_release temp_reset temp_path);
b1edc53d
PB
63
64
65=head1 DESCRIPTION
66
67This module provides Perl scripts easy way to interface the Git version control
68system. The modules have an easy and well-tested way to call arbitrary Git
69commands; in the future, the interface will also provide specialized methods
70for doing easily operations which are not totally trivial to do over
71the generic command interface.
72
73While some commands can be executed outside of any context (e.g. 'version'
5c94f87e 74or 'init'), most operations require a repository context, which in practice
b1edc53d
PB
75means getting an instance of the Git object using the repository() constructor.
76(In the future, we will also get a new_repository() constructor.) All commands
77called as methods of the object are then executed in the context of the
78repository.
79
d5c7721d
PB
80Part of the "repository state" is also information about path to the attached
81working copy (unless you work with a bare repository). You can also navigate
82inside of the working copy using the C<wc_chdir()> method. (Note that
83the repository object is self-contained and will not change working directory
84of your process.)
b1edc53d 85
d5c7721d 86TODO: In the future, we might also do
b1edc53d
PB
87
88 my $remoterepo = $repo->remote_repository (Name => 'cogito', Branch => 'master');
89 $remoterepo ||= Git->remote_repository ('http://git.or.cz/cogito.git/');
90 my @refs = $remoterepo->refs();
91
b1edc53d
PB
92Currently, the module merely wraps calls to external Git tools. In the future,
93it will provide a much faster way to interact with Git by linking directly
94to libgit. This should be completely opaque to the user, though (performance
9751a32a 95increase notwithstanding).
b1edc53d
PB
96
97=cut
98
99
8b9150e3 100use Carp qw(carp croak); # but croak is bad - throw instead
97b16c06 101use Error qw(:try);
48d9e6ae 102use Cwd qw(abs_path cwd);
d1a29af9 103use IPC::Open2 qw(open2);
e41352b2 104use Fcntl qw(SEEK_SET SEEK_CUR);
b1edc53d
PB
105}
106
107
108=head1 CONSTRUCTORS
109
110=over 4
111
112=item repository ( OPTIONS )
113
114=item repository ( DIRECTORY )
115
116=item repository ()
117
118Construct a new repository object.
119C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
120Possible options are:
121
122B<Repository> - Path to the Git repository.
123
124B<WorkingCopy> - Path to the associated working copy; not strictly required
125as many commands will happily crunch on a bare repository.
126
d5c7721d
PB
127B<WorkingSubdir> - Subdirectory in the working copy to work inside.
128Just left undefined if you do not want to limit the scope of operations.
129
130B<Directory> - Path to the Git working directory in its usual setup.
131The C<.git> directory is searched in the directory and all the parent
132directories; if found, C<WorkingCopy> is set to the directory containing
133it and C<Repository> to the C<.git> directory itself. If no C<.git>
134directory was found, the C<Directory> is assumed to be a bare repository,
135C<Repository> is set to point at it and C<WorkingCopy> is left undefined.
136If the C<$GIT_DIR> environment variable is set, things behave as expected
137as well.
b1edc53d 138
b1edc53d
PB
139You should not use both C<Directory> and either of C<Repository> and
140C<WorkingCopy> - the results of that are undefined.
141
142Alternatively, a directory path may be passed as a single scalar argument
143to the constructor; it is equivalent to setting only the C<Directory> option
144field.
145
146Calling the constructor with no options whatsoever is equivalent to
d5c7721d
PB
147calling it with C<< Directory => '.' >>. In general, if you are building
148a standard porcelain command, simply doing C<< Git->repository() >> should
149do the right thing and setup the object to reflect exactly where the user
150is right now.
b1edc53d
PB
151
152=cut
153
154sub repository {
155 my $class = shift;
156 my @args = @_;
157 my %opts = ();
158 my $self;
159
160 if (defined $args[0]) {
161 if ($#args % 2 != 1) {
162 # Not a hash.
97b16c06
PB
163 $#args == 0 or throw Error::Simple("bad usage");
164 %opts = ( Directory => $args[0] );
b1edc53d
PB
165 } else {
166 %opts = @args;
167 }
d5c7721d
PB
168 }
169
11b8a41c
PB
170 if (not defined $opts{Repository} and not defined $opts{WorkingCopy}
171 and not defined $opts{Directory}) {
172 $opts{Directory} = '.';
d5c7721d
PB
173 }
174
11b8a41c 175 if (defined $opts{Directory}) {
64abcc48 176 -d $opts{Directory} or throw Error::Simple("Directory not found: $opts{Directory} $!");
d5c7721d
PB
177
178 my $search = Git->repository(WorkingCopy => $opts{Directory});
179 my $dir;
180 try {
181 $dir = $search->command_oneline(['rev-parse', '--git-dir'],
182 STDERR => 0);
183 } catch Git::Error::Command with {
184 $dir = undef;
185 };
b1edc53d 186
d5c7721d 187 if ($dir) {
71efe0ca 188 $dir =~ m#^/# or $dir = $opts{Directory} . '/' . $dir;
fe53bbc9 189 $opts{Repository} = abs_path($dir);
d5c7721d
PB
190
191 # If --git-dir went ok, this shouldn't die either.
192 my $prefix = $search->command_oneline('rev-parse', '--show-prefix');
193 $dir = abs_path($opts{Directory}) . '/';
194 if ($prefix) {
195 if (substr($dir, -length($prefix)) ne $prefix) {
196 throw Error::Simple("rev-parse confused me - $dir does not have trailing $prefix");
197 }
198 substr($dir, -length($prefix)) = '';
b1edc53d 199 }
d5c7721d
PB
200 $opts{WorkingCopy} = $dir;
201 $opts{WorkingSubdir} = $prefix;
202
203 } else {
204 # A bare repository? Let's see...
205 $dir = $opts{Directory};
206
207 unless (-d "$dir/refs" and -d "$dir/objects" and -e "$dir/HEAD") {
9517e6b8 208 # Mimic git-rev-parse --git-dir error message:
f66bc5f9 209 throw Error::Simple("fatal: Not a git repository: $dir");
d5c7721d
PB
210 }
211 my $search = Git->repository(Repository => $dir);
212 try {
213 $search->command('symbolic-ref', 'HEAD');
214 } catch Git::Error::Command with {
9517e6b8 215 # Mimic git-rev-parse --git-dir error message:
f66bc5f9 216 throw Error::Simple("fatal: Not a git repository: $dir");
d5c7721d
PB
217 }
218
219 $opts{Repository} = abs_path($dir);
b1edc53d 220 }
d5c7721d
PB
221
222 delete $opts{Directory};
b1edc53d
PB
223 }
224
81a71734 225 $self = { opts => \%opts };
b1edc53d
PB
226 bless $self, $class;
227}
228
b1edc53d
PB
229=back
230
231=head1 METHODS
232
233=over 4
234
235=item command ( COMMAND [, ARGUMENTS... ] )
236
d43ba468
PB
237=item command ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )
238
b1edc53d
PB
239Execute the given Git C<COMMAND> (specify it without the 'git-'
240prefix), optionally with the specified extra C<ARGUMENTS>.
241
d43ba468
PB
242The second more elaborate form can be used if you want to further adjust
243the command execution. Currently, only one option is supported:
244
245B<STDERR> - How to deal with the command's error output. By default (C<undef>)
246it is delivered to the caller's C<STDERR>. A false value (0 or '') will cause
247it to be thrown away. If you want to process it, you can get it in a filehandle
248you specify, but you must be extremely careful; if the error output is not
249very short and you want to read it in the same process as where you called
250C<command()>, you are set up for a nice deadlock!
251
b1edc53d
PB
252The method can be called without any instance or on a specified Git repository
253(in that case the command will be run in the repository context).
254
255In scalar context, it returns all the command output in a single string
256(verbatim).
257
258In array context, it returns an array containing lines printed to the
259command's stdout (without trailing newlines).
260
261In both cases, the command's stdin and stderr are the same as the caller's.
262
263=cut
264
265sub command {
d79850e1 266 my ($fh, $ctx) = command_output_pipe(@_);
b1edc53d
PB
267
268 if (not defined wantarray) {
8b9150e3
PB
269 # Nothing to pepper the possible exception with.
270 _cmd_close($fh, $ctx);
b1edc53d
PB
271
272 } elsif (not wantarray) {
273 local $/;
274 my $text = <$fh>;
8b9150e3
PB
275 try {
276 _cmd_close($fh, $ctx);
277 } catch Git::Error::Command with {
278 # Pepper with the output:
279 my $E = shift;
280 $E->{'-outputref'} = \$text;
281 throw $E;
282 };
b1edc53d
PB
283 return $text;
284
285 } else {
286 my @lines = <$fh>;
67e4baf8 287 defined and chomp for @lines;
8b9150e3
PB
288 try {
289 _cmd_close($fh, $ctx);
290 } catch Git::Error::Command with {
291 my $E = shift;
292 $E->{'-outputref'} = \@lines;
293 throw $E;
294 };
b1edc53d
PB
295 return @lines;
296 }
297}
298
299
300=item command_oneline ( COMMAND [, ARGUMENTS... ] )
301
d43ba468
PB
302=item command_oneline ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )
303
b1edc53d
PB
304Execute the given C<COMMAND> in the same way as command()
305does but always return a scalar string containing the first line
306of the command's standard output.
307
308=cut
309
310sub command_oneline {
d79850e1 311 my ($fh, $ctx) = command_output_pipe(@_);
b1edc53d
PB
312
313 my $line = <$fh>;
d5c7721d 314 defined $line and chomp $line;
8b9150e3
PB
315 try {
316 _cmd_close($fh, $ctx);
317 } catch Git::Error::Command with {
318 # Pepper with the output:
319 my $E = shift;
320 $E->{'-outputref'} = \$line;
321 throw $E;
322 };
b1edc53d
PB
323 return $line;
324}
325
326
d79850e1 327=item command_output_pipe ( COMMAND [, ARGUMENTS... ] )
b1edc53d 328
d43ba468
PB
329=item command_output_pipe ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )
330
b1edc53d
PB
331Execute the given C<COMMAND> in the same way as command()
332does but return a pipe filehandle from which the command output can be
333read.
334
d79850e1
PB
335The function can return C<($pipe, $ctx)> in array context.
336See C<command_close_pipe()> for details.
337
b1edc53d
PB
338=cut
339
d79850e1
PB
340sub command_output_pipe {
341 _command_common_pipe('-|', @_);
342}
b1edc53d 343
b1edc53d 344
d79850e1
PB
345=item command_input_pipe ( COMMAND [, ARGUMENTS... ] )
346
d43ba468
PB
347=item command_input_pipe ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )
348
d79850e1
PB
349Execute the given C<COMMAND> in the same way as command_output_pipe()
350does but return an input pipe filehandle instead; the command output
351is not captured.
352
353The function can return C<($pipe, $ctx)> in array context.
354See C<command_close_pipe()> for details.
355
356=cut
357
358sub command_input_pipe {
359 _command_common_pipe('|-', @_);
8b9150e3
PB
360}
361
362
363=item command_close_pipe ( PIPE [, CTX ] )
364
d79850e1 365Close the C<PIPE> as returned from C<command_*_pipe()>, checking
3dff5379 366whether the command finished successfully. The optional C<CTX> argument
8b9150e3 367is required if you want to see the command name in the error message,
d79850e1 368and it is the second value returned by C<command_*_pipe()> when
8b9150e3
PB
369called in array context. The call idiom is:
370
d79850e1
PB
371 my ($fh, $ctx) = $r->command_output_pipe('status');
372 while (<$fh>) { ... }
373 $r->command_close_pipe($fh, $ctx);
8b9150e3
PB
374
375Note that you should not rely on whatever actually is in C<CTX>;
376currently it is simply the command name but in future the context might
377have more complicated structure.
378
379=cut
380
381sub command_close_pipe {
382 my ($self, $fh, $ctx) = _maybe_self(@_);
383 $ctx ||= '<unknown>';
384 _cmd_close($fh, $ctx);
b1edc53d
PB
385}
386
d1a29af9
AR
387=item command_bidi_pipe ( COMMAND [, ARGUMENTS... ] )
388
389Execute the given C<COMMAND> in the same way as command_output_pipe()
390does but return both an input pipe filehandle and an output pipe filehandle.
391
392The function will return return C<($pid, $pipe_in, $pipe_out, $ctx)>.
393See C<command_close_bidi_pipe()> for details.
394
395=cut
396
397sub command_bidi_pipe {
398 my ($pid, $in, $out);
48d9e6ae
MO
399 my ($self) = _maybe_self(@_);
400 local %ENV = %ENV;
401 my $cwd_save = undef;
402 if ($self) {
403 shift;
404 $cwd_save = cwd();
405 _setup_git_cmd_env($self);
406 }
d1a29af9 407 $pid = open2($in, $out, 'git', @_);
48d9e6ae 408 chdir($cwd_save) if $cwd_save;
d1a29af9
AR
409 return ($pid, $in, $out, join(' ', @_));
410}
411
412=item command_close_bidi_pipe ( PID, PIPE_IN, PIPE_OUT [, CTX] )
413
414Close the C<PIPE_IN> and C<PIPE_OUT> as returned from C<command_bidi_pipe()>,
415checking whether the command finished successfully. The optional C<CTX>
416argument is required if you want to see the command name in the error message,
417and it is the fourth value returned by C<command_bidi_pipe()>. The call idiom
418is:
419
420 my ($pid, $in, $out, $ctx) = $r->command_bidi_pipe('cat-file --batch-check');
421 print "000000000\n" $out;
422 while (<$in>) { ... }
423 $r->command_close_bidi_pipe($pid, $in, $out, $ctx);
424
425Note that you should not rely on whatever actually is in C<CTX>;
426currently it is simply the command name but in future the context might
427have more complicated structure.
428
429=cut
430
431sub command_close_bidi_pipe {
108c2aaf 432 local $?;
d1a29af9
AR
433 my ($pid, $in, $out, $ctx) = @_;
434 foreach my $fh ($in, $out) {
435 unless (close $fh) {
436 if ($!) {
437 carp "error closing pipe: $!";
438 } elsif ($? >> 8) {
439 throw Git::Error::Command($ctx, $? >>8);
440 }
441 }
442 }
443
444 waitpid $pid, 0;
445
446 if ($? >> 8) {
447 throw Git::Error::Command($ctx, $? >>8);
448 }
449}
450
b1edc53d
PB
451
452=item command_noisy ( COMMAND [, ARGUMENTS... ] )
453
454Execute the given C<COMMAND> in the same way as command() does but do not
455capture the command output - the standard output is not redirected and goes
456to the standard output of the caller application.
457
458While the method is called command_noisy(), you might want to as well use
459it for the most silent Git commands which you know will never pollute your
460stdout but you want to avoid the overhead of the pipe setup when calling them.
461
462The function returns only after the command has finished running.
463
464=cut
465
466sub command_noisy {
467 my ($self, $cmd, @args) = _maybe_self(@_);
d79850e1 468 _check_valid_cmd($cmd);
b1edc53d
PB
469
470 my $pid = fork;
471 if (not defined $pid) {
97b16c06 472 throw Error::Simple("fork failed: $!");
b1edc53d
PB
473 } elsif ($pid == 0) {
474 _cmd_exec($self, $cmd, @args);
475 }
8b9150e3
PB
476 if (waitpid($pid, 0) > 0 and $?>>8 != 0) {
477 throw Git::Error::Command(join(' ', $cmd, @args), $? >> 8);
b1edc53d
PB
478 }
479}
480
481
63df97ae
PB
482=item version ()
483
484Return the Git version in use.
485
63df97ae
PB
486=cut
487
18b0fc1c
PB
488sub version {
489 my $verstr = command_oneline('--version');
490 $verstr =~ s/^git version //;
491 $verstr;
492}
63df97ae
PB
493
494
eca1f6fd
PB
495=item exec_path ()
496
d5c7721d 497Return path to the Git sub-command executables (the same as
eca1f6fd
PB
498C<git --exec-path>). Useful mostly only internally.
499
eca1f6fd
PB
500=cut
501
18b0fc1c 502sub exec_path { command_oneline('--exec-path') }
eca1f6fd
PB
503
504
89a56bfb
MH
505=item html_path ()
506
507Return path to the Git html documentation (the same as
508C<git --html-path>). Useful mostly only internally.
509
510=cut
511
512sub html_path { command_oneline('--html-path') }
513
38ecf3a3
SS
514=item prompt ( PROMPT )
515
516Query user C<PROMPT> and return answer from user.
517
518Honours GIT_ASKPASS environment variable for querying
519the user. If no GIT_ASKPASS variable is set or an error occoured,
520the terminal is tried as a fallback.
521
522=cut
523
524sub prompt {
525 my ($prompt) = @_;
526 my $ret;
527 if (exists $ENV{'GIT_ASKPASS'}) {
528 $ret = _prompt($ENV{'GIT_ASKPASS'}, $prompt);
529 }
530 if (!defined $ret) {
531 print STDERR $prompt;
532 STDERR->flush;
533 require Term::ReadKey;
534 Term::ReadKey::ReadMode('noecho');
535 $ret = '';
536 while (defined(my $key = Term::ReadKey::ReadKey(0))) {
537 last if $key =~ /[\012\015]/; # \n\r
538 $ret .= $key;
539 }
540 Term::ReadKey::ReadMode('restore');
541 print STDERR "\n";
542 STDERR->flush;
543 }
544 return $ret;
545}
546
547sub _prompt {
548 my ($askpass, $prompt) = @_;
549 return unless length $askpass;
550 my $ret;
551 open my $fh, "-|", $askpass, $prompt or return;
552 $ret = <$fh>;
553 $ret =~ s/[\015\012]//g; # strip \r\n, chomp does not work on all systems (i.e. windows) as expected
554 close ($fh);
555 return $ret;
556}
89a56bfb 557
d5c7721d
PB
558=item repo_path ()
559
560Return path to the git repository. Must be called on a repository instance.
561
562=cut
563
564sub repo_path { $_[0]->{opts}->{Repository} }
565
566
567=item wc_path ()
568
569Return path to the working copy. Must be called on a repository instance.
570
571=cut
572
573sub wc_path { $_[0]->{opts}->{WorkingCopy} }
574
575
576=item wc_subdir ()
577
578Return path to the subdirectory inside of a working copy. Must be called
579on a repository instance.
580
581=cut
582
583sub wc_subdir { $_[0]->{opts}->{WorkingSubdir} ||= '' }
584
585
586=item wc_chdir ( SUBDIR )
587
588Change the working copy subdirectory to work within. The C<SUBDIR> is
589relative to the working copy root directory (not the current subdirectory).
590Must be called on a repository instance attached to a working copy
591and the directory must exist.
592
593=cut
594
595sub wc_chdir {
596 my ($self, $subdir) = @_;
d5c7721d
PB
597 $self->wc_path()
598 or throw Error::Simple("bare repository");
599
600 -d $self->wc_path().'/'.$subdir
64abcc48 601 or throw Error::Simple("subdir not found: $subdir $!");
d5c7721d
PB
602 # Of course we will not "hold" the subdirectory so anyone
603 # can delete it now and we will never know. But at least we tried.
604
605 $self->{opts}->{WorkingSubdir} = $subdir;
606}
607
608
dc2613de
PB
609=item config ( VARIABLE )
610
e0d10e1c 611Retrieve the configuration C<VARIABLE> in the same manner as C<config>
dc2613de
PB
612does. In scalar context requires the variable to be set only one time
613(exception is thrown otherwise), in array context returns allows the
614variable to be set multiple times and returns all the values.
615
dc2613de
PB
616=cut
617
618sub config {
6942a3d7 619 return _config_common({}, @_);
dc2613de
PB
620}
621
622
35c49eea 623=item config_bool ( VARIABLE )
7b9a13ec 624
35c49eea
PB
625Retrieve the bool configuration C<VARIABLE>. The return value
626is usable as a boolean in perl (and C<undef> if it's not defined,
627of course).
7b9a13ec 628
7b9a13ec
TT
629=cut
630
35c49eea 631sub config_bool {
6942a3d7 632 my $val = scalar _config_common({'kind' => '--bool'}, @_);
7b9a13ec 633
6942a3d7
JH
634 # Do not rewrite this as return (defined $val && $val eq 'true')
635 # as some callers do care what kind of falsehood they receive.
636 if (!defined $val) {
637 return undef;
638 } else {
35c49eea 639 return $val eq 'true';
6942a3d7 640 }
7b9a13ec
TT
641}
642
9fef9e27
CS
643
644=item config_path ( VARIABLE )
645
646Retrieve the path configuration C<VARIABLE>. The return value
647is an expanded path or C<undef> if it's not defined.
648
9fef9e27
CS
649=cut
650
651sub config_path {
6942a3d7 652 return _config_common({'kind' => '--path'}, @_);
9fef9e27
CS
653}
654
6942a3d7 655
346d203b
JN
656=item config_int ( VARIABLE )
657
658Retrieve the integer configuration C<VARIABLE>. The return value
659is simple decimal number. An optional value suffix of 'k', 'm',
660or 'g' in the config file will cause the value to be multiplied
661by 1024, 1048576 (1024^2), or 1073741824 (1024^3) prior to output.
662It would return C<undef> if configuration variable is not defined,
663
346d203b
JN
664=cut
665
666sub config_int {
6942a3d7
JH
667 return scalar _config_common({'kind' => '--int'}, @_);
668}
669
670# Common subroutine to implement bulk of what the config* family of methods
671# do. This curently wraps command('config') so it is not so fast.
672sub _config_common {
673 my ($opts) = shift @_;
c2e357c2 674 my ($self, $var) = _maybe_self(@_);
346d203b
JN
675
676 try {
6942a3d7 677 my @cmd = ('config', $opts->{'kind'} ? $opts->{'kind'} : ());
c2e357c2 678 unshift @cmd, $self if $self;
6942a3d7
JH
679 if (wantarray) {
680 return command(@cmd, '--get-all', $var);
681 } else {
682 return command_oneline(@cmd, '--get', $var);
683 }
346d203b
JN
684 } catch Git::Error::Command with {
685 my $E = shift;
686 if ($E->value() == 1) {
687 # Key not found.
6942a3d7 688 return;
346d203b
JN
689 } else {
690 throw $E;
691 }
692 };
693}
7b9a13ec 694
b4c61ed6
JH
695=item get_colorbool ( NAME )
696
697Finds if color should be used for NAMEd operation from the configuration,
698and returns boolean (true for "use color", false for "do not use color").
699
700=cut
701
702sub get_colorbool {
703 my ($self, $var) = @_;
704 my $stdout_to_tty = (-t STDOUT) ? "true" : "false";
705 my $use_color = $self->command_oneline('config', '--get-colorbool',
706 $var, $stdout_to_tty);
707 return ($use_color eq 'true');
708}
709
710=item get_color ( SLOT, COLOR )
711
712Finds color for SLOT from the configuration, while defaulting to COLOR,
713and returns the ANSI color escape sequence:
714
715 print $repo->get_color("color.interactive.prompt", "underline blue white");
716 print "some text";
717 print $repo->get_color("", "normal");
718
719=cut
720
721sub get_color {
722 my ($self, $slot, $default) = @_;
723 my $color = $self->command_oneline('config', '--get-color', $slot, $default);
724 if (!defined $color) {
725 $color = "";
726 }
727 return $color;
728}
729
31a92f6a
PB
730=item remote_refs ( REPOSITORY [, GROUPS [, REFGLOBS ] ] )
731
732This function returns a hashref of refs stored in a given remote repository.
733The hash is in the format C<refname =\> hash>. For tags, the C<refname> entry
734contains the tag object while a C<refname^{}> entry gives the tagged objects.
735
736C<REPOSITORY> has the same meaning as the appropriate C<git-ls-remote>
a7793a74 737argument; either a URL or a remote name (if called on a repository instance).
31a92f6a
PB
738C<GROUPS> is an optional arrayref that can contain 'tags' to return all the
739tags and/or 'heads' to return all the heads. C<REFGLOB> is an optional array
740of strings containing a shell-like glob to further limit the refs returned in
741the hash; the meaning is again the same as the appropriate C<git-ls-remote>
742argument.
743
744This function may or may not be called on a repository instance. In the former
745case, remote names as defined in the repository are recognized as repository
746specifiers.
747
748=cut
749
750sub remote_refs {
751 my ($self, $repo, $groups, $refglobs) = _maybe_self(@_);
752 my @args;
753 if (ref $groups eq 'ARRAY') {
754 foreach (@$groups) {
755 if ($_ eq 'heads') {
756 push (@args, '--heads');
757 } elsif ($_ eq 'tags') {
758 push (@args, '--tags');
759 } else {
760 # Ignore unknown groups for future
761 # compatibility
762 }
763 }
764 }
765 push (@args, $repo);
766 if (ref $refglobs eq 'ARRAY') {
767 push (@args, @$refglobs);
768 }
769
770 my @self = $self ? ($self) : (); # Ultra trickery
771 my ($fh, $ctx) = Git::command_output_pipe(@self, 'ls-remote', @args);
772 my %refs;
773 while (<$fh>) {
774 chomp;
775 my ($hash, $ref) = split(/\t/, $_, 2);
776 $refs{$ref} = $hash;
777 }
778 Git::command_close_pipe(@self, $fh, $ctx);
779 return \%refs;
780}
781
782
c7a30e56
PB
783=item ident ( TYPE | IDENTSTR )
784
785=item ident_person ( TYPE | IDENTSTR | IDENTARRAY )
786
787This suite of functions retrieves and parses ident information, as stored
788in the commit and tag objects or produced by C<var GIT_type_IDENT> (thus
789C<TYPE> can be either I<author> or I<committer>; case is insignificant).
790
5354a56f 791The C<ident> method retrieves the ident information from C<git var>
c7a30e56
PB
792and either returns it as a scalar string or as an array with the fields parsed.
793Alternatively, it can take a prepared ident string (e.g. from the commit
794object) and just parse it.
795
796C<ident_person> returns the person part of the ident - name and email;
797it can take the same arguments as C<ident> or the array returned by C<ident>.
798
799The synopsis is like:
800
801 my ($name, $email, $time_tz) = ident('author');
802 "$name <$email>" eq ident_person('author');
803 "$name <$email>" eq ident_person($name);
804 $time_tz =~ /^\d+ [+-]\d{4}$/;
805
c7a30e56
PB
806=cut
807
808sub ident {
44617928 809 my ($self, $type) = _maybe_self(@_);
c7a30e56
PB
810 my $identstr;
811 if (lc $type eq lc 'committer' or lc $type eq lc 'author') {
44617928
FL
812 my @cmd = ('var', 'GIT_'.uc($type).'_IDENT');
813 unshift @cmd, $self if $self;
814 $identstr = command_oneline(@cmd);
c7a30e56
PB
815 } else {
816 $identstr = $type;
817 }
818 if (wantarray) {
819 return $identstr =~ /^(.*) <(.*)> (\d+ [+-]\d{4})$/;
820 } else {
821 return $identstr;
822 }
823}
824
825sub ident_person {
44617928
FL
826 my ($self, @ident) = _maybe_self(@_);
827 $#ident == 0 and @ident = $self ? $self->ident($ident[0]) : ident($ident[0]);
c7a30e56
PB
828 return "$ident[0] <$ident[1]>";
829}
830
831
24c4b714 832=item hash_object ( TYPE, FILENAME )
b1edc53d 833
58c8dd21
LW
834Compute the SHA1 object id of the given C<FILENAME> considering it is
835of the C<TYPE> object type (C<blob>, C<commit>, C<tree>).
b1edc53d 836
b1edc53d
PB
837The method can be called without any instance or on a specified Git repository,
838it makes zero difference.
839
840The function returns the SHA1 hash.
841
b1edc53d
PB
842=cut
843
18b0fc1c 844# TODO: Support for passing FILEHANDLE instead of FILENAME
e6634ac9
PB
845sub hash_object {
846 my ($self, $type, $file) = _maybe_self(@_);
18b0fc1c 847 command_oneline('hash-object', '-t', $type, $file);
e6634ac9 848}
b1edc53d
PB
849
850
7182530d
AR
851=item hash_and_insert_object ( FILENAME )
852
853Compute the SHA1 object id of the given C<FILENAME> and add the object to the
854object database.
855
856The function returns the SHA1 hash.
857
858=cut
859
860# TODO: Support for passing FILEHANDLE instead of FILENAME
861sub hash_and_insert_object {
862 my ($self, $filename) = @_;
863
864 carp "Bad filename \"$filename\"" if $filename =~ /[\r\n]/;
865
866 $self->_open_hash_and_insert_object_if_needed();
867 my ($in, $out) = ($self->{hash_object_in}, $self->{hash_object_out});
868
869 unless (print $out $filename, "\n") {
870 $self->_close_hash_and_insert_object();
871 throw Error::Simple("out pipe went bad");
872 }
873
874 chomp(my $hash = <$in>);
875 unless (defined($hash)) {
876 $self->_close_hash_and_insert_object();
877 throw Error::Simple("in pipe went bad");
878 }
879
880 return $hash;
881}
882
883sub _open_hash_and_insert_object_if_needed {
884 my ($self) = @_;
885
886 return if defined($self->{hash_object_pid});
887
888 ($self->{hash_object_pid}, $self->{hash_object_in},
889 $self->{hash_object_out}, $self->{hash_object_ctx}) =
48d9e6ae 890 $self->command_bidi_pipe(qw(hash-object -w --stdin-paths --no-filters));
7182530d
AR
891}
892
893sub _close_hash_and_insert_object {
894 my ($self) = @_;
895
896 return unless defined($self->{hash_object_pid});
897
898 my @vars = map { 'hash_object_' . $_ } qw(pid in out ctx);
899
452d36b1
AMS
900 command_close_bidi_pipe(@$self{@vars});
901 delete @$self{@vars};
7182530d
AR
902}
903
904=item cat_blob ( SHA1, FILEHANDLE )
905
906Prints the contents of the blob identified by C<SHA1> to C<FILEHANDLE> and
907returns the number of bytes printed.
908
909=cut
910
911sub cat_blob {
912 my ($self, $sha1, $fh) = @_;
913
914 $self->_open_cat_blob_if_needed();
915 my ($in, $out) = ($self->{cat_blob_in}, $self->{cat_blob_out});
916
917 unless (print $out $sha1, "\n") {
918 $self->_close_cat_blob();
919 throw Error::Simple("out pipe went bad");
920 }
921
922 my $description = <$in>;
923 if ($description =~ / missing$/) {
924 carp "$sha1 doesn't exist in the repository";
d683a0e0 925 return -1;
7182530d
AR
926 }
927
928 if ($description !~ /^[0-9a-fA-F]{40} \S+ (\d+)$/) {
929 carp "Unexpected result returned from git cat-file";
d683a0e0 930 return -1;
7182530d
AR
931 }
932
933 my $size = $1;
934
935 my $blob;
936 my $bytesRead = 0;
937
938 while (1) {
939 my $bytesLeft = $size - $bytesRead;
940 last unless $bytesLeft;
941
942 my $bytesToRead = $bytesLeft < 1024 ? $bytesLeft : 1024;
943 my $read = read($in, $blob, $bytesToRead, $bytesRead);
944 unless (defined($read)) {
945 $self->_close_cat_blob();
946 throw Error::Simple("in pipe went bad");
947 }
948
949 $bytesRead += $read;
950 }
951
952 # Skip past the trailing newline.
953 my $newline;
954 my $read = read($in, $newline, 1);
955 unless (defined($read)) {
956 $self->_close_cat_blob();
957 throw Error::Simple("in pipe went bad");
958 }
959 unless ($read == 1 && $newline eq "\n") {
960 $self->_close_cat_blob();
961 throw Error::Simple("didn't find newline after blob");
962 }
963
964 unless (print $fh $blob) {
965 $self->_close_cat_blob();
966 throw Error::Simple("couldn't write to passed in filehandle");
967 }
968
969 return $size;
970}
971
972sub _open_cat_blob_if_needed {
973 my ($self) = @_;
974
975 return if defined($self->{cat_blob_pid});
976
977 ($self->{cat_blob_pid}, $self->{cat_blob_in},
978 $self->{cat_blob_out}, $self->{cat_blob_ctx}) =
48d9e6ae 979 $self->command_bidi_pipe(qw(cat-file --batch));
7182530d
AR
980}
981
982sub _close_cat_blob {
983 my ($self) = @_;
984
985 return unless defined($self->{cat_blob_pid});
986
987 my @vars = map { 'cat_blob_' . $_ } qw(pid in out ctx);
988
452d36b1
AMS
989 command_close_bidi_pipe(@$self{@vars});
990 delete @$self{@vars};
7182530d 991}
8b9150e3 992
e41352b2
MG
993
994{ # %TEMP_* Lexical Context
995
836ff95d 996my (%TEMP_FILEMAP, %TEMP_FILES);
e41352b2
MG
997
998=item temp_acquire ( NAME )
999
1000Attempts to retreive the temporary file mapped to the string C<NAME>. If an
1001associated temp file has not been created this session or was closed, it is
1002created, cached, and set for autoflush and binmode.
1003
1004Internally locks the file mapped to C<NAME>. This lock must be released with
1005C<temp_release()> when the temp file is no longer needed. Subsequent attempts
1006to retrieve temporary files mapped to the same C<NAME> while still locked will
1007cause an error. This locking mechanism provides a weak guarantee and is not
1008threadsafe. It does provide some error checking to help prevent temp file refs
1009writing over one another.
1010
1011In general, the L<File::Handle> returned should not be closed by consumers as
1012it defeats the purpose of this caching mechanism. If you need to close the temp
1013file handle, then you should use L<File::Temp> or another temp file faculty
1014directly. If a handle is closed and then requested again, then a warning will
1015issue.
1016
1017=cut
1018
1019sub temp_acquire {
bcdd1b44 1020 my $temp_fd = _temp_cache(@_);
e41352b2 1021
836ff95d 1022 $TEMP_FILES{$temp_fd}{locked} = 1;
e41352b2
MG
1023 $temp_fd;
1024}
1025
1026=item temp_release ( NAME )
1027
1028=item temp_release ( FILEHANDLE )
1029
1030Releases a lock acquired through C<temp_acquire()>. Can be called either with
1031the C<NAME> mapping used when acquiring the temp file or with the C<FILEHANDLE>
1032referencing a locked temp file.
1033
1034Warns if an attempt is made to release a file that is not locked.
1035
1036The temp file will be truncated before being released. This can help to reduce
1037disk I/O where the system is smart enough to detect the truncation while data
1038is in the output buffers. Beware that after the temp file is released and
1039truncated, any operations on that file may fail miserably until it is
1040re-acquired. All contents are lost between each release and acquire mapped to
1041the same string.
1042
1043=cut
1044
1045sub temp_release {
1046 my ($self, $temp_fd, $trunc) = _maybe_self(@_);
1047
836ff95d 1048 if (exists $TEMP_FILEMAP{$temp_fd}) {
e41352b2
MG
1049 $temp_fd = $TEMP_FILES{$temp_fd};
1050 }
836ff95d 1051 unless ($TEMP_FILES{$temp_fd}{locked}) {
e41352b2
MG
1052 carp "Attempt to release temp file '",
1053 $temp_fd, "' that has not been locked";
1054 }
1055 temp_reset($temp_fd) if $trunc and $temp_fd->opened;
1056
836ff95d 1057 $TEMP_FILES{$temp_fd}{locked} = 0;
e41352b2
MG
1058 undef;
1059}
1060
1061sub _temp_cache {
bcdd1b44 1062 my ($self, $name) = _maybe_self(@_);
e41352b2 1063
c14c8ceb
MG
1064 _verify_require();
1065
836ff95d 1066 my $temp_fd = \$TEMP_FILEMAP{$name};
e41352b2 1067 if (defined $$temp_fd and $$temp_fd->opened) {
836ff95d 1068 if ($TEMP_FILES{$$temp_fd}{locked}) {
8faea4f3
JS
1069 throw Error::Simple("Temp file with moniker '" .
1070 $name . "' already in use");
e41352b2
MG
1071 }
1072 } else {
1073 if (defined $$temp_fd) {
1074 # then we're here because of a closed handle.
1075 carp "Temp file '", $name,
1076 "' was closed. Opening replacement.";
1077 }
836ff95d 1078 my $fname;
bcdd1b44
MS
1079
1080 my $tmpdir;
1081 if (defined $self) {
1082 $tmpdir = $self->repo_path();
1083 }
1084
836ff95d 1085 ($$temp_fd, $fname) = File::Temp->tempfile(
bcdd1b44 1086 'Git_XXXXXX', UNLINK => 1, DIR => $tmpdir,
e41352b2 1087 ) or throw Error::Simple("couldn't open new temp file");
bcdd1b44 1088
e41352b2
MG
1089 $$temp_fd->autoflush;
1090 binmode $$temp_fd;
836ff95d 1091 $TEMP_FILES{$$temp_fd}{fname} = $fname;
e41352b2
MG
1092 }
1093 $$temp_fd;
1094}
1095
c14c8ceb
MG
1096sub _verify_require {
1097 eval { require File::Temp; require File::Spec; };
1098 $@ and throw Error::Simple($@);
1099}
1100
e41352b2
MG
1101=item temp_reset ( FILEHANDLE )
1102
1103Truncates and resets the position of the C<FILEHANDLE>.
1104
1105=cut
1106
1107sub temp_reset {
1108 my ($self, $temp_fd) = _maybe_self(@_);
1109
1110 truncate $temp_fd, 0
1111 or throw Error::Simple("couldn't truncate file");
1112 sysseek($temp_fd, 0, SEEK_SET) and seek($temp_fd, 0, SEEK_SET)
1113 or throw Error::Simple("couldn't seek to beginning of file");
1114 sysseek($temp_fd, 0, SEEK_CUR) == 0 and tell($temp_fd) == 0
1115 or throw Error::Simple("expected file position to be reset");
1116}
1117
836ff95d
MG
1118=item temp_path ( NAME )
1119
1120=item temp_path ( FILEHANDLE )
1121
1122Returns the filename associated with the given tempfile.
1123
1124=cut
1125
1126sub temp_path {
1127 my ($self, $temp_fd) = _maybe_self(@_);
1128
1129 if (exists $TEMP_FILEMAP{$temp_fd}) {
1130 $temp_fd = $TEMP_FILEMAP{$temp_fd};
1131 }
1132 $TEMP_FILES{$temp_fd}{fname};
1133}
1134
e41352b2 1135sub END {
836ff95d 1136 unlink values %TEMP_FILEMAP if %TEMP_FILEMAP;
e41352b2
MG
1137}
1138
1139} # %TEMP_* Lexical Context
1140
b1edc53d
PB
1141=back
1142
97b16c06 1143=head1 ERROR HANDLING
b1edc53d 1144
97b16c06 1145All functions are supposed to throw Perl exceptions in case of errors.
8b9150e3
PB
1146See the L<Error> module on how to catch those. Most exceptions are mere
1147L<Error::Simple> instances.
1148
1149However, the C<command()>, C<command_oneline()> and C<command_noisy()>
1150functions suite can throw C<Git::Error::Command> exceptions as well: those are
1151thrown when the external command returns an error code and contain the error
1152code as well as access to the captured command's output. The exception class
1153provides the usual C<stringify> and C<value> (command's exit code) methods and
1154in addition also a C<cmd_output> method that returns either an array or a
1155string with the captured command output (depending on the original function
1156call context; C<command_noisy()> returns C<undef>) and $<cmdline> which
1157returns the command and its arguments (but without proper quoting).
1158
d79850e1 1159Note that the C<command_*_pipe()> functions cannot throw this exception since
8b9150e3
PB
1160it has no idea whether the command failed or not. You will only find out
1161at the time you C<close> the pipe; if you want to have that automated,
1162use C<command_close_pipe()>, which can throw the exception.
1163
1164=cut
1165
1166{
1167 package Git::Error::Command;
1168
1169 @Git::Error::Command::ISA = qw(Error);
1170
1171 sub new {
1172 my $self = shift;
1173 my $cmdline = '' . shift;
1174 my $value = 0 + shift;
1175 my $outputref = shift;
1176 my(@args) = ();
1177
1178 local $Error::Depth = $Error::Depth + 1;
1179
1180 push(@args, '-cmdline', $cmdline);
1181 push(@args, '-value', $value);
1182 push(@args, '-outputref', $outputref);
1183
1184 $self->SUPER::new(-text => 'command returned error', @args);
1185 }
1186
1187 sub stringify {
1188 my $self = shift;
1189 my $text = $self->SUPER::stringify;
1190 $self->cmdline() . ': ' . $text . ': ' . $self->value() . "\n";
1191 }
1192
1193 sub cmdline {
1194 my $self = shift;
1195 $self->{'-cmdline'};
1196 }
1197
1198 sub cmd_output {
1199 my $self = shift;
1200 my $ref = $self->{'-outputref'};
1201 defined $ref or undef;
1202 if (ref $ref eq 'ARRAY') {
1203 return @$ref;
1204 } else { # SCALAR
1205 return $$ref;
1206 }
1207 }
1208}
1209
1210=over 4
1211
1212=item git_cmd_try { CODE } ERRMSG
1213
1214This magical statement will automatically catch any C<Git::Error::Command>
1215exceptions thrown by C<CODE> and make your program die with C<ERRMSG>
1216on its lips; the message will have %s substituted for the command line
1217and %d for the exit status. This statement is useful mostly for producing
1218more user-friendly error messages.
1219
1220In case of no exception caught the statement returns C<CODE>'s return value.
1221
1222Note that this is the only auto-exported function.
1223
1224=cut
1225
1226sub git_cmd_try(&$) {
1227 my ($code, $errmsg) = @_;
1228 my @result;
1229 my $err;
1230 my $array = wantarray;
1231 try {
1232 if ($array) {
1233 @result = &$code;
1234 } else {
1235 $result[0] = &$code;
1236 }
1237 } catch Git::Error::Command with {
1238 my $E = shift;
1239 $err = $errmsg;
1240 $err =~ s/\%s/$E->cmdline()/ge;
1241 $err =~ s/\%d/$E->value()/ge;
1242 # We can't croak here since Error.pm would mangle
1243 # that to Error::Simple.
1244 };
1245 $err and croak $err;
1246 return $array ? @result : $result[0];
1247}
1248
1249
1250=back
b1edc53d
PB
1251
1252=head1 COPYRIGHT
1253
1254Copyright 2006 by Petr Baudis E<lt>pasky@suse.czE<gt>.
1255
1256This module is free software; it may be used, copied, modified
1257and distributed under the terms of the GNU General Public Licence,
1258either version 2, or (at your option) any later version.
1259
1260=cut
1261
1262
1263# Take raw method argument list and return ($obj, @args) in case
1264# the method was called upon an instance and (undef, @args) if
1265# it was called directly.
1266sub _maybe_self {
d8b24b93 1267 UNIVERSAL::isa($_[0], 'Git') ? @_ : (undef, @_);
b1edc53d
PB
1268}
1269
d79850e1
PB
1270# Check if the command id is something reasonable.
1271sub _check_valid_cmd {
1272 my ($cmd) = @_;
1273 $cmd =~ /^[a-z0-9A-Z_-]+$/ or throw Error::Simple("bad command: $cmd");
1274}
1275
1276# Common backend for the pipe creators.
1277sub _command_common_pipe {
1278 my $direction = shift;
d43ba468
PB
1279 my ($self, @p) = _maybe_self(@_);
1280 my (%opts, $cmd, @args);
1281 if (ref $p[0]) {
1282 ($cmd, @args) = @{shift @p};
1283 %opts = ref $p[0] ? %{$p[0]} : @p;
1284 } else {
1285 ($cmd, @args) = @p;
1286 }
d79850e1
PB
1287 _check_valid_cmd($cmd);
1288
a6065b54 1289 my $fh;
d3b1785f 1290 if ($^O eq 'MSWin32') {
a6065b54
PB
1291 # ActiveState Perl
1292 #defined $opts{STDERR} and
1293 # warn 'ignoring STDERR option - running w/ ActiveState';
1294 $direction eq '-|' or
1295 die 'input pipe for ActiveState not implemented';
bed118d6
AR
1296 # the strange construction with *ACPIPE is just to
1297 # explain the tie below that we want to bind to
1298 # a handle class, not scalar. It is not known if
1299 # it is something specific to ActiveState Perl or
1300 # just a Perl quirk.
1301 tie (*ACPIPE, 'Git::activestate_pipe', $cmd, @args);
1302 $fh = *ACPIPE;
a6065b54
PB
1303
1304 } else {
1305 my $pid = open($fh, $direction);
1306 if (not defined $pid) {
1307 throw Error::Simple("open failed: $!");
1308 } elsif ($pid == 0) {
1309 if (defined $opts{STDERR}) {
1310 close STDERR;
1311 }
1312 if ($opts{STDERR}) {
1313 open (STDERR, '>&', $opts{STDERR})
1314 or die "dup failed: $!";
1315 }
1316 _cmd_exec($self, $cmd, @args);
d43ba468 1317 }
d79850e1
PB
1318 }
1319 return wantarray ? ($fh, join(' ', $cmd, @args)) : $fh;
1320}
1321
b1edc53d
PB
1322# When already in the subprocess, set up the appropriate state
1323# for the given repository and execute the git command.
1324sub _cmd_exec {
1325 my ($self, @args) = @_;
48d9e6ae
MO
1326 _setup_git_cmd_env($self);
1327 _execv_git_cmd(@args);
1328 die qq[exec "@args" failed: $!];
1329}
1330
1331# set up the appropriate state for git command
1332sub _setup_git_cmd_env {
1333 my $self = shift;
b1edc53d 1334 if ($self) {
d5c7721d 1335 $self->repo_path() and $ENV{'GIT_DIR'} = $self->repo_path();
da159c77
FL
1336 $self->repo_path() and $self->wc_path()
1337 and $ENV{'GIT_WORK_TREE'} = $self->wc_path();
d5c7721d
PB
1338 $self->wc_path() and chdir($self->wc_path());
1339 $self->wc_subdir() and chdir($self->wc_subdir());
b1edc53d 1340 }
b1edc53d
PB
1341}
1342
8062f81c
PB
1343# Execute the given Git command ($_[0]) with arguments ($_[1..])
1344# by searching for it at proper places.
18b0fc1c 1345sub _execv_git_cmd { exec('git', @_); }
8062f81c 1346
b1edc53d
PB
1347# Close pipe to a subprocess.
1348sub _cmd_close {
8b9150e3 1349 my ($fh, $ctx) = @_;
b1edc53d
PB
1350 if (not close $fh) {
1351 if ($!) {
1352 # It's just close, no point in fatalities
1353 carp "error closing pipe: $!";
1354 } elsif ($? >> 8) {
8b9150e3
PB
1355 # The caller should pepper this.
1356 throw Git::Error::Command($ctx, $? >> 8);
b1edc53d
PB
1357 }
1358 # else we might e.g. closed a live stream; the command
1359 # dying of SIGPIPE would drive us here.
1360 }
1361}
1362
1363
7182530d
AR
1364sub DESTROY {
1365 my ($self) = @_;
1366 $self->_close_hash_and_insert_object();
1367 $self->_close_cat_blob();
1368}
b1edc53d
PB
1369
1370
a6065b54
PB
1371# Pipe implementation for ActiveState Perl.
1372
1373package Git::activestate_pipe;
1374use strict;
1375
1376sub TIEHANDLE {
1377 my ($class, @params) = @_;
1378 # FIXME: This is probably horrible idea and the thing will explode
1379 # at the moment you give it arguments that require some quoting,
1380 # but I have no ActiveState clue... --pasky
d3b1785f
AR
1381 # Let's just hope ActiveState Perl does at least the quoting
1382 # correctly.
1383 my @data = qx{git @params};
a6065b54
PB
1384 bless { i => 0, data => \@data }, $class;
1385}
1386
1387sub READLINE {
1388 my $self = shift;
1389 if ($self->{i} >= scalar @{$self->{data}}) {
1390 return undef;
1391 }
2f5b3980
AR
1392 my $i = $self->{i};
1393 if (wantarray) {
1394 $self->{i} = $#{$self->{'data'}} + 1;
1395 return splice(@{$self->{'data'}}, $i);
1396 }
1397 $self->{i} = $i + 1;
1398 return $self->{'data'}->[ $i ];
a6065b54
PB
1399}
1400
1401sub CLOSE {
1402 my $self = shift;
1403 delete $self->{data};
1404 delete $self->{i};
1405}
1406
1407sub EOF {
1408 my $self = shift;
1409 return ($self->{i} >= scalar @{$self->{data}});
1410}
1411
1412
b1edc53d 14131; # Famous last words