# HG changeset patch # User Greg Onufer # Date 1260406560 28800 # 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 -r ebf69364e80f -r 9a4034b630c4 mercurial/patch.py --- a/mercurial/patch.py Wed Dec 23 20:31:35 2009 +0100 +++ b/mercurial/patch.py Wed Dec 09 16:56:00 2009 -0800 @@ -286,6 +286,7 @@ self.hash = {} self.dirty = 0 self.offset = 0 + self.skew = 0 self.rej = [] self.fileprinted = False self.printfile(False) @@ -423,7 +424,10 @@ 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 @@ # 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 @@ 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 -r ebf69364e80f -r 9a4034b630c4 tests/test-patch-offset --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-patch-offset Wed Dec 09 16:56:00 2009 -0800 @@ -0,0 +1,67 @@ +#!/bin/sh + +cat > writepatterns.py <