diff options
author | Petr Baudis <pasky@suse.cz> | 2008-07-08 19:48:04 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2008-07-08 22:46:01 -0700 |
commit | 31a92f6aa47732e93f6685b8d1fd1ac09c1fec44 (patch) | |
tree | 06cfcea954c5772d5ff8f4ff4b0ee54b4b449091 | |
parent | e896912c5edb8f989a2d25e101b2eb14f1a56aa9 (diff) | |
download | git-31a92f6aa47732e93f6685b8d1fd1ac09c1fec44.tar.gz git-31a92f6aa47732e93f6685b8d1fd1ac09c1fec44.tar.xz |
Git.pm: Add remote_refs() git-ls-remote frontend
This patch also converts the good ole' git-remote.perl to use it.
It is otherwise used in the repo.or.cz machinery and I guess other
scripts might find it useful too.
Unfortunately,
git-ls-remote --heads .
is subtly different from
git-ls-remote . refs/heads/
(since the second matches anywhere in the string, not just at the
beginning) so we have to provide interface for both.
Signed-off-by: Petr Baudis <pasky@suse.cz>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rwxr-xr-x | contrib/examples/git-remote.perl | 5 | ||||
-rw-r--r-- | perl/Git.pm | 56 |
2 files changed, 56 insertions, 5 deletions
diff --git a/contrib/examples/git-remote.perl b/contrib/examples/git-remote.perl index b30ed734e..36bd54c98 100755 --- a/contrib/examples/git-remote.perl +++ b/contrib/examples/git-remote.perl @@ -129,10 +129,7 @@ sub update_ls_remote { return if (($harder == 0) || (($harder == 1) && exists $info->{'LS_REMOTE'})); - my @ref = map { - s|^[0-9a-f]{40}\s+refs/heads/||; - $_; - } $git->command(qw(ls-remote --heads), $info->{'URL'}); + my @ref = map { s|refs/heads/||; $_; } keys %{$git->remote_refs($info->{'URL'}, [ 'heads' ])}; $info->{'LS_REMOTE'} = \@ref; } diff --git a/perl/Git.pm b/perl/Git.pm index 97e61efaf..d99e77820 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -56,7 +56,8 @@ require Exporter; @EXPORT_OK = qw(command command_oneline command_noisy command_output_pipe command_input_pipe command_close_pipe command_bidi_pipe command_close_bidi_pipe - version exec_path hash_object git_cmd_try); + version exec_path hash_object git_cmd_try + remote_refs); =head1 DESCRIPTION @@ -668,6 +669,59 @@ sub get_color { return $color; } +=item remote_refs ( REPOSITORY [, GROUPS [, REFGLOBS ] ] ) + +This function returns a hashref of refs stored in a given remote repository. +The hash is in the format C<refname =\> hash>. For tags, the C<refname> entry +contains the tag object while a C<refname^{}> entry gives the tagged objects. + +C<REPOSITORY> has the same meaning as the appropriate C<git-ls-remote> +argument; either an URL or a remote name (if called on a repository instance). +C<GROUPS> is an optional arrayref that can contain 'tags' to return all the +tags and/or 'heads' to return all the heads. C<REFGLOB> is an optional array +of strings containing a shell-like glob to further limit the refs returned in +the hash; the meaning is again the same as the appropriate C<git-ls-remote> +argument. + +This function may or may not be called on a repository instance. In the former +case, remote names as defined in the repository are recognized as repository +specifiers. + +=cut + +sub remote_refs { + my ($self, $repo, $groups, $refglobs) = _maybe_self(@_); + my @args; + if (ref $groups eq 'ARRAY') { + foreach (@$groups) { + if ($_ eq 'heads') { + push (@args, '--heads'); + } elsif ($_ eq 'tags') { + push (@args, '--tags'); + } else { + # Ignore unknown groups for future + # compatibility + } + } + } + push (@args, $repo); + if (ref $refglobs eq 'ARRAY') { + push (@args, @$refglobs); + } + + my @self = $self ? ($self) : (); # Ultra trickery + my ($fh, $ctx) = Git::command_output_pipe(@self, 'ls-remote', @args); + my %refs; + while (<$fh>) { + chomp; + my ($hash, $ref) = split(/\t/, $_, 2); + $refs{$ref} = $hash; + } + Git::command_close_pipe(@self, $fh, $ctx); + return \%refs; +} + + =item ident ( TYPE | IDENTSTR ) =item ident_person ( TYPE | IDENTSTR | IDENTARRAY ) |