--- a/hgext/convert/monotone.py Fri Apr 17 11:16:50 2009 -0500
+++ b/hgext/convert/monotone.py Tue Apr 21 12:53:06 2009 -0500
@@ -106,15 +106,10 @@
value = value.replace(r'\"', '"')
value = value.replace(r'\\', '\\')
certs[name] = value
+ # Monotone may have subsecond dates: 2005-02-05T09:39:12.364306
+ certs["date"] = certs["date"].split('.')[0]
return certs
- def mtnrenamefiles(self, files, fromdir, todir):
- renamed = {}
- for tofile in files:
- if tofile.startswith(todir + '/'):
- renamed[tofile] = fromdir + tofile[len(todir):]
- return renamed
-
# implement the converter_source interface:
def getheads(self):
@@ -127,15 +122,17 @@
#revision = self.mtncmd("get_revision %s" % rev).split("\n\n")
revision = self.mtnrun("get_revision", rev).split("\n\n")
files = {}
+ addedfiles = {}
+ 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
m = self.patch_re.match(e)
if m:
files[m.group(1)] = rev
-
# Delete/rename is handled later when the convert engine
# discovers an IOError exception from getfile,
# but only if we add the "from" file to the list of changes.
@@ -150,14 +147,26 @@
copies[toname] = fromname
files[toname] = rev
files[fromname] = rev
- if self.mtnisdir(toname, rev):
- renamed = self.mtnrenamefiles(self.files, fromname, toname)
- for tofile, fromfile in renamed.items():
- self.ui.debug (_("copying file in renamed dir from '%s' to '%s'") % (fromfile, tofile), '\n')
- files[tofile] = rev
- copies[tofile] = fromfile
- for fromfile in renamed.values():
- files[fromfile] = rev
+ elif self.mtnisdir(toname, rev):
+ renameddirs.append((fromname, toname))
+
+ # Directory renames can be handled only once we have recorded
+ # all new files
+ for fromdir, todir in renameddirs:
+ renamed = {}
+ for tofile in self.files:
+ if tofile in addedfiles:
+ continue
+ if tofile.startswith(todir + '/'):
+ renamed[tofile] = fromdir + tofile[len(todir):]
+ for tofile, fromfile in renamed.items():
+ self.ui.debug (_("copying file in renamed dir from '%s' to '%s'")
+ % (fromfile, tofile), '\n')
+ files[tofile] = rev
+ copies[tofile] = fromfile
+ for fromfile in renamed.values():
+ files[fromfile] = rev
+
return (files.items(), copies)
def getmode(self, name, rev):
--- a/tests/test-convert-cvs-synthetic Fri Apr 17 11:16:50 2009 -0500
+++ b/tests/test-convert-cvs-synthetic Tue Apr 21 12:53:06 2009 -0500
@@ -3,8 +3,6 @@
# This feature requires use of builtin cvsps!
"$TESTDIR/hghave" cvs || exit 80
-# XXX lots of duplication with other test-convert-cvs* scripts
-
set -e
echo "[extensions]" >> $HGRCPATH
@@ -19,47 +17,62 @@
export CVS_OPTIONS=-f
cd ..
-filter='sed "s:$CVSROOT:*REPO*:g"'
+filterpath()
+{
+ eval "$@" | sed "s:$CVSROOT:*REPO*:g"
+}
+
cvscall()
{
- cvs -f "$@" | eval $filter
+ echo cvs -f "$@"
+ cvs -f "$@" 2>&1
}
-cvscall -q -d "$CVSROOT" init
+# output of 'cvs ci' varies unpredictably, so just discard it
+cvsci()
+{
+ echo cvs -f ci "$@"
+ cvs -f ci "$@" >/dev/null 2>&1
+}
+
+filterpath cvscall -d "$CVSROOT" init
mkdir cvsrepo/proj
-cvscall co proj
+cvscall -q co proj
echo % create file1 on the trunk
cd proj
touch file1
-cvscall add file1
-cvscall ci -m"add file1 on trunk" file1
+cvscall -Q add file1
+cvsci -m"add file1 on trunk" file1
echo % create two branches
-cvscall tag -b v1_0
-cvscall tag -b v1_1
+cvscall -q tag -b v1_0
+cvscall -q tag -b v1_1
echo % create file2 on branch v1_0
-cvs up -rv1_0
+cvscall -q up -rv1_0
touch file2
-cvscall add file2
-cvscall ci -m"add file2 on branch v1_0" file2
+cvscall -Q add file2
+cvsci -m"add file2 on branch v1_0" file2
echo % create file3, file4 on branch v1_1
-cvs up -rv1_1
+cvscall -Q up -rv1_1
touch file3
touch file4
-cvscall add file3 file4
-cvscall ci -m"add file3, file4 on branch v1_1" file3 file4
+cvscall -Q add file3 file4
+cvsci -m"add file3, file4 on branch v1_1" file3 file4
echo % merge file2 from v1_0 to v1_1
-cvscall up -jv1_0
-cvscall ci -m"merge file2 from v1_0 to v1_1"
+cvscall -q up -jv1_0
+cvsci -m"merge file2 from v1_0 to v1_1"
+
+echo % cvs rlog output
+filterpath cvscall -q rlog proj | egrep '^(RCS file|revision)'
echo % convert to hg
cd ..
-hg convert proj proj.hg | eval $filter
+filterpath hg convert proj proj.hg
echo % hg log output
hg -R proj.hg log --template "{rev} {desc}\n"
--- a/tests/test-convert-cvs-synthetic.out Fri Apr 17 11:16:50 2009 -0500
+++ b/tests/test-convert-cvs-synthetic.out Tue Apr 21 12:53:06 2009 -0500
@@ -1,37 +1,40 @@
% create cvs repository with one project
-cvs checkout: Updating proj
+cvs -f -d *REPO* init
+cvs -f -q co proj
% create file1 on the trunk
-cvs add: scheduling file `file1' for addition
-cvs add: use `cvs commit' to add this file permanently
-*REPO*/proj/file1,v <-- file1
-initial revision: 1.1
+cvs -f -Q add file1
+cvs -f ci -madd file1 on trunk file1
% create two branches
-cvs tag: Tagging .
+cvs -f -q tag -b v1_0
T file1
-cvs tag: Tagging .
+cvs -f -q tag -b v1_1
T file1
% create file2 on branch v1_0
-cvs update: Updating .
-cvs add: scheduling file `file2' for addition on branch `v1_0'
-cvs add: use `cvs commit' to add this file permanently
-*REPO*/proj/Attic/file2,v <-- file2
-new revision: 1.1.2.1; previous revision: 1.1
+cvs -f -q up -rv1_0
+cvs -f -Q add file2
+cvs -f ci -madd file2 on branch v1_0 file2
% create file3, file4 on branch v1_1
-cvs update: Updating .
-cvs update: `file2' is no longer in the repository
-cvs add: scheduling file `file3' for addition on branch `v1_1'
-cvs add: scheduling file `file4' for addition on branch `v1_1'
-cvs add: use `cvs commit' to add these files permanently
-*REPO*/proj/Attic/file3,v <-- file3
-new revision: 1.1.2.1; previous revision: 1.1
-*REPO*/proj/Attic/file4,v <-- file4
-new revision: 1.1.2.1; previous revision: 1.1
+cvs -f -Q up -rv1_1
+cvs -f -Q add file3 file4
+cvs -f ci -madd file3, file4 on branch v1_1 file3 file4
% merge file2 from v1_0 to v1_1
-cvs update: Updating .
+cvs -f -q up -jv1_0
U file2
-cvs commit: Examining .
-*REPO*/proj/Attic/file2,v <-- file2
-new revision: 1.1.4.2; previous revision: 1.1.4.1
+cvs -f ci -mmerge file2 from v1_0 to v1_1
+% cvs rlog output
+RCS file: *REPO*/proj/file1,v
+revision 1.1
+RCS file: *REPO*/proj/Attic/file2,v
+revision 1.1
+revision 1.1.4.2
+revision 1.1.4.1
+revision 1.1.2.1
+RCS file: *REPO*/proj/Attic/file3,v
+revision 1.1
+revision 1.1.2.1
+RCS file: *REPO*/proj/Attic/file4,v
+revision 1.1
+revision 1.1.2.1
% convert to hg
initializing destination proj.hg repository
using builtin cvsps
--- a/tests/test-convert-mtn Fri Apr 17 11:16:50 2009 -0500
+++ b/tests/test-convert-mtn Tue Apr 21 12:53:06 2009 -0500
@@ -33,9 +33,10 @@
echo a > a
mkdir dir
echo b > dir/b
+echo d > dir/d
python -c 'file("bin", "wb").write("a\\x00b")'
echo c > c
-mtn add a dir/b c bin
+mtn add a dir/b dir/d c bin
mtn ci -m initialize
echo % update monotone working directory
mtn mv a dir/a
@@ -66,6 +67,9 @@
mtn ci -m movedir1
echo '% test subdirectory move'
mtn mv dir dir2
+echo newfile > dir2/newfile
+mtn drop dir2/d
+mtn add dir2/newfile
mtn ci -m movedir
# Test directory removal with empty directory
mkdir dir2/dir
@@ -102,5 +106,7 @@
test -d dir1/subdir2 || echo 'new dir1/subdir2 does not exist!'
test -d dir1/subdir1 && echo 'renamed dir1/subdir1 is still there!'
hg log -v -C -r 4 | grep copies
+echo % check file remove with directory move
+hg manifest -r 5
exit 0
--- a/tests/test-convert-mtn.out Fri Apr 17 11:16:50 2009 -0500
+++ b/tests/test-convert-mtn.out Tue Apr 21 12:53:06 2009 -0500
@@ -5,14 +5,15 @@
mtn: adding c to workspace manifest
mtn: adding dir to workspace manifest
mtn: adding dir/b to workspace manifest
+mtn: adding dir/d to workspace manifest
mtn: beginning commit on branch 'com.selenic.test'
-mtn: committed revision 803ef0bf815e35b951dbd4310acd1e45e675016e
+mtn: committed revision 0f6e5e4f2e7d2a8ef312408f57618abf026afd90
% update monotone working directory
mtn: skipping dir, already accounted for in workspace
mtn: renaming a to dir/a in workspace manifest
mtn: dropping c from workspace manifest
mtn: beginning commit on branch 'com.selenic.test'
-mtn: committed revision 4daf60753d6fe21a06ce5f716303fe55fd6d3a56
+mtn: committed revision 51d0a982464573a2a2cf5ee2c9219c652aaebeff
% convert once
assuming destination repo.mtn-hg
initializing destination repo.mtn-hg repository
@@ -25,7 +26,7 @@
mtn: dropping dir/b from workspace manifest
mtn: renaming bin to bin2 in workspace manifest
mtn: beginning commit on branch 'com.selenic.test'
-mtn: committed revision 6c6977a6ef609ec80e40779f89dbd2772c96de62
+mtn: committed revision ebe58335d85d8cb176b6d0a12be04f5314b998da
% test directory move
mtn: adding dir1 to workspace manifest
mtn: adding dir1/subdir1 to workspace manifest
@@ -33,23 +34,25 @@
mtn: adding dir1/subdir2_other to workspace manifest
mtn: adding dir1/subdir2_other/file1 to workspace manifest
mtn: beginning commit on branch 'com.selenic.test'
-mtn: committed revision e066b1feb2b7a7110450c2c18b5b4462011427d1
+mtn: committed revision a8d62bc04fee4d2936d28e98bbcc81686dd74306
mtn: skipping dir1, already accounted for in workspace
mtn: renaming dir1/subdir1 to dir1/subdir2 in workspace manifest
mtn: beginning commit on branch 'com.selenic.test'
-mtn: committed revision 2ad2409d25bb8d2583b57a3d4c0fa1df62aa1f79
+mtn: committed revision 2c3d241bbbfe538b1b51d910f5676407e3f4d3a6
% test subdirectory move
mtn: renaming dir to dir2 in workspace manifest
+mtn: dropping dir2/d from workspace manifest
+mtn: adding dir2/newfile to workspace manifest
mtn: beginning commit on branch 'com.selenic.test'
-mtn: committed revision a85290b81fc4a8fbce4dc4d956404109842b406e
+mtn: committed revision fdb5a02dae8bfce3a79b3393680af471016e1b4c
mtn: beginning commit on branch 'com.selenic.test'
-mtn: committed revision 7e3c8746060117104f16ff2d9212cf0f810cbff0
+mtn: committed revision 8bbf76d717001d24964e4604739fdcd0f539fc88
mtn: dropping dir2/dir/subdir/f from workspace manifest
mtn: dropping dir2/dir/subdir from workspace manifest
mtn: dropping dir2/dir/emptydir from workspace manifest
mtn: dropping dir2/dir from workspace manifest
mtn: beginning commit on branch 'com.selenic.test'
-mtn: committed revision a97e0433d041a6d253c5dc27e080d544e55d9c19
+mtn: committed revision 2323d4bc324e6c82628dc04d47a9fd32ad24e322
% convert incrementally
assuming destination repo.mtn-hg
scanning source...
@@ -61,12 +64,12 @@
2 movedir
1 emptydir
0 dropdirectory
-5 files updated, 0 files merged, 0 files removed, 0 files unresolved
+6 files updated, 0 files merged, 0 files removed, 0 files unresolved
@ 7 "dropdirectory" files: dir2/dir/subdir/f
|
o 6 "emptydir" files: dir2/dir/subdir/f
|
-o 5 "movedir" files: dir/a dir2/a
+o 5 "movedir" files: dir/a dir/d dir2/a dir2/newfile
|
o 4 "movedir1" files: dir1/subdir1/file1 dir1/subdir2/file1
|
@@ -76,13 +79,14 @@
|
o 1 "update1" files: a bin c dir/a dir/b
|
-o 0 "initialize" files: a bin c dir/b
+o 0 "initialize" files: a bin c dir/b dir/d
% manifest
bin2
dir1/subdir2/file1
dir1/subdir2_other/file1
dir2/a
+dir2/newfile
e
% contents
a
@@ -92,7 +96,15 @@
% check directory move
bin2
dir/a
+dir/d
dir1/subdir2/file1
dir1/subdir2_other/file1
e
copies: dir1/subdir2/file1 (dir1/subdir1/file1)
+% check file remove with directory move
+bin2
+dir1/subdir2/file1
+dir1/subdir2_other/file1
+dir2/a
+dir2/newfile
+e