hgext/largefiles/overrides.py
branchstable
changeset 44129 84a0102c05c7
parent 44015 7ca8aa8840c0
parent 43583 73e6d3346e4f
child 44452 9d2b2df2c2ba
equal deleted inserted replaced
44048:61881b170140 44129:84a0102c05c7
     7 # GNU General Public License version 2 or any later version.
     7 # GNU General Public License version 2 or any later version.
     8 
     8 
     9 '''Overridden Mercurial commands and functions for the largefiles extension'''
     9 '''Overridden Mercurial commands and functions for the largefiles extension'''
    10 from __future__ import absolute_import
    10 from __future__ import absolute_import
    11 
    11 
    12 import contextlib
       
    13 import copy
    12 import copy
    14 import os
    13 import os
    15 
    14 
    16 from mercurial.i18n import _
    15 from mercurial.i18n import _
    17 
    16 
    48     storefactory,
    47     storefactory,
    49 )
    48 )
    50 
    49 
    51 eh = exthelper.exthelper()
    50 eh = exthelper.exthelper()
    52 
    51 
       
    52 lfstatus = lfutil.lfstatus
       
    53 
    53 # -- Utility functions: commonly/repeatedly needed functionality ---------------
    54 # -- Utility functions: commonly/repeatedly needed functionality ---------------
    54 
    55 
    55 
    56 
    56 def composelargefilematcher(match, manifest):
    57 def composelargefilematcher(match, manifest):
    57     '''create a matcher that matches only the largefiles in the original
    58     '''create a matcher that matches only the largefiles in the original
    82     m.matchfn = lambda f: notlfile(f) and origmatchfn(f)
    83     m.matchfn = lambda f: notlfile(f) and origmatchfn(f)
    83     return m
    84     return m
    84 
    85 
    85 
    86 
    86 def addlargefiles(ui, repo, isaddremove, matcher, uipathfn, **opts):
    87 def addlargefiles(ui, repo, isaddremove, matcher, uipathfn, **opts):
    87     large = opts.get(r'large')
    88     large = opts.get('large')
    88     lfsize = lfutil.getminsize(
    89     lfsize = lfutil.getminsize(
    89         ui, lfutil.islfilesrepo(repo), opts.get(r'lfsize')
    90         ui, lfutil.islfilesrepo(repo), opts.get('lfsize')
    90     )
    91     )
    91 
    92 
    92     lfmatcher = None
    93     lfmatcher = None
    93     if lfutil.islfilesrepo(repo):
    94     if lfutil.islfilesrepo(repo):
    94         lfpats = ui.configlist(lfutil.longname, b'patterns')
    95         lfpats = ui.configlist(lfutil.longname, b'patterns')
   129     bad = []
   130     bad = []
   130 
   131 
   131     # Need to lock, otherwise there could be a race condition between
   132     # Need to lock, otherwise there could be a race condition between
   132     # when standins are created and added to the repo.
   133     # when standins are created and added to the repo.
   133     with repo.wlock():
   134     with repo.wlock():
   134         if not opts.get(r'dry_run'):
   135         if not opts.get('dry_run'):
   135             standins = []
   136             standins = []
   136             lfdirstate = lfutil.openlfdirstate(ui, repo)
   137             lfdirstate = lfutil.openlfdirstate(ui, repo)
   137             for f in lfnames:
   138             for f in lfnames:
   138                 standinname = lfutil.standin(f)
   139                 standinname = lfutil.standin(f)
   139                 lfutil.writestandin(
   140                 lfutil.writestandin(
   156 
   157 
   157         added = [f for f in lfnames if f not in bad]
   158         added = [f for f in lfnames if f not in bad]
   158     return added, bad
   159     return added, bad
   159 
   160 
   160 
   161 
   161 @contextlib.contextmanager
       
   162 def lfstatus(repo):
       
   163     oldvalue = getattr(repo, 'lfstatus', False)
       
   164     repo.lfstatus = True
       
   165     try:
       
   166         yield
       
   167     finally:
       
   168         repo.lfstatus = oldvalue
       
   169 
       
   170 
       
   171 def removelargefiles(ui, repo, isaddremove, matcher, uipathfn, dryrun, **opts):
   162 def removelargefiles(ui, repo, isaddremove, matcher, uipathfn, dryrun, **opts):
   172     after = opts.get(r'after')
   163     after = opts.get('after')
   173     m = composelargefilematcher(matcher, repo[None].manifest())
   164     m = composelargefilematcher(matcher, repo[None].manifest())
   174     with lfstatus(repo):
   165     with lfstatus(repo):
   175         s = repo.status(match=m, clean=not isaddremove)
   166         s = repo.status(match=m, clean=not isaddremove)
   176     manifest = repo[None].manifest()
   167     manifest = repo[None].manifest()
   177     modified, added, deleted, clean = [
   168     modified, added, deleted, clean = [
   267             ),
   258             ),
   268         ),
   259         ),
   269     ],
   260     ],
   270 )
   261 )
   271 def overrideadd(orig, ui, repo, *pats, **opts):
   262 def overrideadd(orig, ui, repo, *pats, **opts):
   272     if opts.get(r'normal') and opts.get(r'large'):
   263     if opts.get('normal') and opts.get('large'):
   273         raise error.Abort(_(b'--normal cannot be used with --large'))
   264         raise error.Abort(_(b'--normal cannot be used with --large'))
   274     return orig(ui, repo, *pats, **opts)
   265     return orig(ui, repo, *pats, **opts)
   275 
   266 
   276 
   267 
   277 @eh.wrapfunction(cmdutil, b'add')
   268 @eh.wrapfunction(cmdutil, b'add')
   278 def cmdutiladd(orig, ui, repo, matcher, prefix, uipathfn, explicitonly, **opts):
   269 def cmdutiladd(orig, ui, repo, matcher, prefix, uipathfn, explicitonly, **opts):
   279     # The --normal flag short circuits this override
   270     # The --normal flag short circuits this override
   280     if opts.get(r'normal'):
   271     if opts.get('normal'):
   281         return orig(ui, repo, matcher, prefix, uipathfn, explicitonly, **opts)
   272         return orig(ui, repo, matcher, prefix, uipathfn, explicitonly, **opts)
   282 
   273 
   283     ladded, lbad = addlargefiles(ui, repo, False, matcher, uipathfn, **opts)
   274     ladded, lbad = addlargefiles(ui, repo, False, matcher, uipathfn, **opts)
   284     normalmatcher = composenormalfilematcher(
   275     normalmatcher = composenormalfilematcher(
   285         matcher, repo[None].manifest(), ladded
   276         matcher, repo[None].manifest(), ladded
   475             _(b'verify local largefile contents, not just existence'),
   466             _(b'verify local largefile contents, not just existence'),
   476         ),
   467         ),
   477     ],
   468     ],
   478 )
   469 )
   479 def overrideverify(orig, ui, repo, *pats, **opts):
   470 def overrideverify(orig, ui, repo, *pats, **opts):
   480     large = opts.pop(r'large', False)
   471     large = opts.pop('large', False)
   481     all = opts.pop(r'lfa', False)
   472     all = opts.pop('lfa', False)
   482     contents = opts.pop(r'lfc', False)
   473     contents = opts.pop('lfc', False)
   483 
   474 
   484     result = orig(ui, repo, *pats, **opts)
   475     result = orig(ui, repo, *pats, **opts)
   485     if large or all or contents:
   476     if large or all or contents:
   486         result = result or lfcommands.verifylfiles(ui, repo, all, contents)
   477         result = result or lfcommands.verifylfiles(ui, repo, all, contents)
   487     return result
   478     return result
   490 @eh.wrapcommand(
   481 @eh.wrapcommand(
   491     b'debugstate',
   482     b'debugstate',
   492     opts=[(b'', b'large', None, _(b'display largefiles dirstate'))],
   483     opts=[(b'', b'large', None, _(b'display largefiles dirstate'))],
   493 )
   484 )
   494 def overridedebugstate(orig, ui, repo, *pats, **opts):
   485 def overridedebugstate(orig, ui, repo, *pats, **opts):
   495     large = opts.pop(r'large', False)
   486     large = opts.pop('large', False)
   496     if large:
   487     if large:
   497 
   488 
   498         class fakerepo(object):
   489         class fakerepo(object):
   499             dirstate = lfutil.openlfdirstate(ui, repo)
   490             dirstate = lfutil.openlfdirstate(ui, repo)
   500 
   491 
   973     if not source:
   964     if not source:
   974         source = b'default'
   965         source = b'default'
   975     repo.lfpullsource = source
   966     repo.lfpullsource = source
   976     result = orig(ui, repo, source, **opts)
   967     result = orig(ui, repo, source, **opts)
   977     revspostpull = len(repo)
   968     revspostpull = len(repo)
   978     lfrevs = opts.get(r'lfrev', [])
   969     lfrevs = opts.get('lfrev', [])
   979     if opts.get(r'all_largefiles'):
   970     if opts.get('all_largefiles'):
   980         lfrevs.append(b'pulled()')
   971         lfrevs.append(b'pulled()')
   981     if lfrevs and revspostpull > revsprepull:
   972     if lfrevs and revspostpull > revsprepull:
   982         numcached = 0
   973         numcached = 0
   983         repo.firstpulled = revsprepull  # for pulled() revset expression
   974         repo.firstpulled = revsprepull  # for pulled() revset expression
   984         try:
   975         try:
  1004         )
   995         )
  1005     ],
   996     ],
  1006 )
   997 )
  1007 def overridepush(orig, ui, repo, *args, **kwargs):
   998 def overridepush(orig, ui, repo, *args, **kwargs):
  1008     """Override push command and store --lfrev parameters in opargs"""
   999     """Override push command and store --lfrev parameters in opargs"""
  1009     lfrevs = kwargs.pop(r'lfrev', None)
  1000     lfrevs = kwargs.pop('lfrev', None)
  1010     if lfrevs:
  1001     if lfrevs:
  1011         opargs = kwargs.setdefault(r'opargs', {})
  1002         opargs = kwargs.setdefault('opargs', {})
  1012         opargs[b'lfrevs'] = scmutil.revrange(repo, lfrevs)
  1003         opargs[b'lfrevs'] = scmutil.revrange(repo, lfrevs)
  1013     return orig(ui, repo, *args, **kwargs)
  1004     return orig(ui, repo, *args, **kwargs)
  1014 
  1005 
  1015 
  1006 
  1016 @eh.wrapfunction(exchange, b'pushoperation')
  1007 @eh.wrapfunction(exchange, b'pushoperation')
  1017 def exchangepushoperation(orig, *args, **kwargs):
  1008 def exchangepushoperation(orig, *args, **kwargs):
  1018     """Override pushoperation constructor and store lfrevs parameter"""
  1009     """Override pushoperation constructor and store lfrevs parameter"""
  1019     lfrevs = kwargs.pop(r'lfrevs', None)
  1010     lfrevs = kwargs.pop('lfrevs', None)
  1020     pushop = orig(*args, **kwargs)
  1011     pushop = orig(*args, **kwargs)
  1021     pushop.lfrevs = lfrevs
  1012     pushop.lfrevs = lfrevs
  1022     return pushop
  1013     return pushop
  1023 
  1014 
  1024 
  1015 
  1062 )
  1053 )
  1063 def overrideclone(orig, ui, source, dest=None, **opts):
  1054 def overrideclone(orig, ui, source, dest=None, **opts):
  1064     d = dest
  1055     d = dest
  1065     if d is None:
  1056     if d is None:
  1066         d = hg.defaultdest(source)
  1057         d = hg.defaultdest(source)
  1067     if opts.get(r'all_largefiles') and not hg.islocal(d):
  1058     if opts.get('all_largefiles') and not hg.islocal(d):
  1068         raise error.Abort(
  1059         raise error.Abort(
  1069             _(b'--all-largefiles is incompatible with non-local destination %s')
  1060             _(b'--all-largefiles is incompatible with non-local destination %s')
  1070             % d
  1061             % d
  1071         )
  1062         )
  1072 
  1063 
  1102 @eh.wrapcommand(b'rebase', extension=b'rebase')
  1093 @eh.wrapcommand(b'rebase', extension=b'rebase')
  1103 def overriderebase(orig, ui, repo, **opts):
  1094 def overriderebase(orig, ui, repo, **opts):
  1104     if not util.safehasattr(repo, b'_largefilesenabled'):
  1095     if not util.safehasattr(repo, b'_largefilesenabled'):
  1105         return orig(ui, repo, **opts)
  1096         return orig(ui, repo, **opts)
  1106 
  1097 
  1107     resuming = opts.get(r'continue')
  1098     resuming = opts.get('continue')
  1108     repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
  1099     repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
  1109     repo._lfstatuswriters.append(lambda *msg, **opts: None)
  1100     repo._lfstatuswriters.append(lambda *msg, **opts: None)
  1110     try:
  1101     try:
  1111         return orig(ui, repo, **opts)
  1102         return orig(ui, repo, **opts)
  1112     finally:
  1103     finally:
  1611     return result
  1602     return result
  1612 
  1603 
  1613 
  1604 
  1614 @eh.wrapcommand(b'transplant', extension=b'transplant')
  1605 @eh.wrapcommand(b'transplant', extension=b'transplant')
  1615 def overridetransplant(orig, ui, repo, *revs, **opts):
  1606 def overridetransplant(orig, ui, repo, *revs, **opts):
  1616     resuming = opts.get(r'continue')
  1607     resuming = opts.get('continue')
  1617     repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
  1608     repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
  1618     repo._lfstatuswriters.append(lambda *msg, **opts: None)
  1609     repo._lfstatuswriters.append(lambda *msg, **opts: None)
  1619     try:
  1610     try:
  1620         result = orig(ui, repo, *revs, **opts)
  1611         result = orig(ui, repo, *revs, **opts)
  1621     finally:
  1612     finally:
  1696     return err
  1687     return err
  1697 
  1688 
  1698 
  1689 
  1699 @eh.wrapfunction(merge, b'update')
  1690 @eh.wrapfunction(merge, b'update')
  1700 def mergeupdate(orig, repo, node, branchmerge, force, *args, **kwargs):
  1691 def mergeupdate(orig, repo, node, branchmerge, force, *args, **kwargs):
  1701     matcher = kwargs.get(r'matcher', None)
  1692     matcher = kwargs.get('matcher', None)
  1702     # note if this is a partial update
  1693     # note if this is a partial update
  1703     partial = matcher and not matcher.always()
  1694     partial = matcher and not matcher.always()
  1704     with repo.wlock():
  1695     with repo.wlock():
  1705         # branch |       |         |
  1696         # branch |       |         |
  1706         #  merge | force | partial | action
  1697         #  merge | force | partial | action
  1756 
  1747 
  1757         oldstandins = lfutil.getstandinsstate(repo)
  1748         oldstandins = lfutil.getstandinsstate(repo)
  1758         # Make sure the merge runs on disk, not in-memory. largefiles is not a
  1749         # Make sure the merge runs on disk, not in-memory. largefiles is not a
  1759         # good candidate for in-memory merge (large files, custom dirstate,
  1750         # good candidate for in-memory merge (large files, custom dirstate,
  1760         # matcher usage).
  1751         # matcher usage).
  1761         kwargs[r'wc'] = repo[None]
  1752         kwargs['wc'] = repo[None]
  1762         result = orig(repo, node, branchmerge, force, *args, **kwargs)
  1753         result = orig(repo, node, branchmerge, force, *args, **kwargs)
  1763 
  1754 
  1764         newstandins = lfutil.getstandinsstate(repo)
  1755         newstandins = lfutil.getstandinsstate(repo)
  1765         filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
  1756         filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
  1766 
  1757