perl / Git.pmon commit Convert git-mv to use Git.pm (8f00660)
   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
 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
 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.
 132
 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
 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.
 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.
 157                        $#args == 0 or throw Error::Simple("bad usage");
 158                        %opts = ( Directory => $args[0] );
 159                } else {
 160                        %opts = @args;
 161                }
 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                };
 179
 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)) = '';
 191                        }
 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);
 212                }
 213
 214                delete $opts{Directory};
 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
 230=item command ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )
 231
 232Execute the given Git C<COMMAND> (specify it without the 'git-'
 233prefix), optionally with the specified extra C<ARGUMENTS>.
 234
 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
 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 {
 259        my ($fh, $ctx) = command_output_pipe(@_);
 260
 261        if (not defined wantarray) {
 262                # Nothing to pepper the possible exception with.
 263                _cmd_close($fh, $ctx);
 264
 265        } elsif (not wantarray) {
 266                local $/;
 267                my $text = <$fh>;
 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                };
 276                return $text;
 277
 278        } else {
 279                my @lines = <$fh>;
 280                chomp @lines;
 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                };
 288                return @lines;
 289        }
 290}
 291
 292
 293=item command_oneline ( COMMAND [, ARGUMENTS... ] )
 294
 295=item command_oneline ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )
 296
 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 {
 304        my ($fh, $ctx) = command_output_pipe(@_);
 305
 306        my $line = <$fh>;
 307        defined $line and chomp $line;
 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        };
 316        return $line;
 317}
 318
 319
 320=item command_output_pipe ( COMMAND [, ARGUMENTS... ] )
 321
 322=item command_output_pipe ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )
 323
 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
 328The function can return C<($pipe, $ctx)> in array context.
 329See C<command_close_pipe()> for details.
 330
 331=cut
 332
 333sub command_output_pipe {
 334        _command_common_pipe('-|', @_);
 335}
 336
 337
 338=item command_input_pipe ( COMMAND [, ARGUMENTS... ] )
 339
 340=item command_input_pipe ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )
 341
 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('|-', @_);
 353}
 354
 355
 356=item command_close_pipe ( PIPE [, CTX ] )
 357
 358Close the C<PIPE> as returned from C<command_*_pipe()>, checking
 359whether the command finished successfuly. The optional C<CTX> argument
 360is required if you want to see the command name in the error message,
 361and it is the second value returned by C<command_*_pipe()> when
 362called in array context. The call idiom is:
 363
 364        my ($fh, $ctx) = $r->command_output_pipe('status');
 365        while (<$fh>) { ... }
 366        $r->command_close_pipe($fh, $ctx);
 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);
 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(@_);
 397        _check_valid_cmd($cmd);
 398
 399        my $pid = fork;
 400        if (not defined $pid) {
 401                throw Error::Simple("fork failed: $!");
 402        } elsif ($pid == 0) {
 403                _cmd_exec($self, $cmd, @args);
 404        }
 405        if (waitpid($pid, 0) > 0 and $?>>8 != 0) {
 406                throw Git::Error::Command(join(' ', $cmd, @args), $? >> 8);
 407        }
 408}
 409
 410
 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
 423=item exec_path ()
 424
 425Return path to the Git sub-command executables (the same as
 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
 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
 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
 516
 517=back
 518
 519=head1 ERROR HANDLING
 520
 521All functions are supposed to throw Perl exceptions in case of errors.
 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
 535Note that the C<command_*_pipe()> functions cannot throw this exception since
 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
 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
 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;
 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        }
 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) {
 670                if (defined $opts{STDERR}) {
 671                        close STDERR;
 672                }
 673                if ($opts{STDERR}) {
 674                        open (STDERR, '>&', $opts{STDERR})
 675                                or die "dup failed: $!";
 676                }
 677                _cmd_exec($self, $cmd, @args);
 678        }
 679        return wantarray ? ($fh, join(' ', $cmd, @args)) : $fh;
 680}
 681
 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) {
 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());
 690        }
 691        _execv_git_cmd(@args);
 692        die "exec failed: $!";
 693}
 694
 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
 699# Close pipe to a subprocess.
 700sub _cmd_close {
 701        my ($fh, $ctx) = @_;
 702        if (not close $fh) {
 703                if ($!) {
 704                        # It's just close, no point in fatalities
 705                        carp "error closing pipe: $!";
 706                } elsif ($? >> 8) {
 707                        # The caller should pepper this.
 708                        throw Git::Error::Command($ctx, $? >> 8);
 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
 735        # Having to call throw from the C code is a sure path to insanity.
 736        local $SIG{__DIE__} = sub { throw Error::Simple("@_"); };
 737        &$xsfunc(@args);
 738}
 739
 740sub AUTOLOAD {
 741        my $xsname;
 742        our $AUTOLOAD;
 743        ($xsname = $AUTOLOAD) =~ s/.*:://;
 744        throw Error::Simple("&Git::$xsname not defined") if $xsname =~ /^xs_/;
 745        $xsname = 'xs_'.$xsname;
 746        _call_gate(\&$xsname, @_);
 747}
 748
 749sub DESTROY { }
 750
 751
 7521; # Famous last words