git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
@ 2007-05-17  2:37 Petr Baudis
  2007-05-17  5:58 ` Junio C Hamano
  0 siblings, 1 reply; 13+ messages in thread
From: Petr Baudis @ 2007-05-17  2:37 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Should support all the important features, I guess. Too bad that
	git-ls-remote --heads .
	
is subtly different from

	git-ls-remote . refs/heads/

so we have to provide the interface for specifying both.

This patch also converts git-svn.perl to use it.

Signed-off-by: Petr Baudis <pasky@suse.cz>
---

 git-remote.perl |    5 +----
 perl/Git.pm     |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/git-remote.perl b/git-remote.perl
index 5763799..5403d86 100755
--- a/git-remote.perl
+++ b/git-remote.perl
@@ -128,10 +128,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 = keys %{$git->remote_refs($info->{'URL'}, [ 'heads' ])};
 	$info->{'LS_REMOTE'} = \@ref;
 }
 
diff --git a/perl/Git.pm b/perl/Git.pm
index 8fd3611..9818981 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -51,7 +51,7 @@ require Exporter;
 # Methods which can be called as standalone functions as well:
 @EXPORT_OK = qw(command command_oneline command_noisy
                 command_output_pipe command_input_pipe command_close_pipe
-                version exec_path hash_object git_cmd_try);
+                version exec_path hash_object git_cmd_try remote_refs);
 
 
 =head1 DESCRIPTION
@@ -550,6 +550,59 @@ sub config_bool {
 }
 
 
+=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 )

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
  2007-05-17  2:37 Petr Baudis
@ 2007-05-17  5:58 ` Junio C Hamano
  2007-05-17 11:30   ` Petr Baudis
  0 siblings, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2007-05-17  5:58 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git

Petr Baudis <pasky@suse.cz> writes:

> .... Too bad that
>
> 	git-ls-remote --heads .
> 	
> is subtly different from
>
> 	git-ls-remote . refs/heads/
>
> so we have to provide the interface for specifying both.

I've already heard you say the above elsewhere, but I am not
sure what you exactly mean here.  Mind substantiating it a bit
more clearly?

I think "ls-remote --heads ." is just a special case of giving
"refs/heads/*" as the glob pattern:

        $ git ls-remote --heads . | head -n 3
        3545193735522f733fdb4e345f16ddf131e2007a	refs/heads/ap/ident
        b7993dd57a9cfd5b989f0e2cc5d271a524339318	refs/heads/db/remote
        960ccca6803c9fb57429d43572a9545a96107e32	refs/heads/dh/pack

	$ git ls-remote . refs/heads/ | wc -l
        0

	$ git ls-remote . "refs/heads/*" | head -n 3
        3545193735522f733fdb4e345f16ddf131e2007a	refs/heads/ap/ident
        b7993dd57a9cfd5b989f0e2cc5d271a524339318	refs/heads/db/remote
        960ccca6803c9fb57429d43572a9545a96107e32	refs/heads/dh/pack

	$ git ls-remote . "refs/heads/???/*"
        7841ce79854868eaaa146c1d018b17fc4f3320be	refs/heads/mst/connect

        $ git ls-remote . "refs/*/jc/*" | head -n 4
        80a767ba3b1c69fc41fa5f5fbe4a247757a9c575	refs/heads/jc/blame
        a1481ab7b16c51d4ec7925fd9b38d9cf21f72263	refs/heads/jc/diff
        4e8daa0dca5deb9d391538241939a2a2ad6d36b8	refs/tags/hold/jc/3way
        ff77ab7919e6f31cb6c58bc004217e624b553fb6	refs/tags/hold/jc/changes

So if you really do not want separate interfaces, I think you
could just implement --heads as what it is: a shorthand for
"refs/heads/*".

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
  2007-05-17  5:58 ` Junio C Hamano
@ 2007-05-17 11:30   ` Petr Baudis
  0 siblings, 0 replies; 13+ messages in thread
From: Petr Baudis @ 2007-05-17 11:30 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Thu, May 17, 2007 at 07:58:31AM CEST, Junio C Hamano wrote:
> Petr Baudis <pasky@suse.cz> writes:
> 
> > .... Too bad that
> >
> > 	git-ls-remote --heads .
> > 	
> > is subtly different from
> >
> > 	git-ls-remote . refs/heads/
> >
> > so we have to provide the interface for specifying both.
> 
> I've already heard you say the above elsewhere, but I am not
> sure what you exactly mean here.  Mind substantiating it a bit
> more clearly?

Because the arguments are matched like

	case "/$path" in
	*/$pat )

so if you have remote "refs" and refs/remote/refs/heads/x, git-ls-remote
refs/heads/ is ambiguous. OTOH, --heads always match start of the path.

It's somewhat obscure and probably doesn't really matter for user
interface, but API should be free even of obscure misbehaviour, I
believe.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Ever try. Ever fail. No matter. // Try again. Fail again. Fail better.
		-- Samuel Beckett

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
@ 2007-08-25 22:11 Petr Baudis
  2007-08-26  4:26 ` Junio C Hamano
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Petr Baudis @ 2007-08-25 22:11 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Should support all the important features, I guess. Too bad that
	git-ls-remote --heads .
	
is subtly different from

	git-ls-remote . refs/heads/

so we have to provide the interface for specifying both.

This patch also converts git-remote.perl to use it.

Signed-off-by: Petr Baudis <pasky@suse.cz>
---

 git-remote.perl |    5 +----
 perl/Git.pm     |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/git-remote.perl b/git-remote.perl
index 01cf480..8ce8418 100755
--- a/git-remote.perl
+++ b/git-remote.perl
@@ -128,10 +128,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 = keys %{$git->remote_refs($info->{'URL'}, [ 'heads' ])};
 	$info->{'LS_REMOTE'} = \@ref;
 }
 
diff --git a/perl/Git.pm b/perl/Git.pm
index 3f4080c..3bce733 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -51,7 +51,7 @@ require Exporter;
 # Methods which can be called as standalone functions as well:
 @EXPORT_OK = qw(command command_oneline command_noisy
                 command_output_pipe command_input_pipe command_close_pipe
-                version exec_path hash_object git_cmd_try);
+                version exec_path hash_object git_cmd_try remote_refs);
 
 
 =head1 DESCRIPTION
@@ -550,6 +550,59 @@ sub config_bool {
 }
 
 
+=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 )

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
  2007-08-25 22:11 [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend Petr Baudis
@ 2007-08-26  4:26 ` Junio C Hamano
  2007-08-26  9:58   ` Petr Baudis
  2007-08-30  8:39 ` Jakub Narebski
  2007-08-30 23:37 ` Petr Baudis
  2 siblings, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2007-08-26  4:26 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git

Petr Baudis <pasky@suse.cz> writes:

> diff --git a/git-remote.perl b/git-remote.perl
> index 01cf480..8ce8418 100755
> --- a/git-remote.perl
> +++ b/git-remote.perl
> @@ -128,10 +128,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 = keys %{$git->remote_refs($info->{'URL'}, [ 'heads' ])};
>  	$info->{'LS_REMOTE'} = \@ref;
>  }

IIRC, ls-remote returns refs sorted and this function returns
them as it receives.

Doesn't this change make @ref randomly ordered?  

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
  2007-08-26  4:26 ` Junio C Hamano
@ 2007-08-26  9:58   ` Petr Baudis
  0 siblings, 0 replies; 13+ messages in thread
From: Petr Baudis @ 2007-08-26  9:58 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Sun, Aug 26, 2007 at 06:26:29AM CEST, Junio C Hamano wrote:
> Petr Baudis <pasky@suse.cz> writes:
> 
> > diff --git a/git-remote.perl b/git-remote.perl
> > index 01cf480..8ce8418 100755
> > --- a/git-remote.perl
> > +++ b/git-remote.perl
> > @@ -128,10 +128,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 = keys %{$git->remote_refs($info->{'URL'}, [ 'heads' ])};
> >  	$info->{'LS_REMOTE'} = \@ref;
> >  }
> 
> IIRC, ls-remote returns refs sorted and this function returns
> them as it receives.
> 
> Doesn't this change make @ref randomly ordered?  

Yes, but I couldn't find any place in git-remote.perl where we rely on
the @ref ordering - maybe I'm blind...

-- 
				Petr "Pasky" Baudis
Ever try. Ever fail. No matter. // Try again. Fail again. Fail better.
		-- Samuel Beckett

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
  2007-08-25 22:11 [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend Petr Baudis
  2007-08-26  4:26 ` Junio C Hamano
@ 2007-08-30  8:39 ` Jakub Narebski
  2007-08-30 23:37   ` Petr Baudis
  2007-08-30 23:37 ` Petr Baudis
  2 siblings, 1 reply; 13+ messages in thread
From: Jakub Narebski @ 2007-08-30  8:39 UTC (permalink / raw)
  To: git

[Cc: Petr Baudis <pasky@suse.cz>, git@vger.kernel.org]

Petr Baudis wrote:

> Should support all the important features, I guess. Too bad that
>       git-ls-remote --heads .
>       
> is subtly different from
> 
>       git-ls-remote . refs/heads/
> 
> so we have to provide the interface for specifying both.

Why do not use git-for-each-ref or git-show-refs? If I remember correctly
they _were_ faster than git-ls-remote or git-peek-remote...

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
  2007-08-30  8:39 ` Jakub Narebski
@ 2007-08-30 23:37   ` Petr Baudis
  0 siblings, 0 replies; 13+ messages in thread
From: Petr Baudis @ 2007-08-30 23:37 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git

On Thu, Aug 30, 2007 at 10:39:41AM CEST, Jakub Narebski wrote:
> [Cc: Petr Baudis <pasky@suse.cz>, git@vger.kernel.org]
> 
> Petr Baudis wrote:
> 
> > Should support all the important features, I guess. Too bad that
> >       git-ls-remote --heads .
> >       
> > is subtly different from
> > 
> >       git-ls-remote . refs/heads/
> > 
> > so we have to provide the interface for specifying both.
> 
> Why do not use git-for-each-ref or git-show-refs? If I remember correctly
> they _were_ faster than git-ls-remote or git-peek-remote...

But we want to typically list refs in a remote repository.

-- 
				Petr "Pasky" Baudis
Early to rise and early to bed makes a male healthy and wealthy and dead.
                -- James Thurber

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
  2007-08-25 22:11 [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend Petr Baudis
  2007-08-26  4:26 ` Junio C Hamano
  2007-08-30  8:39 ` Jakub Narebski
@ 2007-08-30 23:37 ` Petr Baudis
  2007-08-31  0:26   ` Junio C Hamano
  2 siblings, 1 reply; 13+ messages in thread
From: Petr Baudis @ 2007-08-30 23:37 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Should support all the important features, I guess. Too bad that
	git-ls-remote --heads .
	
is subtly different from

	git-ls-remote . refs/heads/

so we have to provide the interface for specifying both.

This patch also converts git-remote.perl to use it.

Signed-off-by: Petr Baudis <pasky@suse.cz>
---
This version re-adds missed out stripping of refs/heads/ in git-remote.perl.
---

 git-remote.perl |    5 +----
 perl/Git.pm     |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/git-remote.perl b/git-remote.perl
index 01cf480..1948c5c 100755
--- a/git-remote.perl
+++ b/git-remote.perl
@@ -128,10 +128,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 3f4080c..3bce733 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -51,7 +51,7 @@ require Exporter;
 # Methods which can be called as standalone functions as well:
 @EXPORT_OK = qw(command command_oneline command_noisy
                 command_output_pipe command_input_pipe command_close_pipe
-                version exec_path hash_object git_cmd_try);
+                version exec_path hash_object git_cmd_try remote_refs);
 
 
 =head1 DESCRIPTION
@@ -550,6 +550,59 @@ sub config_bool {
 }
 
 
+=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 )

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
  2007-08-30 23:37 ` Petr Baudis
@ 2007-08-31  0:26   ` Junio C Hamano
  2007-08-31  1:37     ` Petr Baudis
  0 siblings, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2007-08-31  0:26 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git

Petr Baudis <pasky@suse.cz> writes:

> Should support all the important features, I guess. Too bad that
>
> 	git-ls-remote --heads .
> 	
> is subtly different from
>
> 	git-ls-remote . refs/heads/
>
> so we have to provide the interface for specifying both.

Are they subtly different?  To me they look like asking for
completely different things.  IIRC, the patterns are ref globs,
so

	git ls-remote $URL 'refs/heads/*'

would be the same as the former one.

> This patch also converts git-remote.perl to use it.
>
> Signed-off-by: Petr Baudis <pasky@suse.cz>
> ---
> This version re-adds missed out stripping of refs/heads/ in git-remote.perl.

Ah, that was the bug you were talking about on #git channel, I
guess...

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
  2007-08-31  0:26   ` Junio C Hamano
@ 2007-08-31  1:37     ` Petr Baudis
  2007-08-31  2:13       ` Junio C Hamano
  0 siblings, 1 reply; 13+ messages in thread
From: Petr Baudis @ 2007-08-31  1:37 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Fri, Aug 31, 2007 at 02:26:22AM CEST, Junio C Hamano wrote:
> Petr Baudis <pasky@suse.cz> writes:
> 
> > Should support all the important features, I guess. Too bad that
> >
> > 	git-ls-remote --heads .
> > 	
> > is subtly different from
> >
> > 	git-ls-remote . refs/heads/
> >
> > so we have to provide the interface for specifying both.
> 
> Are they subtly different?  To me they look like asking for
> completely different things.  IIRC, the patterns are ref globs,
> so
> 
> 	git ls-remote $URL 'refs/heads/*'
> 
> would be the same as the former one.

Yes, though subtly different, as I've already explained before - for the
case of say

	refs/remotes/evil/refs/heads

> Ah, that was the bug you were talking about on #git channel, I
> guess...

*nod*

-- 
				Petr "Pasky" Baudis
Early to rise and early to bed makes a male healthy and wealthy and dead.
                -- James Thurber

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
  2007-08-31  1:37     ` Petr Baudis
@ 2007-08-31  2:13       ` Junio C Hamano
  0 siblings, 0 replies; 13+ messages in thread
From: Junio C Hamano @ 2007-08-31  2:13 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git

Petr Baudis <pasky@suse.cz> writes:

>> 	git ls-remote $URL 'refs/heads/*'
>> 
>> would be the same as the former one.
>
> Yes, though subtly different, as I've already explained before - for the
> case of say
>
> 	refs/remotes/evil/refs/heads

Are you voting for removal of "ls-remote $URL 'heads/*'" support?
I actually think removing it makes a perfect sense.

>> Ah, that was the bug you were talking about on #git channel, I
>> guess...
>
> *nod*

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
@ 2008-07-08 17:48 Petr Baudis
  0 siblings, 0 replies; 13+ messages in thread
From: Petr Baudis @ 2008-07-08 17:48 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

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>
---

  This is resend after another year. ;-)

 contrib/examples/git-remote.perl |    5 +--
 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 b30ed73..36bd54c 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 97e61ef..d99e778 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 )

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2008-07-08 17:50 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-25 22:11 [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend Petr Baudis
2007-08-26  4:26 ` Junio C Hamano
2007-08-26  9:58   ` Petr Baudis
2007-08-30  8:39 ` Jakub Narebski
2007-08-30 23:37   ` Petr Baudis
2007-08-30 23:37 ` Petr Baudis
2007-08-31  0:26   ` Junio C Hamano
2007-08-31  1:37     ` Petr Baudis
2007-08-31  2:13       ` Junio C Hamano
  -- strict thread matches above, loose matches on Subject: below --
2008-07-08 17:48 Petr Baudis
2007-05-17  2:37 Petr Baudis
2007-05-17  5:58 ` Junio C Hamano
2007-05-17 11:30   ` Petr Baudis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).