Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/patch.py @ 10135:9a4034b630c4 stable
patch: better handling of sequence of offset patch hunks (issue1941)
The built-in patch implementation applied the hunks to the wrong lines of the
file if the file in the repo has been modified to skew the patch line numbers
and the file contains repetitive sequences of lines.
author | Greg Onufer <gonufer@jazzhaiku.com> |
---|---|
date | Wed, 09 Dec 2009 16:56:00 -0800 |
parents | 3f522d2fa633 |
children | 270367ec4d30 6e26e3c2083f |
comparison
equal
deleted
inserted
replaced
10132:ebf69364e80f | 10135:9a4034b630c4 |
---|---|
284 self.ui.warn(_("unable to find '%s' for patching\n") % self.fname) | 284 self.ui.warn(_("unable to find '%s' for patching\n") % self.fname) |
285 | 285 |
286 self.hash = {} | 286 self.hash = {} |
287 self.dirty = 0 | 287 self.dirty = 0 |
288 self.offset = 0 | 288 self.offset = 0 |
289 self.skew = 0 | |
289 self.rej = [] | 290 self.rej = [] |
290 self.fileprinted = False | 291 self.fileprinted = False |
291 self.printfile(False) | 292 self.printfile(False) |
292 self.hunks = 0 | 293 self.hunks = 0 |
293 | 294 |
421 if h.starta == 0: | 422 if h.starta == 0: |
422 start = 0 | 423 start = 0 |
423 else: | 424 else: |
424 start = h.starta + self.offset - 1 | 425 start = h.starta + self.offset - 1 |
425 orig_start = start | 426 orig_start = start |
426 if diffhelpers.testhunk(old, self.lines, start) == 0: | 427 # if there's skew we want to emit the "(offset %d lines)" even |
428 # when the hunk cleanly applies at start + skew, so skip the | |
429 # fast case code | |
430 if self.skew == 0 and diffhelpers.testhunk(old, self.lines, start) == 0: | |
427 if h.rmfile(): | 431 if h.rmfile(): |
428 self.unlink(self.fname) | 432 self.unlink(self.fname) |
429 else: | 433 else: |
430 self.lines[start : start + h.lena] = h.new() | 434 self.lines[start : start + h.lena] = h.new() |
431 self.offset += h.lenb - h.lena | 435 self.offset += h.lenb - h.lena |
437 if h.hunk[-1][0] != ' ': | 441 if h.hunk[-1][0] != ' ': |
438 # if the hunk tried to put something at the bottom of the file | 442 # if the hunk tried to put something at the bottom of the file |
439 # override the start line and use eof here | 443 # override the start line and use eof here |
440 search_start = len(self.lines) | 444 search_start = len(self.lines) |
441 else: | 445 else: |
442 search_start = orig_start | 446 search_start = orig_start + self.skew |
443 | 447 |
444 for fuzzlen in xrange(3): | 448 for fuzzlen in xrange(3): |
445 for toponly in [ True, False ]: | 449 for toponly in [ True, False ]: |
446 old = h.old(fuzzlen, toponly) | 450 old = h.old(fuzzlen, toponly) |
447 | 451 |
449 for l in cand: | 453 for l in cand: |
450 if diffhelpers.testhunk(old, self.lines, l) == 0: | 454 if diffhelpers.testhunk(old, self.lines, l) == 0: |
451 newlines = h.new(fuzzlen, toponly) | 455 newlines = h.new(fuzzlen, toponly) |
452 self.lines[l : l + len(old)] = newlines | 456 self.lines[l : l + len(old)] = newlines |
453 self.offset += len(newlines) - len(old) | 457 self.offset += len(newlines) - len(old) |
458 self.skew = l - orig_start | |
454 self.dirty = 1 | 459 self.dirty = 1 |
455 if fuzzlen: | 460 if fuzzlen: |
456 fuzzstr = "with fuzz %d " % fuzzlen | 461 fuzzstr = "with fuzz %d " % fuzzlen |
457 f = self.ui.warn | 462 f = self.ui.warn |
458 self.printfile(True) | 463 self.printfile(True) |