##// END OF EJS Templates
mercurial: allow fetching phase/evolve attributes in bulk request.
marcink -
r275:1813107a default
parent child Browse files
Show More
@@ -1,746 +1,749 b''
1 # RhodeCode VCSServer provides access to different vcs backends via network.
1 # RhodeCode VCSServer provides access to different vcs backends via network.
2 # Copyright (C) 2014-2017 RodeCode GmbH
2 # Copyright (C) 2014-2017 RodeCode GmbH
3 #
3 #
4 # This program is free software; you can redistribute it and/or modify
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
7 # (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
18 import io
18 import io
19 import logging
19 import logging
20 import stat
20 import stat
21 import urllib
21 import urllib
22 import urllib2
22 import urllib2
23
23
24 from hgext import largefiles, rebase
24 from hgext import largefiles, rebase
25 from hgext.strip import strip as hgext_strip
25 from hgext.strip import strip as hgext_strip
26 from mercurial import commands
26 from mercurial import commands
27 from mercurial import unionrepo
27 from mercurial import unionrepo
28 from mercurial import verify
28 from mercurial import verify
29
29
30 from vcsserver import exceptions
30 from vcsserver import exceptions
31 from vcsserver.base import RepoFactory, obfuscate_qs, raise_from_original
31 from vcsserver.base import RepoFactory, obfuscate_qs, raise_from_original
32 from vcsserver.hgcompat import (
32 from vcsserver.hgcompat import (
33 archival, bin, clone, config as hgconfig, diffopts, hex,
33 archival, bin, clone, config as hgconfig, diffopts, hex,
34 hg_url as url_parser, httpbasicauthhandler, httpdigestauthhandler,
34 hg_url as url_parser, httpbasicauthhandler, httpdigestauthhandler,
35 httppeer, localrepository, match, memctx, exchange, memfilectx, nullrev,
35 httppeer, localrepository, match, memctx, exchange, memfilectx, nullrev,
36 patch, peer, revrange, ui, hg_tag, Abort, LookupError, RepoError,
36 patch, peer, revrange, ui, hg_tag, Abort, LookupError, RepoError,
37 RepoLookupError, InterventionRequired, RequirementError)
37 RepoLookupError, InterventionRequired, RequirementError)
38
38
39 log = logging.getLogger(__name__)
39 log = logging.getLogger(__name__)
40
40
41
41
42 def make_ui_from_config(repo_config):
42 def make_ui_from_config(repo_config):
43 baseui = ui.ui()
43 baseui = ui.ui()
44
44
45 # clean the baseui object
45 # clean the baseui object
46 baseui._ocfg = hgconfig.config()
46 baseui._ocfg = hgconfig.config()
47 baseui._ucfg = hgconfig.config()
47 baseui._ucfg = hgconfig.config()
48 baseui._tcfg = hgconfig.config()
48 baseui._tcfg = hgconfig.config()
49
49
50 for section, option, value in repo_config:
50 for section, option, value in repo_config:
51 baseui.setconfig(section, option, value)
51 baseui.setconfig(section, option, value)
52
52
53 # make our hgweb quiet so it doesn't print output
53 # make our hgweb quiet so it doesn't print output
54 baseui.setconfig('ui', 'quiet', 'true')
54 baseui.setconfig('ui', 'quiet', 'true')
55
55
56 # force mercurial to only use 1 thread, otherwise it may try to set a
56 # force mercurial to only use 1 thread, otherwise it may try to set a
57 # signal in a non-main thread, thus generating a ValueError.
57 # signal in a non-main thread, thus generating a ValueError.
58 baseui.setconfig('worker', 'numcpus', 1)
58 baseui.setconfig('worker', 'numcpus', 1)
59
59
60 # If there is no config for the largefiles extension, we explicitly disable
60 # If there is no config for the largefiles extension, we explicitly disable
61 # it here. This overrides settings from repositories hgrc file. Recent
61 # it here. This overrides settings from repositories hgrc file. Recent
62 # mercurial versions enable largefiles in hgrc on clone from largefile
62 # mercurial versions enable largefiles in hgrc on clone from largefile
63 # repo.
63 # repo.
64 if not baseui.hasconfig('extensions', 'largefiles'):
64 if not baseui.hasconfig('extensions', 'largefiles'):
65 log.debug('Explicitly disable largefiles extension for repo.')
65 log.debug('Explicitly disable largefiles extension for repo.')
66 baseui.setconfig('extensions', 'largefiles', '!')
66 baseui.setconfig('extensions', 'largefiles', '!')
67
67
68 return baseui
68 return baseui
69
69
70
70
71 def reraise_safe_exceptions(func):
71 def reraise_safe_exceptions(func):
72 """Decorator for converting mercurial exceptions to something neutral."""
72 """Decorator for converting mercurial exceptions to something neutral."""
73 def wrapper(*args, **kwargs):
73 def wrapper(*args, **kwargs):
74 try:
74 try:
75 return func(*args, **kwargs)
75 return func(*args, **kwargs)
76 except (Abort, InterventionRequired):
76 except (Abort, InterventionRequired):
77 raise_from_original(exceptions.AbortException)
77 raise_from_original(exceptions.AbortException)
78 except RepoLookupError:
78 except RepoLookupError:
79 raise_from_original(exceptions.LookupException)
79 raise_from_original(exceptions.LookupException)
80 except RequirementError:
80 except RequirementError:
81 raise_from_original(exceptions.RequirementException)
81 raise_from_original(exceptions.RequirementException)
82 except RepoError:
82 except RepoError:
83 raise_from_original(exceptions.VcsException)
83 raise_from_original(exceptions.VcsException)
84 except LookupError:
84 except LookupError:
85 raise_from_original(exceptions.LookupException)
85 raise_from_original(exceptions.LookupException)
86 except Exception as e:
86 except Exception as e:
87 if not hasattr(e, '_vcs_kind'):
87 if not hasattr(e, '_vcs_kind'):
88 log.exception("Unhandled exception in hg remote call")
88 log.exception("Unhandled exception in hg remote call")
89 raise_from_original(exceptions.UnhandledException)
89 raise_from_original(exceptions.UnhandledException)
90 raise
90 raise
91 return wrapper
91 return wrapper
92
92
93
93
94 class MercurialFactory(RepoFactory):
94 class MercurialFactory(RepoFactory):
95
95
96 def _create_config(self, config, hooks=True):
96 def _create_config(self, config, hooks=True):
97 if not hooks:
97 if not hooks:
98 hooks_to_clean = frozenset((
98 hooks_to_clean = frozenset((
99 'changegroup.repo_size', 'preoutgoing.pre_pull',
99 'changegroup.repo_size', 'preoutgoing.pre_pull',
100 'outgoing.pull_logger', 'prechangegroup.pre_push'))
100 'outgoing.pull_logger', 'prechangegroup.pre_push'))
101 new_config = []
101 new_config = []
102 for section, option, value in config:
102 for section, option, value in config:
103 if section == 'hooks' and option in hooks_to_clean:
103 if section == 'hooks' and option in hooks_to_clean:
104 continue
104 continue
105 new_config.append((section, option, value))
105 new_config.append((section, option, value))
106 config = new_config
106 config = new_config
107
107
108 baseui = make_ui_from_config(config)
108 baseui = make_ui_from_config(config)
109 return baseui
109 return baseui
110
110
111 def _create_repo(self, wire, create):
111 def _create_repo(self, wire, create):
112 baseui = self._create_config(wire["config"])
112 baseui = self._create_config(wire["config"])
113 return localrepository(baseui, wire["path"], create)
113 return localrepository(baseui, wire["path"], create)
114
114
115
115
116 class HgRemote(object):
116 class HgRemote(object):
117
117
118 def __init__(self, factory):
118 def __init__(self, factory):
119 self._factory = factory
119 self._factory = factory
120
120
121 self._bulk_methods = {
121 self._bulk_methods = {
122 "affected_files": self.ctx_files,
122 "affected_files": self.ctx_files,
123 "author": self.ctx_user,
123 "author": self.ctx_user,
124 "branch": self.ctx_branch,
124 "branch": self.ctx_branch,
125 "children": self.ctx_children,
125 "children": self.ctx_children,
126 "date": self.ctx_date,
126 "date": self.ctx_date,
127 "message": self.ctx_description,
127 "message": self.ctx_description,
128 "parents": self.ctx_parents,
128 "parents": self.ctx_parents,
129 "status": self.ctx_status,
129 "status": self.ctx_status,
130 "obsolete": self.ctx_obsolete,
131 "phase": self.ctx_phase,
132 "hidden": self.ctx_hidden,
130 "_file_paths": self.ctx_list,
133 "_file_paths": self.ctx_list,
131 }
134 }
132
135
133 @reraise_safe_exceptions
136 @reraise_safe_exceptions
134 def discover_hg_version(self):
137 def discover_hg_version(self):
135 from mercurial import util
138 from mercurial import util
136 return util.version()
139 return util.version()
137
140
138 @reraise_safe_exceptions
141 @reraise_safe_exceptions
139 def archive_repo(self, archive_path, mtime, file_info, kind):
142 def archive_repo(self, archive_path, mtime, file_info, kind):
140 if kind == "tgz":
143 if kind == "tgz":
141 archiver = archival.tarit(archive_path, mtime, "gz")
144 archiver = archival.tarit(archive_path, mtime, "gz")
142 elif kind == "tbz2":
145 elif kind == "tbz2":
143 archiver = archival.tarit(archive_path, mtime, "bz2")
146 archiver = archival.tarit(archive_path, mtime, "bz2")
144 elif kind == 'zip':
147 elif kind == 'zip':
145 archiver = archival.zipit(archive_path, mtime)
148 archiver = archival.zipit(archive_path, mtime)
146 else:
149 else:
147 raise exceptions.ArchiveException(
150 raise exceptions.ArchiveException(
148 'Remote does not support: "%s".' % kind)
151 'Remote does not support: "%s".' % kind)
149
152
150 for f_path, f_mode, f_is_link, f_content in file_info:
153 for f_path, f_mode, f_is_link, f_content in file_info:
151 archiver.addfile(f_path, f_mode, f_is_link, f_content)
154 archiver.addfile(f_path, f_mode, f_is_link, f_content)
152 archiver.done()
155 archiver.done()
153
156
154 @reraise_safe_exceptions
157 @reraise_safe_exceptions
155 def bookmarks(self, wire):
158 def bookmarks(self, wire):
156 repo = self._factory.repo(wire)
159 repo = self._factory.repo(wire)
157 return dict(repo._bookmarks)
160 return dict(repo._bookmarks)
158
161
159 @reraise_safe_exceptions
162 @reraise_safe_exceptions
160 def branches(self, wire, normal, closed):
163 def branches(self, wire, normal, closed):
161 repo = self._factory.repo(wire)
164 repo = self._factory.repo(wire)
162 iter_branches = repo.branchmap().iterbranches()
165 iter_branches = repo.branchmap().iterbranches()
163 bt = {}
166 bt = {}
164 for branch_name, _heads, tip, is_closed in iter_branches:
167 for branch_name, _heads, tip, is_closed in iter_branches:
165 if normal and not is_closed:
168 if normal and not is_closed:
166 bt[branch_name] = tip
169 bt[branch_name] = tip
167 if closed and is_closed:
170 if closed and is_closed:
168 bt[branch_name] = tip
171 bt[branch_name] = tip
169
172
170 return bt
173 return bt
171
174
172 @reraise_safe_exceptions
175 @reraise_safe_exceptions
173 def bulk_request(self, wire, rev, pre_load):
176 def bulk_request(self, wire, rev, pre_load):
174 result = {}
177 result = {}
175 for attr in pre_load:
178 for attr in pre_load:
176 try:
179 try:
177 method = self._bulk_methods[attr]
180 method = self._bulk_methods[attr]
178 result[attr] = method(wire, rev)
181 result[attr] = method(wire, rev)
179 except KeyError:
182 except KeyError:
180 raise exceptions.VcsException(
183 raise exceptions.VcsException(
181 'Unknown bulk attribute: "%s"' % attr)
184 'Unknown bulk attribute: "%s"' % attr)
182 return result
185 return result
183
186
184 @reraise_safe_exceptions
187 @reraise_safe_exceptions
185 def clone(self, wire, source, dest, update_after_clone=False, hooks=True):
188 def clone(self, wire, source, dest, update_after_clone=False, hooks=True):
186 baseui = self._factory._create_config(wire["config"], hooks=hooks)
189 baseui = self._factory._create_config(wire["config"], hooks=hooks)
187 clone(baseui, source, dest, noupdate=not update_after_clone)
190 clone(baseui, source, dest, noupdate=not update_after_clone)
188
191
189 @reraise_safe_exceptions
192 @reraise_safe_exceptions
190 def commitctx(
193 def commitctx(
191 self, wire, message, parents, commit_time, commit_timezone,
194 self, wire, message, parents, commit_time, commit_timezone,
192 user, files, extra, removed, updated):
195 user, files, extra, removed, updated):
193
196
194 def _filectxfn(_repo, memctx, path):
197 def _filectxfn(_repo, memctx, path):
195 """
198 """
196 Marks given path as added/changed/removed in a given _repo. This is
199 Marks given path as added/changed/removed in a given _repo. This is
197 for internal mercurial commit function.
200 for internal mercurial commit function.
198 """
201 """
199
202
200 # check if this path is removed
203 # check if this path is removed
201 if path in removed:
204 if path in removed:
202 # returning None is a way to mark node for removal
205 # returning None is a way to mark node for removal
203 return None
206 return None
204
207
205 # check if this path is added
208 # check if this path is added
206 for node in updated:
209 for node in updated:
207 if node['path'] == path:
210 if node['path'] == path:
208 return memfilectx(
211 return memfilectx(
209 _repo,
212 _repo,
210 path=node['path'],
213 path=node['path'],
211 data=node['content'],
214 data=node['content'],
212 islink=False,
215 islink=False,
213 isexec=bool(node['mode'] & stat.S_IXUSR),
216 isexec=bool(node['mode'] & stat.S_IXUSR),
214 copied=False,
217 copied=False,
215 memctx=memctx)
218 memctx=memctx)
216
219
217 raise exceptions.AbortException(
220 raise exceptions.AbortException(
218 "Given path haven't been marked as added, "
221 "Given path haven't been marked as added, "
219 "changed or removed (%s)" % path)
222 "changed or removed (%s)" % path)
220
223
221 repo = self._factory.repo(wire)
224 repo = self._factory.repo(wire)
222
225
223 commit_ctx = memctx(
226 commit_ctx = memctx(
224 repo=repo,
227 repo=repo,
225 parents=parents,
228 parents=parents,
226 text=message,
229 text=message,
227 files=files,
230 files=files,
228 filectxfn=_filectxfn,
231 filectxfn=_filectxfn,
229 user=user,
232 user=user,
230 date=(commit_time, commit_timezone),
233 date=(commit_time, commit_timezone),
231 extra=extra)
234 extra=extra)
232
235
233 n = repo.commitctx(commit_ctx)
236 n = repo.commitctx(commit_ctx)
234 new_id = hex(n)
237 new_id = hex(n)
235
238
236 return new_id
239 return new_id
237
240
238 @reraise_safe_exceptions
241 @reraise_safe_exceptions
239 def ctx_branch(self, wire, revision):
242 def ctx_branch(self, wire, revision):
240 repo = self._factory.repo(wire)
243 repo = self._factory.repo(wire)
241 ctx = repo[revision]
244 ctx = repo[revision]
242 return ctx.branch()
245 return ctx.branch()
243
246
244 @reraise_safe_exceptions
247 @reraise_safe_exceptions
245 def ctx_children(self, wire, revision):
248 def ctx_children(self, wire, revision):
246 repo = self._factory.repo(wire)
249 repo = self._factory.repo(wire)
247 ctx = repo[revision]
250 ctx = repo[revision]
248 return [child.rev() for child in ctx.children()]
251 return [child.rev() for child in ctx.children()]
249
252
250 @reraise_safe_exceptions
253 @reraise_safe_exceptions
251 def ctx_date(self, wire, revision):
254 def ctx_date(self, wire, revision):
252 repo = self._factory.repo(wire)
255 repo = self._factory.repo(wire)
253 ctx = repo[revision]
256 ctx = repo[revision]
254 return ctx.date()
257 return ctx.date()
255
258
256 @reraise_safe_exceptions
259 @reraise_safe_exceptions
257 def ctx_description(self, wire, revision):
260 def ctx_description(self, wire, revision):
258 repo = self._factory.repo(wire)
261 repo = self._factory.repo(wire)
259 ctx = repo[revision]
262 ctx = repo[revision]
260 return ctx.description()
263 return ctx.description()
261
264
262 @reraise_safe_exceptions
265 @reraise_safe_exceptions
263 def ctx_diff(
266 def ctx_diff(
264 self, wire, revision, git=True, ignore_whitespace=True, context=3):
267 self, wire, revision, git=True, ignore_whitespace=True, context=3):
265 repo = self._factory.repo(wire)
268 repo = self._factory.repo(wire)
266 ctx = repo[revision]
269 ctx = repo[revision]
267 result = ctx.diff(
270 result = ctx.diff(
268 git=git, ignore_whitespace=ignore_whitespace, context=context)
271 git=git, ignore_whitespace=ignore_whitespace, context=context)
269 return list(result)
272 return list(result)
270
273
271 @reraise_safe_exceptions
274 @reraise_safe_exceptions
272 def ctx_files(self, wire, revision):
275 def ctx_files(self, wire, revision):
273 repo = self._factory.repo(wire)
276 repo = self._factory.repo(wire)
274 ctx = repo[revision]
277 ctx = repo[revision]
275 return ctx.files()
278 return ctx.files()
276
279
277 @reraise_safe_exceptions
280 @reraise_safe_exceptions
278 def ctx_list(self, path, revision):
281 def ctx_list(self, path, revision):
279 repo = self._factory.repo(path)
282 repo = self._factory.repo(path)
280 ctx = repo[revision]
283 ctx = repo[revision]
281 return list(ctx)
284 return list(ctx)
282
285
283 @reraise_safe_exceptions
286 @reraise_safe_exceptions
284 def ctx_parents(self, wire, revision):
287 def ctx_parents(self, wire, revision):
285 repo = self._factory.repo(wire)
288 repo = self._factory.repo(wire)
286 ctx = repo[revision]
289 ctx = repo[revision]
287 return [parent.rev() for parent in ctx.parents()]
290 return [parent.rev() for parent in ctx.parents()]
288
291
289 @reraise_safe_exceptions
292 @reraise_safe_exceptions
290 def ctx_phase(self, wire, revision):
293 def ctx_phase(self, wire, revision):
291 repo = self._factory.repo(wire)
294 repo = self._factory.repo(wire)
292 ctx = repo[revision]
295 ctx = repo[revision]
293 # public=0, draft=1, secret=3
296 # public=0, draft=1, secret=3
294 return ctx.phase()
297 return ctx.phase()
295
298
296 @reraise_safe_exceptions
299 @reraise_safe_exceptions
297 def ctx_obsolete(self, wire, revision):
300 def ctx_obsolete(self, wire, revision):
298 repo = self._factory.repo(wire)
301 repo = self._factory.repo(wire)
299 ctx = repo[revision]
302 ctx = repo[revision]
300 return ctx.obsolete()
303 return ctx.obsolete()
301
304
302 @reraise_safe_exceptions
305 @reraise_safe_exceptions
303 def ctx_hidden(self, wire, revision):
306 def ctx_hidden(self, wire, revision):
304 repo = self._factory.repo(wire)
307 repo = self._factory.repo(wire)
305 ctx = repo[revision]
308 ctx = repo[revision]
306 return ctx.hidden()
309 return ctx.hidden()
307
310
308 @reraise_safe_exceptions
311 @reraise_safe_exceptions
309 def ctx_substate(self, wire, revision):
312 def ctx_substate(self, wire, revision):
310 repo = self._factory.repo(wire)
313 repo = self._factory.repo(wire)
311 ctx = repo[revision]
314 ctx = repo[revision]
312 return ctx.substate
315 return ctx.substate
313
316
314 @reraise_safe_exceptions
317 @reraise_safe_exceptions
315 def ctx_status(self, wire, revision):
318 def ctx_status(self, wire, revision):
316 repo = self._factory.repo(wire)
319 repo = self._factory.repo(wire)
317 ctx = repo[revision]
320 ctx = repo[revision]
318 status = repo[ctx.p1().node()].status(other=ctx.node())
321 status = repo[ctx.p1().node()].status(other=ctx.node())
319 # object of status (odd, custom named tuple in mercurial) is not
322 # object of status (odd, custom named tuple in mercurial) is not
320 # correctly serializable, we make it a list, as the underling
323 # correctly serializable, we make it a list, as the underling
321 # API expects this to be a list
324 # API expects this to be a list
322 return list(status)
325 return list(status)
323
326
324 @reraise_safe_exceptions
327 @reraise_safe_exceptions
325 def ctx_user(self, wire, revision):
328 def ctx_user(self, wire, revision):
326 repo = self._factory.repo(wire)
329 repo = self._factory.repo(wire)
327 ctx = repo[revision]
330 ctx = repo[revision]
328 return ctx.user()
331 return ctx.user()
329
332
330 @reraise_safe_exceptions
333 @reraise_safe_exceptions
331 def check_url(self, url, config):
334 def check_url(self, url, config):
332 _proto = None
335 _proto = None
333 if '+' in url[:url.find('://')]:
336 if '+' in url[:url.find('://')]:
334 _proto = url[0:url.find('+')]
337 _proto = url[0:url.find('+')]
335 url = url[url.find('+') + 1:]
338 url = url[url.find('+') + 1:]
336 handlers = []
339 handlers = []
337 url_obj = url_parser(url)
340 url_obj = url_parser(url)
338 test_uri, authinfo = url_obj.authinfo()
341 test_uri, authinfo = url_obj.authinfo()
339 url_obj.passwd = '*****' if url_obj.passwd else url_obj.passwd
342 url_obj.passwd = '*****' if url_obj.passwd else url_obj.passwd
340 url_obj.query = obfuscate_qs(url_obj.query)
343 url_obj.query = obfuscate_qs(url_obj.query)
341
344
342 cleaned_uri = str(url_obj)
345 cleaned_uri = str(url_obj)
343 log.info("Checking URL for remote cloning/import: %s", cleaned_uri)
346 log.info("Checking URL for remote cloning/import: %s", cleaned_uri)
344
347
345 if authinfo:
348 if authinfo:
346 # create a password manager
349 # create a password manager
347 passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
350 passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
348 passmgr.add_password(*authinfo)
351 passmgr.add_password(*authinfo)
349
352
350 handlers.extend((httpbasicauthhandler(passmgr),
353 handlers.extend((httpbasicauthhandler(passmgr),
351 httpdigestauthhandler(passmgr)))
354 httpdigestauthhandler(passmgr)))
352
355
353 o = urllib2.build_opener(*handlers)
356 o = urllib2.build_opener(*handlers)
354 o.addheaders = [('Content-Type', 'application/mercurial-0.1'),
357 o.addheaders = [('Content-Type', 'application/mercurial-0.1'),
355 ('Accept', 'application/mercurial-0.1')]
358 ('Accept', 'application/mercurial-0.1')]
356
359
357 q = {"cmd": 'between'}
360 q = {"cmd": 'between'}
358 q.update({'pairs': "%s-%s" % ('0' * 40, '0' * 40)})
361 q.update({'pairs': "%s-%s" % ('0' * 40, '0' * 40)})
359 qs = '?%s' % urllib.urlencode(q)
362 qs = '?%s' % urllib.urlencode(q)
360 cu = "%s%s" % (test_uri, qs)
363 cu = "%s%s" % (test_uri, qs)
361 req = urllib2.Request(cu, None, {})
364 req = urllib2.Request(cu, None, {})
362
365
363 try:
366 try:
364 log.debug("Trying to open URL %s", cleaned_uri)
367 log.debug("Trying to open URL %s", cleaned_uri)
365 resp = o.open(req)
368 resp = o.open(req)
366 if resp.code != 200:
369 if resp.code != 200:
367 raise exceptions.URLError('Return Code is not 200')
370 raise exceptions.URLError('Return Code is not 200')
368 except Exception as e:
371 except Exception as e:
369 log.warning("URL cannot be opened: %s", cleaned_uri, exc_info=True)
372 log.warning("URL cannot be opened: %s", cleaned_uri, exc_info=True)
370 # means it cannot be cloned
373 # means it cannot be cloned
371 raise exceptions.URLError("[%s] org_exc: %s" % (cleaned_uri, e))
374 raise exceptions.URLError("[%s] org_exc: %s" % (cleaned_uri, e))
372
375
373 # now check if it's a proper hg repo, but don't do it for svn
376 # now check if it's a proper hg repo, but don't do it for svn
374 try:
377 try:
375 if _proto == 'svn':
378 if _proto == 'svn':
376 pass
379 pass
377 else:
380 else:
378 # check for pure hg repos
381 # check for pure hg repos
379 log.debug(
382 log.debug(
380 "Verifying if URL is a Mercurial repository: %s",
383 "Verifying if URL is a Mercurial repository: %s",
381 cleaned_uri)
384 cleaned_uri)
382 httppeer(make_ui_from_config(config), url).lookup('tip')
385 httppeer(make_ui_from_config(config), url).lookup('tip')
383 except Exception as e:
386 except Exception as e:
384 log.warning("URL is not a valid Mercurial repository: %s",
387 log.warning("URL is not a valid Mercurial repository: %s",
385 cleaned_uri)
388 cleaned_uri)
386 raise exceptions.URLError(
389 raise exceptions.URLError(
387 "url [%s] does not look like an hg repo org_exc: %s"
390 "url [%s] does not look like an hg repo org_exc: %s"
388 % (cleaned_uri, e))
391 % (cleaned_uri, e))
389
392
390 log.info("URL is a valid Mercurial repository: %s", cleaned_uri)
393 log.info("URL is a valid Mercurial repository: %s", cleaned_uri)
391 return True
394 return True
392
395
393 @reraise_safe_exceptions
396 @reraise_safe_exceptions
394 def diff(
397 def diff(
395 self, wire, rev1, rev2, file_filter, opt_git, opt_ignorews,
398 self, wire, rev1, rev2, file_filter, opt_git, opt_ignorews,
396 context):
399 context):
397 repo = self._factory.repo(wire)
400 repo = self._factory.repo(wire)
398
401
399 if file_filter:
402 if file_filter:
400 match_filter = match(file_filter[0], '', [file_filter[1]])
403 match_filter = match(file_filter[0], '', [file_filter[1]])
401 else:
404 else:
402 match_filter = file_filter
405 match_filter = file_filter
403 opts = diffopts(git=opt_git, ignorews=opt_ignorews, context=context)
406 opts = diffopts(git=opt_git, ignorews=opt_ignorews, context=context)
404
407
405 try:
408 try:
406 return "".join(patch.diff(
409 return "".join(patch.diff(
407 repo, node1=rev1, node2=rev2, match=match_filter, opts=opts))
410 repo, node1=rev1, node2=rev2, match=match_filter, opts=opts))
408 except RepoLookupError:
411 except RepoLookupError:
409 raise exceptions.LookupException()
412 raise exceptions.LookupException()
410
413
411 @reraise_safe_exceptions
414 @reraise_safe_exceptions
412 def file_history(self, wire, revision, path, limit):
415 def file_history(self, wire, revision, path, limit):
413 repo = self._factory.repo(wire)
416 repo = self._factory.repo(wire)
414
417
415 ctx = repo[revision]
418 ctx = repo[revision]
416 fctx = ctx.filectx(path)
419 fctx = ctx.filectx(path)
417
420
418 def history_iter():
421 def history_iter():
419 limit_rev = fctx.rev()
422 limit_rev = fctx.rev()
420 for obj in reversed(list(fctx.filelog())):
423 for obj in reversed(list(fctx.filelog())):
421 obj = fctx.filectx(obj)
424 obj = fctx.filectx(obj)
422 if limit_rev >= obj.rev():
425 if limit_rev >= obj.rev():
423 yield obj
426 yield obj
424
427
425 history = []
428 history = []
426 for cnt, obj in enumerate(history_iter()):
429 for cnt, obj in enumerate(history_iter()):
427 if limit and cnt >= limit:
430 if limit and cnt >= limit:
428 break
431 break
429 history.append(hex(obj.node()))
432 history.append(hex(obj.node()))
430
433
431 return [x for x in history]
434 return [x for x in history]
432
435
433 @reraise_safe_exceptions
436 @reraise_safe_exceptions
434 def file_history_untill(self, wire, revision, path, limit):
437 def file_history_untill(self, wire, revision, path, limit):
435 repo = self._factory.repo(wire)
438 repo = self._factory.repo(wire)
436 ctx = repo[revision]
439 ctx = repo[revision]
437 fctx = ctx.filectx(path)
440 fctx = ctx.filectx(path)
438
441
439 file_log = list(fctx.filelog())
442 file_log = list(fctx.filelog())
440 if limit:
443 if limit:
441 # Limit to the last n items
444 # Limit to the last n items
442 file_log = file_log[-limit:]
445 file_log = file_log[-limit:]
443
446
444 return [hex(fctx.filectx(cs).node()) for cs in reversed(file_log)]
447 return [hex(fctx.filectx(cs).node()) for cs in reversed(file_log)]
445
448
446 @reraise_safe_exceptions
449 @reraise_safe_exceptions
447 def fctx_annotate(self, wire, revision, path):
450 def fctx_annotate(self, wire, revision, path):
448 repo = self._factory.repo(wire)
451 repo = self._factory.repo(wire)
449 ctx = repo[revision]
452 ctx = repo[revision]
450 fctx = ctx.filectx(path)
453 fctx = ctx.filectx(path)
451
454
452 result = []
455 result = []
453 for i, annotate_data in enumerate(fctx.annotate()):
456 for i, annotate_data in enumerate(fctx.annotate()):
454 ln_no = i + 1
457 ln_no = i + 1
455 node_info, content = annotate_data
458 node_info, content = annotate_data
456 sha = hex(node_info[0].node())
459 sha = hex(node_info[0].node())
457 result.append((ln_no, sha, content))
460 result.append((ln_no, sha, content))
458 return result
461 return result
459
462
460 @reraise_safe_exceptions
463 @reraise_safe_exceptions
461 def fctx_data(self, wire, revision, path):
464 def fctx_data(self, wire, revision, path):
462 repo = self._factory.repo(wire)
465 repo = self._factory.repo(wire)
463 ctx = repo[revision]
466 ctx = repo[revision]
464 fctx = ctx.filectx(path)
467 fctx = ctx.filectx(path)
465 return fctx.data()
468 return fctx.data()
466
469
467 @reraise_safe_exceptions
470 @reraise_safe_exceptions
468 def fctx_flags(self, wire, revision, path):
471 def fctx_flags(self, wire, revision, path):
469 repo = self._factory.repo(wire)
472 repo = self._factory.repo(wire)
470 ctx = repo[revision]
473 ctx = repo[revision]
471 fctx = ctx.filectx(path)
474 fctx = ctx.filectx(path)
472 return fctx.flags()
475 return fctx.flags()
473
476
474 @reraise_safe_exceptions
477 @reraise_safe_exceptions
475 def fctx_size(self, wire, revision, path):
478 def fctx_size(self, wire, revision, path):
476 repo = self._factory.repo(wire)
479 repo = self._factory.repo(wire)
477 ctx = repo[revision]
480 ctx = repo[revision]
478 fctx = ctx.filectx(path)
481 fctx = ctx.filectx(path)
479 return fctx.size()
482 return fctx.size()
480
483
481 @reraise_safe_exceptions
484 @reraise_safe_exceptions
482 def get_all_commit_ids(self, wire, name):
485 def get_all_commit_ids(self, wire, name):
483 repo = self._factory.repo(wire)
486 repo = self._factory.repo(wire)
484 revs = repo.filtered(name).changelog.index
487 revs = repo.filtered(name).changelog.index
485 return map(lambda x: hex(x[7]), revs)[:-1]
488 return map(lambda x: hex(x[7]), revs)[:-1]
486
489
487 @reraise_safe_exceptions
490 @reraise_safe_exceptions
488 def get_config_value(self, wire, section, name, untrusted=False):
491 def get_config_value(self, wire, section, name, untrusted=False):
489 repo = self._factory.repo(wire)
492 repo = self._factory.repo(wire)
490 return repo.ui.config(section, name, untrusted=untrusted)
493 return repo.ui.config(section, name, untrusted=untrusted)
491
494
492 @reraise_safe_exceptions
495 @reraise_safe_exceptions
493 def get_config_bool(self, wire, section, name, untrusted=False):
496 def get_config_bool(self, wire, section, name, untrusted=False):
494 repo = self._factory.repo(wire)
497 repo = self._factory.repo(wire)
495 return repo.ui.configbool(section, name, untrusted=untrusted)
498 return repo.ui.configbool(section, name, untrusted=untrusted)
496
499
497 @reraise_safe_exceptions
500 @reraise_safe_exceptions
498 def get_config_list(self, wire, section, name, untrusted=False):
501 def get_config_list(self, wire, section, name, untrusted=False):
499 repo = self._factory.repo(wire)
502 repo = self._factory.repo(wire)
500 return repo.ui.configlist(section, name, untrusted=untrusted)
503 return repo.ui.configlist(section, name, untrusted=untrusted)
501
504
502 @reraise_safe_exceptions
505 @reraise_safe_exceptions
503 def is_large_file(self, wire, path):
506 def is_large_file(self, wire, path):
504 return largefiles.lfutil.isstandin(path)
507 return largefiles.lfutil.isstandin(path)
505
508
506 @reraise_safe_exceptions
509 @reraise_safe_exceptions
507 def in_largefiles_store(self, wire, sha):
510 def in_largefiles_store(self, wire, sha):
508 repo = self._factory.repo(wire)
511 repo = self._factory.repo(wire)
509 return largefiles.lfutil.instore(repo, sha)
512 return largefiles.lfutil.instore(repo, sha)
510
513
511 @reraise_safe_exceptions
514 @reraise_safe_exceptions
512 def in_user_cache(self, wire, sha):
515 def in_user_cache(self, wire, sha):
513 repo = self._factory.repo(wire)
516 repo = self._factory.repo(wire)
514 return largefiles.lfutil.inusercache(repo.ui, sha)
517 return largefiles.lfutil.inusercache(repo.ui, sha)
515
518
516 @reraise_safe_exceptions
519 @reraise_safe_exceptions
517 def store_path(self, wire, sha):
520 def store_path(self, wire, sha):
518 repo = self._factory.repo(wire)
521 repo = self._factory.repo(wire)
519 return largefiles.lfutil.storepath(repo, sha)
522 return largefiles.lfutil.storepath(repo, sha)
520
523
521 @reraise_safe_exceptions
524 @reraise_safe_exceptions
522 def link(self, wire, sha, path):
525 def link(self, wire, sha, path):
523 repo = self._factory.repo(wire)
526 repo = self._factory.repo(wire)
524 largefiles.lfutil.link(
527 largefiles.lfutil.link(
525 largefiles.lfutil.usercachepath(repo.ui, sha), path)
528 largefiles.lfutil.usercachepath(repo.ui, sha), path)
526
529
527 @reraise_safe_exceptions
530 @reraise_safe_exceptions
528 def localrepository(self, wire, create=False):
531 def localrepository(self, wire, create=False):
529 self._factory.repo(wire, create=create)
532 self._factory.repo(wire, create=create)
530
533
531 @reraise_safe_exceptions
534 @reraise_safe_exceptions
532 def lookup(self, wire, revision, both):
535 def lookup(self, wire, revision, both):
533 # TODO Paris: Ugly hack to "deserialize" long for msgpack
536 # TODO Paris: Ugly hack to "deserialize" long for msgpack
534 if isinstance(revision, float):
537 if isinstance(revision, float):
535 revision = long(revision)
538 revision = long(revision)
536 repo = self._factory.repo(wire)
539 repo = self._factory.repo(wire)
537 try:
540 try:
538 ctx = repo[revision]
541 ctx = repo[revision]
539 except RepoLookupError:
542 except RepoLookupError:
540 raise exceptions.LookupException(revision)
543 raise exceptions.LookupException(revision)
541 except LookupError as e:
544 except LookupError as e:
542 raise exceptions.LookupException(e.name)
545 raise exceptions.LookupException(e.name)
543
546
544 if not both:
547 if not both:
545 return ctx.hex()
548 return ctx.hex()
546
549
547 ctx = repo[ctx.hex()]
550 ctx = repo[ctx.hex()]
548 return ctx.hex(), ctx.rev()
551 return ctx.hex(), ctx.rev()
549
552
550 @reraise_safe_exceptions
553 @reraise_safe_exceptions
551 def pull(self, wire, url, commit_ids=None):
554 def pull(self, wire, url, commit_ids=None):
552 repo = self._factory.repo(wire)
555 repo = self._factory.repo(wire)
553 remote = peer(repo, {}, url)
556 remote = peer(repo, {}, url)
554 if commit_ids:
557 if commit_ids:
555 commit_ids = [bin(commit_id) for commit_id in commit_ids]
558 commit_ids = [bin(commit_id) for commit_id in commit_ids]
556
559
557 return exchange.pull(
560 return exchange.pull(
558 repo, remote, heads=commit_ids, force=None).cgresult
561 repo, remote, heads=commit_ids, force=None).cgresult
559
562
560 @reraise_safe_exceptions
563 @reraise_safe_exceptions
561 def revision(self, wire, rev):
564 def revision(self, wire, rev):
562 repo = self._factory.repo(wire)
565 repo = self._factory.repo(wire)
563 ctx = repo[rev]
566 ctx = repo[rev]
564 return ctx.rev()
567 return ctx.rev()
565
568
566 @reraise_safe_exceptions
569 @reraise_safe_exceptions
567 def rev_range(self, wire, filter):
570 def rev_range(self, wire, filter):
568 repo = self._factory.repo(wire)
571 repo = self._factory.repo(wire)
569 revisions = [rev for rev in revrange(repo, filter)]
572 revisions = [rev for rev in revrange(repo, filter)]
570 return revisions
573 return revisions
571
574
572 @reraise_safe_exceptions
575 @reraise_safe_exceptions
573 def rev_range_hash(self, wire, node):
576 def rev_range_hash(self, wire, node):
574 repo = self._factory.repo(wire)
577 repo = self._factory.repo(wire)
575
578
576 def get_revs(repo, rev_opt):
579 def get_revs(repo, rev_opt):
577 if rev_opt:
580 if rev_opt:
578 revs = revrange(repo, rev_opt)
581 revs = revrange(repo, rev_opt)
579 if len(revs) == 0:
582 if len(revs) == 0:
580 return (nullrev, nullrev)
583 return (nullrev, nullrev)
581 return max(revs), min(revs)
584 return max(revs), min(revs)
582 else:
585 else:
583 return len(repo) - 1, 0
586 return len(repo) - 1, 0
584
587
585 stop, start = get_revs(repo, [node + ':'])
588 stop, start = get_revs(repo, [node + ':'])
586 revs = [hex(repo[r].node()) for r in xrange(start, stop + 1)]
589 revs = [hex(repo[r].node()) for r in xrange(start, stop + 1)]
587 return revs
590 return revs
588
591
589 @reraise_safe_exceptions
592 @reraise_safe_exceptions
590 def revs_from_revspec(self, wire, rev_spec, *args, **kwargs):
593 def revs_from_revspec(self, wire, rev_spec, *args, **kwargs):
591 other_path = kwargs.pop('other_path', None)
594 other_path = kwargs.pop('other_path', None)
592
595
593 # case when we want to compare two independent repositories
596 # case when we want to compare two independent repositories
594 if other_path and other_path != wire["path"]:
597 if other_path and other_path != wire["path"]:
595 baseui = self._factory._create_config(wire["config"])
598 baseui = self._factory._create_config(wire["config"])
596 repo = unionrepo.unionrepository(baseui, other_path, wire["path"])
599 repo = unionrepo.unionrepository(baseui, other_path, wire["path"])
597 else:
600 else:
598 repo = self._factory.repo(wire)
601 repo = self._factory.repo(wire)
599 return list(repo.revs(rev_spec, *args))
602 return list(repo.revs(rev_spec, *args))
600
603
601 @reraise_safe_exceptions
604 @reraise_safe_exceptions
602 def strip(self, wire, revision, update, backup):
605 def strip(self, wire, revision, update, backup):
603 repo = self._factory.repo(wire)
606 repo = self._factory.repo(wire)
604 ctx = repo[revision]
607 ctx = repo[revision]
605 hgext_strip(
608 hgext_strip(
606 repo.baseui, repo, ctx.node(), update=update, backup=backup)
609 repo.baseui, repo, ctx.node(), update=update, backup=backup)
607
610
608 @reraise_safe_exceptions
611 @reraise_safe_exceptions
609 def verify(self, wire,):
612 def verify(self, wire,):
610 repo = self._factory.repo(wire)
613 repo = self._factory.repo(wire)
611 baseui = self._factory._create_config(wire['config'])
614 baseui = self._factory._create_config(wire['config'])
612 baseui.setconfig('ui', 'quiet', 'false')
615 baseui.setconfig('ui', 'quiet', 'false')
613 output = io.BytesIO()
616 output = io.BytesIO()
614
617
615 def write(data, **unused_kwargs):
618 def write(data, **unused_kwargs):
616 output.write(data)
619 output.write(data)
617 baseui.write = write
620 baseui.write = write
618
621
619 repo.ui = baseui
622 repo.ui = baseui
620 verify.verify(repo)
623 verify.verify(repo)
621 return output.getvalue()
624 return output.getvalue()
622
625
623 @reraise_safe_exceptions
626 @reraise_safe_exceptions
624 def tag(self, wire, name, revision, message, local, user,
627 def tag(self, wire, name, revision, message, local, user,
625 tag_time, tag_timezone):
628 tag_time, tag_timezone):
626 repo = self._factory.repo(wire)
629 repo = self._factory.repo(wire)
627 ctx = repo[revision]
630 ctx = repo[revision]
628 node = ctx.node()
631 node = ctx.node()
629
632
630 date = (tag_time, tag_timezone)
633 date = (tag_time, tag_timezone)
631 try:
634 try:
632 hg_tag.tag(repo, name, node, message, local, user, date)
635 hg_tag.tag(repo, name, node, message, local, user, date)
633 except Abort as e:
636 except Abort as e:
634 log.exception("Tag operation aborted")
637 log.exception("Tag operation aborted")
635 # Exception can contain unicode which we convert
638 # Exception can contain unicode which we convert
636 raise exceptions.AbortException(repr(e))
639 raise exceptions.AbortException(repr(e))
637
640
638 @reraise_safe_exceptions
641 @reraise_safe_exceptions
639 def tags(self, wire):
642 def tags(self, wire):
640 repo = self._factory.repo(wire)
643 repo = self._factory.repo(wire)
641 return repo.tags()
644 return repo.tags()
642
645
643 @reraise_safe_exceptions
646 @reraise_safe_exceptions
644 def update(self, wire, node=None, clean=False):
647 def update(self, wire, node=None, clean=False):
645 repo = self._factory.repo(wire)
648 repo = self._factory.repo(wire)
646 baseui = self._factory._create_config(wire['config'])
649 baseui = self._factory._create_config(wire['config'])
647 commands.update(baseui, repo, node=node, clean=clean)
650 commands.update(baseui, repo, node=node, clean=clean)
648
651
649 @reraise_safe_exceptions
652 @reraise_safe_exceptions
650 def identify(self, wire):
653 def identify(self, wire):
651 repo = self._factory.repo(wire)
654 repo = self._factory.repo(wire)
652 baseui = self._factory._create_config(wire['config'])
655 baseui = self._factory._create_config(wire['config'])
653 output = io.BytesIO()
656 output = io.BytesIO()
654 baseui.write = output.write
657 baseui.write = output.write
655 # This is required to get a full node id
658 # This is required to get a full node id
656 baseui.debugflag = True
659 baseui.debugflag = True
657 commands.identify(baseui, repo, id=True)
660 commands.identify(baseui, repo, id=True)
658
661
659 return output.getvalue()
662 return output.getvalue()
660
663
661 @reraise_safe_exceptions
664 @reraise_safe_exceptions
662 def pull_cmd(self, wire, source, bookmark=None, branch=None, revision=None,
665 def pull_cmd(self, wire, source, bookmark=None, branch=None, revision=None,
663 hooks=True):
666 hooks=True):
664 repo = self._factory.repo(wire)
667 repo = self._factory.repo(wire)
665 baseui = self._factory._create_config(wire['config'], hooks=hooks)
668 baseui = self._factory._create_config(wire['config'], hooks=hooks)
666
669
667 # Mercurial internally has a lot of logic that checks ONLY if
670 # Mercurial internally has a lot of logic that checks ONLY if
668 # option is defined, we just pass those if they are defined then
671 # option is defined, we just pass those if they are defined then
669 opts = {}
672 opts = {}
670 if bookmark:
673 if bookmark:
671 opts['bookmark'] = bookmark
674 opts['bookmark'] = bookmark
672 if branch:
675 if branch:
673 opts['branch'] = branch
676 opts['branch'] = branch
674 if revision:
677 if revision:
675 opts['rev'] = revision
678 opts['rev'] = revision
676
679
677 commands.pull(baseui, repo, source, **opts)
680 commands.pull(baseui, repo, source, **opts)
678
681
679 @reraise_safe_exceptions
682 @reraise_safe_exceptions
680 def heads(self, wire, branch=None):
683 def heads(self, wire, branch=None):
681 repo = self._factory.repo(wire)
684 repo = self._factory.repo(wire)
682 baseui = self._factory._create_config(wire['config'])
685 baseui = self._factory._create_config(wire['config'])
683 output = io.BytesIO()
686 output = io.BytesIO()
684
687
685 def write(data, **unused_kwargs):
688 def write(data, **unused_kwargs):
686 output.write(data)
689 output.write(data)
687
690
688 baseui.write = write
691 baseui.write = write
689 if branch:
692 if branch:
690 args = [branch]
693 args = [branch]
691 else:
694 else:
692 args = []
695 args = []
693 commands.heads(baseui, repo, template='{node} ', *args)
696 commands.heads(baseui, repo, template='{node} ', *args)
694
697
695 return output.getvalue()
698 return output.getvalue()
696
699
697 @reraise_safe_exceptions
700 @reraise_safe_exceptions
698 def ancestor(self, wire, revision1, revision2):
701 def ancestor(self, wire, revision1, revision2):
699 repo = self._factory.repo(wire)
702 repo = self._factory.repo(wire)
700 changelog = repo.changelog
703 changelog = repo.changelog
701 lookup = repo.lookup
704 lookup = repo.lookup
702 a = changelog.ancestor(lookup(revision1), lookup(revision2))
705 a = changelog.ancestor(lookup(revision1), lookup(revision2))
703 return hex(a)
706 return hex(a)
704
707
705 @reraise_safe_exceptions
708 @reraise_safe_exceptions
706 def push(self, wire, revisions, dest_path, hooks=True,
709 def push(self, wire, revisions, dest_path, hooks=True,
707 push_branches=False):
710 push_branches=False):
708 repo = self._factory.repo(wire)
711 repo = self._factory.repo(wire)
709 baseui = self._factory._create_config(wire['config'], hooks=hooks)
712 baseui = self._factory._create_config(wire['config'], hooks=hooks)
710 commands.push(baseui, repo, dest=dest_path, rev=revisions,
713 commands.push(baseui, repo, dest=dest_path, rev=revisions,
711 new_branch=push_branches)
714 new_branch=push_branches)
712
715
713 @reraise_safe_exceptions
716 @reraise_safe_exceptions
714 def merge(self, wire, revision):
717 def merge(self, wire, revision):
715 repo = self._factory.repo(wire)
718 repo = self._factory.repo(wire)
716 baseui = self._factory._create_config(wire['config'])
719 baseui = self._factory._create_config(wire['config'])
717 repo.ui.setconfig('ui', 'merge', 'internal:dump')
720 repo.ui.setconfig('ui', 'merge', 'internal:dump')
718
721
719 # In case of sub repositories are used mercurial prompts the user in
722 # In case of sub repositories are used mercurial prompts the user in
720 # case of merge conflicts or different sub repository sources. By
723 # case of merge conflicts or different sub repository sources. By
721 # setting the interactive flag to `False` mercurial doesn't prompt the
724 # setting the interactive flag to `False` mercurial doesn't prompt the
722 # used but instead uses a default value.
725 # used but instead uses a default value.
723 repo.ui.setconfig('ui', 'interactive', False)
726 repo.ui.setconfig('ui', 'interactive', False)
724
727
725 commands.merge(baseui, repo, rev=revision)
728 commands.merge(baseui, repo, rev=revision)
726
729
727 @reraise_safe_exceptions
730 @reraise_safe_exceptions
728 def commit(self, wire, message, username, close_branch=False):
731 def commit(self, wire, message, username, close_branch=False):
729 repo = self._factory.repo(wire)
732 repo = self._factory.repo(wire)
730 baseui = self._factory._create_config(wire['config'])
733 baseui = self._factory._create_config(wire['config'])
731 repo.ui.setconfig('ui', 'username', username)
734 repo.ui.setconfig('ui', 'username', username)
732 commands.commit(baseui, repo, message=message, close_branch=close_branch)
735 commands.commit(baseui, repo, message=message, close_branch=close_branch)
733
736
734 @reraise_safe_exceptions
737 @reraise_safe_exceptions
735 def rebase(self, wire, source=None, dest=None, abort=False):
738 def rebase(self, wire, source=None, dest=None, abort=False):
736 repo = self._factory.repo(wire)
739 repo = self._factory.repo(wire)
737 baseui = self._factory._create_config(wire['config'])
740 baseui = self._factory._create_config(wire['config'])
738 repo.ui.setconfig('ui', 'merge', 'internal:dump')
741 repo.ui.setconfig('ui', 'merge', 'internal:dump')
739 rebase.rebase(
742 rebase.rebase(
740 baseui, repo, base=source, dest=dest, abort=abort, keep=not abort)
743 baseui, repo, base=source, dest=dest, abort=abort, keep=not abort)
741
744
742 @reraise_safe_exceptions
745 @reraise_safe_exceptions
743 def bookmark(self, wire, bookmark, revision=None):
746 def bookmark(self, wire, bookmark, revision=None):
744 repo = self._factory.repo(wire)
747 repo = self._factory.repo(wire)
745 baseui = self._factory._create_config(wire['config'])
748 baseui = self._factory._create_config(wire['config'])
746 commands.bookmark(baseui, repo, bookmark, rev=revision, force=True)
749 commands.bookmark(baseui, repo, bookmark, rev=revision, force=True)
General Comments 0
You need to be logged in to leave comments. Login now