Commit 2f0a44c69e0 by Martin von Zweigbergk

copies: replace duplicatecopies() by function that takes contexts

The callers mostly have context objects, so let's avoid looking up the
same context objects inside `duplicatecopies()`.

I also renamed the function to `graftcopies()` since I think that
better matches its purpose. I did it in the same commit so it's easier
for extensions to switch between the functions.

Differential Revision: https://phab.mercurial-scm.org/D7858
parent bd22e90c54b
......@@ -734,7 +734,8 @@ def replacerev(ui, repo, ctx, filedata, replacements):
extra[b'fix_source'] = ctx.hex()
wctx = context.overlayworkingctx(repo)
wctx.setbase(repo[newp1node])
newp1ctx = repo[newp1node]
wctx.setbase(newp1ctx)
merge.update(
repo,
ctx.rev(),
......@@ -744,9 +745,7 @@ def replacerev(ui, repo, ctx, filedata, replacements):
mergeancestor=False,
wc=wctx,
)
copies.duplicatecopies(
repo, wctx, ctx.rev(), ctx.p1().rev(), skiprev=newp1node
)
copies.graftcopies(repo, wctx, ctx, ctx.p1(), skip=newp1ctx)
for path in filedata.keys():
fctx = ctx[path]
......
......@@ -1481,7 +1481,8 @@ def rebasenode(repo, rev, p1, base, collapse, dest, wctx):
# as well as other data we litter on it in other places.
wctx = repo[None]
repo.dirstate.write(repo.currenttransaction())
repo.ui.debug(b" merge against %d:%s\n" % (rev, repo[rev]))
ctx = repo[rev]
repo.ui.debug(b" merge against %d:%s\n" % (rev, ctx))
if base is not None:
repo.ui.debug(b" detach base %d:%s\n" % (base, repo[base]))
# When collapsing in-place, the parent is the common ancestor, we
......@@ -1496,16 +1497,16 @@ def rebasenode(repo, rev, p1, base, collapse, dest, wctx):
labels=[b'dest', b'source'],
wc=wctx,
)
destctx = repo[dest]
if collapse:
copies.duplicatecopies(repo, wctx, rev, dest)
copies.graftcopies(repo, wctx, ctx, destctx)
else:
# If we're not using --collapse, we need to
# duplicate copies between the revision we're
# rebasing and its first parent, but *not*
# duplicate any copies that have already been
# performed in the destination.
p1rev = repo[rev].p1().rev()
copies.duplicatecopies(repo, wctx, rev, p1rev, skiprev=dest)
copies.graftcopies(repo, wctx, ctx, ctx.p1(), skip=destctx)
return stats
......
......@@ -856,26 +856,26 @@ def _related(f1, f2):
return False
def duplicatecopies(repo, wctx, rev, fromrev, skiprev=None):
"""reproduce copies from fromrev to rev in the dirstate
def graftcopies(repo, wctx, ctx, base, skip=None):
"""reproduce copies between base and ctx in the wctx
If skiprev is specified, it's a revision that should be used to
filter copy records. Any copies that occur between fromrev and
skiprev will not be duplicated, even if they appear in the set of
copies between fromrev and rev.
If skip is specified, it's a revision that should be used to
filter copy records. Any copies that occur between base and
skip will not be duplicated, even if they appear in the set of
copies between base and ctx.
"""
exclude = {}
ctraceconfig = repo.ui.config(b'experimental', b'copytrace')
bctrace = stringutil.parsebool(ctraceconfig)
if skiprev is not None and (
if skip is not None and (
ctraceconfig == b'heuristics' or bctrace or bctrace is None
):
# copytrace='off' skips this line, but not the entire function because
# the line below is O(size of the repo) during a rebase, while the rest
# of the function is much faster (and is required for carrying copy
# metadata across the rebase anyway).
exclude = pathcopies(repo[fromrev], repo[skiprev])
for dst, src in pycompat.iteritems(pathcopies(repo[fromrev], repo[rev])):
exclude = pathcopies(base, skip)
for dst, src in pycompat.iteritems(pathcopies(base, ctx)):
if dst in exclude:
continue
if dst in wctx:
......
......@@ -2635,7 +2635,7 @@ def graft(
repo.setparents(pctx.node(), pother)
repo.dirstate.write(repo.currenttransaction())
# fix up dirstate for copies and renames
copies.duplicatecopies(repo, wctx, ctx.rev(), base.rev())
copies.graftcopies(repo, wctx, ctx, base)
return stats
......
......@@ -28,3 +28,7 @@
* `n in revlog.nodemap` becomes `revlog.index.has_node(n)`,
* `revlog.nodemap[n]` becomes `revlog.index.rev(n)`,
* `revlog.nodemap.get(n)` becomes `revlog.index.get_rev(n)`.
* `copies.duplicatecopies()` was renamed to
`copies.graftcopies()`. Its arguments changed from revision numbers
to context objects.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment