comparison hgext/largefiles/overrides.py @ 50029:28dfb2df4ab9

commit: use `dirstate.change_files` to scope the associated `addremove` This was significantly more complicated than I expected, because multiple extensions get in the way. I introduced a context that lazily open the transaction and associated context to work around these complication. See the inline documentation for details. Introducing the wrapping transaction remove the need for dirstate-guard (one of the ultimate goal of all this), and slightly affect the result of a `hg rollback` after a `hg commit --addremove`. That last part is deemed fine. It aligns the behavior with what happens after a failed `hg commit --addremove` and nobody should be using `hg rollback` anyway. The small output change in the test come from the different transaction timing and fact the transaction now backup the dirstate before the addremove, which might mean "no file to backup" when the repository starts from an empty state.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 15 Feb 2023 11:51:58 +0100
parents 0b4a6912292e
children c3c8ac540513
comparison
equal deleted inserted replaced
50028:a46dfc2b58a3 50029:28dfb2df4ab9
1543 with lfstatus(repo): 1543 with lfstatus(repo):
1544 orig(ui, repo, *pats, **opts) 1544 orig(ui, repo, *pats, **opts)
1545 1545
1546 1546
1547 @eh.wrapfunction(scmutil, b'addremove') 1547 @eh.wrapfunction(scmutil, b'addremove')
1548 def scmutiladdremove(orig, repo, matcher, prefix, uipathfn, opts=None): 1548 def scmutiladdremove(
1549 orig,
1550 repo,
1551 matcher,
1552 prefix,
1553 uipathfn,
1554 opts=None,
1555 open_tr=None,
1556 ):
1549 if opts is None: 1557 if opts is None:
1550 opts = {} 1558 opts = {}
1551 if not lfutil.islfilesrepo(repo): 1559 if not lfutil.islfilesrepo(repo):
1552 return orig(repo, matcher, prefix, uipathfn, opts) 1560 return orig(repo, matcher, prefix, uipathfn, opts, open_tr=open_tr)
1553 # Get the list of missing largefiles so we can remove them 1561 # Get the list of missing largefiles so we can remove them
1554 lfdirstate = lfutil.openlfdirstate(repo.ui, repo) 1562 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1555 unsure, s, mtime_boundary = lfdirstate.status( 1563 unsure, s, mtime_boundary = lfdirstate.status(
1556 matchmod.always(), 1564 matchmod.always(),
1557 subrepos=[], 1565 subrepos=[],
1558 ignored=False, 1566 ignored=False,
1559 clean=False, 1567 clean=False,
1560 unknown=False, 1568 unknown=False,
1561 ) 1569 )
1570
1571 # open the transaction and changing_files context
1572 if open_tr is not None:
1573 open_tr()
1562 1574
1563 # Call into the normal remove code, but the removing of the standin, we want 1575 # Call into the normal remove code, but the removing of the standin, we want
1564 # to have handled by original addremove. Monkey patching here makes sure 1576 # to have handled by original addremove. Monkey patching here makes sure
1565 # we don't remove the standin in the largefiles code, preventing a very 1577 # we don't remove the standin in the largefiles code, preventing a very
1566 # confused state later. 1578 # confused state later.
1590 ) 1602 )
1591 # Now that we've handled largefiles, hand off to the original addremove 1603 # Now that we've handled largefiles, hand off to the original addremove
1592 # function to take care of the rest. Make sure it doesn't do anything with 1604 # function to take care of the rest. Make sure it doesn't do anything with
1593 # largefiles by passing a matcher that will ignore them. 1605 # largefiles by passing a matcher that will ignore them.
1594 matcher = composenormalfilematcher(matcher, repo[None].manifest(), added) 1606 matcher = composenormalfilematcher(matcher, repo[None].manifest(), added)
1595 return orig(repo, matcher, prefix, uipathfn, opts) 1607
1608 return orig(repo, matcher, prefix, uipathfn, opts, open_tr=open_tr)
1596 1609
1597 1610
1598 # Calling purge with --all will cause the largefiles to be deleted. 1611 # Calling purge with --all will cause the largefiles to be deleted.
1599 # Override repo.status to prevent this from happening. 1612 # Override repo.status to prevent this from happening.
1600 @eh.wrapcommand(b'purge') 1613 @eh.wrapcommand(b'purge')