mercurial/linelog.py
changeset 38971 ee97f7a677f3
parent 38970 32b1967b8734
child 43076 2372284d9457
equal deleted inserted replaced
38970:32b1967b8734 38971:ee97f7a677f3
   311         programlen = self._program.__len__
   311         programlen = self._program.__len__
   312         oldproglen = programlen()
   312         oldproglen = programlen()
   313         appendinst = self._program.append
   313         appendinst = self._program.append
   314 
   314 
   315         # insert
   315         # insert
       
   316         blineinfos = []
       
   317         bappend = blineinfos.append
   316         if b1 < b2:
   318         if b1 < b2:
   317             # Determine the jump target for the JGE at the start of
   319             # Determine the jump target for the JGE at the start of
   318             # the new block.
   320             # the new block.
   319             tgt = oldproglen + (b2 - b1 + 1)
   321             tgt = oldproglen + (b2 - b1 + 1)
   320             # Jump to skip the insert if we're at an older revision.
   322             # Jump to skip the insert if we're at an older revision.
   321             appendinst(_jl(rev, tgt))
   323             appendinst(_jl(rev, tgt))
   322             for linenum in pycompat.xrange(b1, b2):
   324             for linenum in pycompat.xrange(b1, b2):
   323                 if _internal_blines is None:
   325                 if _internal_blines is None:
       
   326                     bappend(lineinfo(rev, linenum, programlen()))
   324                     appendinst(_line(rev, linenum))
   327                     appendinst(_line(rev, linenum))
   325                 else:
   328                 else:
   326                     appendinst(_line(*_internal_blines[linenum]))
   329                     newrev, newlinenum = _internal_blines[linenum]
       
   330                     bappend(lineinfo(newrev, newlinenum, programlen()))
       
   331                     appendinst(_line(newrev, newlinenum))
   327         # delete
   332         # delete
   328         if a1 < a2:
   333         if a1 < a2:
   329             if a2 > len(ar.lines):
   334             if a2 > len(ar.lines):
   330                 raise LineLogError(
   335                 raise LineLogError(
   331                     '%d contains %d lines, tried to access line %d' % (
   336                     '%d contains %d lines, tried to access line %d' % (
   340                 # invisible lines between a2-1 and a2 (IOW, lines that
   345                 # invisible lines between a2-1 and a2 (IOW, lines that
   341                 # are added later).
   346                 # are added later).
   342                 endaddr = ar.lines[a2 - 1]._offset + 1
   347                 endaddr = ar.lines[a2 - 1]._offset + 1
   343             appendinst(_jge(rev, endaddr))
   348             appendinst(_jge(rev, endaddr))
   344         # copy instruction from a1
   349         # copy instruction from a1
       
   350         a1instpc = programlen()
   345         appendinst(a1inst)
   351         appendinst(a1inst)
   346         # if a1inst isn't a jump or EOF, then we need to add an unconditional
   352         # if a1inst isn't a jump or EOF, then we need to add an unconditional
   347         # jump back into the program here.
   353         # jump back into the program here.
   348         if not isinstance(a1inst, (_jump, _eof)):
   354         if not isinstance(a1inst, (_jump, _eof)):
   349             appendinst(_jump(0, a1info._offset + 1))
   355             appendinst(_jump(0, a1info._offset + 1))
   350         # Patch instruction at a1, which makes our patch live.
   356         # Patch instruction at a1, which makes our patch live.
   351         self._program[a1info._offset] = _jump(0, oldproglen)
   357         self._program[a1info._offset] = _jump(0, oldproglen)
   352         # For compat with the C version, re-annotate rev so that
   358 
   353         # self.annotateresult is cromulent.. We could fix up the
   359         # Update self._lastannotate in place. This serves as a cache to avoid
   354         # annotateresult in place (which is how the C version works),
   360         # expensive "self.annotate" in this function, when "replacelines" is
   355         # but for now we'll pass on that and see if it matters in
   361         # used continuously.
   356         # practice.
   362         if len(self._lastannotate.lines) > a1:
   357         self.annotate(max(self._lastannotate.rev, rev))
   363             self._lastannotate.lines[a1]._offset = a1instpc
       
   364         else:
       
   365             assert isinstance(a1inst, _eof)
       
   366             self._lastannotate._eof = a1instpc
       
   367         self._lastannotate.lines[a1:a2] = blineinfos
       
   368         self._lastannotate.rev = max(self._lastannotate.rev, rev)
       
   369 
   358         if rev > self._maxrev:
   370         if rev > self._maxrev:
   359             self._maxrev = rev
   371             self._maxrev = rev
   360 
   372 
   361     def annotate(self, rev):
   373     def annotate(self, rev):
   362         pc = 1
   374         pc = 1