66static const char ls_remote_usage [] =
77"git-ls-remote [--upload-pack=<git-upload-pack>] [<host>:]<directory>" ;
88
9+ /*
10+ * pattern is a list of tail-part of accepted refnames. Is there one
11+ * among them that is a suffix of the path? Directory boundary must
12+ * be honored when checking this match. IOW, patterns "master" and
13+ * "sa/master" both match path "refs/hold/sa/master". On the other
14+ * hand, path "refs/hold/foosa/master" is matched by "master" but not
15+ * by "sa/master".
16+ */
17+
18+ static int tail_match (const char * * pattern , const char * path )
19+ {
20+ int pathlen ;
21+ const char * p ;
22+
23+ if (!* pattern )
24+ return 1 ; /* no restriction */
25+
26+ for (pathlen = strlen (path ); (p = * pattern ); pattern ++ ) {
27+ int pfxlen = pathlen - strlen (p );
28+ if (pfxlen < 0 )
29+ continue ; /* pattern is longer, will never match */
30+ if (strcmp (path + pfxlen , p ))
31+ continue ; /* no tail match */
32+ if (!pfxlen || path [pfxlen - 1 ] == '/' )
33+ return 1 ; /* fully match at directory boundary */
34+ }
35+ return 0 ;
36+ }
37+
938int cmd_ls_remote (int argc , const char * * argv , const char * prefix )
1039{
1140 int i ;
1241 const char * dest = NULL ;
1342 int nongit = 0 ;
1443 unsigned flags = 0 ;
1544 const char * uploadpack = NULL ;
45+ const char * * pattern = NULL ;
1646
1747 struct remote * remote ;
1848 struct transport * transport ;
@@ -50,9 +80,9 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
5080 break ;
5181 }
5282
53- if (!dest || i != argc - 1 )
83+ if (!dest )
5484 usage (ls_remote_usage );
55-
85+ pattern = argv + i + 1 ;
5686 remote = nongit ? NULL : remote_get (dest );
5787 if (remote && !remote -> url_nr )
5888 die ("remote %s has no configured URL" , dest );
@@ -65,10 +95,12 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
6595 if (!ref )
6696 return 1 ;
6797
68- while (ref ) {
69- if (check_ref_type (ref , flags ))
70- printf ("%s %s\n" , sha1_to_hex (ref -> old_sha1 ), ref -> name );
71- ref = ref -> next ;
98+ for ( ; ref ; ref = ref -> next ) {
99+ if (!check_ref_type (ref , flags ))
100+ continue ;
101+ if (!tail_match (pattern , ref -> name ))
102+ continue ;
103+ printf ("%s %s\n" , sha1_to_hex (ref -> old_sha1 ), ref -> name );
72104 }
73105 return 0 ;
74106}
0 commit comments