# HG changeset patch # User Patrick Mezard # Date 2008-03-17 22:36:45 # Node ID bace1990ab123f998567b1f2e9584cfc5fc7948d # Parent 9cd6292abfdf3ebc83085984525ae0f8063430c3 patch: fix corner case with update + copy patch handling (issue 937) The self patching of files when diffed with a backup is a bit peculiar to me. It makes sense in mpatch, that's less clear in mercurial patching code. Let's document and preserve it for now. diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -800,13 +800,13 @@ def selectfile(afile_orig, bfile_orig, h while i < pathlen - 1 and path[i] == '/': i += 1 count -= 1 - return path[i:].rstrip() + return path[:i].lstrip(), path[i:].rstrip() nulla = afile_orig == "/dev/null" nullb = bfile_orig == "/dev/null" - afile = pathstrip(afile_orig, strip) + abase, afile = pathstrip(afile_orig, strip) gooda = not nulla and os.path.exists(afile) - bfile = pathstrip(bfile_orig, strip) + bbase, bfile = pathstrip(bfile_orig, strip) if afile == bfile: goodb = gooda else: @@ -815,16 +815,20 @@ def selectfile(afile_orig, bfile_orig, h if reverse: createfunc = hunk.rmfile missing = not goodb and not gooda and not createfunc() + # If afile is "a/b/foo" and bfile is "a/b/foo.orig" we assume the + # diff is between a file and its backup. In this case, the original + # file should be patched (see original mpatch code). + isbackup = (abase == bbase and bfile.startswith(afile)) fname = None if not missing: if gooda and goodb: - fname = (afile in bfile) and afile or bfile + fname = isbackup and afile or bfile elif gooda: fname = afile if not fname: if not nullb: - fname = (afile in bfile) and afile or bfile + fname = isbackup and afile or bfile elif not nulla: fname = afile else: diff --git a/tests/test-import b/tests/test-import --- a/tests/test-import +++ b/tests/test-import @@ -225,3 +225,22 @@ hg import remove.diff hg manifest cd .. +echo % 'test update+rename with common name (issue 927)' +hg init t +cd t +touch a +hg ci -Am t +echo a > a +# Here, bfile.startswith(afile) +hg copy a a2 +hg ci -m copya +hg export --git tip > copy.diff +hg up -C 0 +hg import copy.diff +echo % view a +# a should contain an 'a' +cat a +echo % view a2 +# and a2 should have duplicated it +cat a2 +cd .. diff --git a/tests/test-import.out b/tests/test-import.out --- a/tests/test-import.out +++ b/tests/test-import.out @@ -232,3 +232,11 @@ diff --git a/a b/a diff --git a/b b/b 2 files updated, 0 files merged, 0 files removed, 0 files unresolved applying remove.diff +% test update+rename with common name (issue 927) +adding a +1 files updated, 0 files merged, 1 files removed, 0 files unresolved +applying copy.diff +% view a +a +% view a2 +a