def apply_textdelta(self, file_baton, base_checksum, pool=None): # We know coming in here the file must be one of the following options: # 1) Deleted (invalid, fail an assertion) # 2) Missing a base text (bail quick since we have to fetch a full plaintext) # 3) Has a base text in self.current.files, apply deltas base = '' if not self.meta.is_path_valid(self.current.file): return lambda x: None assert self.current.file not in self.current.deleted, ( 'Cannot apply_textdelta to a deleted file: %s' % self.current.file) assert (self.current.file in self.current.files or self.current.file in self.current.missing), '%s not found' % self.current.file if self.current.file in self.current.missing: return lambda x: None base = self.current.files[self.current.file] source = cStringIO.StringIO(base) target = cStringIO.StringIO() self.stream = target handler, baton = delta.svn_txdelta_apply(source, target, None) if not callable(handler): #pragma: no cover raise hgutil.Abort('Error in Subversion bindings: ' 'cannot call handler!') def txdelt_window(window): try: if not self.meta.is_path_valid(self.current.file): return handler(window, baton) # window being None means commit this file if not window: self.current.files[self.current.file] = target.getvalue() except core.SubversionException, e: #pragma: no cover if e.apr_err == core.SVN_ERR_INCOMPLETE_DATA: self.current.missing.add(self.current.file) else: #pragma: no cover raise hgutil.Abort(*e.args) except: #pragma: no cover
def pull(repo, source, heads=[], force=False): """pull new revisions from Subversion""" assert source.capable('subversion') svn_url = source.svnurl # Split off #rev svn_url, heads, checkout = util.parseurl(svn_url, heads) old_encoding = util.swap_out_encoding() # TODO implement skipto support skipto_rev = 0 try: stopat_rev = int(checkout or 0) except ValueError: raise hgutil.Abort('unrecognised Subversion revision %s: ' 'only numbers work.' % checkout) have_replay = not repo.ui.configbool('hgsubversion', 'stupid') if have_replay and not callable( delta.svn_txdelta_apply(None, None, None)[0]): #pragma: no cover repo.ui.status('You are using old Subversion SWIG bindings. Replay ' 'will not work until you upgrade to 1.5.0 or newer. ' 'Falling back to a slower method that may be buggier. ' 'Please upgrade, or contribute a patch to use the ' 'ctypes bindings instead of SWIG.\n') have_replay = False elif not have_replay: repo.ui.note('fetching stupidly...\n') # TODO: do credentials specified in the URL still work? svn = svnrepo.svnremoterepo(repo.ui, svn_url).svn meta = repo.svnmeta(svn.uuid, svn.subdir) layout = repo.ui.config('hgsubversion', 'layout', 'auto') if layout == 'auto': rootlist = svn.list_dir('', revision=(stopat_rev or None)) if sum(map(lambda x: x in rootlist, ('branches', 'tags', 'trunk'))): layout = 'standard' else: layout = 'single' repo.ui.setconfig('hgsubversion', 'layout', layout) repo.ui.note('using %s layout\n' % layout) start = max(meta.revmap.seen, skipto_rev) initializing_repo = meta.revmap.seen <= 0 ui = repo.ui if initializing_repo and start > 0: raise hgutil.Abort('Revision skipping at repository initialization ' 'remains unimplemented.') oldrevisions = len(meta.revmap) cnt = 0 if stopat_rev: total = stopat_rev - start else: total = svn.HEAD - start try: try: # start converting revisions for r in svn.revisions(start=start, stop=stopat_rev): if (r.author is None and r.message == 'This is an empty revision for padding.'): continue tbdelta = meta.update_branch_tag_map_for_rev(r) # got a 502? Try more than once! tries = 0 converted = False while not converted: try: msg = '' if r.message: msg = r.message.strip() if not msg: msg = util.default_commit_msg else: msg = [s.strip() for s in msg.splitlines() if s][0] w = hgutil.termwidth() bits = (r.revnum, r.author, msg) cnt += 1 ui.status(('[r%d] %s: %s\n' % bits)[:w]) util.progress(ui, 'pull', cnt, total=total) meta.save_tbdelta(tbdelta) close = pullfuns[have_replay](ui, meta, svn, r, tbdelta) meta.committags(r, close) for branch, parent in close.iteritems(): if parent in (None, node.nullid): continue meta.delbranch(branch, parent, r) meta.save() converted = True except svnwrap.SubversionRepoCanNotReplay, e: #pragma: no cover ui.status('%s\n' % e.message) stupidmod.print_your_svn_is_old_message(ui) have_replay = False except core.SubversionException, e: #pragma: no cover if (e.apr_err == core.SVN_ERR_RA_DAV_REQUEST_FAILED and '502' in str(e) and tries < 3): tries += 1 ui.status('Got a 502, retrying (%s)\n' % tries) else: raise hgutil.Abort(*e.args)
def apply_txdelta(base, target): handler, baton = delta.svn_txdelta_apply(cStringIO.StringIO(base), target, None) return (lambda window: handler(window, baton))