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