The changelog object can store recently added revisions in memory
until the transaction is committed. We don't want to lose those
changes even if repo.invalidate(clearfilecache=True), so let's skip
the changelog when it has such 'delayed' changes.
Details
- Reviewers
quark indygreg - Group Reviewers
hg-reviewers - Commits
- rHG01a1c4e66816: repo: skip invalidation of changelog if it has 'delayed' changes (API)
Diff Detail
- Repository
- rHG Mercurial
- Lint
Automatic diff as part of commit; lint not applicable. - Unit
Automatic diff as part of commit; unit tests not applicable.
Event Timeline
Good question. I spent quite a lot of time trying to see if that would work. It was easy to get all tests to pass, but I couldn't get it to work with our extensions (and it didn't seem to be the extensions' faults). One problem was that cl.delayupdate() would happen again after repo.invalidate() and delayupdate() doesn't have a way of taking revisions already written to .a into account (it doesn't check if self._divert is set). Also, I think that writing to .a would mean that hooks would see changes they were not meant to see.
I think this is fine as a workaround now. It's better than losing data.
tests/test-context.py | ||
---|---|---|
185 | Seems like f.write(b'4') is better. |
Aside from the test issue pointed out by @quark, I think this seems reasonable.
@martinvonz is correct that writing the .i.a file has hooks implications. We definitely need to keep the changes in memory.
I'm kinda surprised we haven't hit this bug in core. Unless you can find somewhere we can hit it, I'm leaning towards not taking this on stable.
FWIW, these are the kinds of caching bugs that I think a refactor of the repo class into immutable and mutable components can help prevent. The whole property cache mechanism for various things on localrepo is a bug's nest.
Can this be queued for default now?
tests/test-context.py | ||
---|---|---|
185 | Oops, definitely. I also updated the line above for consistency. I don't know if other places should be updated, so I didn't. |
Seems like f.write(b'4') is better.