##// END OF EJS Templates
check-code.py: Check for bare ^...
Mads Kiilerich -
r10802:6e4cf831 stable
parent child Browse files
Show More
@@ -1,168 +1,169
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # check-code - a style and portability checker for Mercurial
3 # check-code - a style and portability checker for Mercurial
4 #
4 #
5 # Copyright 2010 Matt Mackall <mpm@selenic.com>
5 # Copyright 2010 Matt Mackall <mpm@selenic.com>
6 #
6 #
7 # This software may be used and distributed according to the terms of the
7 # This software may be used and distributed according to the terms of the
8 # GNU General Public License version 2 or any later version.
8 # GNU General Public License version 2 or any later version.
9
9
10 import sys, re, glob
10 import sys, re, glob
11
11
12 def repquote(m):
12 def repquote(m):
13 t = re.sub(r"\w", "x", m.group(2))
13 t = re.sub(r"\w", "x", m.group(2))
14 t = re.sub(r"[^\sx]", "o", t)
14 t = re.sub(r"[^\sx]", "o", t)
15 return m.group(1) + t + m.group(1)
15 return m.group(1) + t + m.group(1)
16
16
17 def repcomment(m):
17 def repcomment(m):
18 return m.group(1) + "#" * len(m.group(2))
18 return m.group(1) + "#" * len(m.group(2))
19
19
20 def repccomment(m):
20 def repccomment(m):
21 t = re.sub(r"((?<=\n) )|\S", "x", m.group(2))
21 t = re.sub(r"((?<=\n) )|\S", "x", m.group(2))
22 return m.group(1) + t + "*/"
22 return m.group(1) + t + "*/"
23
23
24 def repcallspaces(m):
24 def repcallspaces(m):
25 t = re.sub(r"\n\s+", "\n", m.group(2))
25 t = re.sub(r"\n\s+", "\n", m.group(2))
26 return m.group(1) + t
26 return m.group(1) + t
27
27
28 def repinclude(m):
28 def repinclude(m):
29 return m.group(1) + "<foo>"
29 return m.group(1) + "<foo>"
30
30
31 def rephere(m):
31 def rephere(m):
32 t = re.sub(r"\S", "x", m.group(2))
32 t = re.sub(r"\S", "x", m.group(2))
33 return m.group(1) + t
33 return m.group(1) + t
34
34
35
35
36 testpats = [
36 testpats = [
37 (r'(pushd|popd)', "don't use 'pushd' or 'popd', use 'cd'"),
37 (r'(pushd|popd)', "don't use 'pushd' or 'popd', use 'cd'"),
38 (r'\W\$?\(\([^\)]*\)\)', "don't use (()) or $(()), use 'expr'"),
38 (r'\W\$?\(\([^\)]*\)\)', "don't use (()) or $(()), use 'expr'"),
39 (r'^function', "don't use 'function', use old style"),
39 (r'^function', "don't use 'function', use old style"),
40 (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"),
40 (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"),
41 (r'echo.*\\n', "don't use 'echo \\n', use printf"),
41 (r'echo.*\\n', "don't use 'echo \\n', use printf"),
42 (r'^diff.*-\w*N', "don't use 'diff -N'"),
42 (r'^diff.*-\w*N', "don't use 'diff -N'"),
43 (r'(^| )wc[^|]*$', "filter wc output"),
43 (r'(^| )wc[^|]*$', "filter wc output"),
44 (r'head -c', "don't use 'head -c', use 'dd'"),
44 (r'head -c', "don't use 'head -c', use 'dd'"),
45 (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"),
45 (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"),
46 (r'printf.*\\\d\d\d', "don't use 'printf \NNN', use Python"),
46 (r'printf.*\\\d\d\d', "don't use 'printf \NNN', use Python"),
47 (r'printf.*\\x', "don't use printf \\x, use Python"),
47 (r'printf.*\\x', "don't use printf \\x, use Python"),
48 (r'\$\(.*\)', "don't use $(expr), use `expr`"),
48 (r'\$\(.*\)', "don't use $(expr), use `expr`"),
49 (r'rm -rf \*', "don't use naked rm -rf, target a directory"),
49 (r'rm -rf \*', "don't use naked rm -rf, target a directory"),
50 (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w',
50 (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w',
51 "use egrep for extended grep syntax"),
51 "use egrep for extended grep syntax"),
52 (r'/bin/', "don't use explicit paths for tools"),
52 (r'/bin/', "don't use explicit paths for tools"),
53 (r'\$PWD', "don't use $PWD, use `pwd`"),
53 (r'\$PWD', "don't use $PWD, use `pwd`"),
54 (r'[^\n]\Z', "no trailing newline"),
54 (r'[^\n]\Z', "no trailing newline"),
55 (r'export.*=', "don't export and assign at once"),
55 (r'export.*=', "don't export and assign at once"),
56 ('^([^"\']|("[^"]*")|(\'[^\']*\'))*\\^', "^ must be quoted"),
56 ]
57 ]
57
58
58 testfilters = [
59 testfilters = [
59 (r"( *)(#([^\n]*\S)?)", repcomment),
60 (r"( *)(#([^\n]*\S)?)", repcomment),
60 (r"<<(\S+)((.|\n)*?\n\1)", rephere),
61 (r"<<(\S+)((.|\n)*?\n\1)", rephere),
61 ]
62 ]
62
63
63 pypats = [
64 pypats = [
64 (r'^\s*\t', "don't use tabs"),
65 (r'^\s*\t', "don't use tabs"),
65 (r'\S;\s*\n', "semicolon"),
66 (r'\S;\s*\n', "semicolon"),
66 (r'\w,\w', "missing whitespace after ,"),
67 (r'\w,\w', "missing whitespace after ,"),
67 (r'\w[+/*\-<>]\w', "missing whitespace in expression"),
68 (r'\w[+/*\-<>]\w', "missing whitespace in expression"),
68 (r'^\s+\w+=\w+[^,)]$', "missing whitespace in assignment"),
69 (r'^\s+\w+=\w+[^,)]$', "missing whitespace in assignment"),
69 (r'.{85}', "line too long"),
70 (r'.{85}', "line too long"),
70 (r'[^\n]\Z', "no trailing newline"),
71 (r'[^\n]\Z', "no trailing newline"),
71 # (r'^\s+[^_ ][^_. ]+_[^_]+\s*=', "don't use underbars in identifiers"),
72 # (r'^\s+[^_ ][^_. ]+_[^_]+\s*=', "don't use underbars in identifiers"),
72 # (r'\w*[a-z][A-Z]\w*\s*=', "don't use camelcase in identifiers"),
73 # (r'\w*[a-z][A-Z]\w*\s*=', "don't use camelcase in identifiers"),
73 (r'^\s*(if|while|def|class|except|try)\s[^[]*:\s*[^\]#\s]+',
74 (r'^\s*(if|while|def|class|except|try)\s[^[]*:\s*[^\]#\s]+',
74 "linebreak after :"),
75 "linebreak after :"),
75 (r'class\s[^(]:', "old-style class, use class foo(object)"),
76 (r'class\s[^(]:', "old-style class, use class foo(object)"),
76 (r'^\s+del\(', "del isn't a function"),
77 (r'^\s+del\(', "del isn't a function"),
77 (r'^\s+except\(', "except isn't a function"),
78 (r'^\s+except\(', "except isn't a function"),
78 (r',]', "unneeded trailing ',' in list"),
79 (r',]', "unneeded trailing ',' in list"),
79 # (r'class\s[A-Z][^\(]*\((?!Exception)',
80 # (r'class\s[A-Z][^\(]*\((?!Exception)',
80 # "don't capitalize non-exception classes"),
81 # "don't capitalize non-exception classes"),
81 # (r'in range\(', "use xrange"),
82 # (r'in range\(', "use xrange"),
82 # (r'^\s*print\s+', "avoid using print in core and extensions"),
83 # (r'^\s*print\s+', "avoid using print in core and extensions"),
83 (r'[\x80-\xff]', "non-ASCII character literal"),
84 (r'[\x80-\xff]', "non-ASCII character literal"),
84 (r'("\')\.format\(', "str.format() not available in Python 2.4"),
85 (r'("\')\.format\(', "str.format() not available in Python 2.4"),
85 (r'^\s*with\s+', "with not available in Python 2.4"),
86 (r'^\s*with\s+', "with not available in Python 2.4"),
86 (r'if\s.*\selse', "if ... else form not available in Python 2.4"),
87 (r'if\s.*\selse', "if ... else form not available in Python 2.4"),
87 (r'([\(\[]\s\S)|(\S\s[\)\]])', "gratuitous whitespace in () or []"),
88 (r'([\(\[]\s\S)|(\S\s[\)\]])', "gratuitous whitespace in () or []"),
88 # (r'\s\s=', "gratuitous whitespace before ="),
89 # (r'\s\s=', "gratuitous whitespace before ="),
89 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\S', "missing whitespace around operator"),
90 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\S', "missing whitespace around operator"),
90 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\s', "missing whitespace around operator"),
91 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\s', "missing whitespace around operator"),
91 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=)\S', "missing whitespace around operator"),
92 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=)\S', "missing whitespace around operator"),
92 (r'[^+=*!<>&| -](\s=|=\s)[^= ]', "wrong whitespace around ="),
93 (r'[^+=*!<>&| -](\s=|=\s)[^= ]', "wrong whitespace around ="),
93 (r'raise Exception', "don't raise generic exceptions"),
94 (r'raise Exception', "don't raise generic exceptions"),
94 (r'ui\.(status|progress|write|note)\([\'\"]x', "unwrapped ui message"),
95 (r'ui\.(status|progress|write|note)\([\'\"]x', "unwrapped ui message"),
95 ]
96 ]
96
97
97 pyfilters = [
98 pyfilters = [
98 (r"""(''')(([^']|\\'|'{1,2}(?!'))*)'''""", repquote),
99 (r"""(''')(([^']|\\'|'{1,2}(?!'))*)'''""", repquote),
99 (r'''(""")(([^"]|\\"|"{1,2}(?!"))*)"""''', repquote),
100 (r'''(""")(([^"]|\\"|"{1,2}(?!"))*)"""''', repquote),
100 (r'''(?<!")(")(([^"\n]|\\")+)"(?!")''', repquote),
101 (r'''(?<!")(")(([^"\n]|\\")+)"(?!")''', repquote),
101 (r"""(?<!')(')(([^'\n]|\\')+)'(?!')""", repquote),
102 (r"""(?<!')(')(([^'\n]|\\')+)'(?!')""", repquote),
102 (r"( *)(#([^\n]*\S)?)", repcomment),
103 (r"( *)(#([^\n]*\S)?)", repcomment),
103 ]
104 ]
104
105
105 cpats = [
106 cpats = [
106 (r'//', "don't use //-style comments"),
107 (r'//', "don't use //-style comments"),
107 (r'^ ', "don't use spaces to indent"),
108 (r'^ ', "don't use spaces to indent"),
108 (r'\S\t', "don't use tabs except for indent"),
109 (r'\S\t', "don't use tabs except for indent"),
109 (r'(\S\s+|^\s+)\n', "trailing whitespace"),
110 (r'(\S\s+|^\s+)\n', "trailing whitespace"),
110 (r'.{85}', "line too long"),
111 (r'.{85}', "line too long"),
111 (r'(while|if|do|for)\(', "use space after while/if/do/for"),
112 (r'(while|if|do|for)\(', "use space after while/if/do/for"),
112 (r'return\(', "return is not a function"),
113 (r'return\(', "return is not a function"),
113 (r' ;', "no space before ;"),
114 (r' ;', "no space before ;"),
114 (r'\w+\* \w+', "use int *foo, not int* foo"),
115 (r'\w+\* \w+', "use int *foo, not int* foo"),
115 (r'\([^\)]+\) \w+', "use (int)foo, not (int) foo"),
116 (r'\([^\)]+\) \w+', "use (int)foo, not (int) foo"),
116 (r'\S+ (\+\+|--)', "use foo++, not foo ++"),
117 (r'\S+ (\+\+|--)', "use foo++, not foo ++"),
117 (r'\w,\w', "missing whitespace after ,"),
118 (r'\w,\w', "missing whitespace after ,"),
118 (r'\w[+/*]\w', "missing whitespace in expression"),
119 (r'\w[+/*]\w', "missing whitespace in expression"),
119 (r'^#\s+\w', "use #foo, not # foo"),
120 (r'^#\s+\w', "use #foo, not # foo"),
120 (r'[^\n]\Z', "no trailing newline"),
121 (r'[^\n]\Z', "no trailing newline"),
121 ]
122 ]
122
123
123 cfilters = [
124 cfilters = [
124 (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment),
125 (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment),
125 (r'''(?<!")(")(([^"]|\\")+"(?!"))''', repquote),
126 (r'''(?<!")(")(([^"]|\\")+"(?!"))''', repquote),
126 (r'''(#\s*include\s+<)([^>]+)>''', repinclude),
127 (r'''(#\s*include\s+<)([^>]+)>''', repinclude),
127 (r'(\()([^)]+\))', repcallspaces),
128 (r'(\()([^)]+\))', repcallspaces),
128 ]
129 ]
129
130
130 checks = [
131 checks = [
131 ('python', r'.*\.(py|cgi)$', pyfilters, pypats),
132 ('python', r'.*\.(py|cgi)$', pyfilters, pypats),
132 ('test script', r'(.*/)?test-[^.~]*$', testfilters, testpats),
133 ('test script', r'(.*/)?test-[^.~]*$', testfilters, testpats),
133 ('c', r'.*\.c$', cfilters, cpats),
134 ('c', r'.*\.c$', cfilters, cpats),
134 ]
135 ]
135
136
136 if len(sys.argv) == 1:
137 if len(sys.argv) == 1:
137 check = glob.glob("*")
138 check = glob.glob("*")
138 else:
139 else:
139 check = sys.argv[1:]
140 check = sys.argv[1:]
140
141
141 for f in check:
142 for f in check:
142 for name, match, filters, pats in checks:
143 for name, match, filters, pats in checks:
143 fc = 0
144 fc = 0
144 if not re.match(match, f):
145 if not re.match(match, f):
145 continue
146 continue
146 pre = post = open(f).read()
147 pre = post = open(f).read()
147 if "no-" + "check-code" in pre:
148 if "no-" + "check-code" in pre:
148 break
149 break
149 for p, r in filters:
150 for p, r in filters:
150 post = re.sub(p, r, post)
151 post = re.sub(p, r, post)
151 # print post # uncomment to show filtered version
152 # print post # uncomment to show filtered version
152 z = enumerate(zip(pre.splitlines(), post.splitlines(True)))
153 z = enumerate(zip(pre.splitlines(), post.splitlines(True)))
153 for n, l in z:
154 for n, l in z:
154 if "check-code" + "-ignore" in l[0]:
155 if "check-code" + "-ignore" in l[0]:
155 continue
156 continue
156 lc = 0
157 lc = 0
157 for p, msg in pats:
158 for p, msg in pats:
158 if re.search(p, l[1]):
159 if re.search(p, l[1]):
159 if not lc:
160 if not lc:
160 print "%s:%d:" % (f, n + 1)
161 print "%s:%d:" % (f, n + 1)
161 print " > %s" % l[0]
162 print " > %s" % l[0]
162 print " %s" % msg
163 print " %s" % msg
163 lc += 1
164 lc += 1
164 fc += 1
165 fc += 1
165 if fc == 15:
166 if fc == 15:
166 print " (too many errors, giving up)"
167 print " (too many errors, giving up)"
167 break
168 break
168 break
169 break
@@ -1,83 +1,83
1 #!/bin/sh
1 #!/bin/sh
2
2
3 "$TESTDIR/hghave" baz || exit 80
3 "$TESTDIR/hghave" baz || exit 80
4
4
5 mkdir do_not_use_HOME_baz
5 mkdir do_not_use_HOME_baz
6 cd do_not_use_HOME_baz
6 cd do_not_use_HOME_baz
7 HOME=`pwd`; export HOME
7 HOME=`pwd`; export HOME
8 cd ..
8 cd ..
9 baz my-id "mercurial <mercurial@selenic.com>"
9 baz my-id "mercurial <mercurial@selenic.com>"
10
10
11 echo "[extensions]" >> $HGRCPATH
11 echo "[extensions]" >> $HGRCPATH
12 echo "convert=" >> $HGRCPATH
12 echo "convert=" >> $HGRCPATH
13 echo 'graphlog =' >> $HGRCPATH
13 echo 'graphlog =' >> $HGRCPATH
14
14
15 echo % create baz archive
15 echo % create baz archive
16 baz make-archive baz@mercurial--convert hg-test-convert-baz
16 baz make-archive baz@mercurial--convert hg-test-convert-baz
17
17
18 echo % initialize baz repo
18 echo % initialize baz repo
19 mkdir baz-repo
19 mkdir baz-repo
20 cd baz-repo/
20 cd baz-repo/
21 baz init-tree baz@mercurial--convert/baz--test--0
21 baz init-tree baz@mercurial--convert/baz--test--0
22 baz import
22 baz import
23
23
24 echo % create initial files
24 echo % create initial files
25 echo 'this is a file' > a
25 echo 'this is a file' > a
26 baz add a
26 baz add a
27 mkdir src
27 mkdir src
28 baz add src
28 baz add src
29 cd src
29 cd src
30 dd count=1 if=/dev/zero of=b > /dev/null 2> /dev/null
30 dd count=1 if=/dev/zero of=b > /dev/null 2> /dev/null
31 baz add b
31 baz add b
32 # HACK: hide GNU tar-1.22 "tar: The --preserve option is deprecated, use --preserve-permissions --preserve-order instead"
32 # HACK: hide GNU tar-1.22 "tar: The --preserve option is deprecated, use --preserve-permissions --preserve-order instead"
33 baz commit -s "added a file, src and src/b (binary)" 2>&1 | grep -v ^tar
33 baz commit -s "added a file, src and src/b (binary)" 2>&1 | grep -v '^tar'
34
34
35 echo % create link file and modify a
35 echo % create link file and modify a
36 ln -s ../a a-link
36 ln -s ../a a-link
37 baz add a-link
37 baz add a-link
38 echo 'this a modification to a' >> ../a
38 echo 'this a modification to a' >> ../a
39 baz commit -s "added link to a and modify a"
39 baz commit -s "added link to a and modify a"
40
40
41 echo % create second link and modify b
41 echo % create second link and modify b
42 ln -s ../a a-link-2
42 ln -s ../a a-link-2
43 baz add a-link-2
43 baz add a-link-2
44 dd count=1 seek=1 if=/dev/zero of=b > /dev/null 2> /dev/null
44 dd count=1 seek=1 if=/dev/zero of=b > /dev/null 2> /dev/null
45 baz commit -s "added second link and modify b"
45 baz commit -s "added second link and modify b"
46
46
47 echo % b file to link and a-link-2 to regular file
47 echo % b file to link and a-link-2 to regular file
48 rm -f a-link-2
48 rm -f a-link-2
49 echo 'this is now a regular file' > a-link-2
49 echo 'this is now a regular file' > a-link-2
50 ln -sf ../a b
50 ln -sf ../a b
51 baz commit -s "file to link and link to file test"
51 baz commit -s "file to link and link to file test"
52
52
53 echo % move a-link-2 file and src directory
53 echo % move a-link-2 file and src directory
54 cd ..
54 cd ..
55 baz mv src/a-link-2 c
55 baz mv src/a-link-2 c
56 baz mv src test
56 baz mv src test
57 baz commit -s "move and rename a-link-2 file and src directory"
57 baz commit -s "move and rename a-link-2 file and src directory"
58
58
59 echo % move and add the moved file again
59 echo % move and add the moved file again
60 echo e > e
60 echo e > e
61 baz add e
61 baz add e
62 baz commit -s "add e"
62 baz commit -s "add e"
63 baz mv e f
63 baz mv e f
64 echo ee > e
64 echo ee > e
65 baz add e
65 baz add e
66 baz commit -s "move e and recreate it again"
66 baz commit -s "move e and recreate it again"
67 cd ..
67 cd ..
68
68
69 echo % converting baz repo to Mercurial
69 echo % converting baz repo to Mercurial
70 hg convert baz-repo baz-repo-hg
70 hg convert baz-repo baz-repo-hg
71
71
72 baz register-archive -d baz@mercurial--convert
72 baz register-archive -d baz@mercurial--convert
73
73
74 glog()
74 glog()
75 {
75 {
76 hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
76 hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
77 }
77 }
78
78
79 echo % show graph log
79 echo % show graph log
80 glog -R baz-repo-hg
80 glog -R baz-repo-hg
81 hg up -q -R baz-repo-hg
81 hg up -q -R baz-repo-hg
82 hg -R baz-repo-hg manifest --debug
82 hg -R baz-repo-hg manifest --debug
83 hg -R baz-repo-hg log -r 5 -r 7 -C --debug | grep copies
83 hg -R baz-repo-hg log -r 5 -r 7 -C --debug | grep copies
@@ -1,118 +1,118
1 #!/bin/sh
1 #!/bin/sh
2
2
3 # This feature requires use of builtin cvsps!
3 # This feature requires use of builtin cvsps!
4 "$TESTDIR/hghave" cvs || exit 80
4 "$TESTDIR/hghave" cvs || exit 80
5
5
6 set -e
6 set -e
7
7
8 echo "[extensions]" >> $HGRCPATH
8 echo "[extensions]" >> $HGRCPATH
9 echo "convert = " >> $HGRCPATH
9 echo "convert = " >> $HGRCPATH
10 echo "graphlog = " >> $HGRCPATH
10 echo "graphlog = " >> $HGRCPATH
11
11
12 echo % create cvs repository with one project
12 echo % create cvs repository with one project
13 mkdir cvsrepo
13 mkdir cvsrepo
14 cd cvsrepo
14 cd cvsrepo
15 CVSROOT=`pwd`
15 CVSROOT=`pwd`
16 export CVSROOT
16 export CVSROOT
17 CVS_OPTIONS=-f
17 CVS_OPTIONS=-f
18 export CVS_OPTIONS
18 export CVS_OPTIONS
19 cd ..
19 cd ..
20
20
21 filterpath()
21 filterpath()
22 {
22 {
23 eval "$@" | sed "s:$CVSROOT:*REPO*:g"
23 eval "$@" | sed "s:$CVSROOT:*REPO*:g"
24 }
24 }
25
25
26 cvscall()
26 cvscall()
27 {
27 {
28 echo cvs -f "$@"
28 echo cvs -f "$@"
29 cvs -f "$@" 2>&1
29 cvs -f "$@" 2>&1
30 }
30 }
31
31
32 # output of 'cvs ci' varies unpredictably, so just discard it
32 # output of 'cvs ci' varies unpredictably, so just discard it
33 cvsci()
33 cvsci()
34 {
34 {
35 echo cvs -f ci "$@"
35 echo cvs -f ci "$@"
36 cvs -f ci "$@" >/dev/null 2>&1
36 cvs -f ci "$@" >/dev/null 2>&1
37 }
37 }
38
38
39 filterpath cvscall -d "$CVSROOT" init
39 filterpath cvscall -d "$CVSROOT" init
40 mkdir cvsrepo/proj
40 mkdir cvsrepo/proj
41
41
42 cvscall -q co proj
42 cvscall -q co proj
43
43
44 echo % create file1 on the trunk
44 echo % create file1 on the trunk
45 cd proj
45 cd proj
46 touch file1
46 touch file1
47 cvscall -Q add file1
47 cvscall -Q add file1
48 cvsci -m"add file1 on trunk" file1
48 cvsci -m"add file1 on trunk" file1
49
49
50 echo % create two branches
50 echo % create two branches
51 cvscall -q tag -b v1_0
51 cvscall -q tag -b v1_0
52 cvscall -q tag -b v1_1
52 cvscall -q tag -b v1_1
53
53
54 echo % create file2 on branch v1_0
54 echo % create file2 on branch v1_0
55 cvscall -Q up -rv1_0
55 cvscall -Q up -rv1_0
56 touch file2
56 touch file2
57 cvscall -Q add file2
57 cvscall -Q add file2
58 cvsci -m"add file2" file2
58 cvsci -m"add file2" file2
59
59
60 echo % create file3, file4 on branch v1_1
60 echo % create file3, file4 on branch v1_1
61 cvscall -Q up -rv1_1
61 cvscall -Q up -rv1_1
62 touch file3
62 touch file3
63 touch file4
63 touch file4
64 cvscall -Q add file3 file4
64 cvscall -Q add file3 file4
65 cvsci -m"add file3, file4 on branch v1_1" file3 file4
65 cvsci -m"add file3, file4 on branch v1_1" file3 file4
66
66
67 echo % merge file2 from v1_0 to v1_1
67 echo % merge file2 from v1_0 to v1_1
68 cvscall -Q up -jv1_0
68 cvscall -Q up -jv1_0
69 cvsci -m"MERGE from v1_0: add file2"
69 cvsci -m"MERGE from v1_0: add file2"
70
70
71 # Step things up a notch: now we make the history really hairy, with
71 # Step things up a notch: now we make the history really hairy, with
72 # changes bouncing back and forth between trunk and v1_2 and merges
72 # changes bouncing back and forth between trunk and v1_2 and merges
73 # going both ways. (I.e., try to model the real world.)
73 # going both ways. (I.e., try to model the real world.)
74
74
75 echo "% create branch v1_2"
75 echo "% create branch v1_2"
76 cvscall -Q up -A
76 cvscall -Q up -A
77 cvscall -q tag -b v1_2
77 cvscall -q tag -b v1_2
78
78
79 echo "% create file5 on branch v1_2"
79 echo "% create file5 on branch v1_2"
80 cvscall -Q up -rv1_2
80 cvscall -Q up -rv1_2
81 touch file5
81 touch file5
82 cvs -Q add file5
82 cvs -Q add file5
83 cvsci -m"add file5 on v1_2"
83 cvsci -m"add file5 on v1_2"
84
84
85 echo "% create file6 on trunk post-v1_2"
85 echo "% create file6 on trunk post-v1_2"
86 cvscall -Q up -A
86 cvscall -Q up -A
87 touch file6
87 touch file6
88 cvscall -Q add file6
88 cvscall -Q add file6
89 cvsci -m"add file6 on trunk post-v1_2"
89 cvsci -m"add file6 on trunk post-v1_2"
90
90
91 echo "% merge file5 from v1_2 to trunk"
91 echo "% merge file5 from v1_2 to trunk"
92 cvscall -Q up -A
92 cvscall -Q up -A
93 cvscall -Q up -jv1_2 file5
93 cvscall -Q up -jv1_2 file5
94 cvsci -m"MERGE from v1_2: add file5"
94 cvsci -m"MERGE from v1_2: add file5"
95
95
96 echo "% merge file6 from trunk to v1_2"
96 echo "% merge file6 from trunk to v1_2"
97 cvscall -Q up -rv1_2
97 cvscall -Q up -rv1_2
98 cvscall up -jHEAD file6
98 cvscall up -jHEAD file6
99 cvsci -m"MERGE from HEAD: add file6"
99 cvsci -m"MERGE from HEAD: add file6"
100
100
101 echo % cvs rlog output
101 echo % cvs rlog output
102 filterpath cvscall -q rlog proj | egrep '^(RCS file|revision)'
102 filterpath cvscall -q rlog proj | egrep '^(RCS file|revision)'
103
103
104 echo "% convert to hg (#1)"
104 echo "% convert to hg (#1)"
105 cd ..
105 cd ..
106 filterpath hg convert --datesort proj proj.hg
106 filterpath hg convert --datesort proj proj.hg
107
107
108 echo "% hg glog output (#1)"
108 echo "% hg glog output (#1)"
109 hg -R proj.hg glog --template "{rev} {desc}\n"
109 hg -R proj.hg glog --template "{rev} {desc}\n"
110
110
111 echo "% convert to hg (#2: with merge detection)"
111 echo "% convert to hg (#2: with merge detection)"
112 filterpath hg convert \
112 filterpath hg convert \
113 --config convert.cvsps.mergefrom="\"^MERGE from (\S+):\"" \
113 --config convert.cvsps.mergefrom='"^MERGE from (\S+):"' \
114 --datesort \
114 --datesort \
115 proj proj.hg2
115 proj proj.hg2
116
116
117 echo "% hg glog output (#2)"
117 echo "% hg glog output (#2)"
118 hg -R proj.hg2 glog --template "{rev} {desc}\n"
118 hg -R proj.hg2 glog --template "{rev} {desc}\n"
General Comments 0
You need to be logged in to leave comments. Login now