# HG changeset patch # User Alexis S. L. Carvalho # Date 1188352105 10800 # Node ID 0fc16031bb458ae3f02ec947cfba3b8361961dcb # Parent 8040f2e4cad04e82cf7b67b7d671024f3a9af90f Make hg diff --git -r revA:revB detect (inverted) copies if revA > revB diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -1161,9 +1161,10 @@ def diff(repo, node1=None, node2=None, f # returns False if there was no rename between ctx1 and ctx2 # returns None if the file was created between ctx1 and ctx2 # returns the (file, node) present in ctx1 that was renamed to f in ctx2 - def renamed(f): - startrev = ctx1.rev() - c = ctx2 + # This will only really work if c1 is the Nth 1st parent of c2. + def renamed(c1, c2, man, f): + startrev = c1.rev() + c = c2 crev = c.rev() if crev is None: crev = repo.changelog.count() @@ -1179,7 +1180,7 @@ def diff(repo, node1=None, node2=None, f crev = c.parents()[0].rev() # try to reuse c = getctx(crev) - if f not in man1: + if f not in man: return None if f == orig: return False @@ -1193,11 +1194,27 @@ def diff(repo, node1=None, node2=None, f if opts.git: copied = {} - for f in added: - src = renamed(f) + c1, c2 = ctx1, ctx2 + files = added + man = man1 + if node2 and ctx1.rev() >= ctx2.rev(): + # renamed() starts at c2 and walks back in history until c1. + # Since ctx1.rev() >= ctx2.rev(), invert ctx2 and ctx1 to + # detect (inverted) copies. + c1, c2 = ctx2, ctx1 + files = removed + man = ctx2.manifest() + for f in files: + src = renamed(c1, c2, man, f) if src: copied[f] = src - srcs = [x[1] for x in copied.items()] + if ctx1 == c2: + # invert the copied dict + copied = dict([(v, k) for (k, v) in copied.iteritems()]) + # If we've renamed file foo to bar (copied['bar'] = 'foo'), + # avoid showing a diff for foo if we're going to show + # the rename to bar. + srcs = [x[1] for x in copied.iteritems() if x[0] in added] all = modified + added + removed all.sort() diff --git a/tests/test-git-export b/tests/test-git-export --- a/tests/test-git-export +++ b/tests/test-git-export @@ -78,6 +78,8 @@ hg mv dst2 dst3 hg ci -m 'mv dst2 dst3; revert start' -d '0 0' hg diff --git -r 9:11 +echo '% reversed' +hg diff --git -r 11:9 echo a >> foo hg add foo @@ -92,12 +94,18 @@ hg ci -m 'change bar' echo echo '% file created before r1 and renamed before r2' hg diff --git -r -3:-1 +echo '% reversed' +hg diff --git -r -1:-3 echo echo '% file created in r1 and renamed before r2' hg diff --git -r -4:-1 +echo '% reversed' +hg diff --git -r -1:-4 echo echo '% file created after r1 and renamed before r2' hg diff --git -r -5:-1 +echo '% reversed' +hg diff --git -r -1:-5 echo echo '% comparing with the working dir' @@ -139,6 +147,8 @@ 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 +echo '% reversed' +hg diff --git -r -1 -r -2 echo '% there should be a trailing TAB if there are spaces in the file name' echo foo > 'with spaces' 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 @@ -75,6 +75,10 @@ rename to renamed.bin diff --git a/dst2 b/dst3 rename from dst2 rename to dst3 +% reversed +diff --git a/dst3 b/dst2 +rename from dst3 +rename to dst2 % file created before r1 and renamed before r2 diff --git a/foo b/bar @@ -86,6 +90,16 @@ rename to bar a b +c +% reversed +diff --git a/bar b/foo +rename from bar +rename to foo +--- a/foo ++++ b/foo +@@ -1,3 +1,2 @@ a + a + b +-c % file created in r1 and renamed before r2 diff --git a/foo b/bar @@ -97,6 +111,16 @@ rename to bar a +b +c +% reversed +diff --git a/bar b/foo +rename from bar +rename to foo +--- a/foo ++++ b/foo +@@ -1,3 +1,1 @@ a + a +-b +-c % file created after r1 and renamed before r2 diff --git a/bar b/bar @@ -107,6 +131,15 @@ new file mode 100644 +a +b +c +% reversed +diff --git a/bar b/bar +deleted file mode 100644 +--- a/bar ++++ /dev/null +@@ -1,3 +0,0 @@ +-a +-b +-c % comparing with the working dir % there's a copy in the working dir... @@ -145,6 +178,16 @@ rename to brand-new3 diff --git a/brand-new2 b/brand-new3-2 copy from brand-new2 copy to brand-new3-2 +% reversed +diff --git a/brand-new3 b/brand-new2 +rename from brand-new3 +rename to brand-new2 +diff --git a/brand-new3-2 b/brand-new3-2 +deleted file mode 100644 +--- a/brand-new3-2 ++++ /dev/null +@@ -1,1 +0,0 @@ +- % there should be a trailing TAB if there are spaces in the file name diff --git a/with spaces b/with spaces new file mode 100644