diff --git a/hgext/uncommit.py b/hgext/uncommit.py --- a/hgext/uncommit.py +++ b/hgext/uncommit.py @@ -99,44 +99,6 @@ extra=ctx.extra()) return repo.commitctx(new) -def _movedirstate(repo, newctx, match=None): - """Move the dirstate to newctx and adjust it as necessary.""" - oldctx = repo['.'] - ds = repo.dirstate - ds.setparents(newctx.node(), node.nullid) - copies = dict(ds.copies()) - s = newctx.status(oldctx, match=match) - for f in s.modified: - if ds[f] == 'r': - # modified + removed -> removed - continue - ds.normallookup(f) - - for f in s.added: - if ds[f] == 'r': - # added + removed -> unknown - ds.drop(f) - elif ds[f] != 'a': - ds.add(f) - - for f in s.removed: - if ds[f] == 'a': - # removed + added -> normal - ds.normallookup(f) - elif ds[f] != 'r': - ds.remove(f) - - # Merge old parent and old working dir copies - oldcopies = copiesmod.pathcopies(newctx, oldctx, match) - oldcopies.update(copies) - copies = dict((dst, oldcopies.get(src, src)) - for dst, src in oldcopies.iteritems()) - # Adjust the dirstate copies - for dst, src in copies.iteritems(): - if (src not in newctx or dst in newctx or ds[dst] != 'a'): - src = None - ds.copy(src, dst) - @command('uncommit', [('', 'keep', None, _('allow an empty commit after uncommiting')), ('', 'allow-dirty-working-copy', False, @@ -193,7 +155,7 @@ mapping[old.node()] = () with repo.dirstate.parentchange(): - _movedirstate(repo, repo[newid], match) + scmutil.movedirstate(repo, repo[newid], match) scmutil.cleanupnodes(repo, mapping, 'uncommit', fixphase=True) @@ -255,7 +217,7 @@ dirstate = repo.dirstate with dirstate.parentchange(): - _movedirstate(repo, newpredctx) + scmutil.movedirstate(repo, newpredctx) mapping = {curctx.node(): (newprednode,)} scmutil.cleanupnodes(repo, mapping, 'unamend', fixphase=True) diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -28,6 +28,7 @@ ) from . import ( + copies as copiesmod, encoding, error, match as matchmod, @@ -1253,6 +1254,44 @@ elif not dryrun: wctx.copy(origsrc, dst) +def movedirstate(repo, newctx, match=None): + """Move the dirstate to newctx and adjust it as necessary.""" + oldctx = repo['.'] + ds = repo.dirstate + ds.setparents(newctx.node(), nullid) + copies = dict(ds.copies()) + s = newctx.status(oldctx, match=match) + for f in s.modified: + if ds[f] == 'r': + # modified + removed -> removed + continue + ds.normallookup(f) + + for f in s.added: + if ds[f] == 'r': + # added + removed -> unknown + ds.drop(f) + elif ds[f] != 'a': + ds.add(f) + + for f in s.removed: + if ds[f] == 'a': + # removed + added -> normal + ds.normallookup(f) + elif ds[f] != 'r': + ds.remove(f) + + # Merge old parent and old working dir copies + oldcopies = copiesmod.pathcopies(newctx, oldctx, match) + oldcopies.update(copies) + copies = dict((dst, oldcopies.get(src, src)) + for dst, src in oldcopies.iteritems()) + # Adjust the dirstate copies + for dst, src in copies.iteritems(): + if (src not in newctx or dst in newctx or ds[dst] != 'a'): + src = None + ds.copy(src, dst) + def writerequires(opener, requirements): with opener('requires', 'w', atomictemp=True) as fp: for r in sorted(requirements):