Mercurial > hgsubversion
view hgsubversion/replay.py @ 1601:5d8603f080c5
compathacks: add compat code for ui.makeprogress() deprecation
ui.makeprogress() is deprecated and will be dropped in 5.1. This patch adds
compat code for that. The compat code is plain copy of compat code available in
evolve extension.
author | Pulkit Goyal <pulkit@yandex-team.ru> |
---|---|
date | Mon, 04 Feb 2019 20:56:39 +0300 |
parents | 7bb6562feb85 |
children |
line wrap: on
line source
import errno import traceback from mercurial import error as hgerror from mercurial import revlog from mercurial import node from mercurial import context import compathacks import svnexternals import util class MissingPlainTextError(Exception): """Exception raised when the repo lacks a source file required for replaying a txdelta. """ class ReplayException(Exception): """Exception raised when you try and commit but the replay encountered an exception. """ def updateexternals(ui, meta, current): # TODO fix and re-enable externals for single-directory clones if not current.externals or meta.layout == 'single': return # accumulate externals records for all branches revnum = current.rev.revnum branches = {} for path, entry in current.externals.iteritems(): if not meta.is_path_valid(path): continue p, b, bp = meta.split_branch_path(path) if bp not in branches: parent = meta.get_parent_revision(revnum, b) pctx = meta.repo[parent] branches[bp] = (svnexternals.parse(ui, pctx), pctx) branches[bp][0][p] = entry # register externals file changes for bp, (external, pctx) in branches.iteritems(): if bp and bp[-1] != '/': bp += '/' updates = svnexternals.getchanges(ui, meta.repo, pctx, external) for fn, data in updates.iteritems(): path = (bp and bp + fn) or fn if data is not None: current.set(path, data, False, False) else: current.delete(path) def convert_rev(ui, meta, svn, r, tbdelta, firstrun): try: return _convert_rev(ui, meta, svn, r, tbdelta, firstrun) finally: meta.editor.current.close() def _convert_rev(ui, meta, svn, r, tbdelta, firstrun): editor = meta.editor editor.current.clear() editor.current.rev = r editor.setsvn(svn) if firstrun and meta.revmap.firstpulled <= 0: # We know nothing about this project, so fetch everything before # trying to apply deltas. ui.debug('replay: fetching full revision\n') svn.get_revision(r.revnum, editor) else: svn.get_replay(r.revnum, editor, meta.revmap.firstpulled) editor.close() current = editor.current updateexternals(ui, meta, current) if current.exception is not None: # pragma: no cover traceback.print_exception(*current.exception) raise ReplayException() files_to_commit = current.files() branch_batches = {} rev = current.rev date = meta.fixdate(rev.date) # build up the branches that have files on them failoninvalid = ui.configbool('hgsubversion', 'failoninvalidreplayfile', False) for f in files_to_commit: if not meta.is_path_valid(f): if failoninvalid: raise hgerror.Abort('file %s should not be in commit list' % f) continue p, b = meta.split_branch_path(f)[:2] if b not in branch_batches: branch_batches[b] = [] if p: branch_batches[b].append((p, f)) closebranches = {} for branch in tbdelta['branches'][1]: branchedits = meta.revmap.branchedits(branch, rev.revnum) if len(branchedits) < 1: # can't close a branch that never existed continue ha = branchedits[0][1] closebranches[branch] = ha extraempty = (set(tbdelta['branches'][0]) - (set(current.emptybranches) | set(branch_batches.keys()))) current.emptybranches.update([(x, False) for x in extraempty]) # 1. handle normal commits closedrevs = closebranches.values() for branch, files in branch_batches.iteritems(): if branch in current.emptybranches and files: del current.emptybranches[branch] if meta.skipbranch(branch): # make sure we also get rid of it from emptybranches if branch in current.emptybranches: del current.emptybranches[branch] continue files = dict(files) parents = meta.get_parent_revision(rev.revnum, branch), revlog.nullid if parents[0] in closedrevs and branch in meta.closebranches: continue extra = meta.genextra(rev.revnum, branch) tag = None if branch is not None: # New regular tag without modifications, it will be committed by # svnmeta.committag(), we can skip the whole branch for now tag = meta.get_path_tag(meta.remotename(branch)) if (tag and tag not in meta.tags and branch not in meta.branches and branch not in meta.repo.branchmap() and not files): continue parentctx = meta.repo[parents[0]] if tag: if parentctx.node() == node.nullid: continue extra.update({'branch': parentctx.extra().get('branch', None), 'close': 1}) def filectxfn(repo, memctx, path): current_file = files[path] try: data, isexec, islink, copied = current.pop(current_file) except IOError: return compathacks.filectxfn_deleted_reraise(memctx) if isexec is None or islink is None: flags = parentctx.flags(path) if isexec is None: isexec = 'x' in flags if islink is None: islink = 'l' in flags if data is not None: if islink: if data.startswith('link '): data = data[len('link '):] else: ui.debug('file marked as link, but may contain data: ' '%s\n' % current_file) else: data = parentctx.filectx(path).data() return compathacks.makememfilectx(repo, memctx=memctx, path=path, data=data, islink=islink, isexec=isexec, copied=copied) meta.mapbranch(extra) if 'branch' not in extra: extra['branch'] = 'default' current_ctx = context.memctx(meta.repo, parents, util.forceutf8(meta.getmessage(rev)), [util.forceutf8(f) for f in files.keys()], filectxfn, util.forceutf8(meta.authors[rev.author]), date, extra) new_hash = meta.repo.svn_commitctx(current_ctx) util.describe_commit(ui, new_hash, branch) if (rev.revnum, branch) not in meta.revmap and not tag: meta.revmap[rev.revnum, branch] = new_hash if tag: meta.movetag(tag, new_hash, rev, date) meta.addedtags.pop(tag, None) # 2. handle branches that need to be committed without any files for branch in current.emptybranches: if meta.skipbranch(branch): continue ha = meta.get_parent_revision(rev.revnum, branch) if ha == node.nullid: continue files = [] def del_all_files(*args): raise IOError(errno.ENOENT, 'deleting all files') # True here means nuke all files. This happens when you # replace a branch root with an empty directory if current.emptybranches[branch]: files = meta.repo[ha].files() extra = meta.genextra(rev.revnum, branch) meta.mapbranch(extra) current_ctx = context.memctx(meta.repo, (ha, node.nullid), util.forceutf8(meta.getmessage(rev)), [util.forceutf8(f) for f in files], del_all_files, util.forceutf8(meta.authors[rev.author]), date, extra) new_hash = meta.repo.svn_commitctx(current_ctx) util.describe_commit(ui, new_hash, branch) if (rev.revnum, branch) not in meta.revmap: meta.revmap[rev.revnum, branch] = new_hash return closebranches