Patchwork copies: fix detection of divergent directory renames

login
register
mail settings
Submitter Matt Mackall
Date Jan. 14, 2016, 8:18 p.m.
Message ID <bd0fd63e29dc589709fe.1452802736@ruin.waste.org>
Download mbox | patch
Permalink /patch/12767/
State Superseded
Commit 602add6ad9e519598e72c873f7a6581dbbb9e390
Delegated to: Pierre-Yves David
Headers show

Comments

Matt Mackall - Jan. 14, 2016, 8:18 p.m.
# HG changeset patch
# User Matt Mackall <mpm@selenic.com>
# Date 1452701405 21600
#      Wed Jan 13 10:10:05 2016 -0600
# Node ID bd0fd63e29dc589709fe5232b32bef3533445754
# Parent  0ac5b7ee5dc20b9d25effe654c3f73335db19e5b
copies: fix detection of divergent directory renames

If we move all the files out of one directory, but into two different
directories, we should not consider it a directory rename. The
detection of this case was broken.
Long Vu - Jan. 14, 2016, 8:43 p.m.
Thanks Matt for the quick patch.

Nice to also test merging in the other direction.

Minor comments below.


On Thu, Jan 14, 2016 at 3:18 PM, Matt Mackall <mpm@selenic.com> wrote:
> # HG changeset patch
> # User Matt Mackall <mpm@selenic.com>
> # Date 1452701405 21600
> #      Wed Jan 13 10:10:05 2016 -0600
> # Node ID bd0fd63e29dc589709fe5232b32bef3533445754
> # Parent  0ac5b7ee5dc20b9d25effe654c3f73335db19e5b
> copies: fix detection of divergent directory renames
>
> If we move all the files out of one directory, but into two different
> directories, we should not consider it a directory rename. The
> detection of this case was broken.
>
> diff -r 0ac5b7ee5dc2 -r bd0fd63e29dc mercurial/copies.py
> --- a/mercurial/copies.py       Sun Jan 10 08:03:58 2016 +0000
> +++ b/mercurial/copies.py       Wed Jan 13 10:10:05 2016 -0600
> @@ -401,13 +401,13 @@
>              continue
>          elif dsrc in d1 and ddst in d1:
>              # directory wasn't entirely moved locally
> -            invalid.add(dsrc)
> +            invalid.add(dsrc + "/")
>          elif dsrc in d2 and ddst in d2:
>              # directory wasn't entirely moved remotely
> -            invalid.add(dsrc)
> -        elif dsrc in dirmove and dirmove[dsrc] != ddst:
> +            invalid.add(dsrc + "/")
> +        elif dsrc + "/" in dirmove and dirmove[dsrc + "/"] != ddst + "/":
>              # files from the same directory moved to two different places
> -            invalid.add(dsrc)
> +            invalid.add(dsrc + "/")
>          else:
>              # looks good so far
>              dirmove[dsrc + "/"] = ddst + "/"
> diff -r 0ac5b7ee5dc2 -r bd0fd63e29dc tests/test-rename-dir-merge.t
> --- a/tests/test-rename-dir-merge.t     Sun Jan 10 08:03:58 2016 +0000
> +++ b/tests/test-rename-dir-merge.t     Wed Jan 13 10:10:05 2016 -0600
> @@ -231,3 +231,55 @@
>    R a/f
>
>    $ cd ..
> +
> +Test renames to separate directories
> +
> +  $ hg init a
> +  $ cd a
> +  $ mkdir a
> +  $ touch a/s
> +  $ touch a/t
> +  $ hg ci -Am0
> +  adding a/s
> +  adding a/t
> +
> +Add more files
> +
> +  $ touch a/s2
> +  $ touch a/t2
> +  $ hg ci -Am1
> +  adding a/s2
> +  adding a/t2
> +
> +Do moves on a branch
> +
> +  $ hg up 0
> +  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
> +  $ mkdir s
> +  $ mkdir t
> +  $ hg mv a/s s
> +  $ hg mv a/t t
> +  $ hg ci -Am2
> +  created new head
> +
> +Merge shouldn't move s2, t2
> +
> +  $ hg merge
> +  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  (branch merge, don't forget to commit)
> +  $ hg st

hg st --copies?

To show this will be a add operation and not a rename (no copies).

> +  M a/s2
> +  M a/t2
> +
> +Try the merge in the other direction
> +
> +  $ hg up -C 1
> +  4 files updated, 0 files merged, 2 files removed, 0 files unresolved
> +  $ hg merge
> +  2 files updated, 0 files merged, 2 files removed, 0 files unresolved
> +  (branch merge, don't forget to commit)
> +  $ hg st

Use hg st --copies also?

To show this is a rename (copies under the "M" entries?)

> +  M s/s
> +  M t/t
> +  R a/s
> +  R a/t
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff -r 0ac5b7ee5dc2 -r bd0fd63e29dc mercurial/copies.py
--- a/mercurial/copies.py	Sun Jan 10 08:03:58 2016 +0000
+++ b/mercurial/copies.py	Wed Jan 13 10:10:05 2016 -0600
@@ -401,13 +401,13 @@ 
             continue
         elif dsrc in d1 and ddst in d1:
             # directory wasn't entirely moved locally
-            invalid.add(dsrc)
+            invalid.add(dsrc + "/")
         elif dsrc in d2 and ddst in d2:
             # directory wasn't entirely moved remotely
-            invalid.add(dsrc)
-        elif dsrc in dirmove and dirmove[dsrc] != ddst:
+            invalid.add(dsrc + "/")
+        elif dsrc + "/" in dirmove and dirmove[dsrc + "/"] != ddst + "/":
             # files from the same directory moved to two different places
-            invalid.add(dsrc)
+            invalid.add(dsrc + "/")
         else:
             # looks good so far
             dirmove[dsrc + "/"] = ddst + "/"
diff -r 0ac5b7ee5dc2 -r bd0fd63e29dc tests/test-rename-dir-merge.t
--- a/tests/test-rename-dir-merge.t	Sun Jan 10 08:03:58 2016 +0000
+++ b/tests/test-rename-dir-merge.t	Wed Jan 13 10:10:05 2016 -0600
@@ -231,3 +231,55 @@ 
   R a/f
 
   $ cd ..
+
+Test renames to separate directories
+
+  $ hg init a
+  $ cd a
+  $ mkdir a
+  $ touch a/s
+  $ touch a/t
+  $ hg ci -Am0
+  adding a/s
+  adding a/t
+
+Add more files
+
+  $ touch a/s2
+  $ touch a/t2
+  $ hg ci -Am1
+  adding a/s2
+  adding a/t2
+
+Do moves on a branch
+
+  $ hg up 0
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ mkdir s
+  $ mkdir t
+  $ hg mv a/s s
+  $ hg mv a/t t
+  $ hg ci -Am2
+  created new head
+
+Merge shouldn't move s2, t2
+
+  $ hg merge
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg st
+  M a/s2
+  M a/t2
+
+Try the merge in the other direction
+
+  $ hg up -C 1
+  4 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ hg merge
+  2 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg st
+  M s/s
+  M t/t
+  R a/s
+  R a/t