mercurial/patch.py
branchstable
changeset 16121 ccba74472af2
parent 16112 d7829b2ecf32
child 16122 9ef3a4a2c6c0
equal deleted inserted replaced
16119:5de83d9ca79c 16121:ccba74472af2
   726             # hunk data before patching. Otherwise, preserve input
   726             # hunk data before patching. Otherwise, preserve input
   727             # line-endings.
   727             # line-endings.
   728             h = h.getnormalized()
   728             h = h.getnormalized()
   729 
   729 
   730         # fast case first, no offsets, no fuzz
   730         # fast case first, no offsets, no fuzz
   731         old = h.old()
   731         old, new = h.fuzzit(0, False)
   732         start = h.starta + self.offset
   732         start = h.starta + self.offset
   733         # zero length hunk ranges already have their start decremented
   733         # zero length hunk ranges already have their start decremented
   734         if h.lena:
   734         if h.lena:
   735             start -= 1
   735             start -= 1
   736         orig_start = start
   736         orig_start = start
   739         # fast case code
   739         # fast case code
   740         if self.skew == 0 and diffhelpers.testhunk(old, self.lines, start) == 0:
   740         if self.skew == 0 and diffhelpers.testhunk(old, self.lines, start) == 0:
   741             if self.remove:
   741             if self.remove:
   742                 self.backend.unlink(self.fname)
   742                 self.backend.unlink(self.fname)
   743             else:
   743             else:
   744                 self.lines[start : start + h.lena] = h.new()
   744                 self.lines[start : start + h.lena] = new
   745                 self.offset += h.lenb - h.lena
   745                 self.offset += h.lenb - h.lena
   746                 self.dirty = True
   746                 self.dirty = True
   747             return 0
   747             return 0
   748 
   748 
   749         # ok, we couldn't match the hunk. Lets look for offsets and fuzz it
   749         # ok, we couldn't match the hunk. Lets look for offsets and fuzz it
   757         else:
   757         else:
   758             search_start = orig_start + self.skew
   758             search_start = orig_start + self.skew
   759 
   759 
   760         for fuzzlen in xrange(3):
   760         for fuzzlen in xrange(3):
   761             for toponly in [True, False]:
   761             for toponly in [True, False]:
   762                 old = h.old(fuzzlen, toponly)
   762                 old, new = h.fuzzit(fuzzlen, toponly)
   763 
   763 
   764                 cand = self.findlines(old[0][1:], search_start)
   764                 cand = self.findlines(old[0][1:], search_start)
   765                 for l in cand:
   765                 for l in cand:
   766                     if diffhelpers.testhunk(old, self.lines, l) == 0:
   766                     if diffhelpers.testhunk(old, self.lines, l) == 0:
   767                         newlines = h.new(fuzzlen, toponly)
   767                         self.lines[l : l + len(old)] = new
   768                         self.lines[l : l + len(old)] = newlines
   768                         self.offset += len(new) - len(old)
   769                         self.offset += len(newlines) - len(old)
       
   770                         self.skew = l - orig_start
   769                         self.skew = l - orig_start
   771                         self.dirty = True
   770                         self.dirty = True
   772                         offset = l - orig_start - fuzzlen
   771                         offset = l - orig_start - fuzzlen
   773                         if fuzzlen:
   772                         if fuzzlen:
   774                             msg = _("Hunk #%d succeeded at %d "
   773                             msg = _("Hunk #%d succeeded at %d "
   969             lr.push(l)
   968             lr.push(l)
   970 
   969 
   971     def complete(self):
   970     def complete(self):
   972         return len(self.a) == self.lena and len(self.b) == self.lenb
   971         return len(self.a) == self.lena and len(self.b) == self.lenb
   973 
   972 
   974     def fuzzit(self, l, fuzz, toponly):
   973     def _fuzzit(self, old, new, fuzz, toponly):
   975         # this removes context lines from the top and bottom of list 'l'.  It
   974         # this removes context lines from the top and bottom of list 'l'.  It
   976         # checks the hunk to make sure only context lines are removed, and then
   975         # checks the hunk to make sure only context lines are removed, and then
   977         # returns a new shortened list of lines.
   976         # returns a new shortened list of lines.
   978         fuzz = min(fuzz, len(l)-1)
   977         fuzz = min(fuzz, len(old)-1)
   979         if fuzz:
   978         if fuzz:
   980             top = 0
   979             top = 0
   981             bot = 0
   980             bot = 0
   982             hlen = len(self.hunk)
   981             hlen = len(self.hunk)
   983             for x in xrange(hlen - 1):
   982             for x in xrange(hlen - 1):
  1003             if top < context:
  1002             if top < context:
  1004                 top = max(0, fuzz - (context - top))
  1003                 top = max(0, fuzz - (context - top))
  1005             else:
  1004             else:
  1006                 top = min(fuzz, top)
  1005                 top = min(fuzz, top)
  1007 
  1006 
  1008             return l[top:len(l)-bot]
  1007             return old[top:len(old)-bot], new[top:len(new)-bot]
  1009         return l
  1008         return old, new
  1010 
  1009 
  1011     def old(self, fuzz=0, toponly=False):
  1010     def fuzzit(self, fuzz, toponly):
  1012         return self.fuzzit(self.a, fuzz, toponly)
  1011         return self._fuzzit(self.a, self.b, fuzz, toponly)
  1013 
       
  1014     def new(self, fuzz=0, toponly=False):
       
  1015         return self.fuzzit(self.b, fuzz, toponly)
       
  1016 
  1012 
  1017 class binhunk(object):
  1013 class binhunk(object):
  1018     'A binary patch file. Only understands literals so far.'
  1014     'A binary patch file. Only understands literals so far.'
  1019     def __init__(self, lr):
  1015     def __init__(self, lr):
  1020         self.text = None
  1016         self.text = None