Details
Details
- Reviewers
- None
- Group Reviewers
Restricted Project
Diff Detail
Diff Detail
- Repository
- rFBHGX Facebook Mercurial Extensions
- Lint
Lint Skipped - Unit
Unit Tests Skipped
Restricted Project |
Lint Skipped |
Unit Tests Skipped |
Path | Packages | |||
---|---|---|---|---|
M | hgext3rd/lfs/wrapper.py (14 lines) | |||
M | remotefilelog/remotefilelog.py (14 lines) | |||
M | remotefilelog/shallowutil.py (12 lines) |
Status | Author | Revision | |
---|---|---|---|
Closed | martinvonz | ||
Abandoned | martinvonz | ||
Closed | martinvonz |
from mercurial.i18n import _ | from mercurial.i18n import _ | ||||
from mercurial.node import bin, nullid, short | from mercurial.node import bin, nullid, short | ||||
from . import ( | from . import ( | ||||
blobstore, | blobstore, | ||||
pointer, | pointer, | ||||
) | ) | ||||
if util.safehasattr(revlog, 'parsemeta'): | |||||
# Since 0596d274 | |||||
_parsemeta = revlog.parsemeta | |||||
_packmeta = revlog.packmeta | |||||
else: | |||||
_parsemeta = filelog.parsemeta | |||||
_packmeta = filelog.packmeta | |||||
def supportedoutgoingversions(orig, repo): | def supportedoutgoingversions(orig, repo): | ||||
versions = orig(repo) | versions = orig(repo) | ||||
versions.discard('01') | versions.discard('01') | ||||
versions.discard('02') | versions.discard('02') | ||||
versions.add('03') | versions.add('03') | ||||
return versions | return versions | ||||
def allsupportedversions(orig, ui): | def allsupportedversions(orig, ui): | ||||
# pack hg filelog metadata | # pack hg filelog metadata | ||||
hgmeta = {} | hgmeta = {} | ||||
for k in p.keys(): | for k in p.keys(): | ||||
if k.startswith('x-hg-'): | if k.startswith('x-hg-'): | ||||
name = k[len('x-hg-'):] | name = k[len('x-hg-'):] | ||||
hgmeta[name] = p[k] | hgmeta[name] = p[k] | ||||
if hgmeta or text.startswith('\1\n'): | if hgmeta or text.startswith('\1\n'): | ||||
text = filelog.packmeta(hgmeta, text) | text = _packmeta(hgmeta, text) | ||||
return (text, True) | return (text, True) | ||||
def writetostore(self, text): | def writetostore(self, text): | ||||
# hg filelog metadata (includes rename, etc) | # hg filelog metadata (includes rename, etc) | ||||
hgmeta, offset = filelog.parsemeta(text) | hgmeta, offset = _parsemeta(text) | ||||
if offset and offset > 0: | if offset and offset > 0: | ||||
# lfs blob does not contain hg filelog metadata | # lfs blob does not contain hg filelog metadata | ||||
text = text[offset:] | text = text[offset:] | ||||
# git-lfs only supports sha256 | # git-lfs only supports sha256 | ||||
oid = hashlib.sha256(text).hexdigest() | oid = hashlib.sha256(text).hexdigest() | ||||
self.opener.lfslocalblobstore.write(oid, text) | self.opener.lfslocalblobstore.write(oid, text) | ||||
return bool(flags & revlog.REVIDX_EXTSTORED) | return bool(flags & revlog.REVIDX_EXTSTORED) | ||||
def filelogaddrevision(orig, self, text, transaction, link, p1, p2, | def filelogaddrevision(orig, self, text, transaction, link, p1, p2, | ||||
cachedelta=None, node=None, | cachedelta=None, node=None, | ||||
flags=revlog.REVIDX_DEFAULT_FLAGS, **kwds): | flags=revlog.REVIDX_DEFAULT_FLAGS, **kwds): | ||||
threshold = self.opener.options['lfsthreshold'] | threshold = self.opener.options['lfsthreshold'] | ||||
textlen = len(text) | textlen = len(text) | ||||
# exclude hg rename meta from file size | # exclude hg rename meta from file size | ||||
meta, offset = filelog.parsemeta(text) | meta, offset = _parsemeta(text) | ||||
if offset: | if offset: | ||||
textlen -= offset | textlen -= offset | ||||
if threshold and textlen > threshold: | if threshold and textlen > threshold: | ||||
flags |= revlog.REVIDX_EXTSTORED | flags |= revlog.REVIDX_EXTSTORED | ||||
return orig(self, text, transaction, link, p1, p2, cachedelta=cachedelta, | return orig(self, text, transaction, link, p1, p2, cachedelta=cachedelta, | ||||
node=node, flags=flags, **kwds) | node=node, flags=flags, **kwds) |
# remotefilelog.py - filelog implementation where filelog history is stored | # remotefilelog.py - filelog implementation where filelog history is stored | ||||
# remotely | # remotely | ||||
# | # | ||||
# Copyright 2013 Facebook, Inc. | # Copyright 2013 Facebook, Inc. | ||||
# | # | ||||
# This software may be used and distributed according to the terms of the | # This software may be used and distributed according to the terms of the | ||||
# GNU General Public License version 2 or any later version. | # GNU General Public License version 2 or any later version. | ||||
from __future__ import absolute_import | from __future__ import absolute_import | ||||
from . import ( | from . import ( | ||||
constants, | constants, | ||||
fileserverclient, | fileserverclient, | ||||
shallowutil, | shallowutil, | ||||
) | ) | ||||
import collections, os | import collections, os | ||||
from mercurial.node import bin, nullid | from mercurial.node import bin, nullid | ||||
from mercurial import filelog, revlog, mdiff, ancestor, error | from mercurial import filelog, revlog, mdiff, ancestor, error, util | ||||
from mercurial.i18n import _ | from mercurial.i18n import _ | ||||
if util.safehasattr(revlog, 'parsemeta'): | |||||
# Since 0596d274 | |||||
_parsemeta = revlog.parsemeta | |||||
else: | |||||
_parsemeta = filelog.parsemeta | |||||
class remotefilelognodemap(object): | class remotefilelognodemap(object): | ||||
def __init__(self, filename, store): | def __init__(self, filename, store): | ||||
self._filename = filename | self._filename = filename | ||||
self._store = store | self._store = store | ||||
def __contains__(self, node): | def __contains__(self, node): | ||||
missing = self._store.getmissing([(self._filename, node)]) | missing = self._store.getmissing([(self._filename, node)]) | ||||
return not bool(missing) | return not bool(missing) | ||||
return data | return data | ||||
def addrevision(self, text, transaction, linknode, p1, p2, cachedelta=None, | def addrevision(self, text, transaction, linknode, p1, p2, cachedelta=None, | ||||
node=None, flags=revlog.REVIDX_DEFAULT_FLAGS): | node=None, flags=revlog.REVIDX_DEFAULT_FLAGS): | ||||
# text passed to "addrevision" includes hg filelog metadata header | # text passed to "addrevision" includes hg filelog metadata header | ||||
if node is None: | if node is None: | ||||
node = revlog.hash(text, p1, p2) | node = revlog.hash(text, p1, p2) | ||||
meta, metaoffset = filelog.parsemeta(text) | meta, metaoffset = _parsemeta(text) | ||||
rawtext, validatehash = self._processflags(text, flags, 'write') | rawtext, validatehash = self._processflags(text, flags, 'write') | ||||
return self.addrawrevision(rawtext, transaction, linknode, p1, p2, | return self.addrawrevision(rawtext, transaction, linknode, p1, p2, | ||||
node, flags, cachedelta, | node, flags, cachedelta, | ||||
_metatuple=(meta, metaoffset)) | _metatuple=(meta, metaoffset)) | ||||
def addrawrevision(self, rawtext, transaction, linknode, p1, p2, node, | def addrawrevision(self, rawtext, transaction, linknode, p1, p2, node, | ||||
flags, cachedelta=None, _metatuple=None): | flags, cachedelta=None, _metatuple=None): | ||||
if _metatuple: | if _metatuple: | ||||
# _metatuple: used by "addrevision" internally by remotefilelog | # _metatuple: used by "addrevision" internally by remotefilelog | ||||
# meta was parsed confidently | # meta was parsed confidently | ||||
meta, metaoffset = _metatuple | meta, metaoffset = _metatuple | ||||
else: | else: | ||||
# not from self.addrevision, but something else (repo._filecommit) | # not from self.addrevision, but something else (repo._filecommit) | ||||
# calls addrawrevision directly. remotefilelog needs to get and | # calls addrawrevision directly. remotefilelog needs to get and | ||||
# strip filelog metadata. | # strip filelog metadata. | ||||
# we don't have confidence about whether rawtext contains filelog | # we don't have confidence about whether rawtext contains filelog | ||||
# metadata or not (flag processor could replace it), so we just | # metadata or not (flag processor could replace it), so we just | ||||
# parse it as best-effort. | # parse it as best-effort. | ||||
# in LFS (flags != 0)'s case, the best way is to call LFS code to | # in LFS (flags != 0)'s case, the best way is to call LFS code to | ||||
# get the meta information, instead of filelog.parsemeta. | # get the meta information, instead of _parsemeta. | ||||
meta, metaoffset = filelog.parsemeta(rawtext) | meta, metaoffset = _parsemeta(rawtext) | ||||
if flags != 0: | if flags != 0: | ||||
# when flags != 0, be conservative and do not mangle rawtext, since | # when flags != 0, be conservative and do not mangle rawtext, since | ||||
# a read flag processor expects the text not being mangled at all. | # a read flag processor expects the text not being mangled at all. | ||||
metaoffset = 0 | metaoffset = 0 | ||||
if metaoffset: | if metaoffset: | ||||
# remotefilelog fileblob stores copy metadata in its ancestortext, | # remotefilelog fileblob stores copy metadata in its ancestortext, | ||||
# not its main blob. so we need to remove filelog metadata | # not its main blob. so we need to remove filelog metadata | ||||
# (containing copy information) from text. | # (containing copy information) from text. |
# shallowutil.py -- remotefilelog utilities | # shallowutil.py -- remotefilelog utilities | ||||
# | # | ||||
# Copyright 2014 Facebook, Inc. | # Copyright 2014 Facebook, Inc. | ||||
# | # | ||||
# This software may be used and distributed according to the terms of the | # This software may be used and distributed according to the terms of the | ||||
# GNU General Public License version 2 or any later version. | # GNU General Public License version 2 or any later version. | ||||
from __future__ import absolute_import | from __future__ import absolute_import | ||||
import errno, hashlib, os, stat, struct, tempfile | import errno, hashlib, os, stat, struct, tempfile | ||||
from collections import defaultdict | from collections import defaultdict | ||||
from mercurial import filelog, revlog, util, error | from mercurial import filelog, revlog, util, error | ||||
from mercurial.i18n import _ | from mercurial.i18n import _ | ||||
from . import constants | from . import constants | ||||
if util.safehasattr(revlog, 'parsemeta'): | |||||
# Since 0596d274 | |||||
_parsemeta = revlog.parsemeta | |||||
_packmeta = revlog.packmeta | |||||
else: | |||||
_parsemeta = filelog.parsemeta | |||||
_packmeta = filelog.packmeta | |||||
if os.name != 'nt': | if os.name != 'nt': | ||||
import grp | import grp | ||||
def interposeclass(container, classname): | def interposeclass(container, classname): | ||||
'''Interpose a class into the hierarchies of all loaded subclasses. This | '''Interpose a class into the hierarchies of all loaded subclasses. This | ||||
function is intended for use as a decorator. | function is intended for use as a decorator. | ||||
import mymodule | import mymodule | ||||
"""returns a string that matches the revlog contents in a | """returns a string that matches the revlog contents in a | ||||
traditional revlog | traditional revlog | ||||
""" | """ | ||||
meta = {} | meta = {} | ||||
if copyfrom or text.startswith('\1\n'): | if copyfrom or text.startswith('\1\n'): | ||||
if copyfrom: | if copyfrom: | ||||
meta['copy'] = copyfrom | meta['copy'] = copyfrom | ||||
meta['copyrev'] = copyrev | meta['copyrev'] = copyrev | ||||
text = filelog.packmeta(meta, text) | text = _packmeta(meta, text) | ||||
return text | return text | ||||
def parsemeta(text): | def parsemeta(text): | ||||
"""parse mercurial filelog metadata""" | """parse mercurial filelog metadata""" | ||||
meta, size = filelog.parsemeta(text) | meta, size = _parsemeta(text) | ||||
if text.startswith('\1\n'): | if text.startswith('\1\n'): | ||||
s = text.index('\1\n', 2) | s = text.index('\1\n', 2) | ||||
text = text[s + 2:] | text = text[s + 2:] | ||||
return meta or {}, text | return meta or {}, text | ||||
def sumdicts(*dicts): | def sumdicts(*dicts): | ||||
"""Adds all the values of *dicts together into one dictionary. This assumes | """Adds all the values of *dicts together into one dictionary. This assumes | ||||
the values in *dicts are all summable. | the values in *dicts are all summable. |