Example #1
0
 def linelog(self):
     if self._linelog is None:
         if os.path.exists(self.linelogpath):
             with open(self.linelogpath, 'rb') as f:
                 try:
                     self._linelog = linelogmod.linelog.fromdata(f.read())
                 except linelogmod.LineLogError:
                     self._linelog = linelogmod.linelog()
         else:
             self._linelog = linelogmod.linelog()
     return self._linelog
Example #2
0
 def testanothersimplecase(self):
     ll = linelog.linelog()
     ll.replacelines(3, 0, 0, 0, 2)
     ll.replacelines(4, 0, 2, 0, 0)
     self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(4)], [])
     self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(3)],
                      [(3, 0), (3, 1)])
     # rev 2 is empty because contents were only ever introduced in rev 3
     self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(2)], [])
Example #3
0
    def annotatealllines(self, rev, showpath=False, showlines=False):
        """(rev : str) -> [(node : str, linenum : int, path : str)]

        the result has the same format with annotate, but include all (including
        deleted) lines up to rev. call this after calling annotate(rev, ...) for
        better performance and accuracy.
        """
        revfctx = self._resolvefctx(rev, resolverev=True, adjustctx=True)

        # find a chain from rev to anything in the mainbranch
        if revfctx not in self.revmap:
            chain = [revfctx]
            a = ''
            while True:
                f = chain[-1]
                pl = self._parentfunc(f)
                if not pl:
                    break
                if pl[0] in self.revmap:
                    a = pl[0].data()
                    break
                chain.append(pl[0])

            # both self.linelog and self.revmap is backed by filesystem. now
            # we want to modify them but do not want to write changes back to
            # files. so we create in-memory objects and copy them. it's like
            # a "fork".
            linelog = linelogmod.linelog()
            linelog.copyfrom(self.linelog)
            linelog.annotate(linelog.maxrev)
            revmap = revmapmod.revmap()
            revmap.copyfrom(self.revmap)

            for f in reversed(chain):
                b = f.data()
                blocks = list(self._diffblocks(a, b))
                self._doappendrev(linelog, revmap, f, blocks)
                a = b
        else:
            # fastpath: use existing linelog, revmap as we don't write to them
            linelog = self.linelog
            revmap = self.revmap

        lines = linelog.getalllines()
        hsh = revfctx.node()
        llrev = revmap.hsh2rev(hsh)
        result = [(revmap.rev2hsh(r), l) for r, l in lines if r <= llrev]
        # cannot use _refineannotateresult since we need custom logic for
        # resolving line contents
        if showpath:
            result = self._addpathtoresult(result, revmap)
        if showlines:
            linecontents = self._resolvelines(result, revmap, linelog)
            result = (result, linecontents)
        return result
Example #4
0
 def testparseclinelogfile(self):
     # This data is what the replacements in testsimpleedits
     # produce when fed to the original linelog.c implementation.
     data = (b'\x00\x00\x00\x0c\x00\x00\x00\x0f'
             b'\x00\x00\x00\x00\x00\x00\x00\x02'
             b'\x00\x00\x00\x05\x00\x00\x00\x06'
             b'\x00\x00\x00\x06\x00\x00\x00\x00'
             b'\x00\x00\x00\x00\x00\x00\x00\x07'
             b'\x00\x00\x00\x06\x00\x00\x00\x02'
             b'\x00\x00\x00\x00\x00\x00\x00\x00'
             b'\x00\x00\x00\t\x00\x00\x00\t'
             b'\x00\x00\x00\x00\x00\x00\x00\x0c'
             b'\x00\x00\x00\x08\x00\x00\x00\x05'
             b'\x00\x00\x00\x06\x00\x00\x00\x01'
             b'\x00\x00\x00\x00\x00\x00\x00\x05'
             b'\x00\x00\x00\x0c\x00\x00\x00\x05'
             b'\x00\x00\x00\n\x00\x00\x00\x01'
             b'\x00\x00\x00\x00\x00\x00\x00\t')
     llc = linelog.linelog.fromdata(data)
     self.assertEqual([(l.rev, l.linenum) for l in llc.annotate(1)], [
         (1, 0),
         (1, 1),
         (1, 2),
     ])
     self.assertEqual([(l.rev, l.linenum) for l in llc.annotate(2)], [
         (1, 0),
         (2, 1),
         (1, 2),
     ])
     self.assertEqual([(l.rev, l.linenum) for l in llc.annotate(3)], [
         (1, 0),
         (1, 2),
     ])
     # Check we emit the same bytecode.
     ll = linelog.linelog()
     # Initial revision: add lines 0, 1, and 2
     ll.replacelines(1, 0, 0, 0, 3)
     # Replace line 1 with a new line
     ll.replacelines(2, 1, 2, 1, 2)
     # delete a line out of 2
     ll.replacelines(3, 1, 2, 0, 0)
     diff = '\n   ' + '\n   '.join(
         difflib.unified_diff(ll.debugstr().splitlines(),
                              llc.debugstr().splitlines(),
                              'python',
                              'c',
                              lineterm=''))
     self.assertEqual(ll._program, llc._program,
                      'Program mismatch: ' + diff)
     # Done as a secondary step so we get a better result if the
     # program is where the mismatch is.
     self.assertEqual(ll, llc)
     self.assertEqual(ll.encode(), data)
Example #5
0
 def _buildlinelog(self):
     """calculate the initial linelog based on self.content{,line}s.
     this is similar to running a partial "annotate".
     """
     llog = linelog.linelog()
     a, alines = b'', []
     for i in pycompat.xrange(len(self.contents)):
         b, blines = self.contents[i], self.contentlines[i]
         llrev = i * 2 + 1
         chunks = self._alldiffchunks(a, b, alines, blines)
         for a1, a2, b1, b2 in reversed(list(chunks)):
             llog.replacelines(llrev, a1, a2, b1, b2)
         a, alines = b, blines
     return llog
Example #6
0
 def testrandomedits(self):
     # Inspired by original linelog tests.
     seed = random.random()
     numrevs = 2000
     ll = linelog.linelog()
     # Populate linelog
     for lines, rev, a1, a2, b1, b2, blines, usevec in _genedits(
             seed, numrevs):
         if usevec:
             ll.replacelines_vec(rev, a1, a2, blines)
         else:
             ll.replacelines(rev, a1, a2, b1, b2)
         ar = ll.annotate(rev)
         self.assertEqual(ll.annotateresult, lines)
     # Verify we can get back these states by annotating each rev
     for lines, rev, a1, a2, b1, b2, blines, usevec in _genedits(
             seed, numrevs):
         ar = ll.annotate(rev)
         self.assertEqual([(l.rev, l.linenum) for l in ar], lines)
Example #7
0
 def testsimpleedits(self):
     ll = linelog.linelog()
     # Initial revision: add lines 0, 1, and 2
     ll.replacelines(1, 0, 0, 0, 3)
     self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(1)], [
         (1, 0),
         (1, 1),
         (1, 2),
     ])
     # Replace line 1 with a new line
     ll.replacelines(2, 1, 2, 1, 2)
     self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(2)], [
         (1, 0),
         (2, 1),
         (1, 2),
     ])
     # delete a line out of 2
     ll.replacelines(3, 1, 2, 0, 0)
     self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(3)], [
         (1, 0),
         (1, 2),
     ])
     # annotation of 1 is unchanged
     self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(1)], [
         (1, 0),
         (1, 1),
         (1, 2),
     ])
     ll.annotate(3)  # set internal state to revision 3
     start = ll.getoffset(0)
     end = ll.getoffset(1)
     self.assertEqual(ll.getalllines(start, end), [
         (1, 0),
         (2, 1),
         (1, 1),
     ])
     self.assertEqual(ll.getalllines(), [
         (1, 0),
         (2, 1),
         (1, 1),
         (1, 2),
     ])
Example #8
0
 def testlinelogencodedecode(self):
     program = [
         linelog._eof(0, 0),
         linelog._jge(41, 42),
         linelog._jump(0, 43),
         linelog._eof(0, 0),
         linelog._jl(44, 45),
         linelog._line(46, 47),
     ]
     ll = linelog.linelog(program, maxrev=100)
     enc = ll.encode()
     # round-trips okay
     self.assertEqual(linelog.linelog.fromdata(enc)._program, ll._program)
     self.assertEqual(linelog.linelog.fromdata(enc), ll)
     # This encoding matches the encoding used by hg-experimental's
     # linelog file, or is supposed to if it doesn't.
     self.assertEqual(enc, (b'\x00\x00\x01\x90\x00\x00\x00\x06'
                            b'\x00\x00\x00\xa4\x00\x00\x00*'
                            b'\x00\x00\x00\x00\x00\x00\x00+'
                            b'\x00\x00\x00\x00\x00\x00\x00\x00'
                            b'\x00\x00\x00\xb1\x00\x00\x00-'
                            b'\x00\x00\x00\xba\x00\x00\x00/'))