--- a/hgext/convert/bzr.py Wed Apr 22 20:15:55 2009 -0300
+++ b/hgext/convert/bzr.py Thu Apr 23 16:52:25 2009 +0200
@@ -148,6 +148,11 @@
# bazaar tracks directories, mercurial does not, so
# we have to rename the directory contents
if kind[1] == 'directory':
+ if kind[0] not in (None, 'directory'):
+ # Replacing 'something' with a directory, record it
+ # so it can be removed.
+ changes.append((self.recode(paths[0]), revid))
+
if None not in paths and paths[0] != paths[1]:
# neither an add nor an delete - a move
# rename all directory contents manually
--- a/hgext/convert/monotone.py Wed Apr 22 20:15:55 2009 -0300
+++ b/hgext/convert/monotone.py Thu Apr 23 16:52:25 2009 +0200
@@ -113,7 +113,8 @@
value = value.replace(r'\\', '\\')
certs[name] = value
# Monotone may have subsecond dates: 2005-02-05T09:39:12.364306
- certs["date"] = certs["date"].split('.')[0]
+ # and all times are stored in UTC
+ certs["date"] = certs["date"].split('.')[0] + " UTC"
return certs
# implement the converter_source interface:
@@ -128,14 +129,14 @@
#revision = self.mtncmd("get_revision %s" % rev).split("\n\n")
revision = self.mtnrun("get_revision", rev).split("\n\n")
files = {}
- addedfiles = {}
+ ignoremove = {}
renameddirs = []
copies = {}
for e in revision:
m = self.add_file_re.match(e)
if m:
files[m.group(1)] = rev
- addedfiles[m.group(1)] = rev
+ ignoremove[m.group(1)] = rev
m = self.patch_re.match(e)
if m:
files[m.group(1)] = rev
@@ -150,6 +151,7 @@
toname = m.group(2)
fromname = m.group(1)
if self.mtnisfile(toname, rev):
+ ignoremove[toname] = 1
copies[toname] = fromname
files[toname] = rev
files[fromname] = rev
@@ -161,10 +163,14 @@
for fromdir, todir in renameddirs:
renamed = {}
for tofile in self.files:
- if tofile in addedfiles:
+ if tofile in ignoremove:
continue
if tofile.startswith(todir + '/'):
renamed[tofile] = fromdir + tofile[len(todir):]
+ # Avoid chained moves like:
+ # d1(/a) => d3/d1(/a)
+ # d2 => d3
+ ignoremove[tofile] = 1
for tofile, fromfile in renamed.items():
self.ui.debug (_("copying file in renamed directory "
"from '%s' to '%s'")
--- a/tests/hghave Wed Apr 22 20:15:55 2009 -0300
+++ b/tests/hghave Thu Apr 23 16:52:25 2009 +0200
@@ -31,6 +31,14 @@
except ImportError:
return False
+def has_bzr114():
+ try:
+ import bzrlib
+ return (bzrlib.__doc__ != None
+ and bzrlib.version_info[:2] == (1, 14))
+ except ImportError:
+ return False
+
def has_cvs():
re = r'Concurrent Versions System.*?server'
return matchoutput('cvs --version 2>&1', re)
@@ -163,6 +171,7 @@
checks = {
"baz": (has_baz, "GNU Arch baz client"),
"bzr": (has_bzr, "Canonical's Bazaar client"),
+ "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"),
"cvs": (has_cvs, "cvs client/server"),
"cvsps": (has_cvsps, "cvsps utility"),
"darcs": (has_darcs, "darcs client"),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-convert-bzr-114 Thu Apr 23 16:52:25 2009 +0200
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+"$TESTDIR/hghave" bzr114 || exit 80
+
+. "$TESTDIR/bzr-definitions"
+
+# The file/directory replacement can only be reproduced on
+# bzr >= 1.4. Merge it back in test-convert-bzr-directories once
+# this version becomes mainstream.
+echo % replace file with dir
+mkdir test-replace-file-with-dir
+cd test-replace-file-with-dir
+bzr init -q source
+cd source
+echo d > d
+bzr add -q d
+bzr commit -q -m 'add d file'
+rm d
+mkdir d
+bzr add -q d
+bzr commit -q -m 'replace with d dir'
+echo a > d/a
+bzr add -q d/a
+bzr commit -q -m 'add d/a'
+cd ..
+hg convert source source-hg
+manifest source-hg tip
+cd source-hg
+hg update
+cd ../..
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-convert-bzr-114.out Thu Apr 23 16:52:25 2009 +0200
@@ -0,0 +1,11 @@
+% replace file with dir
+initializing destination source-hg repository
+scanning source...
+sorting...
+converting...
+2 add d file
+1 replace with d dir
+0 add d/a
+% manifest of tip
+644 d/a
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/tests/test-convert-mtn Wed Apr 22 20:15:55 2009 -0300
+++ b/tests/test-convert-mtn Thu Apr 23 16:52:25 2009 +0200
@@ -80,6 +80,34 @@
mtn ci -m emptydir
mtn drop -R dir2/dir
mtn ci -m dropdirectory
+echo '% test directory and file move'
+mkdir -p dir3/d1
+echo a > dir3/a
+mtn add dir3/a dir3/d1
+mtn ci -m dirfilemove
+mtn mv dir3/a dir3/d1/a
+mtn mv dir3/d1 dir3/d2
+mtn ci -m dirfilemove2
+echo '% test directory move into another directory move'
+mkdir dir4
+mkdir dir5
+echo a > dir4/a
+mtn add dir4/a dir5
+mtn ci -m dirdirmove
+mtn mv dir5 dir6
+mtn mv dir4 dir6/dir4
+mtn ci -m dirdirmove2
+echo '% test diverging directory moves'
+mkdir -p dir7/dir9/dir8
+echo a > dir7/dir9/dir8/a
+echo b > dir7/dir9/b
+echo c > dir7/c
+mtn add -R dir7
+mtn ci -m divergentdirmove
+mtn mv dir7 dir7-2
+mtn mv dir7-2/dir9 dir9-2
+mtn mv dir9-2/dir8 dir8-2
+mtn ci -m divergentdirmove2
cd ..
echo % convert incrementally
@@ -108,5 +136,11 @@
hg log -v -C -r 4 | grep copies
echo % check file remove with directory move
hg manifest -r 5
+echo % check file move with directory move
+hg manifest -r 9
+echo % check file directory directory move
+hg manifest -r 11
+echo % check divergent directory moves
+hg manifest -r 13
exit 0
--- a/tests/test-convert-mtn.out Wed Apr 22 20:15:55 2009 -0300
+++ b/tests/test-convert-mtn.out Thu Apr 23 16:52:25 2009 +0200
@@ -53,19 +53,74 @@
mtn: dropping dir2/dir from workspace manifest
mtn: beginning commit on branch 'com.selenic.test'
mtn: committed revision 2323d4bc324e6c82628dc04d47a9fd32ad24e322
+% test directory and file move
+mtn: adding dir3 to workspace manifest
+mtn: adding dir3/a to workspace manifest
+mtn: adding dir3/d1 to workspace manifest
+mtn: beginning commit on branch 'com.selenic.test'
+mtn: committed revision 47b192f720faa622f48c68d1eb075b26d405aa8b
+mtn: skipping dir3/d1, already accounted for in workspace
+mtn: renaming dir3/a to dir3/d1/a in workspace manifest
+mtn: skipping dir3, already accounted for in workspace
+mtn: renaming dir3/d1 to dir3/d2 in workspace manifest
+mtn: beginning commit on branch 'com.selenic.test'
+mtn: committed revision 8b543a400d3ee7f6d4bb1835b9b9e3747c8cb632
+% test directory move into another directory move
+mtn: adding dir4 to workspace manifest
+mtn: adding dir4/a to workspace manifest
+mtn: adding dir5 to workspace manifest
+mtn: beginning commit on branch 'com.selenic.test'
+mtn: committed revision 466e0b2afc7a55aa2b4ab2f57cb240bb6cd66fc7
+mtn: renaming dir5 to dir6 in workspace manifest
+mtn: skipping dir6, already accounted for in workspace
+mtn: renaming dir4 to dir6/dir4 in workspace manifest
+mtn: beginning commit on branch 'com.selenic.test'
+mtn: committed revision 3d1f77ebad0c23a5d14911be3b670f990991b749
+% test diverging directory moves
+mtn: adding dir7 to workspace manifest
+mtn: adding dir7/c to workspace manifest
+mtn: adding dir7/dir9 to workspace manifest
+mtn: adding dir7/dir9/b to workspace manifest
+mtn: adding dir7/dir9/dir8 to workspace manifest
+mtn: adding dir7/dir9/dir8/a to workspace manifest
+mtn: beginning commit on branch 'com.selenic.test'
+mtn: committed revision 08a08511f18b428d840199b062de90d0396bc2ed
+mtn: renaming dir7 to dir7-2 in workspace manifest
+mtn: renaming dir7-2/dir9 to dir9-2 in workspace manifest
+mtn: renaming dir9-2/dir8 to dir8-2 in workspace manifest
+mtn: beginning commit on branch 'com.selenic.test'
+mtn: committed revision 4a736634505795f17786fffdf2c9cbf5b11df6f6
% convert incrementally
assuming destination repo.mtn-hg
scanning source...
sorting...
converting...
-5 update2 "with" quotes
-4 createdir1
-3 movedir1
-2 movedir
-1 emptydir
-0 dropdirectory
-6 files updated, 0 files merged, 0 files removed, 0 files unresolved
-@ 7 "dropdirectory" files: dir2/dir/subdir/f
+11 update2 "with" quotes
+10 createdir1
+9 movedir1
+8 movedir
+7 emptydir
+6 dropdirectory
+5 dirfilemove
+4 dirfilemove2
+3 dirdirmove
+2 dirdirmove2
+1 divergentdirmove
+0 divergentdirmove2
+11 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@ 13 "divergentdirmove2" files: dir7-2/c dir7/c dir7/dir9/b dir7/dir9/dir8/a dir8-2/a dir9-2/b
+|
+o 12 "divergentdirmove" files: dir7/c dir7/dir9/b dir7/dir9/dir8/a
+|
+o 11 "dirdirmove2" files: dir4/a dir6/dir4/a
+|
+o 10 "dirdirmove" files: dir4/a
+|
+o 9 "dirfilemove2" files: dir3/a dir3/d2/a
+|
+o 8 "dirfilemove" files: dir3/a
+|
+o 7 "dropdirectory" files: dir2/dir/subdir/f
|
o 6 "emptydir" files: dir2/dir/subdir/f
|
@@ -87,6 +142,11 @@
dir1/subdir2_other/file1
dir2/a
dir2/newfile
+dir3/d2/a
+dir6/dir4/a
+dir7-2/c
+dir8-2/a
+dir9-2/b
e
% contents
a
@@ -108,3 +168,32 @@
dir2/a
dir2/newfile
e
+% check file move with directory move
+bin2
+dir1/subdir2/file1
+dir1/subdir2_other/file1
+dir2/a
+dir2/newfile
+dir3/d2/a
+e
+% check file directory directory move
+bin2
+dir1/subdir2/file1
+dir1/subdir2_other/file1
+dir2/a
+dir2/newfile
+dir3/d2/a
+dir6/dir4/a
+e
+% check divergent directory moves
+bin2
+dir1/subdir2/file1
+dir1/subdir2_other/file1
+dir2/a
+dir2/newfile
+dir3/d2/a
+dir6/dir4/a
+dir7-2/c
+dir8-2/a
+dir9-2/b
+e