{"thread":{"id":"14349","subject":"[PATCH] Git.pm: Add remote_refs() git-ls-remote frontend","startedAt":"2008-07-08T17:48:04Z","lastAt":"2008-07-08T17:48:04Z","messageCount":1,"participants":["Petr Baudis"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"82618","messageId":"20080708173523.7359.63945.stgit@rover.dkm.cz","threadId":"14349","inReplyTo":null,"subject":"[PATCH] Git.pm: Add remote_refs() git-ls-remote frontend","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2008-07-08T17:48:04Z","receivedAt":"2008-07-08T17:48:04Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"This patch also converts the good ole' git-remote.perl to use it.\nIt is otherwise used in the repo.or.cz machinery and I guess other\nscripts might find it useful too.\n\nUnfortunately,\n\n\tgit-ls-remote --heads .\n\t\nis subtly different from\n\n\tgit-ls-remote . refs/heads/\n\n(since the second matches anywhere in the string, not just at the\nbeginning) so we have to provide interface for both.\n\nSigned-off-by: Petr Baudis <pasky@suse.cz>\n---\n\n  This is resend after another year. ;-)\n\n contrib/examples/git-remote.perl |    5 +--\n perl/Git.pm                      |   56 +++++++++++++++++++++++++++++++++++++-\n 2 files changed, 56 insertions(+), 5 deletions(-)\n\n\ndiff --git a/contrib/examples/git-remote.perl b/contrib/examples/git-remote.perl\nindex b30ed73..36bd54c 100755\n--- a/contrib/examples/git-remote.perl\n+++ b/contrib/examples/git-remote.perl\n@@ -129,10 +129,7 @@ sub update_ls_remote {\n \treturn if (($harder == 0) ||\n \t\t   (($harder == 1) && exists $info->{'LS_REMOTE'}));\n \n-\tmy @ref = map {\n-\t\ts|^[0-9a-f]{40}\\s+refs/heads/||;\n-\t\t$_;\n-\t} $git->command(qw(ls-remote --heads), $info->{'URL'});\n+\tmy @ref = map { s|refs/heads/||; $_; } keys %{$git->remote_refs($info->{'URL'}, [ 'heads' ])};\n \t$info->{'LS_REMOTE'} = \\@ref;\n }\n \ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex 97e61ef..d99e778 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -56,7 +56,8 @@ require Exporter;\n @EXPORT_OK = qw(command command_oneline command_noisy\n                 command_output_pipe command_input_pipe command_close_pipe\n                 command_bidi_pipe command_close_bidi_pipe\n-                version exec_path hash_object git_cmd_try);\n+                version exec_path hash_object git_cmd_try\n+                remote_refs);\n \n \n =head1 DESCRIPTION\n@@ -668,6 +669,59 @@ sub get_color {\n \treturn $color;\n }\n \n+=item remote_refs ( REPOSITORY [, GROUPS [, REFGLOBS ] ] )\n+\n+This function returns a hashref of refs stored in a given remote repository.\n+The hash is in the format C<refname =\\> hash>. For tags, the C<refname> entry\n+contains the tag object while a C<refname^{}> entry gives the tagged objects.\n+\n+C<REPOSITORY> has the same meaning as the appropriate C<git-ls-remote>\n+argument; either an URL or a remote name (if called on a repository instance).\n+C<GROUPS> is an optional arrayref that can contain 'tags' to return all the\n+tags and/or 'heads' to return all the heads. C<REFGLOB> is an optional array\n+of strings containing a shell-like glob to further limit the refs returned in\n+the hash; the meaning is again the same as the appropriate C<git-ls-remote>\n+argument.\n+\n+This function may or may not be called on a repository instance. In the former\n+case, remote names as defined in the repository are recognized as repository\n+specifiers.\n+\n+=cut\n+\n+sub remote_refs {\n+\tmy ($self, $repo, $groups, $refglobs) = _maybe_self(@_);\n+\tmy @args;\n+\tif (ref $groups eq 'ARRAY') {\n+\t\tforeach (@$groups) {\n+\t\t\tif ($_ eq 'heads') {\n+\t\t\t\tpush (@args, '--heads');\n+\t\t\t} elsif ($_ eq 'tags') {\n+\t\t\t\tpush (@args, '--tags');\n+\t\t\t} else {\n+\t\t\t\t# Ignore unknown groups for future\n+\t\t\t\t# compatibility\n+\t\t\t}\n+\t\t}\n+\t}\n+\tpush (@args, $repo);\n+\tif (ref $refglobs eq 'ARRAY') {\n+\t\tpush (@args, @$refglobs);\n+\t}\n+\n+\tmy @self = $self ? ($self) : (); # Ultra trickery\n+\tmy ($fh, $ctx) = Git::command_output_pipe(@self, 'ls-remote', @args);\n+\tmy %refs;\n+\twhile (<$fh>) {\n+\t\tchomp;\n+\t\tmy ($hash, $ref) = split(/\\t/, $_, 2);\n+\t\t$refs{$ref} = $hash;\n+\t}\n+\tGit::command_close_pipe(@self, $fh, $ctx);\n+\treturn \\%refs;\n+}\n+\n+\n =item ident ( TYPE | IDENTSTR )\n \n =item ident_person ( TYPE | IDENTSTR | IDENTARRAY )\n"}]}