# HG changeset patch # User Anton Shestakov # Date 1580369530 -25200 # Node ID f159c32bbf2d660a96a87d7e21a2a9a1b4d3db78 # Parent 308c1e09f80f4bb774275fa10702e9880f613304# Parent e9e5751f8de43ccd545c9b621c556412cf053cd0 test-compat: merge mercurial-4.7 into mercurial-4.6 diff -r 308c1e09f80f -r f159c32bbf2d hgext3rd/evolve/cmdrewrite.py --- a/hgext3rd/evolve/cmdrewrite.py Thu Jan 23 17:40:59 2020 +0700 +++ b/hgext3rd/evolve/cmdrewrite.py Thu Jan 30 14:32:10 2020 +0700 @@ -291,8 +291,10 @@ def _touchedbetween(repo, source, dest, match=None): touched = set() - for files in repo.status(source, dest, match=match)[:3]: - touched.update(files) + st = repo.status(source, dest, match=match) + touched.update(st.modified) + touched.update(st.added) + touched.update(st.removed) return touched def _commitfiltered(repo, ctx, match, target=None, message=None, user=None, @@ -364,8 +366,8 @@ # and considering only the files which are changed between oldctx and # ctx, and the status of what changed between oldctx and ctx will help # us in defining the exact behavior - m, a, r = repo.status(oldctx, ctx, match=match)[:3] - for f in m: + st = repo.status(oldctx, ctx, match=match) + for f in st.modified: # These are files which are modified between oldctx and ctx which # contains two cases: 1) Were modified in oldctx and some # modifications are uncommitted @@ -381,7 +383,7 @@ continue ds.normallookup(f) - for f in a: + for f in st.added: # These are the files which are added between oldctx and ctx(new # one), which means the files which were removed in oldctx # but uncommitted completely while making the ctx @@ -394,7 +396,7 @@ continue ds.remove(f) - for f in r: + for f in st.removed: # These are files which are removed between oldctx and ctx, which # means the files which were added in oldctx and were completely # uncommitted in ctx. If a added file is partially uncommitted, that @@ -408,21 +410,21 @@ continue ds.add(f) else: - m, a, r = repo.status(oldctx.p1(), oldctx, match=match)[:3] - for f in m: + st = repo.status(oldctx.p1(), oldctx, match=match) + for f in st.modified: if ds[f] == b'r': # modified + removed -> removed continue ds.normallookup(f) - for f in a: + for f in st.added: if ds[f] == b'r': # added + removed -> unknown ds.drop(f) elif ds[f] != b'a': ds.add(f) - for f in r: + for f in st.removed: if ds[f] == b'a': # removed + added -> normal ds.normallookup(f) @@ -434,8 +436,8 @@ if interactive: # Interactive had different meaning of the variables so restoring the # original meaning to use them - m, a, r = repo.status(oldctx.p1(), oldctx, match=match)[:3] - for f in (m + a): + st = repo.status(oldctx.p1(), oldctx, match=match) + for f in (st.modified + st.added): src = oldctx[f].renamed() if src: oldcopies[f] = src[0] @@ -574,7 +576,7 @@ if opts.get('revert'): hg.updaterepo(repo, newid, True) else: - with repo.dirstate.parentchange(): + with repo.dirstate.parentchange(), compat.parentchange(repo): repo.dirstate.setparents(newid, node.nullid) _uncommitdirstate(repo, old, match, interactive) if not repo[newid].files(): @@ -1230,8 +1232,8 @@ rewriteutil.presplitupdate(repo, ui, prev, ctx) def haschanges(matcher=None): - modified, added, removed, deleted = repo.status(match=matcher)[:4] - return modified or added or removed or deleted + st = repo.status(match=matcher) + return st.modified or st.added or st.removed or st.deleted msg = (b"HG: This is the original pre-split commit message. " b"Edit it as appropriate.\n\n") msg += ctx.description() @@ -1294,10 +1296,12 @@ ui.status(_(b'discarding remaining changes\n')) target = newcommits[0] if pats: - status = repo.status(match=matcher)[:4] + status = repo.status(match=matcher) dirty = set() - for i in status: - dirty.update(i) + dirty.update(status.modified) + dirty.update(status.added) + dirty.update(status.removed) + dirty.update(status.deleted) dirty = sorted(dirty) cmdutil.revert(ui, repo, repo[target], (target, node.nullid), *dirty) @@ -1441,7 +1445,7 @@ tr = repo.currenttransaction() phases.retractboundary(repo, tr, ctx.phase(), [new]) if ctx in repo[None].parents(): - with repo.dirstate.parentchange(): + with repo.dirstate.parentchange(), compat.parentchange(repo): repo.dirstate.setparents(new, node.nullid) @eh.command( diff -r 308c1e09f80f -r f159c32bbf2d hgext3rd/evolve/compat.py --- a/hgext3rd/evolve/compat.py Thu Jan 23 17:40:59 2020 +0700 +++ b/hgext3rd/evolve/compat.py Thu Jan 30 14:32:10 2020 +0700 @@ -6,8 +6,9 @@ Compatibility module """ +import array +import contextlib import inspect -import array from mercurial import ( context, @@ -530,3 +531,12 @@ if util.safehasattr(cl.index, 'get_rev'): return cl.index.get_rev return cl.nodemap.get + +@contextlib.contextmanager +def parentchange(repo): + try: + yield + finally: + # hg <= 5.2 (85c4cd73996b) + if util.safehasattr(repo, '_quick_access_changeid_invalidate'): + repo._quick_access_changeid_invalidate() diff -r 308c1e09f80f -r f159c32bbf2d hgext3rd/evolve/evolvecmd.py --- a/hgext3rd/evolve/evolvecmd.py Thu Jan 23 17:40:59 2020 +0700 +++ b/hgext3rd/evolve/evolvecmd.py Thu Jan 30 14:32:10 2020 +0700 @@ -279,6 +279,7 @@ text += bumped.description() memctx = wctx.tomemctx(text, parents=(prec.node(), nodemod.nullid), + branch=bumped.branch(), date=bumped.date(), extra=bumped.extra(), user=bumped.user()) @@ -295,7 +296,7 @@ flag=obsolete.bumpedfix, operation=b'evolve') bmupdate(newid) # reroute the working copy parent to the new changeset - with repo.dirstate.parentchange(): + with repo.dirstate.parentchange(), compat.parentchange(repo): repo.dirstate.setparents(newid, nodemod.nullid) return (True, replacementnode) @@ -622,7 +623,7 @@ othernode = evolvestate[b'other-divergent'] otherdiv = repo[othernode] - with repo.dirstate.parentchange(): + with repo.dirstate.parentchange(), compat.parentchange(repo): repo.dirstate.setparents(publicnode, nodemod.nullid) dirstatedance(repo, divergent, publicnode, None) # check if node to be committed has changes same as public one @@ -635,7 +636,7 @@ operation=b'evolve') return (True, publicnode) try: - with repo.dirstate.parentchange(): + with repo.dirstate.parentchange(), compat.parentchange(repo): repo.dirstate.setparents(resparent, nodemod.nullid) dirstatedance(repo, divergent, resparent, None) @@ -1005,12 +1006,16 @@ assert tr is not None r = _evolvemerge(repo, orig, dest, pctx, keepbranch) if compat.hasconflict(r): # some conflict - with repo.dirstate.parentchange(): + with repo.dirstate.parentchange(), compat.parentchange(repo): repo.setparents(dest.node(), orig.node()) repo.dirstate.write(tr) # fix up dirstate for copies and renames - copies.duplicatecopies(repo, repo[None], dest.rev(), - orig.p1().rev()) + if util.safehasattr(copies, 'graftcopies'): + copies.graftcopies(repo[None], dest, orig.p1()) + else: + # hg <= 5.2 (2f0a44c69e07) + copies.duplicatecopies(repo, repo[None], dest.rev(), + orig.p1().rev()) dirstatedance(repo, dest, orig.node(), None) hint = _(b"see 'hg help evolve.interrupted'") raise error.InterventionRequired(_(b"unresolved merge conflicts"), @@ -2145,14 +2150,14 @@ # p1 is obsolete and p2 is not obsolete, current working # directory parent should be successor of p1, so we should # set dirstate parents to (succ of p1, p2) - with repo.dirstate.parentchange(): + with repo.dirstate.parentchange(), compat.parentchange(repo): repo.dirstate.setparents(currentp1, ctxparents[1].node()) elif p2obs and not p1obs: # p2 is obsolete and p1 is not obsolete, current working # directory parent should be successor of p2, so we should # set dirstate parents to (succ of p2, p1) - with repo.dirstate.parentchange(): + with repo.dirstate.parentchange(), compat.parentchange(repo): repo.dirstate.setparents(ctxparents[0].node(), currentp1) @@ -2160,12 +2165,12 @@ # both the parents were obsoleted, if orphanmerge is set, we # are processing the second parent first (to keep parent order) if evolvestate.get(b'orphanmerge'): - with repo.dirstate.parentchange(): + with repo.dirstate.parentchange(), compat.parentchange(repo): repo.dirstate.setparents(ctxparents[0].node(), currentp1) pass else: - with repo.dirstate.parentchange(): + with repo.dirstate.parentchange(), compat.parentchange(repo): repo.dirstate.setparents(repo.dirstate.parents()[0], nodemod.nullid) with repo.ui.configoverride(overrides, b'evolve-continue'): diff -r 308c1e09f80f -r f159c32bbf2d tests/test-evolve-orphan-merge.t --- a/tests/test-evolve-orphan-merge.t Thu Jan 23 17:40:59 2020 +0700 +++ b/tests/test-evolve-orphan-merge.t Thu Jan 30 14:32:10 2020 +0700 @@ -529,13 +529,17 @@ case where merge commit becomes orphan with its ancestors pruned up until a point where the other parent of merge is the first non-pruned ancestor. - $ hg evolve -r . +Note: allowing an empty commit here to have the same output on all hg versions. +In newer versions or Mercurial this command would not create a new commit. +hg <= 5.2 (32d11a23c9cf) + + $ hg evolve -r . --config ui.allowemptycommit=true move:[28] merged l and x atop:[0] added hgignore - working directory is now at b61ba77b924a + working directory is now at * (glob) $ hg glog - @ 29:b61ba77b924a merged l and x + @ 29:* merged l and x (glob) | () draft o 0:8fa14d15e168 added hgignore () draft