# HG changeset patch # User Martin von Zweigbergk # Date 1552322549 25200 # Node ID 232d4b9d391a6d73f8ae81af238766540c386f31 # Parent a791623458efab59f438c4fd60d292af24a9706b uncommit: move _movedirstate() to scmutil for reuse The function should be applicable generically when moving from one commit to another. I'll try to add more callers when I find time. I'm not convinced it's handling all the cases correctly, but we should have a generic function for this kind of operation, so I think it belongs somewhere in core (not in the uncommit extension). Differential Revision: https://phab.mercurial-scm.org/D6119 diff -r a791623458ef -r 232d4b9d391a hgext/uncommit.py --- a/hgext/uncommit.py Mon Mar 11 09:20:26 2019 -0700 +++ b/hgext/uncommit.py Mon Mar 11 09:42:29 2019 -0700 @@ -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 -r a791623458ef -r 232d4b9d391a mercurial/scmutil.py --- a/mercurial/scmutil.py Mon Mar 11 09:20:26 2019 -0700 +++ b/mercurial/scmutil.py Mon Mar 11 09:42:29 2019 -0700 @@ -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):