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
--- 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)
--- 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):