[patch] convert/filemap: rename of moved files results in lost file (issue2243)

Edward Lee edilee at mozilla.com
Mon Jun 21 02:32:29 CDT 2010


http://mercurial.selenic.com/bts/msg12855

Prevent renamed moved files from being deleted (as well as losing
annotation/blame if a later changeset revives the deleted file).

Ed
-------------- next part --------------
# HG changeset patch
# User Edward Lee <edilee at mozilla.com>
# Date 1277101246 25200
# Node ID 3454c2f03702b40314a46626139e2e78b3597168
# Parent  42408cd43f55be6d24ada3a41bc4261b15c94384
convert/filemap: rename of moved files results in lost file (issue2243)

diff --git a/hgext/convert/filemap.py b/hgext/convert/filemap.py
--- a/hgext/convert/filemap.py
+++ b/hgext/convert/filemap.py
@@ -321,18 +321,28 @@ class filemap_source(converter_source):
         # able to get the files later on in getfile, we hide the
         # original filename in the rev part of the return value.
         changes, copies = self.base.getchanges(rev)
         newnames = {}
         files = []
         for f, r in changes:
             newf = self.filemapper(f)
             if newf:
-                files.append((newf, (f, r)))
-                newnames[f] = newf
+                # If we already have a mapping, it must be a move of an already
+                # convert-renamed file, so we make sure to give the filename of
+                # the one that will exist after the move.
+                if newf in newnames:
+                    try:
+                        self.base.getfile(f, r)
+                        files.remove((newf, newnames[newf]))
+                    except IOError:
+                        continue
+
+                newnames[newf] = (f, r)
+                files.append((newf, newnames[newf]))
 
         ncopies = {}
         for c in copies:
             newc = self.filemapper(c)
             if newc:
                 newsource = self.filemapper(copies[c])
                 if newsource:
                     ncopies[newc] = newsource
diff --git a/tests/test-convert-filemap b/tests/test-convert-filemap
--- a/tests/test-convert-filemap
+++ b/tests/test-convert-filemap
@@ -103,28 +103,57 @@ splitrepo 'partial conversion' 'foo' '-r
 splitrepo 'complete the partial conversion' 'foo'
 
 splitrepo 'copied file; source not included in new repo' copied
 hg --cwd copied.repo debugrename copied
 
 splitrepo 'copied file; source included in new repo' 'foo copied'
 hg --cwd foo-copied.repo debugrename copied
 
+cd source
+mkdir rename
+echo a > rename/a
+echo z > rename/z
+hg ci -qAm '9: add rename/a rename/z'
+
+hg mv rename/a rename/b
+hg mv rename/z rename/y
+hg ci -m '10: move a->b z->y'
+
+cd ..
+glog -R source
+
 cat > renames.fmap <<EOF
 include dir
 exclude dir/file2
 rename dir dir2
 include foo
 include copied
 rename foo foo2
 rename copied copied2
+include rename/a
+include rename/b
+include rename/y
+include rename/z
+rename rename/a rename/ab
+rename rename/b rename/ab
+rename rename/y rename/yz
+rename rename/z rename/yz
 exclude dir/subdir
 include dir/subdir/file3
 EOF
 hg -q convert --filemap renames.fmap --datesort source renames.repo
 hg up -q -R renames.repo
 glog -R renames.repo
 hg -R renames.repo manifest --debug
 hg --cwd renames.repo debugrename copied2
 echo 'copied:'
 hg --cwd source cat copied
 echo 'copied2:'
 hg --cwd renames.repo cat copied2
+echo 'rename/b:'
+hg --cwd source cat rename/b
+echo 'rename/ab:'
+hg --cwd renames.repo cat rename/ab
+echo 'rename/y:'
+hg --cwd source cat rename/y
+echo 'rename/yz:'
+hg --cwd renames.repo cat rename/yz
diff --git a/tests/test-convert-filemap.out b/tests/test-convert-filemap.out
--- a/tests/test-convert-filemap.out
+++ b/tests/test-convert-filemap.out
@@ -133,27 +133,61 @@ o  2 "2: change foo" files: foo
 |
 o  1 "1: add bar quux; copy foo to copied" files: copied
 |
 o  0 "0: add foo baz dir/" files: foo
 
 7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644   copied
 9a7b52012991e4873687192c3e17e61ba3e837a3 644   foo
 copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
-@  4 "8: change foo" files: foo2
+@  10 "10: move a->b z->y" files: rename/a rename/b rename/y rename/z
+|
+o  9 "9: add rename/a rename/z" files: rename/a rename/z
+|
+o  8 "8: change foo" files: foo
+|
+o    7 "7: second merge; change bar" files: bar baz
+|\
+| o  6 "6: change foo baz" files: baz foo
+| |
+o |  5 "5: change bar baz quux" files: bar baz quux
+|/
+o    4 "4: first merge; change bar baz" files: bar baz
+|\
+| o  3 "3: change bar quux" files: bar quux
+| |
+o |  2 "2: change foo" files: foo
+|/
+o  1 "1: add bar quux; copy foo to copied" files: bar copied quux
+|
+o  0 "0: add foo baz dir/" files: baz dir/file dir/file2 dir/subdir/file3 dir/subdir/file4 foo
+
+@  5 "9: add rename/a rename/z" files: rename/ab rename/yz
+|
+o  4 "8: change foo" files: foo2
 |
 o  3 "6: change foo baz" files: foo2
 |
 o  2 "2: change foo" files: foo2
 |
 o  1 "1: add bar quux; copy foo to copied" files: copied2
 |
 o  0 "0: add foo baz dir/" files: dir2/file dir2/subdir/file3 foo2
 
 d43feacba7a4f1f2080dde4a4b985bd8a0236d46 644   copied2
 3e20847584beff41d7cd16136b7331ab3d754be0 644   dir2/file
 5fe139720576e18e34bcc9f79174db8897c8afe9 644   dir2/subdir/file3
 9a7b52012991e4873687192c3e17e61ba3e837a3 644   foo2
+b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 644   rename/ab
+69a1b67522704ec122181c0890bd16e9d3e7516a 644   rename/yz
 copied2 renamed from foo2:2ed2a3912a0b24502043eae84ee4b279c18b90dd
 copied:
 foo
 copied2:
 foo
+rename/b:
+a
+rename/ab:
+a
+rename/y:
+z
+rename/yz:
+z


More information about the Mercurial-devel mailing list