# HG changeset patch # User Greg Onufer # Date 2009-12-10 00:56:00 # Node ID 9a4034b630c4218db26091c75175ed3168ea42cb # Parent ebf69364e80f289b289d5807631a93ede2c9f936 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. diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -286,6 +286,7 @@ class patchfile(object): self.hash = {} self.dirty = 0 self.offset = 0 + self.skew = 0 self.rej = [] self.fileprinted = False self.printfile(False) @@ -423,7 +424,10 @@ class patchfile(object): else: start = h.starta + self.offset - 1 orig_start = start - if diffhelpers.testhunk(old, self.lines, start) == 0: + # if there's skew we want to emit the "(offset %d lines)" even + # when the hunk cleanly applies at start + skew, so skip the + # fast case code + if self.skew == 0 and diffhelpers.testhunk(old, self.lines, start) == 0: if h.rmfile(): self.unlink(self.fname) else: @@ -439,7 +443,7 @@ class patchfile(object): # override the start line and use eof here search_start = len(self.lines) else: - search_start = orig_start + search_start = orig_start + self.skew for fuzzlen in xrange(3): for toponly in [ True, False ]: @@ -451,6 +455,7 @@ class patchfile(object): newlines = h.new(fuzzlen, toponly) self.lines[l : l + len(old)] = newlines self.offset += len(newlines) - len(old) + self.skew = l - orig_start self.dirty = 1 if fuzzlen: fuzzstr = "with fuzz %d " % fuzzlen diff --git a/tests/test-patch-offset b/tests/test-patch-offset new file mode 100755 --- /dev/null +++ b/tests/test-patch-offset @@ -0,0 +1,67 @@ +#!/bin/sh + +cat > writepatterns.py <