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