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