diff --git a/hgext/lfs/__init__.py b/hgext/lfs/__init__.py --- a/hgext/lfs/__init__.py +++ b/hgext/lfs/__init__.py @@ -124,6 +124,8 @@ Configs:: from __future__ import absolute_import +import sys + from mercurial.i18n import _ from mercurial import ( @@ -204,6 +206,12 @@ command = registrar.command(cmdtable) templatekeyword = registrar.templatekeyword() filesetpredicate = registrar.filesetpredicate() +lfsprocessor = ( + wrapper.readfromstore, + wrapper.writetostore, + wrapper.bypasscheckhash, +) + def featuresetup(ui, supported): # don't die on seeing a repo with the lfs requirement supported |= {'lfs'} @@ -302,12 +310,28 @@ def wrapfilelog(filelog): wrapfunction(filelog, 'renamed', wrapper.filelogrenamed) wrapfunction(filelog, 'size', wrapper.filelogsize) +def _resolverevlogstorevfsoptions(orig, ui, requirements, features): + opts = orig(ui, requirements, features) + for name, module in extensions.extensions(ui): + if module is sys.modules[__name__]: + if revlog.REVIDX_EXTSTORED in opts[b'flagprocessors']: + msg = (_(b"cannot register multiple processors on flag '%#x'.") + % revlog.REVIDX_EXTSTORED) + raise error.Abort(msg) + + opts[b'flagprocessors'][revlog.REVIDX_EXTSTORED] = lfsprocessor + break + + return opts + def extsetup(ui): wrapfilelog(filelog.filelog) wrapfunction = extensions.wrapfunction wrapfunction(localrepo, 'makefilestorage', wrapper.localrepomakefilestorage) + wrapfunction(localrepo, 'resolverevlogstorevfsoptions', + _resolverevlogstorevfsoptions) wrapfunction(cmdutil, '_updatecatformatter', wrapper._updatecatformatter) wrapfunction(scmutil, 'wrapconvertsink', wrapper.convertsink) @@ -334,15 +358,6 @@ def extsetup(ui): wrapfunction(context.basefilectx, 'isbinary', wrapper.filectxisbinary) context.basefilectx.islfs = wrapper.filectxislfs - revlog.addflagprocessor( - revlog.REVIDX_EXTSTORED, - ( - wrapper.readfromstore, - wrapper.writetostore, - wrapper.bypasscheckhash, - ), - ) - scmutil.fileprefetchhooks.add('lfs', wrapper._prefetchfiles) # Make bundle choose changegroup3 instead of changegroup2. This affects diff --git a/tests/test-lfs-serve.t b/tests/test-lfs-serve.t --- a/tests/test-lfs-serve.t +++ b/tests/test-lfs-serve.t @@ -35,6 +35,26 @@ make command server magic visible $ hg init server $ SERVER_REQUIRES="$TESTTMP/server/.hg/requires" + $ cat > $TESTTMP/debugprocessors.py < from mercurial import ( + > cmdutil, + > commands, + > pycompat, + > registrar, + > ) + > cmdtable = {} + > command = registrar.command(cmdtable) + > @command(b'debugprocessors', [], b'FILE') + > def debugprocessors(ui, repo, file_=None, **opts): + > opts = pycompat.byteskwargs(opts) + > opts[b'changelog'] = False + > opts[b'manifest'] = False + > opts[b'dir'] = False + > rl = cmdutil.openrevlog(repo, b'debugprocessors', file_, opts) + > for flag, proc in rl._flagprocessors.iteritems(): + > ui.status(b"registered processor '%#x'\n" % (flag)) + > EOF + Skip the experimental.changegroup3=True config. Failure to agree on this comes first, and causes a "ValueError: no common changegroup version" or "abort: HTTP Error 500: Internal Server Error", if the extension is only loaded on one @@ -42,6 +62,8 @@ side. If that *is* enabled, the subsequ for flag '0x2000'!" if the extension is only loaded on one side (possibly also masked by the Internal Server Error message). $ cat >> $HGRCPATH < [extensions] + > debugprocessors = $TESTTMP/debugprocessors.py > [experimental] > lfs.disableusercache = True > [lfs] @@ -51,6 +73,8 @@ masked by the Internal Server Error mess > push_ssl=False > EOF + $ cp $HGRCPATH $HGRCPATH.orig + #if lfsremote-on $ hg --config extensions.lfs= -R server \ > serve -p $HGPORT -d --pid-file=hg.pid --errorlog=$TESTTMP/errors.log @@ -307,6 +331,103 @@ lfs content, and the extension enabled. $ hg identify http://localhost:$HGPORT c729025cc5e3 + $ mv $HGRCPATH $HGRCPATH.tmp + $ cp $HGRCPATH.orig $HGRCPATH + + >>> from __future__ import absolute_import + >>> from hgclient import check, readchannel, runcommand + >>> @check + ... def checkflags(server): + ... readchannel(server) + ... print('') + ... print('# LFS required- both lfs and non-lfs revlogs have 0x2000 flag') + ... runcommand(server, ['debugprocessors', 'lfs.bin', '-R', + ... '../server']) + ... runcommand(server, ['debugprocessors', 'nonlfs2.txt', '-R', + ... '../server']) + ... runcommand(server, ['config', 'extensions', '--cwd', + ... '../server']) + ... + ... print("\n# LFS not enabled- revlogs don't have 0x2000 flag") + ... runcommand(server, ['debugprocessors', 'nonlfs3.txt']) + ... runcommand(server, ['config', 'extensions']) + + # LFS required- both lfs and non-lfs revlogs have 0x2000 flag + *** runcommand debugprocessors lfs.bin -R ../server + registered processor '0x8000' + registered processor '0x2000' + *** runcommand debugprocessors nonlfs2.txt -R ../server + registered processor '0x8000' + registered processor '0x2000' + *** runcommand config extensions --cwd ../server + extensions.debugprocessors=$TESTTMP/debugprocessors.py + extensions.lfs= + + # LFS not enabled- revlogs don't have 0x2000 flag + *** runcommand debugprocessors nonlfs3.txt + registered processor '0x8000' + *** runcommand config extensions + extensions.debugprocessors=$TESTTMP/debugprocessors.py + + $ rm $HGRCPATH + $ mv $HGRCPATH.tmp $HGRCPATH + + $ hg clone $TESTTMP/client $TESTTMP/nonlfs -qr 0 --config extensions.lfs= + $ cat >> $TESTTMP/nonlfs/.hg/hgrc < [extensions] + > lfs = ! + > EOF + + >>> from __future__ import absolute_import, print_function + >>> from hgclient import check, readchannel, runcommand + >>> @check + ... def checkflags2(server): + ... readchannel(server) + ... print('') + ... print('# LFS enabled- both lfs and non-lfs revlogs have 0x2000 flag') + ... runcommand(server, ['debugprocessors', 'lfs.bin', '-R', + ... '../server']) + ... runcommand(server, ['debugprocessors', 'nonlfs2.txt', '-R', + ... '../server']) + ... runcommand(server, ['config', 'extensions', '--cwd', + ... '../server']) + ... + ... print('\n# LFS enabled without requirement- revlogs have 0x2000 flag') + ... runcommand(server, ['debugprocessors', 'nonlfs3.txt']) + ... runcommand(server, ['config', 'extensions']) + ... + ... print("\n# LFS disabled locally- revlogs don't have 0x2000 flag") + ... runcommand(server, ['debugprocessors', 'nonlfs.txt', '-R', + ... '../nonlfs']) + ... runcommand(server, ['config', 'extensions', '--cwd', + ... '../nonlfs']) + + # LFS enabled- both lfs and non-lfs revlogs have 0x2000 flag + *** runcommand debugprocessors lfs.bin -R ../server + registered processor '0x8000' + registered processor '0x2000' + *** runcommand debugprocessors nonlfs2.txt -R ../server + registered processor '0x8000' + registered processor '0x2000' + *** runcommand config extensions --cwd ../server + extensions.debugprocessors=$TESTTMP/debugprocessors.py + extensions.lfs= + + # LFS enabled without requirement- revlogs have 0x2000 flag + *** runcommand debugprocessors nonlfs3.txt + registered processor '0x8000' + registered processor '0x2000' + *** runcommand config extensions + extensions.debugprocessors=$TESTTMP/debugprocessors.py + extensions.lfs= + + # LFS disabled locally- revlogs don't have 0x2000 flag + *** runcommand debugprocessors nonlfs.txt -R ../nonlfs + registered processor '0x8000' + *** runcommand config extensions --cwd ../nonlfs + extensions.debugprocessors=$TESTTMP/debugprocessors.py + extensions.lfs=! + -------------------------------------------------------------------------------- Case #6: client with lfs content and the extension enabled; server with lfs content, and the extension enabled.