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