hgext/narrow/narrowrevlog.py
branchstable
changeset 40404 956ec6f1320d
parent 40131 535fc8a22365
parent 40403 bf249bb60087
child 40405 4185bc53d1e3
equal deleted inserted replaced
40131:535fc8a22365 40404:956ec6f1320d
     1 # narrowrevlog.py - revlog storing irrelevant nodes as "ellipsis" nodes
       
     2 #
       
     3 # Copyright 2017 Google, Inc.
       
     4 #
       
     5 # This software may be used and distributed according to the terms of the
       
     6 # GNU General Public License version 2 or any later version.
       
     7 
       
     8 from __future__ import absolute_import
       
     9 
       
    10 from mercurial import (
       
    11    revlog,
       
    12    util,
       
    13 )
       
    14 
       
    15 def readtransform(self, text):
       
    16     return text, False
       
    17 
       
    18 def writetransform(self, text):
       
    19     return text, False
       
    20 
       
    21 def rawtransform(self, text):
       
    22     return False
       
    23 
       
    24 revlog.addflagprocessor(revlog.REVIDX_ELLIPSIS,
       
    25                         (readtransform, writetransform, rawtransform))
       
    26 
       
    27 def setup():
       
    28     # We just wanted to add the flag processor, which is done at module
       
    29     # load time.
       
    30     pass
       
    31 
       
    32 def makenarrowfilelog(fl, narrowmatch):
       
    33     class narrowfilelog(fl.__class__):
       
    34         def renamed(self, node):
       
    35             # Renames that come from outside the narrowspec are
       
    36             # problematic at least for git-diffs, because we lack the
       
    37             # base text for the rename. This logic was introduced in
       
    38             # 3cd72b1 of narrowhg (authored by martinvonz, reviewed by
       
    39             # adgar), but that revision doesn't have any additional
       
    40             # commentary on what problems we can encounter.
       
    41             m = super(narrowfilelog, self).renamed(node)
       
    42             if m and not narrowmatch(m[0]):
       
    43                 return None
       
    44             return m
       
    45 
       
    46         def size(self, rev):
       
    47             # We take advantage of the fact that remotefilelog
       
    48             # lacks a node() method to just skip the
       
    49             # rename-checking logic when on remotefilelog. This
       
    50             # might be incorrect on other non-revlog-based storage
       
    51             # engines, but for now this seems to be fine.
       
    52             #
       
    53             # TODO: when remotefilelog is in core, improve this to
       
    54             # explicitly look for remotefilelog instead of cheating
       
    55             # with a hasattr check.
       
    56             if util.safehasattr(self, 'node'):
       
    57                 node = self.node(rev)
       
    58                 # Because renamed() is overridden above to
       
    59                 # sometimes return None even if there is metadata
       
    60                 # in the revlog, size can be incorrect for
       
    61                 # copies/renames, so we need to make sure we call
       
    62                 # the super class's implementation of renamed()
       
    63                 # for the purpose of size calculation.
       
    64                 if super(narrowfilelog, self).renamed(node):
       
    65                     return len(self.read(node))
       
    66             return super(narrowfilelog, self).size(rev)
       
    67 
       
    68         def cmp(self, node, text):
       
    69             different = super(narrowfilelog, self).cmp(node, text)
       
    70             if different:
       
    71                 # Similar to size() above, if the file was copied from
       
    72                 # a file outside the narrowspec, the super class's
       
    73                 # would have returned True because we tricked it into
       
    74                 # thinking that the file was not renamed.
       
    75                 if super(narrowfilelog, self).renamed(node):
       
    76                     t2 = self.read(node)
       
    77                     return t2 != text
       
    78             return different
       
    79 
       
    80     fl.__class__ = narrowfilelog