@@ -11,7 +11,9 @@ pub enum Error {
11
11
#[ error( "Both sides of the specification need a pattern, like 'a/*:b/*'" ) ]
12
12
PatternUnbalanced ,
13
13
#[ error( transparent) ]
14
- Refname ( #[ from] git_validate:: refname:: Error ) ,
14
+ ReferenceName ( #[ from] git_validate:: refname:: Error ) ,
15
+ #[ error( transparent) ]
16
+ RevSpec ( #[ from] git_revision:: spec:: parse:: Error ) ,
15
17
}
16
18
17
19
pub ( crate ) mod function {
@@ -84,8 +86,8 @@ pub(crate) mod function {
84
86
}
85
87
} ;
86
88
87
- let ( src, src_had_pattern) = validated ( src) ?;
88
- let ( dst, dst_had_pattern) = validated ( dst) ?;
89
+ let ( src, src_had_pattern) = validated ( src, operation == Operation :: Push ) ?;
90
+ let ( dst, dst_had_pattern) = validated ( dst, false ) ?;
89
91
if mode != Mode :: Negative && src_had_pattern != dst_had_pattern {
90
92
return Err ( Error :: PatternUnbalanced ) ;
91
93
}
@@ -97,7 +99,7 @@ pub(crate) mod function {
97
99
} )
98
100
}
99
101
100
- fn validated ( spec : Option < & BStr > ) -> Result < ( Option < & BStr > , bool ) , Error > {
102
+ fn validated ( spec : Option < & BStr > , allow_revspecs : bool ) -> Result < ( Option < & BStr > , bool ) , Error > {
101
103
match spec {
102
104
Some ( spec) => {
103
105
let glob_count = spec. iter ( ) . filter ( |b| * * b == b'*' ) . take ( 2 ) . count ( ) ;
@@ -111,11 +113,87 @@ pub(crate) mod function {
111
113
buf[ glob_pos] = b'a' ;
112
114
git_validate:: reference:: name_partial ( buf. as_bstr ( ) ) ?;
113
115
} else {
114
- git_validate:: reference:: name_partial ( spec) ?;
116
+ git_validate:: reference:: name_partial ( spec)
117
+ . map_err ( Error :: from)
118
+ . or_else ( |err| {
119
+ if allow_revspecs {
120
+ match git_revision:: spec:: parse ( spec, & mut super :: revparse:: Noop ) {
121
+ Ok ( _) => {
122
+ if spec. iter ( ) . any ( |b| b. is_ascii_whitespace ( ) ) {
123
+ Err ( err)
124
+ } else {
125
+ Ok ( spec)
126
+ }
127
+ }
128
+ Err ( err) => Err ( err. into ( ) ) ,
129
+ }
130
+ } else {
131
+ Err ( err)
132
+ }
133
+ } ) ?;
115
134
}
116
135
Ok ( ( Some ( spec) , glob_count == 1 ) )
117
136
}
118
137
None => Ok ( ( None , false ) ) ,
119
138
}
120
139
}
121
140
}
141
+
142
+ mod revparse {
143
+ use bstr:: BStr ;
144
+ use git_revision:: spec:: parse:: delegate:: {
145
+ Kind , Navigate , PeelTo , PrefixHint , ReflogLookup , Revision , SiblingBranch , Traversal ,
146
+ } ;
147
+
148
+ pub ( crate ) struct Noop ;
149
+
150
+ impl Revision for Noop {
151
+ fn find_ref ( & mut self , _name : & BStr ) -> Option < ( ) > {
152
+ Some ( ( ) )
153
+ }
154
+
155
+ fn disambiguate_prefix ( & mut self , _prefix : git_hash:: Prefix , _hint : Option < PrefixHint < ' _ > > ) -> Option < ( ) > {
156
+ Some ( ( ) )
157
+ }
158
+
159
+ fn reflog ( & mut self , _query : ReflogLookup ) -> Option < ( ) > {
160
+ Some ( ( ) )
161
+ }
162
+
163
+ fn nth_checked_out_branch ( & mut self , _branch_no : usize ) -> Option < ( ) > {
164
+ Some ( ( ) )
165
+ }
166
+
167
+ fn sibling_branch ( & mut self , _kind : SiblingBranch ) -> Option < ( ) > {
168
+ Some ( ( ) )
169
+ }
170
+ }
171
+
172
+ impl Navigate for Noop {
173
+ fn traverse ( & mut self , _kind : Traversal ) -> Option < ( ) > {
174
+ Some ( ( ) )
175
+ }
176
+
177
+ fn peel_until ( & mut self , _kind : PeelTo < ' _ > ) -> Option < ( ) > {
178
+ Some ( ( ) )
179
+ }
180
+
181
+ fn find ( & mut self , _regex : & BStr , _negated : bool ) -> Option < ( ) > {
182
+ Some ( ( ) )
183
+ }
184
+
185
+ fn index_lookup ( & mut self , _path : & BStr , _stage : u8 ) -> Option < ( ) > {
186
+ Some ( ( ) )
187
+ }
188
+ }
189
+
190
+ impl Kind for Noop {
191
+ fn kind ( & mut self , _kind : git_revision:: spec:: Kind ) -> Option < ( ) > {
192
+ Some ( ( ) )
193
+ }
194
+ }
195
+
196
+ impl git_revision:: spec:: parse:: Delegate for Noop {
197
+ fn done ( & mut self ) { }
198
+ }
199
+ }
0 commit comments