14 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND |
14 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND |
15 from mercurial import graphmod, patch |
15 from mercurial import graphmod, patch |
16 from mercurial import help as helpmod |
16 from mercurial import help as helpmod |
17 from mercurial import scmutil |
17 from mercurial import scmutil |
18 from mercurial.i18n import _ |
18 from mercurial.i18n import _ |
|
19 from mercurial.error import ParseError, RepoLookupError, Abort |
|
20 from mercurial import revset |
19 |
21 |
20 # __all__ is populated with the allowed commands. Be sure to add to it if |
22 # __all__ is populated with the allowed commands. Be sure to add to it if |
21 # you're adding a new command, or the new command won't work. |
23 # you're adding a new command, or the new command won't work. |
22 |
24 |
23 __all__ = [ |
25 __all__ = [ |
141 if miss: |
144 if miss: |
142 continue |
145 continue |
143 |
146 |
144 yield ctx |
147 yield ctx |
145 |
148 |
|
149 def revsetsearch(revs): |
|
150 for r in revs: |
|
151 yield web.repo[r] |
|
152 |
146 searchfuncs = { |
153 searchfuncs = { |
147 MODE_REVISION: revsearch, |
154 MODE_REVISION: revsearch, |
148 MODE_KEYWORD: keywordsearch, |
155 MODE_KEYWORD: keywordsearch, |
|
156 MODE_REVSET: revsetsearch, |
149 } |
157 } |
150 |
158 |
151 def getsearchmode(query): |
159 def getsearchmode(query): |
152 try: |
160 try: |
153 ctx = web.repo[query] |
161 ctx = web.repo[query] |
154 except (error.RepoError, error.LookupError): |
162 except (error.RepoError, error.LookupError): |
155 return MODE_KEYWORD, query |
163 # query is not an exact revision pointer, need to |
|
164 # decide if it's a revset expession or keywords |
|
165 pass |
156 else: |
166 else: |
157 return MODE_REVISION, ctx |
167 return MODE_REVISION, ctx |
|
168 |
|
169 revdef = 'reverse(%s)' % query |
|
170 try: |
|
171 tree, pos = revset.parse(revdef) |
|
172 except ParseError: |
|
173 # can't parse to a revset tree |
|
174 return MODE_KEYWORD, query |
|
175 |
|
176 if revset.depth(tree) <= 2: |
|
177 # no revset syntax used |
|
178 return MODE_KEYWORD, query |
|
179 |
|
180 if util.any((token, (value or '')[:3]) == ('string', 're:') |
|
181 for token, value, pos in revset.tokenize(revdef)): |
|
182 return MODE_KEYWORD, query |
|
183 |
|
184 funcsused = revset.funcsused(tree) |
|
185 if not funcsused.issubset(revset.safesymbols): |
|
186 return MODE_KEYWORD, query |
|
187 |
|
188 mfunc = revset.match(web.repo.ui, revdef) |
|
189 try: |
|
190 revs = mfunc(web.repo, list(web.repo)) |
|
191 return MODE_REVSET, revs |
|
192 # ParseError: wrongly placed tokens, wrongs arguments, etc |
|
193 # RepoLookupError: no such revision, e.g. in 'revision:' |
|
194 # Abort: bookmark/tag not exists |
|
195 # LookupError: ambiguous identifier, e.g. in '(bc)' on a large repo |
|
196 except (ParseError, RepoLookupError, Abort, LookupError): |
|
197 return MODE_KEYWORD, query |
158 |
198 |
159 def changelist(**map): |
199 def changelist(**map): |
160 count = 0 |
200 count = 0 |
161 |
201 |
162 for ctx in searchfunc(funcarg): |
202 for ctx in searchfunc(funcarg): |