diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -547,6 +547,7 @@ def diff(repo, node1=None, node2=None, f all = modified + added + removed all.sort() + gone = {} for f in all: to = None tn = None @@ -574,7 +575,11 @@ def diff(repo, node1=None, node2=None, f a, arev = copied[f] omode = gitmode(mmap.execf(a)) addmodehdr(header, omode, mode) - op = a in removed and 'rename' or 'copy' + if a in removed and a not in gone: + op = 'rename' + gone[a] = 1 + else: + op = 'copy' header.append('%s from %s\n' % (op, a)) header.append('%s to %s\n' % (op, f)) to = getfile(a).read(arev) diff --git a/tests/test-git-export b/tests/test-git-export --- a/tests/test-git-export +++ b/tests/test-git-export @@ -127,3 +127,11 @@ hg diff --git echo echo '% created between r1 and parent of wd; renamed in the wd' hg diff --git -r -2 +hg ci -m 'mv brand-new brand-new2' + +echo '% one file is copied to many destinations and removed' +hg cp brand-new2 brand-new3 +hg mv brand-new2 brand-new3-2 +hg ci -m 'multiple renames/copies' +hg diff --git -r -2 -r -1 + diff --git a/tests/test-git-export.out b/tests/test-git-export.out --- a/tests/test-git-export.out +++ b/tests/test-git-export.out @@ -133,3 +133,10 @@ new file mode 100644 +++ b/brand-new2 @@ -0,0 +1,1 @@ + +% one file is copied to many destinations and removed +diff --git a/brand-new2 b/brand-new3 +rename from brand-new2 +rename to brand-new3 +diff --git a/brand-new2 b/brand-new3-2 +copy from brand-new2 +copy to brand-new3-2