changeset 5260:0fc16031bb45

Make hg diff --git -r revA:revB detect (inverted) copies if revA > revB
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
date Tue, 28 Aug 2007 22:48:25 -0300
parents 8040f2e4cad0
children 15a108ad7adb
files mercurial/patch.py tests/test-git-export tests/test-git-export.out
diffstat 3 files changed, 77 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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()
--- 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'
--- 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