Mercurial > hg
changeset 47597:4b76f5ca79c4
mq: update the dirstate and its parent within a `parentchange` context
This is more correct, and move our plan of separated API for different dirstate
usage forward.
note: maybe the `parentchange` context manager should replace the dirstateguard
entirely ? (in this case we should probably deprecated dirstateguard).
Differential Revision: https://phab.mercurial-scm.org/D11017
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 08 Jul 2021 03:42:14 +0200 |
parents | 791e2333d3d3 |
children | 305356a7ec99 |
files | hgext/mq.py |
diffstat | 1 files changed, 63 insertions(+), 61 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/mq.py Thu Jul 08 01:20:46 2021 +0200 +++ b/hgext/mq.py Thu Jul 08 03:42:14 2021 +0200 @@ -2002,67 +2002,69 @@ bmlist = repo[top].bookmarks() - dsguard = None - try: - dsguard = dirstateguard.dirstateguard(repo, b'mq.refresh') - if diffopts.git or diffopts.upgrade: - copies = {} - for dst in a: - src = repo.dirstate.copied(dst) - # during qfold, the source file for copies may - # be removed. Treat this as a simple add. - if src is not None and src in repo.dirstate: - copies.setdefault(src, []).append(dst) - repo.dirstate.add(dst) - # remember the copies between patchparent and qtip - for dst in aaa: - src = ctx[dst].copysource() - if src: - copies.setdefault(src, []).extend( - copies.get(dst, []) - ) - if dst in a: - copies[src].append(dst) - # we can't copy a file created by the patch itself - if dst in copies: - del copies[dst] - for src, dsts in pycompat.iteritems(copies): - for dst in dsts: - repo.dirstate.copy(src, dst) - else: - for dst in a: - repo.dirstate.add(dst) - # Drop useless copy information - for f in list(repo.dirstate.copies()): - repo.dirstate.copy(None, f) - for f in r: - repo.dirstate.remove(f) - # if the patch excludes a modified file, mark that - # file with mtime=0 so status can see it. - mm = [] - for i in pycompat.xrange(len(m) - 1, -1, -1): - if not match1(m[i]): - mm.append(m[i]) - del m[i] - for f in m: - repo.dirstate.normal(f) - for f in mm: - repo.dirstate.normallookup(f) - for f in forget: - repo.dirstate.drop(f) - - user = ph.user or ctx.user() - - oldphase = repo[top].phase() - - # assumes strip can roll itself back if interrupted - repo.setparents(*cparents) - self.applied.pop() - self.applieddirty = True - strip(self.ui, repo, [top], update=False, backup=False) - dsguard.close() - finally: - release(dsguard) + with repo.dirstate.parentchange(): + # XXX do we actually need the dirstateguard + dsguard = None + try: + dsguard = dirstateguard.dirstateguard(repo, b'mq.refresh') + if diffopts.git or diffopts.upgrade: + copies = {} + for dst in a: + src = repo.dirstate.copied(dst) + # during qfold, the source file for copies may + # be removed. Treat this as a simple add. + if src is not None and src in repo.dirstate: + copies.setdefault(src, []).append(dst) + repo.dirstate.add(dst) + # remember the copies between patchparent and qtip + for dst in aaa: + src = ctx[dst].copysource() + if src: + copies.setdefault(src, []).extend( + copies.get(dst, []) + ) + if dst in a: + copies[src].append(dst) + # we can't copy a file created by the patch itself + if dst in copies: + del copies[dst] + for src, dsts in pycompat.iteritems(copies): + for dst in dsts: + repo.dirstate.copy(src, dst) + else: + for dst in a: + repo.dirstate.add(dst) + # Drop useless copy information + for f in list(repo.dirstate.copies()): + repo.dirstate.copy(None, f) + for f in r: + repo.dirstate.remove(f) + # if the patch excludes a modified file, mark that + # file with mtime=0 so status can see it. + mm = [] + for i in pycompat.xrange(len(m) - 1, -1, -1): + if not match1(m[i]): + mm.append(m[i]) + del m[i] + for f in m: + repo.dirstate.normal(f) + for f in mm: + repo.dirstate.normallookup(f) + for f in forget: + repo.dirstate.drop(f) + + user = ph.user or ctx.user() + + oldphase = repo[top].phase() + + # assumes strip can roll itself back if interrupted + repo.setparents(*cparents) + self.applied.pop() + self.applieddirty = True + strip(self.ui, repo, [top], update=False, backup=False) + dsguard.close() + finally: + release(dsguard) try: # might be nice to attempt to roll back strip after this