Example #1
0
    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
Example #2
0
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)
Example #3
0
def apply_txdelta(base, target):
    handler, baton = delta.svn_txdelta_apply(cStringIO.StringIO(base),
                                             target, None)
    return (lambda window: handler(window, baton))
Example #4
0
def apply_txdelta(base, target):
    handler, baton = delta.svn_txdelta_apply(cStringIO.StringIO(base), target,
                                             None)
    return (lambda window: handler(window, baton))