Git.pm: tentative fix to test the freshly built Git.pm
[git/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
10use strict;
11
12
13BEGIN {
14
15our ($VERSION, @ISA, @EXPORT, @EXPORT_OK);
16
17# Totally unstable API.
18$VERSION = '0.01';
19
20
21=head1 SYNOPSIS
22
23 use Git;
24
25 my $version = Git::command_oneline('version');
26
8b9150e3
PB
27 git_cmd_try { Git::command_noisy('update-server-info') }
28 '%s failed w/ code %d';
b1edc53d
PB
29
30 my $repo = Git->repository (Directory => '/srv/git/cogito.git');
31
32
33 my @revs = $repo->command('rev-list', '--since=last monday', '--all');
34
d79850e1 35 my ($fh, $c) = $repo->command_output_pipe('rev-list', '--since=last monday', '--all');
b1edc53d 36 my $lastrev = <$fh>; chomp $lastrev;
8b9150e3 37 $repo->command_close_pipe($fh, $c);
b1edc53d 38
d43ba468
PB
39 my $lastrev = $repo->command_oneline( [ 'rev-list', '--all' ],
40 STDERR => 0 );
b1edc53d
PB
41
42=cut
43
44
45require Exporter;
46
47@ISA = qw(Exporter);
48
8b9150e3 49@EXPORT = qw(git_cmd_try);
b1edc53d
PB
50
51# Methods which can be called as standalone functions as well:
d79850e1
PB
52@EXPORT_OK = qw(command command_oneline command_noisy
53 command_output_pipe command_input_pipe command_close_pipe
8b9150e3 54 version exec_path hash_object git_cmd_try);
b1edc53d
PB
55
56
57=head1 DESCRIPTION
58
59This module provides Perl scripts easy way to interface the Git version control
60system. The modules have an easy and well-tested way to call arbitrary Git
61commands; in the future, the interface will also provide specialized methods
62for doing easily operations which are not totally trivial to do over
63the generic command interface.
64
65While some commands can be executed outside of any context (e.g. 'version'
66or 'init-db'), most operations require a repository context, which in practice
67means getting an instance of the Git object using the repository() constructor.
68(In the future, we will also get a new_repository() constructor.) All commands
69called as methods of the object are then executed in the context of the
70repository.
71
d5c7721d
PB
72Part of the "repository state" is also information about path to the attached
73working copy (unless you work with a bare repository). You can also navigate
74inside of the working copy using the C<wc_chdir()> method. (Note that
75the repository object is self-contained and will not change working directory
76of your process.)
b1edc53d 77
d5c7721d 78TODO: In the future, we might also do
b1edc53d
PB
79
80 my $remoterepo = $repo->remote_repository (Name => 'cogito', Branch => 'master');
81 $remoterepo ||= Git->remote_repository ('http://git.or.cz/cogito.git/');
82 my @refs = $remoterepo->refs();
83
b1edc53d
PB
84Currently, the module merely wraps calls to external Git tools. In the future,
85it will provide a much faster way to interact with Git by linking directly
86to libgit. This should be completely opaque to the user, though (performance
87increate nonwithstanding).
88
89=cut
90
91
8b9150e3 92use Carp qw(carp croak); # but croak is bad - throw instead
97b16c06 93use Error qw(:try);
d5c7721d 94use Cwd qw(abs_path);
b1edc53d
PB
95
96require XSLoader;
97XSLoader::load('Git', $VERSION);
98
99}
100
101
102=head1 CONSTRUCTORS
103
104=over 4
105
106=item repository ( OPTIONS )
107
108=item repository ( DIRECTORY )
109
110=item repository ()
111
112Construct a new repository object.
113C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
114Possible options are:
115
116B<Repository> - Path to the Git repository.
117
118B<WorkingCopy> - Path to the associated working copy; not strictly required
119as many commands will happily crunch on a bare repository.
120
d5c7721d
PB
121B<WorkingSubdir> - Subdirectory in the working copy to work inside.
122Just left undefined if you do not want to limit the scope of operations.
123
124B<Directory> - Path to the Git working directory in its usual setup.
125The C<.git> directory is searched in the directory and all the parent
126directories; if found, C<WorkingCopy> is set to the directory containing
127it and C<Repository> to the C<.git> directory itself. If no C<.git>
128directory was found, the C<Directory> is assumed to be a bare repository,
129C<Repository> is set to point at it and C<WorkingCopy> is left undefined.
130If the C<$GIT_DIR> environment variable is set, things behave as expected
131as well.
b1edc53d 132
b1edc53d
PB
133You should not use both C<Directory> and either of C<Repository> and
134C<WorkingCopy> - the results of that are undefined.
135
136Alternatively, a directory path may be passed as a single scalar argument
137to the constructor; it is equivalent to setting only the C<Directory> option
138field.
139
140Calling the constructor with no options whatsoever is equivalent to
d5c7721d
PB
141calling it with C<< Directory => '.' >>. In general, if you are building
142a standard porcelain command, simply doing C<< Git->repository() >> should
143do the right thing and setup the object to reflect exactly where the user
144is right now.
b1edc53d
PB
145
146=cut
147
148sub repository {
149 my $class = shift;
150 my @args = @_;
151 my %opts = ();
152 my $self;
153
154 if (defined $args[0]) {
155 if ($#args % 2 != 1) {
156 # Not a hash.
97b16c06
PB
157 $#args == 0 or throw Error::Simple("bad usage");
158 %opts = ( Directory => $args[0] );
b1edc53d
PB
159 } else {
160 %opts = @args;
161 }
d5c7721d
PB
162 }
163
164 if (not defined $opts{Repository} and not defined $opts{WorkingCopy}) {
165 $opts{Directory} ||= '.';
166 }
167
168 if ($opts{Directory}) {
169 -d $opts{Directory} or throw Error::Simple("Directory not found: $!");
170
171 my $search = Git->repository(WorkingCopy => $opts{Directory});
172 my $dir;
173 try {
174 $dir = $search->command_oneline(['rev-parse', '--git-dir'],
175 STDERR => 0);
176 } catch Git::Error::Command with {
177 $dir = undef;
178 };
b1edc53d 179
d5c7721d
PB
180 if ($dir) {
181 $opts{Repository} = abs_path($dir);
182
183 # If --git-dir went ok, this shouldn't die either.
184 my $prefix = $search->command_oneline('rev-parse', '--show-prefix');
185 $dir = abs_path($opts{Directory}) . '/';
186 if ($prefix) {
187 if (substr($dir, -length($prefix)) ne $prefix) {
188 throw Error::Simple("rev-parse confused me - $dir does not have trailing $prefix");
189 }
190 substr($dir, -length($prefix)) = '';
b1edc53d 191 }
d5c7721d
PB
192 $opts{WorkingCopy} = $dir;
193 $opts{WorkingSubdir} = $prefix;
194
195 } else {
196 # A bare repository? Let's see...
197 $dir = $opts{Directory};
198
199 unless (-d "$dir/refs" and -d "$dir/objects" and -e "$dir/HEAD") {
200 # Mimick git-rev-parse --git-dir error message:
201 throw Error::Simple('fatal: Not a git repository');
202 }
203 my $search = Git->repository(Repository => $dir);
204 try {
205 $search->command('symbolic-ref', 'HEAD');
206 } catch Git::Error::Command with {
207 # Mimick git-rev-parse --git-dir error message:
208 throw Error::Simple('fatal: Not a git repository');
209 }
210
211 $opts{Repository} = abs_path($dir);
b1edc53d 212 }
d5c7721d
PB
213
214 delete $opts{Directory};
b1edc53d
PB
215 }
216
217 $self = { opts => \%opts };
218 bless $self, $class;
219}
220
221
222=back
223
224=head1 METHODS
225
226=over 4
227
228=item command ( COMMAND [, ARGUMENTS... ] )
229
d43ba468
PB
230=item command ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )
231
b1edc53d
PB
232Execute the given Git C<COMMAND> (specify it without the 'git-'
233prefix), optionally with the specified extra C<ARGUMENTS>.
234
d43ba468
PB
235The second more elaborate form can be used if you want to further adjust
236the command execution. Currently, only one option is supported:
237
238B<STDERR> - How to deal with the command's error output. By default (C<undef>)
239it is delivered to the caller's C<STDERR>. A false value (0 or '') will cause
240it to be thrown away. If you want to process it, you can get it in a filehandle
241you specify, but you must be extremely careful; if the error output is not
242very short and you want to read it in the same process as where you called
243C<command()>, you are set up for a nice deadlock!
244
b1edc53d
PB
245The method can be called without any instance or on a specified Git repository
246(in that case the command will be run in the repository context).
247
248In scalar context, it returns all the command output in a single string
249(verbatim).
250
251In array context, it returns an array containing lines printed to the
252command's stdout (without trailing newlines).
253
254In both cases, the command's stdin and stderr are the same as the caller's.
255
256=cut
257
258sub command {
d79850e1 259 my ($fh, $ctx) = command_output_pipe(@_);
b1edc53d
PB
260
261 if (not defined wantarray) {
8b9150e3
PB
262 # Nothing to pepper the possible exception with.
263 _cmd_close($fh, $ctx);
b1edc53d
PB
264
265 } elsif (not wantarray) {
266 local $/;
267 my $text = <$fh>;
8b9150e3
PB
268 try {
269 _cmd_close($fh, $ctx);
270 } catch Git::Error::Command with {
271 # Pepper with the output:
272 my $E = shift;
273 $E->{'-outputref'} = \$text;
274 throw $E;
275 };
b1edc53d
PB
276 return $text;
277
278 } else {
279 my @lines = <$fh>;
b1edc53d 280 chomp @lines;
8b9150e3
PB
281 try {
282 _cmd_close($fh, $ctx);
283 } catch Git::Error::Command with {
284 my $E = shift;
285 $E->{'-outputref'} = \@lines;
286 throw $E;
287 };
b1edc53d
PB
288 return @lines;
289 }
290}
291
292
293=item command_oneline ( COMMAND [, ARGUMENTS... ] )
294
d43ba468
PB
295=item command_oneline ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )
296
b1edc53d
PB
297Execute the given C<COMMAND> in the same way as command()
298does but always return a scalar string containing the first line
299of the command's standard output.
300
301=cut
302
303sub command_oneline {
d79850e1 304 my ($fh, $ctx) = command_output_pipe(@_);
b1edc53d
PB
305
306 my $line = <$fh>;
d5c7721d 307 defined $line and chomp $line;
8b9150e3
PB
308 try {
309 _cmd_close($fh, $ctx);
310 } catch Git::Error::Command with {
311 # Pepper with the output:
312 my $E = shift;
313 $E->{'-outputref'} = \$line;
314 throw $E;
315 };
b1edc53d
PB
316 return $line;
317}
318
319
d79850e1 320=item command_output_pipe ( COMMAND [, ARGUMENTS... ] )
b1edc53d 321
d43ba468
PB
322=item command_output_pipe ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )
323
b1edc53d
PB
324Execute the given C<COMMAND> in the same way as command()
325does but return a pipe filehandle from which the command output can be
326read.
327
d79850e1
PB
328The function can return C<($pipe, $ctx)> in array context.
329See C<command_close_pipe()> for details.
330
b1edc53d
PB
331=cut
332
d79850e1
PB
333sub command_output_pipe {
334 _command_common_pipe('-|', @_);
335}
b1edc53d 336
b1edc53d 337
d79850e1
PB
338=item command_input_pipe ( COMMAND [, ARGUMENTS... ] )
339
d43ba468
PB
340=item command_input_pipe ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )
341
d79850e1
PB
342Execute the given C<COMMAND> in the same way as command_output_pipe()
343does but return an input pipe filehandle instead; the command output
344is not captured.
345
346The function can return C<($pipe, $ctx)> in array context.
347See C<command_close_pipe()> for details.
348
349=cut
350
351sub command_input_pipe {
352 _command_common_pipe('|-', @_);
8b9150e3
PB
353}
354
355
356=item command_close_pipe ( PIPE [, CTX ] )
357
d79850e1 358Close the C<PIPE> as returned from C<command_*_pipe()>, checking
8b9150e3
PB
359whether the command finished successfuly. The optional C<CTX> argument
360is required if you want to see the command name in the error message,
d79850e1 361and it is the second value returned by C<command_*_pipe()> when
8b9150e3
PB
362called in array context. The call idiom is:
363
d79850e1
PB
364 my ($fh, $ctx) = $r->command_output_pipe('status');
365 while (<$fh>) { ... }
366 $r->command_close_pipe($fh, $ctx);
8b9150e3
PB
367
368Note that you should not rely on whatever actually is in C<CTX>;
369currently it is simply the command name but in future the context might
370have more complicated structure.
371
372=cut
373
374sub command_close_pipe {
375 my ($self, $fh, $ctx) = _maybe_self(@_);
376 $ctx ||= '<unknown>';
377 _cmd_close($fh, $ctx);
b1edc53d
PB
378}
379
380
381=item command_noisy ( COMMAND [, ARGUMENTS... ] )
382
383Execute the given C<COMMAND> in the same way as command() does but do not
384capture the command output - the standard output is not redirected and goes
385to the standard output of the caller application.
386
387While the method is called command_noisy(), you might want to as well use
388it for the most silent Git commands which you know will never pollute your
389stdout but you want to avoid the overhead of the pipe setup when calling them.
390
391The function returns only after the command has finished running.
392
393=cut
394
395sub command_noisy {
396 my ($self, $cmd, @args) = _maybe_self(@_);
d79850e1 397 _check_valid_cmd($cmd);
b1edc53d
PB
398
399 my $pid = fork;
400 if (not defined $pid) {
97b16c06 401 throw Error::Simple("fork failed: $!");
b1edc53d
PB
402 } elsif ($pid == 0) {
403 _cmd_exec($self, $cmd, @args);
404 }
8b9150e3
PB
405 if (waitpid($pid, 0) > 0 and $?>>8 != 0) {
406 throw Git::Error::Command(join(' ', $cmd, @args), $? >> 8);
b1edc53d
PB
407 }
408}
409
410
63df97ae
PB
411=item version ()
412
413Return the Git version in use.
414
415Implementation of this function is very fast; no external command calls
416are involved.
417
418=cut
419
420# Implemented in Git.xs.
421
422
eca1f6fd
PB
423=item exec_path ()
424
d5c7721d 425Return path to the Git sub-command executables (the same as
eca1f6fd
PB
426C<git --exec-path>). Useful mostly only internally.
427
428Implementation of this function is very fast; no external command calls
429are involved.
430
431=cut
432
433# Implemented in Git.xs.
434
435
d5c7721d
PB
436=item repo_path ()
437
438Return path to the git repository. Must be called on a repository instance.
439
440=cut
441
442sub repo_path { $_[0]->{opts}->{Repository} }
443
444
445=item wc_path ()
446
447Return path to the working copy. Must be called on a repository instance.
448
449=cut
450
451sub wc_path { $_[0]->{opts}->{WorkingCopy} }
452
453
454=item wc_subdir ()
455
456Return path to the subdirectory inside of a working copy. Must be called
457on a repository instance.
458
459=cut
460
461sub wc_subdir { $_[0]->{opts}->{WorkingSubdir} ||= '' }
462
463
464=item wc_chdir ( SUBDIR )
465
466Change the working copy subdirectory to work within. The C<SUBDIR> is
467relative to the working copy root directory (not the current subdirectory).
468Must be called on a repository instance attached to a working copy
469and the directory must exist.
470
471=cut
472
473sub wc_chdir {
474 my ($self, $subdir) = @_;
475
476 $self->wc_path()
477 or throw Error::Simple("bare repository");
478
479 -d $self->wc_path().'/'.$subdir
480 or throw Error::Simple("subdir not found: $!");
481 # Of course we will not "hold" the subdirectory so anyone
482 # can delete it now and we will never know. But at least we tried.
483
484 $self->{opts}->{WorkingSubdir} = $subdir;
485}
486
487
b1edc53d
PB
488=item hash_object ( FILENAME [, TYPE ] )
489
490=item hash_object ( FILEHANDLE [, TYPE ] )
491
492Compute the SHA1 object id of the given C<FILENAME> (or data waiting in
493C<FILEHANDLE>) considering it is of the C<TYPE> object type (C<blob>
494(default), C<commit>, C<tree>).
495
496In case of C<FILEHANDLE> passed instead of file name, all the data
497available are read and hashed, and the filehandle is automatically
498closed. The file handle should be freshly opened - if you have already
499read anything from the file handle, the results are undefined (since
500this function works directly with the file descriptor and internal
501PerlIO buffering might have messed things up).
502
503The method can be called without any instance or on a specified Git repository,
504it makes zero difference.
505
506The function returns the SHA1 hash.
507
508Implementation of this function is very fast; no external command calls
509are involved.
510
511=cut
512
513# Implemented in Git.xs.
514
515
8b9150e3 516
b1edc53d
PB
517=back
518
97b16c06 519=head1 ERROR HANDLING
b1edc53d 520
97b16c06 521All functions are supposed to throw Perl exceptions in case of errors.
8b9150e3
PB
522See the L<Error> module on how to catch those. Most exceptions are mere
523L<Error::Simple> instances.
524
525However, the C<command()>, C<command_oneline()> and C<command_noisy()>
526functions suite can throw C<Git::Error::Command> exceptions as well: those are
527thrown when the external command returns an error code and contain the error
528code as well as access to the captured command's output. The exception class
529provides the usual C<stringify> and C<value> (command's exit code) methods and
530in addition also a C<cmd_output> method that returns either an array or a
531string with the captured command output (depending on the original function
532call context; C<command_noisy()> returns C<undef>) and $<cmdline> which
533returns the command and its arguments (but without proper quoting).
534
d79850e1 535Note that the C<command_*_pipe()> functions cannot throw this exception since
8b9150e3
PB
536it has no idea whether the command failed or not. You will only find out
537at the time you C<close> the pipe; if you want to have that automated,
538use C<command_close_pipe()>, which can throw the exception.
539
540=cut
541
542{
543 package Git::Error::Command;
544
545 @Git::Error::Command::ISA = qw(Error);
546
547 sub new {
548 my $self = shift;
549 my $cmdline = '' . shift;
550 my $value = 0 + shift;
551 my $outputref = shift;
552 my(@args) = ();
553
554 local $Error::Depth = $Error::Depth + 1;
555
556 push(@args, '-cmdline', $cmdline);
557 push(@args, '-value', $value);
558 push(@args, '-outputref', $outputref);
559
560 $self->SUPER::new(-text => 'command returned error', @args);
561 }
562
563 sub stringify {
564 my $self = shift;
565 my $text = $self->SUPER::stringify;
566 $self->cmdline() . ': ' . $text . ': ' . $self->value() . "\n";
567 }
568
569 sub cmdline {
570 my $self = shift;
571 $self->{'-cmdline'};
572 }
573
574 sub cmd_output {
575 my $self = shift;
576 my $ref = $self->{'-outputref'};
577 defined $ref or undef;
578 if (ref $ref eq 'ARRAY') {
579 return @$ref;
580 } else { # SCALAR
581 return $$ref;
582 }
583 }
584}
585
586=over 4
587
588=item git_cmd_try { CODE } ERRMSG
589
590This magical statement will automatically catch any C<Git::Error::Command>
591exceptions thrown by C<CODE> and make your program die with C<ERRMSG>
592on its lips; the message will have %s substituted for the command line
593and %d for the exit status. This statement is useful mostly for producing
594more user-friendly error messages.
595
596In case of no exception caught the statement returns C<CODE>'s return value.
597
598Note that this is the only auto-exported function.
599
600=cut
601
602sub git_cmd_try(&$) {
603 my ($code, $errmsg) = @_;
604 my @result;
605 my $err;
606 my $array = wantarray;
607 try {
608 if ($array) {
609 @result = &$code;
610 } else {
611 $result[0] = &$code;
612 }
613 } catch Git::Error::Command with {
614 my $E = shift;
615 $err = $errmsg;
616 $err =~ s/\%s/$E->cmdline()/ge;
617 $err =~ s/\%d/$E->value()/ge;
618 # We can't croak here since Error.pm would mangle
619 # that to Error::Simple.
620 };
621 $err and croak $err;
622 return $array ? @result : $result[0];
623}
624
625
626=back
b1edc53d
PB
627
628=head1 COPYRIGHT
629
630Copyright 2006 by Petr Baudis E<lt>pasky@suse.czE<gt>.
631
632This module is free software; it may be used, copied, modified
633and distributed under the terms of the GNU General Public Licence,
634either version 2, or (at your option) any later version.
635
636=cut
637
638
639# Take raw method argument list and return ($obj, @args) in case
640# the method was called upon an instance and (undef, @args) if
641# it was called directly.
642sub _maybe_self {
643 # This breaks inheritance. Oh well.
644 ref $_[0] eq 'Git' ? @_ : (undef, @_);
645}
646
d79850e1
PB
647# Check if the command id is something reasonable.
648sub _check_valid_cmd {
649 my ($cmd) = @_;
650 $cmd =~ /^[a-z0-9A-Z_-]+$/ or throw Error::Simple("bad command: $cmd");
651}
652
653# Common backend for the pipe creators.
654sub _command_common_pipe {
655 my $direction = shift;
d43ba468
PB
656 my ($self, @p) = _maybe_self(@_);
657 my (%opts, $cmd, @args);
658 if (ref $p[0]) {
659 ($cmd, @args) = @{shift @p};
660 %opts = ref $p[0] ? %{$p[0]} : @p;
661 } else {
662 ($cmd, @args) = @p;
663 }
d79850e1
PB
664 _check_valid_cmd($cmd);
665
666 my $pid = open(my $fh, $direction);
667 if (not defined $pid) {
668 throw Error::Simple("open failed: $!");
669 } elsif ($pid == 0) {
d43ba468
PB
670 if (defined $opts{STDERR}) {
671 close STDERR;
672 }
673 if ($opts{STDERR}) {
674 open (STDERR, '>&', $opts{STDERR})
675 or die "dup failed: $!";
676 }
d79850e1
PB
677 _cmd_exec($self, $cmd, @args);
678 }
679 return wantarray ? ($fh, join(' ', $cmd, @args)) : $fh;
680}
681
b1edc53d
PB
682# When already in the subprocess, set up the appropriate state
683# for the given repository and execute the git command.
684sub _cmd_exec {
685 my ($self, @args) = @_;
686 if ($self) {
d5c7721d
PB
687 $self->repo_path() and $ENV{'GIT_DIR'} = $self->repo_path();
688 $self->wc_path() and chdir($self->wc_path());
689 $self->wc_subdir() and chdir($self->wc_subdir());
b1edc53d 690 }
97b16c06
PB
691 _execv_git_cmd(@args);
692 die "exec failed: $!";
b1edc53d
PB
693}
694
8062f81c
PB
695# Execute the given Git command ($_[0]) with arguments ($_[1..])
696# by searching for it at proper places.
697# _execv_git_cmd(), implemented in Git.xs.
698
b1edc53d
PB
699# Close pipe to a subprocess.
700sub _cmd_close {
8b9150e3 701 my ($fh, $ctx) = @_;
b1edc53d
PB
702 if (not close $fh) {
703 if ($!) {
704 # It's just close, no point in fatalities
705 carp "error closing pipe: $!";
706 } elsif ($? >> 8) {
8b9150e3
PB
707 # The caller should pepper this.
708 throw Git::Error::Command($ctx, $? >> 8);
b1edc53d
PB
709 }
710 # else we might e.g. closed a live stream; the command
711 # dying of SIGPIPE would drive us here.
712 }
713}
714
715
716# Trickery for .xs routines: In order to avoid having some horrid
717# C code trying to do stuff with undefs and hashes, we gate all
718# xs calls through the following and in case we are being ran upon
719# an instance call a C part of the gate which will set up the
720# environment properly.
721sub _call_gate {
722 my $xsfunc = shift;
723 my ($self, @args) = _maybe_self(@_);
724
725 if (defined $self) {
726 # XXX: We ignore the WorkingCopy! To properly support
727 # that will require heavy changes in libgit.
728
729 # XXX: And we ignore everything else as well. libgit
730 # at least needs to be extended to let us specify
731 # the $GIT_DIR instead of looking it up in environment.
732 #xs_call_gate($self->{opts}->{Repository});
733 }
734
97b16c06
PB
735 # Having to call throw from the C code is a sure path to insanity.
736 local $SIG{__DIE__} = sub { throw Error::Simple("@_"); };
b1edc53d
PB
737 &$xsfunc(@args);
738}
739
740sub AUTOLOAD {
741 my $xsname;
742 our $AUTOLOAD;
743 ($xsname = $AUTOLOAD) =~ s/.*:://;
97b16c06 744 throw Error::Simple("&Git::$xsname not defined") if $xsname =~ /^xs_/;
b1edc53d
PB
745 $xsname = 'xs_'.$xsname;
746 _call_gate(\&$xsname, @_);
747}
748
749sub DESTROY { }
750
751
7521; # Famous last words