__init__.py
203 lines
| 7.1 KiB
| text/x-python
|
PythonLexer
|
r15168 | # Copyright 2009-2010 Gregory P. Ward | ||
# Copyright 2009-2010 Intelerad Medical Systems Incorporated | ||||
# Copyright 2010-2011 Fog Creek Software | ||||
# Copyright 2010-2011 Unity Technologies | ||||
# | ||||
# This software may be used and distributed according to the terms of the | ||||
# GNU General Public License version 2 or any later version. | ||||
'''track large binary files | ||||
|
r15230 | Large binary files tend to be not very compressible, not very | ||
diffable, and not at all mergeable. Such files are not handled | ||||
efficiently by Mercurial's storage format (revlog), which is based on | ||||
compressed binary deltas; storing large binary files as regular | ||||
Mercurial files wastes bandwidth and disk space and increases | ||||
Mercurial's memory usage. The largefiles extension addresses these | ||||
problems by adding a centralized client-server layer on top of | ||||
Mercurial: largefiles live in a *central store* out on the network | ||||
somewhere, and you only fetch the revisions that you need when you | ||||
need them. | ||||
largefiles works by maintaining a "standin file" in .hglf/ for each | ||||
largefile. The standins are small (41 bytes: an SHA-1 hash plus | ||||
newline) and are tracked by Mercurial. Largefile revisions are | ||||
identified by the SHA-1 hash of their contents, which is written to | ||||
the standin. largefiles uses that revision ID to get/put largefile | ||||
revisions from/to the central store. This saves both disk space and | ||||
bandwidth, since you don't need to retrieve all historical revisions | ||||
of large files when you clone or pull. | ||||
To start a new repository or add new large binary files, just add | ||||
|
r15352 | --large to your :hg:`add` command. For example:: | ||
|
r15230 | |||
$ dd if=/dev/urandom of=randomdata count=2000 | ||||
$ hg add --large randomdata | ||||
|
r28798 | $ hg commit -m "add randomdata as a largefile" | ||
|
r15230 | |||
When you push a changeset that adds/modifies largefiles to a remote | ||||
repository, its largefile revisions will be uploaded along with it. | ||||
Note that the remote Mercurial must also have the largefiles extension | ||||
enabled for this to work. | ||||
|
r15168 | |||
|
r15230 | When you pull a changeset that affects largefiles from a remote | ||
|
r18975 | repository, the largefiles for the changeset will by default not be | ||
pulled down. However, when you update to such a revision, any | ||||
largefiles needed by that revision are downloaded and cached (if | ||||
they have never been downloaded before). One way to pull largefiles | ||||
when pulling is thus to use --update, which will update your working | ||||
copy to the latest pulled revision (and thereby downloading any new | ||||
largefiles). | ||||
|
r18704 | |||
|
r18976 | If you want to pull largefiles you don't need for update yet, then | ||
|
r18978 | you can use pull with the `--lfrev` option or the :hg:`lfpull` command. | ||
|
r18976 | |||
|
r19071 | If you know you are pulling from a non-default location and want to | ||
download all the largefiles that correspond to the new changesets at | ||||
|
r18979 | the same time, then you can pull with `--lfrev "pulled()"`. | ||
|
r18975 | If you just want to ensure that you will have the largefiles needed to | ||
merge or rebase with new heads that you are pulling, then you can pull | ||||
|
r18979 | with `--lfrev "head(pulled())"` flag to pre-emptively download any largefiles | ||
|
r18704 | that are new in the heads you are pulling. | ||
|
r18599 | |||
|
r18975 | Keep in mind that network access may now be required to update to | ||
changesets that you have not previously updated to. The nature of the | ||||
largefiles extension means that updating is no longer guaranteed to | ||||
be a local-only operation. | ||||
|
r15230 | |||
If you already have large files tracked by Mercurial without the | ||||
largefiles extension, you will need to convert your repository in | ||||
|
r15352 | order to benefit from largefiles. This is done with the | ||
:hg:`lfconvert` command:: | ||||
|
r15230 | |||
$ hg lfconvert --size 10 oldrepo newrepo | ||||
|
r15168 | |||
|
r15230 | In repositories that already have largefiles in them, any new file | ||
over 10MB will automatically be added as a largefile. To change this | ||||
|
r15304 | threshold, set ``largefiles.minsize`` in your Mercurial config file | ||
to the minimum size in megabytes to track as a largefile, or use the | ||||
|
r15230 | --lfsize option to the add command (also in megabytes):: | ||
[largefiles] | ||||
|
r15304 | minsize = 2 | ||
|
r15230 | |||
$ hg add --lfsize 2 | ||||
The ``largefiles.patterns`` config option allows you to specify a list | ||||
|
r15352 | of filename patterns (see :hg:`help patterns`) that should always be | ||
|
r15230 | tracked as largefiles:: | ||
[largefiles] | ||||
patterns = | ||||
*.jpg | ||||
|
r33815 | re:.*\\.(png|bmp)$ | ||
|
r15230 | library.zip | ||
content/audio/* | ||||
Files that match one of these patterns will be added as largefiles | ||||
regardless of their size. | ||||
|
r15743 | |||
The ``largefiles.minsize`` and ``largefiles.patterns`` config options | ||||
will be ignored for any repositories not already containing a | ||||
largefile. To add the first largefile to a repository, you must | ||||
explicitly do so with the --large flag passed to the :hg:`add` | ||||
command. | ||||
|
r15168 | ''' | ||
|
r29306 | from __future__ import absolute_import | ||
|
r15168 | |||
|
r29306 | from mercurial import ( | ||
|
r41095 | cmdutil, | ||
extensions, | ||||
|
r41089 | exthelper, | ||
|
r29306 | hg, | ||
|
r41095 | httppeer, | ||
|
r29306 | localrepo, | ||
|
r41095 | sshpeer, | ||
wireprotov1server, | ||||
|
r29306 | ) | ||
|
r15168 | |||
|
r29306 | from . import ( | ||
lfcommands, | ||||
overrides, | ||||
proto, | ||||
reposetup, | ||||
) | ||||
|
r15168 | |||
|
r29841 | # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | ||
|
r25186 | # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | ||
# be specifying the version(s) of Mercurial they are tested with, or | ||||
# leave the attribute unspecified. | ||||
|
r43347 | testedwith = b'ships-with-hg-core' | ||
|
r17233 | |||
|
r41089 | eh = exthelper.exthelper() | ||
|
r41091 | eh.merge(lfcommands.eh) | ||
eh.merge(overrides.eh) | ||||
|
r41092 | eh.merge(proto.eh) | ||
|
r34756 | |||
|
r43346 | eh.configitem( | ||
|
r43347 | b'largefiles', b'minsize', default=eh.configitem.dynamicdefault, | ||
|
r34756 | ) | ||
|
r43346 | eh.configitem( | ||
|
r43347 | b'largefiles', b'patterns', default=list, | ||
|
r34757 | ) | ||
|
r43346 | eh.configitem( | ||
|
r43347 | b'largefiles', b'usercache', default=None, | ||
|
r34758 | ) | ||
|
r41091 | cmdtable = eh.cmdtable | ||
|
r41089 | configtable = eh.configtable | ||
|
r41091 | extsetup = eh.finalextsetup | ||
|
r15168 | reposetup = reposetup.reposetup | ||
|
r41091 | uisetup = eh.finaluisetup | ||
|
r19779 | |||
|
r43346 | |||
|
r19779 | def featuresetup(ui, supported): | ||
|
r19928 | # don't die on seeing a repo with the largefiles requirement | ||
|
r43347 | supported |= {b'largefiles'} | ||
|
r19779 | |||
|
r43346 | |||
|
r41091 | @eh.uisetup | ||
def _uisetup(ui): | ||||
|
r37153 | localrepo.featuresetupfuncs.add(featuresetup) | ||
|
r20858 | hg.wirepeersetupfuncs.append(proto.wirereposetup) | ||
|
r41095 | |||
|
r43347 | cmdutil.outgoinghooks.add(b'largefiles', overrides.outgoinghook) | ||
cmdutil.summaryremotehooks.add(b'largefiles', overrides.summaryremotehook) | ||||
|
r41095 | |||
# create the new wireproto commands ... | ||||
|
r43347 | wireprotov1server.wireprotocommand(b'putlfile', b'sha', permission=b'push')( | ||
|
r43346 | proto.putlfile | ||
) | ||||
|
r43347 | wireprotov1server.wireprotocommand(b'getlfile', b'sha', permission=b'pull')( | ||
|
r43346 | proto.getlfile | ||
) | ||||
|
r43347 | wireprotov1server.wireprotocommand( | ||
b'statlfile', b'sha', permission=b'pull' | ||||
)(proto.statlfile) | ||||
wireprotov1server.wireprotocommand(b'lheads', b'', permission=b'pull')( | ||||
|
r43346 | wireprotov1server.heads | ||
) | ||||
|
r41095 | |||
|
r43346 | extensions.wrapfunction( | ||
|
r43347 | wireprotov1server.commands[b'heads'], b'func', proto.heads | ||
|
r43346 | ) | ||
|
r41095 | # TODO also wrap wireproto.commandsv2 once heads is implemented there. | ||
# can't do this in reposetup because it needs to have happened before | ||||
# wirerepo.__init__ is called | ||||
proto.ssholdcallstream = sshpeer.sshv1peer._callstream | ||||
proto.httpoldcallstream = httppeer.httppeer._callstream | ||||
sshpeer.sshv1peer._callstream = proto.sshrepocallstream | ||||
httppeer.httppeer._callstream = proto.httprepocallstream | ||||
# override some extensions' stuff as well | ||||
for name, module in extensions.extensions(): | ||||
|
r43347 | if name == b'rebase': | ||
|
r41095 | # TODO: teach exthelper to handle this | ||
|
r46118 | extensions.wrapfunction( | ||
module, b'rebase', overrides.overriderebasecmd | ||||
) | ||||
|
r43346 | |||
|
r15168 | |||
|
r41097 | revsetpredicate = eh.revsetpredicate | ||