[Bug 6852] New: Unable to disentangle changing_parents and changing_files
mercurial-bugs at mercurial-scm.org
mercurial-bugs at mercurial-scm.org
Mon Nov 20 21:46:28 UTC 2023
https://bz.mercurial-scm.org/show_bug.cgi?id=6852
Bug ID: 6852
Summary: Unable to disentangle changing_parents and
changing_files
Product: Mercurial
Version: 6.4
Hardware: All
OS: All
Status: UNCONFIRMED
Severity: bug
Priority: wish
Component: Mercurial
Assignee: bugzilla at mercurial-scm.org
Reporter: jaraco at jaraco.com
CC: mercurial-devel at mercurial-scm.org
Python Version: ---
Mercurial 6.4 introduced `dirstate.changing_files` and made it mutually
exclusive with `dirstate.changing_parents`. Unfortunately, we've been unable
downstream to successfully honor this new constraint when accounting for
auto-widen operations.
As one particular example, consider an `hg copy` operation. The downstream
implementation adds these overrides for `cmdutil.copy` and
`scmutil.dirstatecopy`:
```
@eh.wrapfunction(cmdutil, 'copy')
def _overridecopy(orig, ui, repo, pats, opts, rename=False):
if not pats or len(pats) == 1 or not citcutil.is_citc(repo):
return orig(ui, repo, pats, opts, rename)
srcs = pats[:-1]
with repo.wlock(), repo.lock(), repo.transaction(b'citcrepo'):
wctx = repo[None]
sourcematcher = scmutil.match(wctx, srcs, opts, globbed=True)
_expandnarrowspecfrommatcher(ui, repo, sourcematcher)
return orig(ui, repo, pats, opts, rename)
@eh.wrapfunction(scmutil, 'dirstatecopy')
def _overridedirstatecopy(orig, ui, repo, wctx, src, dst, **kwargs):
if not citcutil.is_citc(repo):
return orig(ui, repo, wctx, src, dst, **kwargs)
with repo.wlock(), repo.lock(), repo.transaction(b'citcrepo'):
_expand_narrow_for_files(repo, [dst])
return orig(ui, repo, wctx, src, dst, **kwargs)
```
Note that `_expand_narrow_for_files` and `_expandnarrowspecfrommatcher` both
expand the narrow spec:
```
def _expandnarrowspec(repo, addedincludes, expanddirstate=True):
"""Add the specified includes to narrowspec and update the dirstate."""
if not addedincludes:
return
repo.ui.log(
b'google_hgext',
b'expanding narrowspec, adding %s\n',
pycompat.bytestr(addedincludes),
)
# Only start a transaction after we know we're going to be modifying stuff.
with repo.wlock(), repo.lock(), repo.transaction(b'expandnarrowspec'):
# Read the current narrowspec that matches the dirstate.
includes, excludes = repo.narrowpats
# Let's keep any excludes the user may have manually added, even
# though it's not something we recommend or support.
newspec = (includes | addedincludes, excludes)
# Set the new narrowspec (the one we got from CitC), so
# manifest.walk() will be able to find the files to add. The
# manifests are generated on the fly, so we don't need to download
# them first, just add their paths to the narrowspec.
repo.setnarrowpats(*newspec)
if expanddirstate:
updateworkingcopy(repo)
```
Which updates the working copy and thus requires a `changing_parents` context:
```
def updateworkingcopy(repo):
with (
repo.wlock(),
repo.lock(),
repo.transaction(b'auto-widen'),
_changing_parents(repo),
):
narrowspec.updateworkingcopy(repo)
narrowspec.copytoworkingcopy(repo)
```
However, the copy command [unconditionally grabs
`changing_files`](https://foss.heptapod.net/mercurial/mercurial-devel/-/blob/1625fe807c04a490f9516bc8e14140e570c06146/mercurial/commands.py#L2502).
Even if one injects a layer between `commands.copy` and `cmdutil.copy` in order
for `_overridecopy` to inject its changing_parents behavior before
changing_files is entered, `cmdutil.copy` (with the changing_files context)
internally calls `scmutil.dirstatecopy`, which for autowiden requires the
changing_parents` context.
We've tried suppressing the `ProgrammingErrors` raised during
`_expandnarrowspec` (in addition to injecting `_overridecopy` early) in the
hopes that the earlier handling would be sufficient, but it's not the case. It
does seem to be the case that expanding the narrowspec in _overridedirstatecopy
is necessary, even for file copy operations.
Where we have seen some success is in [patching Mercurial to disable the
enforcement](https://gist.github.com/jaraco/a29a40517186e251eeab446ca2400aba)
in `changing_files` and `changing_parents` contexts (bypassing the
enforcement), since presumably these checks were unnecessary before and are
merely a nuisance (for now). Obviously, this condition is suboptimal and could
lead to further incompatibility down the road.
The question we'd like to answer:
How can one implicitly widen the narrow spec (which requires
`changing_parents`) during a `scmutil.dirstatecopy`, which is called by
`cmdutil.copy`, which holds a `changing_files` context?
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the Mercurial-devel
mailing list