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 27 git_cmd_try { Git::command_noisy('update-server-info') } 28 '%s failed w/ code %d'; 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 35 my ($fh, $c) = $repo->command_output_pipe('rev-list', '--since=last monday', '--all'); 36 my $lastrev = <$fh>; chomp $lastrev; 37 $repo->command_close_pipe($fh, $c); 38 39 my $lastrev = $repo->command_oneline( [ 'rev-list', '--all' ], 40 STDERR => 0 ); 41 42=cut 43 44 45require Exporter; 46 47@ISA=qw(Exporter); 48 49@EXPORT=qw(git_cmd_try); 50 51# Methods which can be called as standalone functions as well: 52@EXPORT_OK=qw(command command_oneline command_noisy 53 command_output_pipe command_input_pipe command_close_pipe 54 version exec_path hash_object git_cmd_try); 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 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.) 77 78TODO: In the future, we might also do 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 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 92use Carp qw(carp croak);# but croak is bad - throw instead 93use Error qw(:try); 94use Cwd qw(abs_path); 95 96require XSLoader; 97XSLoader::load('Git',$VERSION); 98 99} 100 101my$instance_id=0; 102 103 104=head1 CONSTRUCTORS 105 106=over 4 107 108=item repository ( OPTIONS ) 109 110=item repository ( DIRECTORY ) 111 112=item repository () 113 114Construct a new repository object. 115C<OPTIONS> are passed in a hash like fashion, using key and value pairs. 116Possible options are: 117 118B<Repository> - Path to the Git repository. 119 120B<WorkingCopy> - Path to the associated working copy; not strictly required 121as many commands will happily crunch on a bare repository. 122 123B<WorkingSubdir> - Subdirectory in the working copy to work inside. 124Just left undefined if you do not want to limit the scope of operations. 125 126B<Directory> - Path to the Git working directory in its usual setup. 127The C<.git> directory is searched in the directory and all the parent 128directories; if found, C<WorkingCopy> is set to the directory containing 129it and C<Repository> to the C<.git> directory itself. If no C<.git> 130directory was found, the C<Directory> is assumed to be a bare repository, 131C<Repository> is set to point at it and C<WorkingCopy> is left undefined. 132If the C<$GIT_DIR> environment variable is set, things behave as expected 133as well. 134 135You should not use both C<Directory> and either of C<Repository> and 136C<WorkingCopy> - the results of that are undefined. 137 138Alternatively, a directory path may be passed as a single scalar argument 139to the constructor; it is equivalent to setting only the C<Directory> option 140field. 141 142Calling the constructor with no options whatsoever is equivalent to 143calling it with C<< Directory => '.' >>. In general, if you are building 144a standard porcelain command, simply doing C<< Git->repository() >> should 145do the right thing and setup the object to reflect exactly where the user 146is right now. 147 148=cut 149 150sub repository { 151my$class=shift; 152my@args=@_; 153my%opts= (); 154my$self; 155 156if(defined$args[0]) { 157if($#args%2!=1) { 158# Not a hash. 159$#args==0or throw Error::Simple("bad usage"); 160%opts= ( Directory =>$args[0] ); 161}else{ 162%opts=@args; 163} 164} 165 166if(not defined$opts{Repository}and not defined$opts{WorkingCopy}) { 167$opts{Directory} ||='.'; 168} 169 170if($opts{Directory}) { 171-d $opts{Directory}or throw Error::Simple("Directory not found:$!"); 172 173my$search= Git->repository(WorkingCopy =>$opts{Directory}); 174my$dir; 175try{ 176$dir=$search->command_oneline(['rev-parse','--git-dir'], 177 STDERR =>0); 178} catch Git::Error::Command with { 179$dir=undef; 180}; 181 182if($dir) { 183$dir=~ m#^/# or $dir = $opts{Directory} . '/' . $dir; 184$opts{Repository} =$dir; 185 186# If --git-dir went ok, this shouldn't die either. 187my$prefix=$search->command_oneline('rev-parse','--show-prefix'); 188$dir= abs_path($opts{Directory}) .'/'; 189if($prefix) { 190if(substr($dir, -length($prefix))ne$prefix) { 191 throw Error::Simple("rev-parse confused me -$dirdoes not have trailing$prefix"); 192} 193substr($dir, -length($prefix)) =''; 194} 195$opts{WorkingCopy} =$dir; 196$opts{WorkingSubdir} =$prefix; 197 198}else{ 199# A bare repository? Let's see... 200$dir=$opts{Directory}; 201 202unless(-d "$dir/refs"and-d "$dir/objects"and-e "$dir/HEAD") { 203# Mimick git-rev-parse --git-dir error message: 204 throw Error::Simple('fatal: Not a git repository'); 205} 206my$search= Git->repository(Repository =>$dir); 207try{ 208$search->command('symbolic-ref','HEAD'); 209} catch Git::Error::Command with { 210# Mimick git-rev-parse --git-dir error message: 211 throw Error::Simple('fatal: Not a git repository'); 212} 213 214$opts{Repository} = abs_path($dir); 215} 216 217delete$opts{Directory}; 218} 219 220$self= { opts => \%opts, id =>$instance_id++}; 221bless$self,$class; 222} 223 224 225=back 226 227=head1 METHODS 228 229=over 4 230 231=item command ( COMMAND [, ARGUMENTS... ] ) 232 233=item command ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } ) 234 235Execute the given Git C<COMMAND> (specify it without the 'git-' 236prefix), optionally with the specified extra C<ARGUMENTS>. 237 238The second more elaborate form can be used if you want to further adjust 239the command execution. Currently, only one option is supported: 240 241B<STDERR> - How to deal with the command's error output. By default (C<undef>) 242it is delivered to the caller's C<STDERR>. A false value (0 or '') will cause 243it to be thrown away. If you want to process it, you can get it in a filehandle 244you specify, but you must be extremely careful; if the error output is not 245very short and you want to read it in the same process as where you called 246C<command()>, you are set up for a nice deadlock! 247 248The method can be called without any instance or on a specified Git repository 249(in that case the command will be run in the repository context). 250 251In scalar context, it returns all the command output in a single string 252(verbatim). 253 254In array context, it returns an array containing lines printed to the 255command's stdout (without trailing newlines). 256 257In both cases, the command's stdin and stderr are the same as the caller's. 258 259=cut 260 261sub command { 262my($fh,$ctx) = command_output_pipe(@_); 263 264if(not defined wantarray) { 265# Nothing to pepper the possible exception with. 266 _cmd_close($fh,$ctx); 267 268}elsif(not wantarray) { 269local$/; 270my$text= <$fh>; 271try{ 272 _cmd_close($fh,$ctx); 273} catch Git::Error::Command with { 274# Pepper with the output: 275my$E=shift; 276$E->{'-outputref'} = \$text; 277 throw $E; 278}; 279return$text; 280 281}else{ 282my@lines= <$fh>; 283chomp@lines; 284try{ 285 _cmd_close($fh,$ctx); 286} catch Git::Error::Command with { 287my$E=shift; 288$E->{'-outputref'} = \@lines; 289 throw $E; 290}; 291return@lines; 292} 293} 294 295 296=item command_oneline ( COMMAND [, ARGUMENTS... ] ) 297 298=item command_oneline ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } ) 299 300Execute the given C<COMMAND> in the same way as command() 301does but always return a scalar string containing the first line 302of the command's standard output. 303 304=cut 305 306sub command_oneline { 307my($fh,$ctx) = command_output_pipe(@_); 308 309my$line= <$fh>; 310defined$lineand chomp$line; 311try{ 312 _cmd_close($fh,$ctx); 313} catch Git::Error::Command with { 314# Pepper with the output: 315my$E=shift; 316$E->{'-outputref'} = \$line; 317 throw $E; 318}; 319return$line; 320} 321 322 323=item command_output_pipe ( COMMAND [, ARGUMENTS... ] ) 324 325=item command_output_pipe ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } ) 326 327Execute the given C<COMMAND> in the same way as command() 328does but return a pipe filehandle from which the command output can be 329read. 330 331The function can return C<($pipe, $ctx)> in array context. 332See C<command_close_pipe()> for details. 333 334=cut 335 336sub command_output_pipe { 337 _command_common_pipe('-|',@_); 338} 339 340 341=item command_input_pipe ( COMMAND [, ARGUMENTS... ] ) 342 343=item command_input_pipe ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } ) 344 345Execute the given C<COMMAND> in the same way as command_output_pipe() 346does but return an input pipe filehandle instead; the command output 347is not captured. 348 349The function can return C<($pipe, $ctx)> in array context. 350See C<command_close_pipe()> for details. 351 352=cut 353 354sub command_input_pipe { 355 _command_common_pipe('|-',@_); 356} 357 358 359=item command_close_pipe ( PIPE [, CTX ] ) 360 361Close the C<PIPE> as returned from C<command_*_pipe()>, checking 362whether the command finished successfuly. The optional C<CTX> argument 363is required if you want to see the command name in the error message, 364and it is the second value returned by C<command_*_pipe()> when 365called in array context. The call idiom is: 366 367 my ($fh, $ctx) = $r->command_output_pipe('status'); 368 while (<$fh>) { ... } 369 $r->command_close_pipe($fh, $ctx); 370 371Note that you should not rely on whatever actually is in C<CTX>; 372currently it is simply the command name but in future the context might 373have more complicated structure. 374 375=cut 376 377sub command_close_pipe { 378my($self,$fh,$ctx) = _maybe_self(@_); 379$ctx||='<unknown>'; 380 _cmd_close($fh,$ctx); 381} 382 383 384=item command_noisy ( COMMAND [, ARGUMENTS... ] ) 385 386Execute the given C<COMMAND> in the same way as command() does but do not 387capture the command output - the standard output is not redirected and goes 388to the standard output of the caller application. 389 390While the method is called command_noisy(), you might want to as well use 391it for the most silent Git commands which you know will never pollute your 392stdout but you want to avoid the overhead of the pipe setup when calling them. 393 394The function returns only after the command has finished running. 395 396=cut 397 398sub command_noisy { 399my($self,$cmd,@args) = _maybe_self(@_); 400 _check_valid_cmd($cmd); 401 402my$pid=fork; 403if(not defined$pid) { 404 throw Error::Simple("fork failed:$!"); 405}elsif($pid==0) { 406 _cmd_exec($self,$cmd,@args); 407} 408if(waitpid($pid,0) >0and$?>>8!=0) { 409 throw Git::Error::Command(join(' ',$cmd,@args),$?>>8); 410} 411} 412 413 414=item version () 415 416Return the Git version in use. 417 418Implementation of this function is very fast; no external command calls 419are involved. 420 421=cut 422 423# Implemented in Git.xs. 424 425 426=item exec_path () 427 428Return path to the Git sub-command executables (the same as 429C<git --exec-path>). Useful mostly only internally. 430 431Implementation of this function is very fast; no external command calls 432are involved. 433 434=cut 435 436# Implemented in Git.xs. 437 438 439=item repo_path () 440 441Return path to the git repository. Must be called on a repository instance. 442 443=cut 444 445sub repo_path {$_[0]->{opts}->{Repository} } 446 447 448=item wc_path () 449 450Return path to the working copy. Must be called on a repository instance. 451 452=cut 453 454sub wc_path {$_[0]->{opts}->{WorkingCopy} } 455 456 457=item wc_subdir () 458 459Return path to the subdirectory inside of a working copy. Must be called 460on a repository instance. 461 462=cut 463 464sub wc_subdir {$_[0]->{opts}->{WorkingSubdir} ||=''} 465 466 467=item wc_chdir ( SUBDIR ) 468 469Change the working copy subdirectory to work within. The C<SUBDIR> is 470relative to the working copy root directory (not the current subdirectory). 471Must be called on a repository instance attached to a working copy 472and the directory must exist. 473 474=cut 475 476sub wc_chdir { 477my($self,$subdir) =@_; 478$self->wc_path() 479or throw Error::Simple("bare repository"); 480 481-d $self->wc_path().'/'.$subdir 482or throw Error::Simple("subdir not found:$!"); 483# Of course we will not "hold" the subdirectory so anyone 484# can delete it now and we will never know. But at least we tried. 485 486$self->{opts}->{WorkingSubdir} =$subdir; 487} 488 489 490=item config ( VARIABLE ) 491 492Retrieve the configuration C<VARIABLE> in the same manner as C<repo-config> 493does. In scalar context requires the variable to be set only one time 494(exception is thrown otherwise), in array context returns allows the 495variable to be set multiple times and returns all the values. 496 497Must be called on a repository instance. 498 499This currently wraps command('repo-config') so it is not so fast. 500 501=cut 502 503sub config { 504my($self,$var) =@_; 505$self->repo_path() 506or throw Error::Simple("not a repository"); 507 508try{ 509if(wantarray) { 510return$self->command('repo-config','--get-all',$var); 511}else{ 512return$self->command_oneline('repo-config','--get',$var); 513} 514} catch Git::Error::Command with { 515my$E=shift; 516if($E->value() ==1) { 517# Key not found. 518returnundef; 519}else{ 520 throw $E; 521} 522}; 523} 524 525 526=item ident ( TYPE | IDENTSTR ) 527 528=item ident_person ( TYPE | IDENTSTR | IDENTARRAY ) 529 530This suite of functions retrieves and parses ident information, as stored 531in the commit and tag objects or produced by C<var GIT_type_IDENT> (thus 532C<TYPE> can be either I<author> or I<committer>; case is insignificant). 533 534The C<ident> method retrieves the ident information from C<git-var> 535and either returns it as a scalar string or as an array with the fields parsed. 536Alternatively, it can take a prepared ident string (e.g. from the commit 537object) and just parse it. 538 539C<ident_person> returns the person part of the ident - name and email; 540it can take the same arguments as C<ident> or the array returned by C<ident>. 541 542The synopsis is like: 543 544 my ($name, $email, $time_tz) = ident('author'); 545 "$name <$email>" eq ident_person('author'); 546 "$name <$email>" eq ident_person($name); 547 $time_tz =~ /^\d+ [+-]\d{4}$/; 548 549Both methods must be called on a repository instance. 550 551=cut 552 553sub ident { 554my($self,$type) =@_; 555my$identstr; 556if(lc$typeeq lc'committer'or lc$typeeq lc'author') { 557$identstr=$self->command_oneline('var','GIT_'.uc($type).'_IDENT'); 558}else{ 559$identstr=$type; 560} 561if(wantarray) { 562return$identstr=~/^(.*) <(.*)> (\d+ [+-]\d{4})$/; 563}else{ 564return$identstr; 565} 566} 567 568sub ident_person { 569my($self,@ident) =@_; 570$#ident==0and@ident=$self->ident($ident[0]); 571return"$ident[0] <$ident[1]>"; 572} 573 574 575=item get_object ( TYPE, SHA1 ) 576 577Return contents of the given object in a scalar string. If the object has 578not been found, undef is returned; however, do not rely on this! Currently, 579if you use multiple repositories at once, get_object() on one repository 580_might_ return the object even though it exists only in another repository. 581(But do not rely on this behaviour either.) 582 583The method must be called on a repository instance. 584 585Implementation of this method is very fast; no external command calls 586are involved. That's why it is broken, too. ;-) 587 588=cut 589 590# Implemented in Git.xs. 591 592 593=item hash_object ( TYPE, FILENAME ) 594 595=item hash_object ( TYPE, FILEHANDLE ) 596 597Compute the SHA1 object id of the given C<FILENAME> (or data waiting in 598C<FILEHANDLE>) considering it is of the C<TYPE> object type (C<blob>, 599C<commit>, C<tree>). 600 601In case of C<FILEHANDLE> passed instead of file name, all the data 602available are read and hashed, and the filehandle is automatically 603closed. The file handle should be freshly opened - if you have already 604read anything from the file handle, the results are undefined (since 605this function works directly with the file descriptor and internal 606PerlIO buffering might have messed things up). 607 608The method can be called without any instance or on a specified Git repository, 609it makes zero difference. 610 611The function returns the SHA1 hash. 612 613Implementation of this function is very fast; no external command calls 614are involved. 615 616=cut 617 618sub hash_object { 619my($self,$type,$file) = _maybe_self(@_); 620 621# hash_object_* implemented in Git.xs. 622 623if(ref($file)eq'GLOB') { 624my$hash= hash_object_pipe($type,fileno($file)); 625close$file; 626return$hash; 627}else{ 628 hash_object_file($type,$file); 629} 630} 631 632 633 634=back 635 636=head1 ERROR HANDLING 637 638All functions are supposed to throw Perl exceptions in case of errors. 639See the L<Error> module on how to catch those. Most exceptions are mere 640L<Error::Simple> instances. 641 642However, the C<command()>, C<command_oneline()> and C<command_noisy()> 643functions suite can throw C<Git::Error::Command> exceptions as well: those are 644thrown when the external command returns an error code and contain the error 645code as well as access to the captured command's output. The exception class 646provides the usual C<stringify> and C<value> (command's exit code) methods and 647in addition also a C<cmd_output> method that returns either an array or a 648string with the captured command output (depending on the original function 649call context; C<command_noisy()> returns C<undef>) and $<cmdline> which 650returns the command and its arguments (but without proper quoting). 651 652Note that the C<command_*_pipe()> functions cannot throw this exception since 653it has no idea whether the command failed or not. You will only find out 654at the time you C<close> the pipe; if you want to have that automated, 655use C<command_close_pipe()>, which can throw the exception. 656 657=cut 658 659{ 660package Git::Error::Command; 661 662@Git::Error::Command::ISA =qw(Error); 663 664sub new { 665my$self=shift; 666my$cmdline=''.shift; 667my$value=0+shift; 668my$outputref=shift; 669my(@args) = (); 670 671local$Error::Depth =$Error::Depth +1; 672 673push(@args,'-cmdline',$cmdline); 674push(@args,'-value',$value); 675push(@args,'-outputref',$outputref); 676 677$self->SUPER::new(-text =>'command returned error',@args); 678} 679 680sub stringify { 681my$self=shift; 682my$text=$self->SUPER::stringify; 683$self->cmdline() .': '.$text.': '.$self->value() ."\n"; 684} 685 686sub cmdline { 687my$self=shift; 688$self->{'-cmdline'}; 689} 690 691sub cmd_output { 692my$self=shift; 693my$ref=$self->{'-outputref'}; 694defined$refor undef; 695if(ref$refeq'ARRAY') { 696return@$ref; 697}else{# SCALAR 698return$$ref; 699} 700} 701} 702 703=over 4 704 705=item git_cmd_try { CODE } ERRMSG 706 707This magical statement will automatically catch any C<Git::Error::Command> 708exceptions thrown by C<CODE> and make your program die with C<ERRMSG> 709on its lips; the message will have %s substituted for the command line 710and %d for the exit status. This statement is useful mostly for producing 711more user-friendly error messages. 712 713In case of no exception caught the statement returns C<CODE>'s return value. 714 715Note that this is the only auto-exported function. 716 717=cut 718 719sub git_cmd_try(&$) { 720my($code,$errmsg) =@_; 721my@result; 722my$err; 723my$array=wantarray; 724try{ 725if($array) { 726@result= &$code; 727}else{ 728$result[0] = &$code; 729} 730} catch Git::Error::Command with { 731my$E=shift; 732$err=$errmsg; 733$err=~s/\%s/$E->cmdline()/ge; 734$err=~s/\%d/$E->value()/ge; 735# We can't croak here since Error.pm would mangle 736# that to Error::Simple. 737}; 738$errand croak $err; 739return$array?@result:$result[0]; 740} 741 742 743=back 744 745=head1 COPYRIGHT 746 747Copyright 2006 by Petr Baudis E<lt>pasky@suse.czE<gt>. 748 749This module is free software; it may be used, copied, modified 750and distributed under the terms of the GNU General Public Licence, 751either version 2, or (at your option) any later version. 752 753=cut 754 755 756# Take raw method argument list and return ($obj, @args) in case 757# the method was called upon an instance and (undef, @args) if 758# it was called directly. 759sub _maybe_self { 760# This breaks inheritance. Oh well. 761ref$_[0]eq'Git'?@_: (undef,@_); 762} 763 764# Check if the command id is something reasonable. 765sub _check_valid_cmd { 766my($cmd) =@_; 767$cmd=~/^[a-z0-9A-Z_-]+$/or throw Error::Simple("bad command:$cmd"); 768} 769 770# Common backend for the pipe creators. 771sub _command_common_pipe { 772my$direction=shift; 773my($self,@p) = _maybe_self(@_); 774my(%opts,$cmd,@args); 775if(ref$p[0]) { 776($cmd,@args) = @{shift@p}; 777%opts=ref$p[0] ? %{$p[0]} :@p; 778}else{ 779($cmd,@args) =@p; 780} 781 _check_valid_cmd($cmd); 782 783my$fh; 784if($^Oeq'##INSERT_ACTIVESTATE_STRING_HERE##') { 785# ActiveState Perl 786#defined $opts{STDERR} and 787# warn 'ignoring STDERR option - running w/ ActiveState'; 788$directioneq'-|'or 789die'input pipe for ActiveState not implemented'; 790 tie ($fh,'Git::activestate_pipe',$cmd,@args); 791 792}else{ 793my$pid=open($fh,$direction); 794if(not defined$pid) { 795 throw Error::Simple("open failed:$!"); 796}elsif($pid==0) { 797if(defined$opts{STDERR}) { 798close STDERR; 799} 800if($opts{STDERR}) { 801open(STDERR,'>&',$opts{STDERR}) 802or die"dup failed:$!"; 803} 804 _cmd_exec($self,$cmd,@args); 805} 806} 807returnwantarray? ($fh,join(' ',$cmd,@args)) :$fh; 808} 809 810# When already in the subprocess, set up the appropriate state 811# for the given repository and execute the git command. 812sub _cmd_exec { 813my($self,@args) =@_; 814if($self) { 815$self->repo_path()and$ENV{'GIT_DIR'} =$self->repo_path(); 816$self->wc_path()and chdir($self->wc_path()); 817$self->wc_subdir()and chdir($self->wc_subdir()); 818} 819 _execv_git_cmd(@args); 820die"exec failed:$!"; 821} 822 823# Execute the given Git command ($_[0]) with arguments ($_[1..]) 824# by searching for it at proper places. 825# _execv_git_cmd(), implemented in Git.xs. 826 827# Close pipe to a subprocess. 828sub _cmd_close { 829my($fh,$ctx) =@_; 830if(not close$fh) { 831if($!) { 832# It's just close, no point in fatalities 833 carp "error closing pipe:$!"; 834}elsif($?>>8) { 835# The caller should pepper this. 836 throw Git::Error::Command($ctx,$?>>8); 837} 838# else we might e.g. closed a live stream; the command 839# dying of SIGPIPE would drive us here. 840} 841} 842 843 844# Trickery for .xs routines: In order to avoid having some horrid 845# C code trying to do stuff with undefs and hashes, we gate all 846# xs calls through the following and in case we are being ran upon 847# an instance call a C part of the gate which will set up the 848# environment properly. 849sub _call_gate { 850my$xsfunc=shift; 851my($self,@args) = _maybe_self(@_); 852 853if(defined$self) { 854# XXX: We ignore the WorkingCopy! To properly support 855# that will require heavy changes in libgit. 856# For now, when we will need to do it we could temporarily 857# chdir() there and then chdir() back after the call is done. 858 859 xs__call_gate($self->{id},$self->repo_path()); 860} 861 862# Having to call throw from the C code is a sure path to insanity. 863local$SIG{__DIE__} =sub{ throw Error::Simple("@_"); }; 864&$xsfunc(@args); 865} 866 867sub AUTOLOAD { 868my$xsname; 869our$AUTOLOAD; 870($xsname=$AUTOLOAD) =~s/.*:://; 871 throw Error::Simple("&Git::$xsnamenot defined")if$xsname=~/^xs_/; 872$xsname='xs_'.$xsname; 873 _call_gate(\&$xsname,@_); 874} 875 876sub DESTROY { } 877 878 879# Pipe implementation for ActiveState Perl. 880 881package Git::activestate_pipe; 882use strict; 883 884sub TIEHANDLE { 885my($class,@params) =@_; 886# FIXME: This is probably horrible idea and the thing will explode 887# at the moment you give it arguments that require some quoting, 888# but I have no ActiveState clue... --pasky 889my$cmdline=join" ",@params; 890my@data=qx{$cmdline}; 891bless{ i =>0, data => \@data},$class; 892} 893 894sub READLINE { 895my$self=shift; 896if($self->{i} >=scalar@{$self->{data}}) { 897returnundef; 898} 899return$self->{'data'}->[$self->{i}++ ]; 900} 901 902sub CLOSE { 903my$self=shift; 904delete$self->{data}; 905delete$self->{i}; 906} 907 908sub EOF { 909my$self=shift; 910return($self->{i} >=scalar@{$self->{data}}); 911} 912 913 9141;# Famous last words