[PATCH 1 of 1] convert: make convert from cvs recognise branch points correctly

Henrik Stuart henrik.stuart at edlund.dk
Tue Apr 7 06:15:07 CDT 2009


# HG changeset patch
# User Henrik Stuart <henrik.stuart at edlund.dk>
# Date 1239102718 -7200
# Node ID 02d52263001a5679429d0d22677797db50f153d6
# Parent  685ce2f7ee35dfe29d296f80ba2dff124a1caa63
convert: make convert from cvs recognise branch points correctly

This patch fixes issue 1447 by using the symbolic names for branches in the rlog output to determine the branch point for each file and then finding the latest possible branch point in the given changesets such that all the file revisions match and the date is earlier than the branch commit. For commits on non-branches, the current functionality is maintained.

diff -r 685ce2f7ee35 -r 02d52263001a hgext/convert/cvsps.py
--- a/hgext/convert/cvsps.py	Mon Apr 06 20:11:00 2009 +0200
+++ b/hgext/convert/cvsps.py	Tue Apr 07 13:11:58 2009 +0200
@@ -35,6 +35,7 @@
         .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)
+        .branchesto- list of branches that are branched to from here
     '''
     def __init__(self, **entries):
         self.__dict__.update(entries)
@@ -378,6 +379,8 @@
             # clean up the results and save in the log.
             store = False
             e.tags = util.sort([scache(x) for x in tags.get(e.revision, [])])
+            e.branchesto = [tag for tag in branchmap if len(branchmap[tag].split('.')) > 2 and branchmap[tag].split('.')[-2] == '0' and e.revision == tuple([int(x) for x in branchmap[tag].split('.')[:-2]])]
+
             e.comment = scache('\n'.join(e.comment))
 
             revn = len(e.revision)
@@ -599,8 +602,30 @@
 
         c.parents = []
         if p is not None:
+            parent_idx = p
             p = changesets[p]
 
+            if p is not None:
+                if c.branch != p.branch:
+                    earliest_commit = min([l.date for l in log if l.branch == c.branch]) # necessary as the first commit on a branch can be broken into multiple bites
+
+                    q = parent_idx
+                    seen_branched_files = util.set([e.file for e in c.entries]) # already in p at the latest
+                    while q + 1 < i: # only need to search up to current
+                        qcs = changesets[q + 1]
+
+                        if qcs.date >= earliest_commit:
+                            break
+
+                        if any([e.file in seen_branched_files for e in qcs.entries]):
+                            break # we cannot progress past this place
+
+                        seen_branched_files |= util.set([e.file for e in qcs.entries if c.branch in e.branchesto])
+                                
+                        q += 1
+
+                    p = changesets[q]
+
             # Ensure no changeset has a synthetic changeset as a parent.
             while p.synthetic:
                 assert len(p.parents) <= 1, \
diff -r 685ce2f7ee35 -r 02d52263001a tests/test-convert-cvs-branchpoints
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-convert-cvs-branchpoints	Tue Apr 07 13:11:58 2009 +0200
@@ -0,0 +1,157 @@
+#!/bin/bash
+
+"$TESTDIR/hghave" cvs || exit 80
+
+cvscall()
+{
+    cvs -f "$@"
+}
+
+createmaster()
+{
+    rm -rf master
+    mkdir master
+    pushd master > /dev/null
+    export CVSROOT=`pwd`
+    popd > /dev/null
+    cvscall -q -d "$CVSROOT" init
+    mkdir -p master/work
+    rm -rf work
+    cvscall -q -d "$CVSROOT" co -d work work
+}
+
+hgcvsps()
+{
+    hg debugcvsps -x --parents work | sed -e 's/Author:.*/Author:/' -e 's/Date:.*/Date:/'
+}
+
+echo "[extensions]" >> $HGRCPATH
+echo "convert = " >> $HGRCPATH
+echo "graphlog = " >> $HGRCPATH
+echo "[convert]" >> $HGRCPATH
+echo "cvsps=builtin" >> $HGRCPATH
+
+createvar0()
+{
+    echo Creating 1447 var 0
+    createmaster
+    pushd work > /dev/null
+    echo a > a.txt
+    echo b > b.txt
+    cvscall -q add *.txt
+    cvscall -q ci -m "initial" | sed 's/.*,v.*/checking in/g'
+    echo "b fix" >> b.txt
+    cvscall -q ci -m "b fix" | sed 's/.*,v.*/checking in/g'
+    echo "a fix" >> a.txt
+    cvscall -q ci -m "a fix" | sed 's/.*,v.*/checking in/g'
+    cvscall -q rtag -b BRANCH work
+    cvscall -q up -r BRANCH
+    echo "b branch fix" >> b.txt
+    cvscall -q ci -m "b branch fix" | sed 's/.*,v.*/checking in/g'
+    hgcvsps
+    popd > /dev/null
+}
+
+createvar1()
+{
+    echo Creating 1447 var 1
+    createmaster
+    pushd work > /dev/null
+    echo a > a.txt
+    echo b > b.txt
+    cvscall -q add *.txt
+    cvscall -q ci -m "initial" | sed 's/.*,v.*/checking in/g'
+    echo "b fix" >> b.txt
+    cvscall -q ci -m "b fix" | sed 's/.*,v.*/checking in/g'
+    echo "a fix" >> a.txt
+    cvscall -q ci -m "a fix" | sed 's/.*,v.*/checking in/g'
+    cvscall -q tag FOO
+    echo "b fix 2" >> b.txt
+    cvscall -q ci -m "b fix 2" | sed 's/.*,v.*/checking in/g'
+    cvscall -q up -r 1.2 *.txt
+    cvscall -q rtag -b -r FOO BRANCH work
+    cvscall -q up -r BRANCH
+    echo "b branch fix" >> b.txt
+    cvscall -q ci -m "b branch fix" | sed 's/.*,v.*/checking in/g'
+    hgcvsps
+    popd > /dev/null
+}
+
+createvar2()
+{
+    echo Creating 1447 var 2
+    createmaster
+    pushd work > /dev/null
+    echo a > a.txt
+    echo b > b.txt
+    cvscall -q add *.txt
+    cvscall -q ci -m "initial" | sed 's/.*,v.*/checking in/g'
+    echo "b fix" >> b.txt
+    cvscall -q ci -m "b fix" | sed 's/.*,v.*/checking in/g'
+    echo "a fix" >> a.txt
+    cvscall -q ci -m "a fix" | sed 's/.*,v.*/checking in/g'
+    cvscall -q tag FOO
+    echo "a fix 2" >> a.txt
+    cvscall -q ci -m "a fix 2" | sed 's/.*,v.*/checking in/g'
+    cvscall -q up -r 1.2 *.txt
+    cvscall -q rtag -b -r FOO BRANCH work
+    cvscall -q up -r BRANCH
+    echo "b branch fix" >> b.txt
+    cvscall -q ci -m "b branch fix" | sed 's/.*,v.*/checking in/g'
+    hgcvsps
+    popd > /dev/null
+}
+
+createvar3()
+{
+    echo Creating 1447 var 3
+    createmaster
+    pushd work > /dev/null
+    echo a > a.txt
+    echo b > b.txt
+    cvscall -q add *.txt
+    cvscall -q ci -m "initial" | sed 's/.*,v.*/checking in/g'
+    echo "b fix" >> b.txt
+    cvscall -q ci -m "b fix" | sed 's/.*,v.*/checking in/g'
+    echo "a fix" >> a.txt
+    cvscall -q ci -m "a fix" | sed 's/.*,v.*/checking in/g'
+    cvscall -q rtag -b BRANCH work
+    cvscall -q up -r BRANCH
+    echo "b branch fix" >> b.txt
+    cvscall -q ci -m "b branch fix" | sed 's/.*,v.*/checking in/g'
+    cvscall -q up -A
+    echo "b fix 2" >> b.txt
+    cvscall -q ci -m "b fix 2" | sed 's/.*,v.*/checking in/g'
+    hgcvsps
+    popd > /dev/null
+}
+
+createvar4()
+{
+    echo Creating 1447 var 3
+    createmaster
+    pushd work > /dev/null
+    echo a > a.txt
+    echo b > b.txt
+    cvscall -q add *.txt
+    cvscall -q ci -m "initial" | sed 's/.*,v.*/checking in/g'
+    echo "b fix" >> b.txt
+    cvscall -q ci -m "b fix" | sed 's/.*,v.*/checking in/g'
+    echo "a fix" >> a.txt
+    cvscall -q ci -m "a fix" | sed 's/.*,v.*/checking in/g'
+    cvscall -q rtag -b BRANCH work
+    cvscall -q up -r BRANCH
+    echo "b branch fix" >> b.txt
+    cvscall -q ci -m "b branch fix" | sed 's/.*,v.*/checking in/g'
+    cvscall -q up -A
+    echo "a fix 2" >> a.txt
+    cvscall -q ci -m "a fix 2" | sed 's/.*,v.*/checking in/g'
+    hgcvsps
+    popd > /dev/null
+}
+
+createvar0
+createvar1
+createvar2
+createvar3
+createvar4
diff -r 685ce2f7ee35 -r 02d52263001a tests/test-convert-cvs-branchpoints.out
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-convert-cvs-branchpoints.out	Tue Apr 07 13:11:58 2009 +0200
@@ -0,0 +1,408 @@
+Creating 1447 var 0
+cvs add: use `cvs commit' to add these files permanently
+checking in
+initial revision: 1.1
+checking in
+initial revision: 1.1
+checking in
+new revision: 1.2; previous revision: 1.1
+checking in
+new revision: 1.2; previous revision: 1.1
+checking in
+new revision: 1.2.2.1; previous revision: 1.2
+collecting CVS rlog
+5 log entries
+creating changesets
+4 changeset entries
+---------------------
+PatchSet 1 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Log:
+initial
+
+Members: 
+	a.txt:INITIAL->1.1 
+	b.txt:INITIAL->1.1 
+
+---------------------
+PatchSet 2 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Parent: 1
+Log:
+b fix
+
+Members: 
+	b.txt:1.1->1.2 
+
+---------------------
+PatchSet 3 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Parent: 2
+Log:
+a fix
+
+Members: 
+	a.txt:1.1->1.2 
+
+---------------------
+PatchSet 4 
+Date:
+Author:
+Branch: BRANCH
+Tag: (none) 
+Parent: 3
+Log:
+b branch fix
+
+Members: 
+	b.txt:1.2->1.2.2.1 
+
+Creating 1447 var 1
+cvs add: use `cvs commit' to add these files permanently
+checking in
+initial revision: 1.1
+checking in
+initial revision: 1.1
+checking in
+new revision: 1.2; previous revision: 1.1
+checking in
+new revision: 1.2; previous revision: 1.1
+T a.txt
+T b.txt
+checking in
+new revision: 1.3; previous revision: 1.2
+U b.txt
+checking in
+new revision: 1.2.2.1; previous revision: 1.2
+collecting CVS rlog
+6 log entries
+creating changesets
+5 changeset entries
+---------------------
+PatchSet 1 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Log:
+initial
+
+Members: 
+	a.txt:INITIAL->1.1 
+	b.txt:INITIAL->1.1 
+
+---------------------
+PatchSet 2 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Parent: 1
+Log:
+b fix
+
+Members: 
+	b.txt:1.1->1.2 
+
+---------------------
+PatchSet 3 
+Date:
+Author:
+Branch: HEAD
+Tag: FOO 
+Parent: 2
+Log:
+a fix
+
+Members: 
+	a.txt:1.1->1.2 
+
+---------------------
+PatchSet 4 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Parent: 3
+Log:
+b fix 2
+
+Members: 
+	b.txt:1.2->1.3 
+
+---------------------
+PatchSet 5 
+Date:
+Author:
+Branch: BRANCH
+Tag: (none) 
+Parent: 3
+Log:
+b branch fix
+
+Members: 
+	b.txt:1.2->1.2.2.1 
+
+Creating 1447 var 2
+cvs add: use `cvs commit' to add these files permanently
+checking in
+initial revision: 1.1
+checking in
+initial revision: 1.1
+checking in
+new revision: 1.2; previous revision: 1.1
+checking in
+new revision: 1.2; previous revision: 1.1
+T a.txt
+T b.txt
+checking in
+new revision: 1.3; previous revision: 1.2
+U a.txt
+checking in
+new revision: 1.2.2.1; previous revision: 1.2
+collecting CVS rlog
+6 log entries
+creating changesets
+5 changeset entries
+---------------------
+PatchSet 1 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Log:
+initial
+
+Members: 
+	a.txt:INITIAL->1.1 
+	b.txt:INITIAL->1.1 
+
+---------------------
+PatchSet 2 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Parent: 1
+Log:
+b fix
+
+Members: 
+	b.txt:1.1->1.2 
+
+---------------------
+PatchSet 3 
+Date:
+Author:
+Branch: HEAD
+Tag: FOO 
+Parent: 2
+Log:
+a fix
+
+Members: 
+	a.txt:1.1->1.2 
+
+---------------------
+PatchSet 4 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Parent: 3
+Log:
+a fix 2
+
+Members: 
+	a.txt:1.2->1.3 
+
+---------------------
+PatchSet 5 
+Date:
+Author:
+Branch: BRANCH
+Tag: (none) 
+Parent: 3
+Log:
+b branch fix
+
+Members: 
+	b.txt:1.2->1.2.2.1 
+
+Creating 1447 var 3
+cvs add: use `cvs commit' to add these files permanently
+checking in
+initial revision: 1.1
+checking in
+initial revision: 1.1
+checking in
+new revision: 1.2; previous revision: 1.1
+checking in
+new revision: 1.2; previous revision: 1.1
+checking in
+new revision: 1.2.2.1; previous revision: 1.2
+U b.txt
+checking in
+new revision: 1.3; previous revision: 1.2
+collecting CVS rlog
+6 log entries
+creating changesets
+5 changeset entries
+---------------------
+PatchSet 1 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Log:
+initial
+
+Members: 
+	a.txt:INITIAL->1.1 
+	b.txt:INITIAL->1.1 
+
+---------------------
+PatchSet 2 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Parent: 1
+Log:
+b fix
+
+Members: 
+	b.txt:1.1->1.2 
+
+---------------------
+PatchSet 3 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Parent: 2
+Log:
+a fix
+
+Members: 
+	a.txt:1.1->1.2 
+
+---------------------
+PatchSet 4 
+Date:
+Author:
+Branch: BRANCH
+Tag: (none) 
+Parent: 3
+Log:
+b branch fix
+
+Members: 
+	b.txt:1.2->1.2.2.1 
+
+---------------------
+PatchSet 5 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Parent: 3
+Log:
+b fix 2
+
+Members: 
+	b.txt:1.2->1.3 
+
+Creating 1447 var 3
+cvs add: use `cvs commit' to add these files permanently
+checking in
+initial revision: 1.1
+checking in
+initial revision: 1.1
+checking in
+new revision: 1.2; previous revision: 1.1
+checking in
+new revision: 1.2; previous revision: 1.1
+checking in
+new revision: 1.2.2.1; previous revision: 1.2
+U b.txt
+checking in
+new revision: 1.3; previous revision: 1.2
+collecting CVS rlog
+6 log entries
+creating changesets
+5 changeset entries
+---------------------
+PatchSet 1 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Log:
+initial
+
+Members: 
+	a.txt:INITIAL->1.1 
+	b.txt:INITIAL->1.1 
+
+---------------------
+PatchSet 2 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Parent: 1
+Log:
+b fix
+
+Members: 
+	b.txt:1.1->1.2 
+
+---------------------
+PatchSet 3 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Parent: 2
+Log:
+a fix
+
+Members: 
+	a.txt:1.1->1.2 
+
+---------------------
+PatchSet 4 
+Date:
+Author:
+Branch: BRANCH
+Tag: (none) 
+Parent: 3
+Log:
+b branch fix
+
+Members: 
+	b.txt:1.2->1.2.2.1 
+
+---------------------
+PatchSet 5 
+Date:
+Author:
+Branch: HEAD
+Tag: (none) 
+Parent: 3
+Log:
+a fix 2
+
+Members: 
+	a.txt:1.2->1.3 
+


More information about the Mercurial-devel mailing list