convert: added cvsnt mergepoint support
authorHenrik Stuart <henrik.stuart@edlund.dk>
Thu, 02 Apr 2009 14:48:06 +0200
changeset 7956 3e7611a83230
parent 7955 c3d4ff03ec72
child 7957 88a2687fbd38
convert: added cvsnt mergepoint support
hgext/convert/cvsps.py
tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints
tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints.out
tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints.rlog
--- a/hgext/convert/cvsps.py	Thu Mar 26 16:58:50 2009 +0200
+++ b/hgext/convert/cvsps.py	Thu Apr 02 14:48:06 2009 +0200
@@ -34,6 +34,7 @@
         .revision  - revision number as tuple
         .tags      - list of tags on the file
         .synthetic - is this a synthetic "file ... added on ..." revision?
+        .mergepoint- the branch that has been merged from (if present in rlog output)
     '''
     def __init__(self, **entries):
         self.__dict__.update(entries)
@@ -105,7 +106,7 @@
     re_31 = re.compile('----------------------------$')
     re_32 = re.compile('=============================================================================$')
     re_50 = re.compile('revision ([\\d.]+)(\s+locked by:\s+.+;)?$')
-    re_60 = re.compile(r'date:\s+(.+);\s+author:\s+(.+);\s+state:\s+(.+?);(\s+lines:\s+(\+\d+)?\s+(-\d+)?;)?')
+    re_60 = re.compile(r'date:\s+(.+);\s+author:\s+(.+);\s+state:\s+(.+?);(\s+lines:\s+(\+\d+)?\s+(-\d+)?;)?(.*mergepoint:\s+([^;]+);)?')
     re_70 = re.compile('branches: (.+);$')
 
     file_added_re = re.compile(r'file [^/]+ was (initially )?added on branch')
@@ -187,6 +188,7 @@
 
     # state machine begins here
     tags = {}     # dictionary of revisions on current file with their tags
+    branchmap = {} # mapping between branch names and revision numbers
     state = 0
     store = False # set when a new record can be appended
 
@@ -244,6 +246,7 @@
         elif state == 2:
             # expect 'symbolic names'
             if re_20.match(line):
+                branchmap = {}
                 state = 3
 
         elif state == 3:
@@ -261,6 +264,7 @@
                 if rev not in tags:
                     tags[rev] = []
                 tags[rev].append(match.group(1))
+                branchmap[match.group(1)] = match.group(2)
 
             elif re_31.match(line):
                 state = 5
@@ -311,6 +315,18 @@
                 e.lines = (0, int(match.group(6)))
             else:
                 e.lines = None
+
+            if match.group(7): # cvsnt mergepoint
+                myrev = match.group(8).split('.')
+                if len(myrev) == 2: # head
+                    e.mergepoint = 'HEAD'
+                else:
+                    myrev = '.'.join(myrev[:-2] + ['0', myrev[-2]])
+                    branches = [b for b in branchmap if branchmap[b] == myrev]
+                    assert len(branches) == 1, 'unknown branch: %s' % e.mergepoint
+                    e.mergepoint = branches[0]
+            else:
+                e.mergepoint = None
             e.comment = []
             state = 7
 
@@ -420,6 +436,7 @@
         .parents   - list of one or two parent changesets
         .tags      - list of tags on this changeset
         .synthetic - from synthetic revision "file ... added on branch ..."
+        .mergepoint- the branch that has been merged from (if present in rlog output)
     '''
     def __init__(self, **entries):
         self.__dict__.update(entries)
@@ -448,7 +465,8 @@
                    (c.date[0] + c.date[1]) + fuzz) and
                   e.file not in files):
             c = changeset(comment=e.comment, author=e.author,
-                          branch=e.branch, date=e.date, entries=[])
+                          branch=e.branch, date=e.date, entries=[],
+                          mergepoint=e.mergepoint)
             changesets.append(c)
             files = {}
             if len(changesets) % 100 == 0:
@@ -595,6 +613,11 @@
             if p is not None:
                 c.parents.append(p)
 
+        if c.mergepoint:
+            if c.mergepoint == 'HEAD':
+                c.mergepoint = None
+            c.parents.append(changesets[branches[c.mergepoint]])
+
         if mergefrom:
             m = mergefrom.search(c.comment)
             if m:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints	Thu Apr 02 14:48:06 2009 +0200
@@ -0,0 +1,78 @@
+#!/bin/bash
+
+"$TESTDIR/hghave" cvs || exit 80
+
+cvscall()
+{
+    cvs -f "$@"
+}
+
+hgcat()
+{
+    hg --cwd src-hg cat -r tip "$1"
+}
+
+echo "[extensions]" >> $HGRCPATH
+echo "convert = " >> $HGRCPATH
+echo "graphlog = " >> $HGRCPATH
+echo "[convert]" >> $HGRCPATH
+echo "cvsps=builtin" >> $HGRCPATH
+
+echo % create cvs repository
+mkdir cvsmaster
+cd cvsmaster
+export CVSROOT=`pwd`
+export CVS_OPTIONS=-f
+cd ..
+
+cvscall -q -d "$CVSROOT" init
+
+cvscall -q checkout -d cvsworktmp .
+cd cvsworktmp
+mkdir foo
+cvscall -q add foo | sed -e 's/Directory .* added to the repository//g'
+cd foo
+echo foo > foo.txt
+cvscall -q add foo.txt 
+cvscall -q ci -m "foo.txt" | sed 's/.*,v.*/checking in/g'
+ 
+cd ../..
+rm -rf cvsworktmp
+
+cvscall -q checkout -d cvswork foo
+
+cd cvswork
+
+cvscall -q rtag -b -R MYBRANCH1 foo
+cvscall -q up -P -r MYBRANCH1
+echo bar > foo.txt
+cvscall -q ci -m "bar" | sed 's/.*,v.*/checking in/g'
+echo baz > foo.txt
+cvscall -q ci -m "baz" | sed 's/.*,v.*/checking in/g'
+
+cvscall -q rtag -b -R -r MYBRANCH1 MYBRANCH1_2 foo
+cvscall -q up -P -r MYBRANCH1_2
+
+echo bazzie > foo.txt
+cvscall -q ci -m "bazzie" | sed 's/.*,v.*/checking in/g'
+
+cvscall -q rtag -b -R MYBRANCH1_1 foo
+cvscall -q up -P -r MYBRANCH1_1
+
+echo quux > foo.txt
+cvscall -q ci -m "quux" | sed 's/.*,v.*/checking in/g'
+cvscall -q up -P -jMYBRANCH1 | sed 's/RCS file: .*,v/merging MYBRANCH1/g'
+echo xyzzy > foo.txt
+cvscall -q ci -m "merge" | sed 's/.*,v.*/checking in/g'
+
+cvscall -q up -P -A
+
+cvscall -q up -P -jMYBRANCH1_2 | sed 's/RCS file: .*,v/merging MYBRANCH1_2/g'
+cvscall -q ci -m "merge" | sed 's/.*,v.*/checking in/g'
+
+REALCVS=`which cvs`
+echo "for x in \$*; do if [ \"\$x\" = \"rlog\" ]; then echo \"RCS file: $CVSROOT/foo/foo.txt,v\"; cat $TESTDIR/test-convert-cvs-builtincvsps-cvsnt-mergepoints.rlog; exit 0; fi; done; $REALCVS \$*" > cvs
+chmod +x cvs
+PATH=.:${PATH} hg debugcvsps --parents foo | sed -e 's/Author:.*/Author:/' -e 's/Date:.*/Date:/'
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints.out	Thu Apr 02 14:48:06 2009 +0200
@@ -0,0 +1,138 @@
+% create cvs repository
+U cvsworktmp/CVSROOT/checkoutlist
+U cvsworktmp/CVSROOT/commitinfo
+U cvsworktmp/CVSROOT/config
+U cvsworktmp/CVSROOT/cvswrappers
+U cvsworktmp/CVSROOT/loginfo
+U cvsworktmp/CVSROOT/modules
+U cvsworktmp/CVSROOT/notify
+U cvsworktmp/CVSROOT/postadmin
+U cvsworktmp/CVSROOT/postproxy
+U cvsworktmp/CVSROOT/posttag
+U cvsworktmp/CVSROOT/postwatch
+U cvsworktmp/CVSROOT/preproxy
+U cvsworktmp/CVSROOT/rcsinfo
+U cvsworktmp/CVSROOT/taginfo
+U cvsworktmp/CVSROOT/verifymsg
+
+cvs add: use `cvs commit' to add this file permanently
+checking in
+initial revision: 1.1
+U cvswork/foo.txt
+checking in
+new revision: 1.1.2.1; previous revision: 1.1
+checking in
+new revision: 1.1.2.2; previous revision: 1.1.2.1
+checking in
+new revision: 1.1.2.2.2.1; previous revision: 1.1.2.2
+U foo.txt
+checking in
+new revision: 1.1.4.1; previous revision: 1.1
+rcsmerge: warning: conflicts during merge
+merging MYBRANCH1
+retrieving revision 1.1
+retrieving revision 1.1.2.2
+Merging differences between 1.1 and 1.1.2.2 into foo.txt
+checking in
+new revision: 1.1.4.2; previous revision: 1.1.4.1
+U foo.txt
+merging MYBRANCH1_2
+retrieving revision 1.1
+retrieving revision 1.1.2.2.2.1
+Merging differences between 1.1 and 1.1.2.2.2.1 into foo.txt
+checking in
+new revision: 1.2; previous revision: 1.1
+collecting CVS rlog
+7 log entries
+creating changesets
+7 changeset entries
+---------------------
+PatchSet 1 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Log:
+foo.txt
+
+Members: 
+	foo.txt:INITIAL->1.1 
+
+---------------------
+PatchSet 2 
+Date:
+Author:
+Branch: MYBRANCH1
+Tag: (none) 
+Parent: 1
+Log:
+bar
+
+Members: 
+	foo.txt:1.1->1.1.2.1 
+
+---------------------
+PatchSet 3 
+Date:
+Author:
+Branch: MYBRANCH1
+Tag: (none) 
+Parent: 2
+Log:
+baz
+
+Members: 
+	foo.txt:1.1.2.1->1.1.2.2 
+
+---------------------
+PatchSet 4 
+Date:
+Author:
+Branch: MYBRANCH1_1
+Tag: (none) 
+Parent: 1
+Log:
+quux
+
+Members: 
+	foo.txt:1.1->1.1.4.1 
+
+---------------------
+PatchSet 5 
+Date:
+Author:
+Branch: MYBRANCH1_2
+Tag: (none) 
+Parent: 3
+Log:
+bazzie
+
+Members: 
+	foo.txt:1.1.2.2->1.1.2.2.2.1 
+
+---------------------
+PatchSet 6 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Parents: 1,5
+Log:
+merge
+
+Members: 
+	foo.txt:1.1->1.2 
+
+---------------------
+PatchSet 7 
+Date:
+Author:
+Branch: MYBRANCH1_1
+Tag: (none) 
+Parents: 4,3
+Log:
+merge
+
+Members: 
+	foo.txt:1.1.4.1->1.1.4.2 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints.rlog	Thu Apr 02 14:48:06 2009 +0200
@@ -0,0 +1,42 @@
+head: 1.2
+branch:
+locks: strict
+access list:
+symbolic names:
+	MYBRANCH1_2: 1.1.2.2.0.2
+	MYBRANCH1_1: 1.1.0.4
+	MYBRANCH1: 1.1.0.2
+keyword substitution: kv
+total revisions: 8;	selected revisions: 8
+description:
+----------------------------
+revision 1.2
+date: 2009/04/02 07:00:32;  author: user;  state: Exp;  lines: +1 -1;  kopt: kv;  commitid: 14d449d462903487;  mergepoint: 1.1.2.2.2.1;  filename: foo.txt;
+merge
+----------------------------
+revision 1.1
+date: 2009/04/02 06:50:43;  author: user;  state: Exp;  kopt: kv;  commitid: 17ac49d460432d04;  filename: foo.txt;
+branches:  1.1.2;  1.1.4;
+foo.txt
+----------------------------
+revision 1.1.4.2
+date: 2009/04/02 07:02:51;  author: user;  state: Exp;  lines: +1 -0;  kopt: kv;  commitid: 170049d4631b364d;  mergepoint: 1.1.2.2;  filename: foo.txt;
+merge
+----------------------------
+revision 1.1.4.1
+date: 2009/04/02 06:53:42;  author: user;  state: Exp;  lines: +1 -1;  kopt: kv;  commitid: dc849d460f52f49;  filename: foo.txt;
+quux
+----------------------------
+revision 1.1.2.2
+date: 2009/04/02 06:53:20;  author: user;  state: Exp;  lines: +1 -1;  kopt: kv;  commitid: 8ec49d460e02f04;  filename: foo.txt;
+branches:  1.1.2.2.2;
+baz
+----------------------------
+revision 1.1.2.1
+date: 2009/04/02 06:52:38;  author: user;  state: Exp;  lines: +1 -1;  kopt: kv;  commitid: d5049d460b62e7b;  filename: foo.txt;
+bar
+----------------------------
+revision 1.1.2.2.2.1
+date: 2009/04/02 06:55:42;  author: user;  state: Exp;  lines: +1 -1;  kopt: kv;  commitid: 11c849d4616d30d1;  filename: foo.txt;
+bazzie
+=============================================================================