diff --git a/hgext/convert/cvsps.py b/hgext/convert/cvsps.py --- a/hgext/convert/cvsps.py +++ b/hgext/convert/cvsps.py @@ -34,6 +34,7 @@ class logentry(object): .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 @@ def createlog(ui, directory=None, root=" 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 @@ def createlog(ui, directory=None, root=" # 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 @@ def createlog(ui, directory=None, root=" elif state == 2: # expect 'symbolic names' if re_20.match(line): + branchmap = {} state = 3 elif state == 3: @@ -261,6 +264,7 @@ def createlog(ui, directory=None, root=" 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 @@ def createlog(ui, directory=None, root=" 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 @@ class changeset(object): .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 @@ def createchangeset(ui, log, fuzz=60, me (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 @@ def createchangeset(ui, log, fuzz=60, me 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: diff --git a/tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints b/tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints new file mode 100644 --- /dev/null +++ b/tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints @@ -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 .. diff --git a/tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints.out b/tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints.out new file mode 100644 --- /dev/null +++ b/tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints.out @@ -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 + diff --git a/tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints.rlog b/tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints.rlog new file mode 100644 --- /dev/null +++ b/tests/test-convert-cvs-builtincvsps-cvsnt-mergepoints.rlog @@ -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 +=============================================================================