##// END OF EJS Templates
convert: cvs.py - Allow user to use built-in CVS changeset code....
Frank Kingswood -
r6690:127e8c34 default
parent child Browse files
Show More
@@ -0,0 +1,60 b''
1 #!/bin/sh
2
3 # This is http://www.selenic.com/mercurial/bts/issue1148
4
5 "$TESTDIR/hghave" cvs || exit 80
6
7 cvscall()
8 {
9 cvs -f "$@"
10 }
11
12 echo "[extensions]" >> $HGRCPATH
13 echo "convert = " >> $HGRCPATH
14 echo "graphlog = " >> $HGRCPATH
15 echo "[convert]" >> $HGRCPATH
16 echo "cvsps=builtin" >> $HGRCPATH
17
18 echo % create cvs repository
19 mkdir cvsrepo
20 cd cvsrepo
21 export CVSROOT=`pwd`
22 export CVS_OPTIONS=-f
23 cd ..
24
25 cvscall -q -d "$CVSROOT" init
26
27 echo % Create a new project
28
29 mkdir src
30 cd src
31 echo "1" > a > b
32 cvscall import -m "init" src v0 r0
33 cd ..
34 cvscall co src
35 cd src
36
37 echo % Branch the project
38
39 cvscall tag -b BRANCH
40 cvscall up -r BRANCH
41
42 echo % Modify file a, then b, then a
43
44 echo "2" > a
45 cvscall ci -m "mod a" | grep '<--' | sed -e 's:.*src/\(.*\),v.*:checking in src/\1,v:g'
46
47 echo "2" > b
48 cvscall ci -m "mod b" | grep '<--' | sed -e 's:.*src/\(.*\),v.*:checking in src/\1,v:g'
49
50 echo "3" > a
51 cvscall ci -m "mod a again" | grep '<--' | sed -e 's:.*src/\(.*\),v.*:checking in src/\1,v:g'
52
53 echo % Convert
54
55 cd ..
56 hg convert src | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g'
57
58 echo % Check the result
59
60 hg -R src-hg glog --template '#rev# (#branches#) #desc# files: #files#\n'
@@ -0,0 +1,53 b''
1 % create cvs repository
2 % Create a new project
3 N src/a
4 N src/b
5
6 No conflicts created by this import
7
8 cvs checkout: Updating src
9 U src/a
10 U src/b
11 % Branch the project
12 cvs tag: Tagging .
13 T a
14 T b
15 cvs update: Updating .
16 % Modify file a, then b, then a
17 cvs commit: Examining .
18 checking in src/a,v
19 cvs commit: Examining .
20 checking in src/b,v
21 cvs commit: Examining .
22 checking in src/a,v
23 % Convert
24 assuming destination src-hg
25 initializing destination src-hg repository
26 using builtin cvsps
27 collecting CVS rlog
28 7 log entries
29 creating changesets
30 5 changeset entries
31 connecting to cvsrepo
32 scanning source...
33 sorting...
34 converting...
35 4 Initial revision
36 3 init
37 2 mod a
38 1 mod b
39 0 mod a again
40 updating tags
41 % Check the result
42 o 5 () update tags files: .hgtags
43 |
44 | o 4 (BRANCH) mod a again files: a
45 | |
46 | o 3 (BRANCH) mod b files: b
47 | |
48 | o 2 (BRANCH) mod a files: a
49 | |
50 | o 1 (v0) init files:
51 |/
52 o 0 () Initial revision files: a b
53
@@ -0,0 +1,99 b''
1 #!/bin/sh
2
3 "$TESTDIR/hghave" cvs || exit 80
4
5 cvscall()
6 {
7 cvs -f "$@"
8 }
9
10 echo "[extensions]" >> $HGRCPATH
11 echo "convert = " >> $HGRCPATH
12 echo "graphlog = " >> $HGRCPATH
13 echo "[convert]" >> $HGRCPATH
14 echo "cvsps=builtin" >> $HGRCPATH
15
16 echo % create cvs repository
17 mkdir cvsrepo
18 cd cvsrepo
19 export CVSROOT=`pwd`
20 export CVS_OPTIONS=-f
21 cd ..
22
23 cvscall -q -d "$CVSROOT" init
24
25 echo % create source directory
26 mkdir src-temp
27 cd src-temp
28 echo a > a
29 mkdir b
30 cd b
31 echo c > c
32 cd ..
33
34 echo % import source directory
35 cvscall -q import -m import src INITIAL start
36 cd ..
37
38 echo % checkout source directory
39 cvscall -q checkout src
40
41 echo % commit a new revision changing b/c
42 cd src
43 sleep 1
44 echo c >> b/c
45 cvscall -q commit -mci0 . | grep '<--' |\
46 sed -e 's:.*src/\(.*\),v.*:checking in src/\1,v:g'
47 cd ..
48
49 echo % convert fresh repo
50 hg convert src src-hg | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g'
51 cat src-hg/a
52 cat src-hg/b/c
53
54 echo % convert fresh repo with --filemap
55 echo include b/c > filemap
56 hg convert --filemap filemap src src-filemap | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g'
57 cat src-hg/b/c
58 hg -R src-filemap log --template '#rev# #desc# files: #files#\n'
59
60 echo % commit new file revisions
61 cd src
62 echo a >> a
63 echo c >> b/c
64 cvscall -q commit -mci1 . | grep '<--' |\
65 sed -e 's:.*src/\(.*\),v.*:checking in src/\1,v:g'
66 cd ..
67
68 echo % convert again
69 hg convert src src-hg | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g'
70 cat src-hg/a
71 cat src-hg/b/c
72
73 echo % convert again with --filemap
74 hg convert --filemap filemap src src-filemap | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g'
75 cat src-hg/b/c
76 hg -R src-filemap log --template '#rev# #desc# files: #files#\n'
77
78 echo % commit branch
79 cd src
80 cvs -q update -r1.1 b/c
81 cvs -q tag -b branch
82 cvs -q update -r branch
83 echo d >> b/c
84 cvs -q commit -mci2 . | grep '<--' |\
85 sed -e 's:.*src/\(.*\),v.*:checking in src/\1,v:g'
86 cd ..
87
88 echo % convert again
89 hg convert src src-hg | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g'
90 cat src-hg/a
91 cat src-hg/b/c
92
93 echo % convert again with --filemap
94 hg convert --filemap filemap src src-filemap | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g'
95 cat src-hg/b/c
96 hg -R src-filemap log --template '#rev# #desc# files: #files#\n'
97
98 echo "graphlog = " >> $HGRCPATH
99 hg -R src-hg glog --template '#rev# (#branches#) #desc# files: #files#\n'
@@ -0,0 +1,139 b''
1 % create cvs repository
2 % create source directory
3 % import source directory
4 N src/a
5 N src/b/c
6
7 No conflicts created by this import
8
9 % checkout source directory
10 U src/a
11 U src/b/c
12 % commit a new revision changing b/c
13 checking in src/b/c,v
14 % convert fresh repo
15 initializing destination src-hg repository
16 using builtin cvsps
17 collecting CVS rlog
18 5 log entries
19 creating changesets
20 3 changeset entries
21 connecting to cvsrepo
22 scanning source...
23 sorting...
24 converting...
25 2 Initial revision
26 1 import
27 0 ci0
28 updating tags
29 a
30 c
31 c
32 % convert fresh repo with --filemap
33 initializing destination src-filemap repository
34 using builtin cvsps
35 collecting CVS rlog
36 5 log entries
37 creating changesets
38 3 changeset entries
39 connecting to cvsrepo
40 scanning source...
41 sorting...
42 converting...
43 2 Initial revision
44 1 import
45 rolling back last transaction
46 0 ci0
47 updating tags
48 c
49 c
50 2 update tags files: .hgtags
51 1 ci0 files: b/c
52 0 Initial revision files: b/c
53 % commit new file revisions
54 checking in src/a,v
55 checking in src/b/c,v
56 % convert again
57 using builtin cvsps
58 collecting CVS rlog
59 7 log entries
60 creating changesets
61 4 changeset entries
62 connecting to cvsrepo
63 scanning source...
64 sorting...
65 converting...
66 0 ci1
67 a
68 a
69 c
70 c
71 c
72 % convert again with --filemap
73 using builtin cvsps
74 collecting CVS rlog
75 7 log entries
76 creating changesets
77 4 changeset entries
78 connecting to cvsrepo
79 scanning source...
80 sorting...
81 converting...
82 0 ci1
83 c
84 c
85 c
86 3 ci1 files: b/c
87 2 update tags files: .hgtags
88 1 ci0 files: b/c
89 0 Initial revision files: b/c
90 % commit branch
91 U b/c
92 T a
93 T b/c
94 checking in src/b/c,v
95 % convert again
96 using builtin cvsps
97 collecting CVS rlog
98 8 log entries
99 creating changesets
100 5 changeset entries
101 connecting to cvsrepo
102 scanning source...
103 sorting...
104 converting...
105 0 ci2
106 a
107 a
108 c
109 d
110 % convert again with --filemap
111 using builtin cvsps
112 collecting CVS rlog
113 8 log entries
114 creating changesets
115 5 changeset entries
116 connecting to cvsrepo
117 scanning source...
118 sorting...
119 converting...
120 0 ci2
121 c
122 d
123 4 ci2 files: b/c
124 3 ci1 files: b/c
125 2 update tags files: .hgtags
126 1 ci0 files: b/c
127 0 Initial revision files: b/c
128 o 5 (branch) ci2 files: b/c
129 |
130 | o 4 () ci1 files: a b/c
131 | |
132 | o 3 () update tags files: .hgtags
133 | |
134 | o 2 () ci0 files: b/c
135 |/
136 | o 1 (INITIAL) import files:
137 |/
138 o 0 () Initial revision files: a b/c
139
@@ -3,8 +3,10 b''
3 import os, locale, re, socket
3 import os, locale, re, socket
4 from cStringIO import StringIO
4 from cStringIO import StringIO
5 from mercurial import util
5 from mercurial import util
6 from mercurial.i18n import _
6
7
7 from common import NoRepo, commit, converter_source, checktool
8 from common import NoRepo, commit, converter_source, checktool
9 import cvsps
8
10
9 class convert_cvs(converter_source):
11 class convert_cvs(converter_source):
10 def __init__(self, ui, path, rev=None):
12 def __init__(self, ui, path, rev=None):
@@ -14,10 +16,13 b' class convert_cvs(converter_source):'
14 if not os.path.exists(cvs):
16 if not os.path.exists(cvs):
15 raise NoRepo("%s does not look like a CVS checkout" % path)
17 raise NoRepo("%s does not look like a CVS checkout" % path)
16
18
19 checktool('cvs')
17 self.cmd = ui.config('convert', 'cvsps', 'cvsps -A -u --cvs-direct -q')
20 self.cmd = ui.config('convert', 'cvsps', 'cvsps -A -u --cvs-direct -q')
18 cvspsexe = self.cmd.split(None, 1)[0]
21 cvspsexe = self.cmd.split(None, 1)[0]
19 for tool in (cvspsexe, 'cvs'):
22 self.builtin = cvspsexe == 'builtin'
20 checktool(tool)
23
24 if not self.builtin:
25 checktool(cvspsexe)
21
26
22 self.changeset = {}
27 self.changeset = {}
23 self.files = {}
28 self.files = {}
@@ -28,10 +33,11 b' class convert_cvs(converter_source):'
28 self.cvsroot = file(os.path.join(cvs, "Root")).read()[:-1]
33 self.cvsroot = file(os.path.join(cvs, "Root")).read()[:-1]
29 self.cvsrepo = file(os.path.join(cvs, "Repository")).read()[:-1]
34 self.cvsrepo = file(os.path.join(cvs, "Repository")).read()[:-1]
30 self.encoding = locale.getpreferredencoding()
35 self.encoding = locale.getpreferredencoding()
31 self._parse()
36
37 self._parse(ui)
32 self._connect()
38 self._connect()
33
39
34 def _parse(self):
40 def _parse(self, ui):
35 if self.changeset:
41 if self.changeset:
36 return
42 return
37
43
@@ -56,80 +62,114 b' class convert_cvs(converter_source):'
56 id = None
62 id = None
57 state = 0
63 state = 0
58 filerevids = {}
64 filerevids = {}
59 for l in util.popen(cmd):
65
60 if state == 0: # header
66 if self.builtin:
61 if l.startswith("PatchSet"):
67 # builtin cvsps code
62 id = l[9:-2]
68 ui.status(_('using builtin cvsps\n'))
63 if maxrev and int(id) > maxrev:
69
64 # ignore everything
70 db = cvsps.createlog(ui, cache='update')
65 state = 3
71 db = cvsps.createchangeset(ui, db,
66 elif l.startswith("Date"):
72 fuzz=int(ui.config('convert', 'cvsps.fuzz', 60)),
67 date = util.parsedate(l[6:-1], ["%Y/%m/%d %H:%M:%S"])
73 mergeto=ui.config('convert', 'cvsps.mergeto', None),
68 date = util.datestr(date)
74 mergefrom=ui.config('convert', 'cvsps.mergefrom', None))
69 elif l.startswith("Branch"):
75
70 branch = l[8:-1]
76 for cs in db:
71 self.parent[id] = self.lastbranch.get(branch, 'bad')
77 if maxrev and cs.id>maxrev:
72 self.lastbranch[branch] = id
78 break
73 elif l.startswith("Ancestor branch"):
79 id = str(cs.id)
74 ancestor = l[17:-1]
80 cs.author = self.recode(cs.author)
75 # figure out the parent later
81 self.lastbranch[cs.branch] = id
76 self.parent[id] = self.lastbranch[ancestor]
82 cs.comment = self.recode(cs.comment)
77 elif l.startswith("Author"):
83 date = util.datestr(cs.date)
78 author = self.recode(l[8:-1])
84 self.tags.update(dict.fromkeys(cs.tags, id))
79 elif l.startswith("Tag:") or l.startswith("Tags:"):
85
80 t = l[l.index(':')+1:]
86 files = {}
81 t = [ut.strip() for ut in t.split(',')]
87 for f in cs.entries:
82 if (len(t) > 1) or (t[0] and (t[0] != "(none)")):
88 files[f.file] = "%s%s" % ('.'.join([str(x) for x in f.revision]),
83 self.tags.update(dict.fromkeys(t, id))
89 ['', '(DEAD)'][f.dead])
84 elif l.startswith("Log:"):
85 # switch to gathering log
86 state = 1
87 log = ""
88 elif state == 1: # log
89 if l == "Members: \n":
90 # switch to gathering members
91 files = {}
92 oldrevs = []
93 log = self.recode(log[:-1])
94 state = 2
95 else:
96 # gather log
97 log += l
98 elif state == 2: # members
99 if l == "\n": # start of next entry
100 state = 0
101 p = [self.parent[id]]
102 if id == "1":
103 p = []
104 if branch == "HEAD":
105 branch = ""
106 if branch:
107 latest = None
108 # the last changeset that contains a base
109 # file is our parent
110 for r in oldrevs:
111 latest = max(filerevids.get(r, None), latest)
112 if latest:
113 p = [latest]
114
90
115 # add current commit to set
91 # add current commit to set
116 c = commit(author=author, date=date, parents=p,
92 c = commit(author=cs.author, date=date,
117 desc=log, branch=branch)
93 parents=[str(p.id) for p in cs.parents],
118 self.changeset[id] = c
94 desc=cs.comment, branch=cs.branch or '')
119 self.files[id] = files
95 self.changeset[id] = c
120 else:
96 self.files[id] = files
121 colon = l.rfind(':')
97 else:
122 file = l[1:colon]
98 # external cvsps
123 rev = l[colon+1:-2]
99 for l in util.popen(cmd):
124 oldrev, rev = rev.split("->")
100 if state == 0: # header
125 files[file] = rev
101 if l.startswith("PatchSet"):
102 id = l[9:-2]
103 if maxrev and int(id) > maxrev:
104 # ignore everything
105 state = 3
106 elif l.startswith("Date"):
107 date = util.parsedate(l[6:-1], ["%Y/%m/%d %H:%M:%S"])
108 date = util.datestr(date)
109 elif l.startswith("Branch"):
110 branch = l[8:-1]
111 self.parent[id] = self.lastbranch.get(branch, 'bad')
112 self.lastbranch[branch] = id
113 elif l.startswith("Ancestor branch"):
114 ancestor = l[17:-1]
115 # figure out the parent later
116 self.parent[id] = self.lastbranch[ancestor]
117 elif l.startswith("Author"):
118 author = self.recode(l[8:-1])
119 elif l.startswith("Tag:") or l.startswith("Tags:"):
120 t = l[l.index(':')+1:]
121 t = [ut.strip() for ut in t.split(',')]
122 if (len(t) > 1) or (t[0] and (t[0] != "(none)")):
123 self.tags.update(dict.fromkeys(t, id))
124 elif l.startswith("Log:"):
125 # switch to gathering log
126 state = 1
127 log = ""
128 elif state == 1: # log
129 if l == "Members: \n":
130 # switch to gathering members
131 files = {}
132 oldrevs = []
133 log = self.recode(log[:-1])
134 state = 2
135 else:
136 # gather log
137 log += l
138 elif state == 2: # members
139 if l == "\n": # start of next entry
140 state = 0
141 p = [self.parent[id]]
142 if id == "1":
143 p = []
144 if branch == "HEAD":
145 branch = ""
146 if branch:
147 latest = None
148 # the last changeset that contains a base
149 # file is our parent
150 for r in oldrevs:
151 latest = max(filerevids.get(r, None), latest)
152 if latest:
153 p = [latest]
126
154
127 # save some information for identifying branch points
155 # add current commit to set
128 oldrevs.append("%s:%s" % (oldrev, file))
156 c = commit(author=author, date=date, parents=p,
129 filerevids["%s:%s" % (rev, file)] = id
157 desc=log, branch=branch)
130 elif state == 3:
158 self.changeset[id] = c
131 # swallow all input
159 self.files[id] = files
132 continue
160 else:
161 colon = l.rfind(':')
162 file = l[1:colon]
163 rev = l[colon+1:-2]
164 oldrev, rev = rev.split("->")
165 files[file] = rev
166
167 # save some information for identifying branch points
168 oldrevs.append("%s:%s" % (oldrev, file))
169 filerevids["%s:%s" % (rev, file)] = id
170 elif state == 3:
171 # swallow all input
172 continue
133
173
134 self.heads = self.lastbranch.values()
174 self.heads = self.lastbranch.values()
135 finally:
175 finally:
General Comments 0
You need to be logged in to leave comments. Login now