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