comparison hgext/convert/subversion.py @ 26587:56b2bcea2529

error: get Abort from 'error' instead of 'util' The home of 'Abort' is 'error' not 'util' however, a lot of code seems to be confused about that and gives all the credit to 'util' instead of the hardworking 'error'. In a spirit of equity, we break the cycle of injustice and give back to 'error' the respect it deserves. And screw that 'util' poser. For great justice.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Thu, 08 Oct 2015 12:55:45 -0700
parents baea47cafe75
children a434f15dc0f4
comparison
equal deleted inserted replaced
26586:d51c658d3f04 26587:56b2bcea2529
4 4
5 import os, re, sys, tempfile, urllib, urllib2 5 import os, re, sys, tempfile, urllib, urllib2
6 import xml.dom.minidom 6 import xml.dom.minidom
7 import cPickle as pickle 7 import cPickle as pickle
8 8
9 from mercurial import strutil, scmutil, util, encoding 9 from mercurial import strutil, scmutil, util, encoding, error
10 from mercurial.i18n import _ 10 from mercurial.i18n import _
11 11
12 propertycache = util.propertycache 12 propertycache = util.propertycache
13 13
14 # Subversion stuff. Works best with very recent Python SVN bindings 14 # Subversion stuff. Works best with very recent Python SVN bindings
139 def debugsvnlog(ui, **opts): 139 def debugsvnlog(ui, **opts):
140 """Fetch SVN log in a subprocess and channel them back to parent to 140 """Fetch SVN log in a subprocess and channel them back to parent to
141 avoid memory collection issues. 141 avoid memory collection issues.
142 """ 142 """
143 if svn is None: 143 if svn is None:
144 raise util.Abort(_('debugsvnlog could not load Subversion python ' 144 raise error.Abort(_('debugsvnlog could not load Subversion python '
145 'bindings')) 145 'bindings'))
146 146
147 util.setbinary(sys.stdin) 147 util.setbinary(sys.stdin)
148 util.setbinary(sys.stdout) 148 util.setbinary(sys.stdout)
149 args = decodeargs(sys.stdin.read()) 149 args = decodeargs(sys.stdin.read())
157 def __iter__(self): 157 def __iter__(self):
158 while True: 158 while True:
159 try: 159 try:
160 entry = pickle.load(self._stdout) 160 entry = pickle.load(self._stdout)
161 except EOFError: 161 except EOFError:
162 raise util.Abort(_('Mercurial failed to run itself, check' 162 raise error.Abort(_('Mercurial failed to run itself, check'
163 ' hg executable is in PATH')) 163 ' hg executable is in PATH'))
164 try: 164 try:
165 orig_paths, revnum, author, date, message = entry 165 orig_paths, revnum, author, date, message = entry
166 except (TypeError, ValueError): 166 except (TypeError, ValueError):
167 if entry is None: 167 if entry is None:
168 break 168 break
169 raise util.Abort(_("log stream exception '%s'") % entry) 169 raise error.Abort(_("log stream exception '%s'") % entry)
170 yield entry 170 yield entry
171 171
172 def close(self): 172 def close(self):
173 if self._stdout: 173 if self._stdout:
174 self._stdout.close() 174 self._stdout.close()
325 "to libsvn version %s") 325 "to libsvn version %s")
326 % (self.url, svnversion)) 326 % (self.url, svnversion))
327 327
328 if revs: 328 if revs:
329 if len(revs) > 1: 329 if len(revs) > 1:
330 raise util.Abort(_('subversion source does not support ' 330 raise error.Abort(_('subversion source does not support '
331 'specifying multiple revisions')) 331 'specifying multiple revisions'))
332 try: 332 try:
333 latest = int(revs[0]) 333 latest = int(revs[0])
334 except ValueError: 334 except ValueError:
335 raise util.Abort(_('svn: revision %s is not an integer') % 335 raise error.Abort(_('svn: revision %s is not an integer') %
336 revs[0]) 336 revs[0])
337 337
338 self.trunkname = self.ui.config('convert', 'svn.trunk', 338 self.trunkname = self.ui.config('convert', 'svn.trunk',
339 'trunk').strip('/') 339 'trunk').strip('/')
340 self.startrev = self.ui.config('convert', 'svn.startrev', default=0) 340 self.startrev = self.ui.config('convert', 'svn.startrev', default=0)
341 try: 341 try:
342 self.startrev = int(self.startrev) 342 self.startrev = int(self.startrev)
343 if self.startrev < 0: 343 if self.startrev < 0:
344 self.startrev = 0 344 self.startrev = 0
345 except ValueError: 345 except ValueError:
346 raise util.Abort(_('svn: start revision %s is not an integer') 346 raise error.Abort(_('svn: start revision %s is not an integer')
347 % self.startrev) 347 % self.startrev)
348 348
349 try: 349 try:
350 self.head = self.latest(self.module, latest) 350 self.head = self.latest(self.module, latest)
351 except SvnPathNotFound: 351 except SvnPathNotFound:
352 self.head = None 352 self.head = None
353 if not self.head: 353 if not self.head:
354 raise util.Abort(_('no revision found in module %s') 354 raise error.Abort(_('no revision found in module %s')
355 % self.module) 355 % self.module)
356 self.last_changed = self.revnum(self.head) 356 self.last_changed = self.revnum(self.head)
357 357
358 self._changescache = (None, None) 358 self._changescache = (None, None)
359 359
394 if not self.exists(path, rev): 394 if not self.exists(path, rev):
395 if self.module.endswith(path) and name == 'trunk': 395 if self.module.endswith(path) and name == 'trunk':
396 # we are converting from inside this directory 396 # we are converting from inside this directory
397 return None 397 return None
398 if cfgpath: 398 if cfgpath:
399 raise util.Abort(_('expected %s to be at %r, but not found') 399 raise error.Abort(_('expected %s to be at %r, but not found'
400 % (name, path)) 400 ) % (name, path))
401 return None 401 return None
402 self.ui.note(_('found %s at %r\n') % (name, path)) 402 self.ui.note(_('found %s at %r\n') % (name, path))
403 return path 403 return path
404 404
405 rev = optrev(self.last_changed) 405 rev = optrev(self.last_changed)
413 if trunk: 413 if trunk:
414 oldmodule = self.module or '' 414 oldmodule = self.module or ''
415 self.module += '/' + trunk 415 self.module += '/' + trunk
416 self.head = self.latest(self.module, self.last_changed) 416 self.head = self.latest(self.module, self.last_changed)
417 if not self.head: 417 if not self.head:
418 raise util.Abort(_('no revision found in module %s') 418 raise error.Abort(_('no revision found in module %s')
419 % self.module) 419 % self.module)
420 420
421 # First head in the list is the module's head 421 # First head in the list is the module's head
422 self.heads = [self.head] 422 self.heads = [self.head]
423 if self.tags is not None: 423 if self.tags is not None:
440 (branch, self.revnum(brevid))) 440 (branch, self.revnum(brevid)))
441 self.heads.append(brevid) 441 self.heads.append(brevid)
442 442
443 if self.startrev and self.heads: 443 if self.startrev and self.heads:
444 if len(self.heads) > 1: 444 if len(self.heads) > 1:
445 raise util.Abort(_('svn: start revision is not supported ' 445 raise error.Abort(_('svn: start revision is not supported '
446 'with more than one branch')) 446 'with more than one branch'))
447 revnum = self.revnum(self.heads[0]) 447 revnum = self.revnum(self.heads[0])
448 if revnum < self.startrev: 448 if revnum < self.startrev:
449 raise util.Abort( 449 raise error.Abort(
450 _('svn: no revision found after start revision %d') 450 _('svn: no revision found after start revision %d')
451 % self.startrev) 451 % self.startrev)
452 452
453 return self.heads 453 return self.heads
454 454
500 stop = self.lastrevs.get(module, 0) 500 stop = self.lastrevs.get(module, 0)
501 if revnum < stop: 501 if revnum < stop:
502 stop = revnum + 1 502 stop = revnum + 1
503 self._fetch_revisions(revnum, stop) 503 self._fetch_revisions(revnum, stop)
504 if rev not in self.commits: 504 if rev not in self.commits:
505 raise util.Abort(_('svn: revision %s not found') % revnum) 505 raise error.Abort(_('svn: revision %s not found') % revnum)
506 revcommit = self.commits[rev] 506 revcommit = self.commits[rev]
507 # caller caches the result, so free it here to release memory 507 # caller caches the result, so free it here to release memory
508 del self.commits[rev] 508 del self.commits[rev]
509 return revcommit 509 return revcommit
510 510
511 def checkrevformat(self, revstr, mapname='splicemap'): 511 def checkrevformat(self, revstr, mapname='splicemap'):
512 """ fails if revision format does not match the correct format""" 512 """ fails if revision format does not match the correct format"""
513 if not re.match(r'svn:[0-9a-f]{8,8}-[0-9a-f]{4,4}-' 513 if not re.match(r'svn:[0-9a-f]{8,8}-[0-9a-f]{4,4}-'
514 '[0-9a-f]{4,4}-[0-9a-f]{4,4}-[0-9a-f]' 514 '[0-9a-f]{4,4}-[0-9a-f]{4,4}-[0-9a-f]'
515 '{12,12}(.*)\@[0-9]+$',revstr): 515 '{12,12}(.*)\@[0-9]+$',revstr):
516 raise util.Abort(_('%s entry %s is not a valid revision' 516 raise error.Abort(_('%s entry %s is not a valid revision'
517 ' identifier') % (mapname, revstr)) 517 ' identifier') % (mapname, revstr))
518 518
519 def numcommits(self): 519 def numcommits(self):
520 return int(self.head.rsplit('@', 1)[1]) - self.startrev 520 return int(self.head.rsplit('@', 1)[1]) - self.startrev
521 521
949 except SvnPathNotFound: 949 except SvnPathNotFound:
950 pass 950 pass
951 except SubversionException as xxx_todo_changeme: 951 except SubversionException as xxx_todo_changeme:
952 (inst, num) = xxx_todo_changeme.args 952 (inst, num) = xxx_todo_changeme.args
953 if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION: 953 if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
954 raise util.Abort(_('svn: branch has no revision %s') 954 raise error.Abort(_('svn: branch has no revision %s')
955 % to_revnum) 955 % to_revnum)
956 raise 956 raise
957 957
958 def getfile(self, file, rev): 958 def getfile(self, file, rev):
959 # TODO: ra.get_file transmits the whole file instead of diffs. 959 # TODO: ra.get_file transmits the whole file instead of diffs.
1050 stdin, stdout = util.popen2(util.quotecommand(cmd)) 1050 stdin, stdout = util.popen2(util.quotecommand(cmd))
1051 stdin.write(arg) 1051 stdin.write(arg)
1052 try: 1052 try:
1053 stdin.close() 1053 stdin.close()
1054 except IOError: 1054 except IOError:
1055 raise util.Abort(_('Mercurial failed to run itself, check' 1055 raise error.Abort(_('Mercurial failed to run itself, check'
1056 ' hg executable is in PATH')) 1056 ' hg executable is in PATH'))
1057 return logstream(stdout) 1057 return logstream(stdout)
1058 1058
1059 pre_revprop_change = '''#!/bin/sh 1059 pre_revprop_change = '''#!/bin/sh
1060 1060
1300 except AttributeError: 1300 except AttributeError:
1301 if parents and not files: 1301 if parents and not files:
1302 return parents[0] 1302 return parents[0]
1303 self.ui.warn(_('unexpected svn output:\n')) 1303 self.ui.warn(_('unexpected svn output:\n'))
1304 self.ui.warn(output) 1304 self.ui.warn(output)
1305 raise util.Abort(_('unable to cope with svn output')) 1305 raise error.Abort(_('unable to cope with svn output'))
1306 if commit.rev: 1306 if commit.rev:
1307 self.run('propset', 'hg:convert-rev', commit.rev, 1307 self.run('propset', 'hg:convert-rev', commit.rev,
1308 revprop=True, revision=rev) 1308 revprop=True, revision=rev)
1309 if commit.branch and commit.branch != 'default': 1309 if commit.branch and commit.branch != 'default':
1310 self.run('propset', 'hg:convert-branch', commit.branch, 1310 self.run('propset', 'hg:convert-branch', commit.branch,
1327 def hascommitforsplicemap(self, rev): 1327 def hascommitforsplicemap(self, rev):
1328 # This is not correct as one can convert to an existing subversion 1328 # This is not correct as one can convert to an existing subversion
1329 # repository and childmap would not list all revisions. Too bad. 1329 # repository and childmap would not list all revisions. Too bad.
1330 if rev in self.childmap: 1330 if rev in self.childmap:
1331 return True 1331 return True
1332 raise util.Abort(_('splice map revision %s not found in subversion ' 1332 raise error.Abort(_('splice map revision %s not found in subversion '
1333 'child map (revision lookups are not implemented)') 1333 'child map (revision lookups are not implemented)')
1334 % rev) 1334 % rev)