##// END OF EJS Templates
Issue 882: add standard hook to reject text files with CRLF....
Jesse Glick -
r5675:a5fe27b8 default
parent child Browse files
Show More
@@ -0,0 +1,56 b''
1 #!/bin/sh
2
3 hg init
4 echo '[hooks]' >> .hg/hgrc
5 echo 'pretxncommit.crlf = python:hgext.win32text.forbidcrlf' >> .hg/hgrc
6 echo 'pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf' >> .hg/hgrc
7 cat .hg/hgrc
8 echo
9
10 echo hello > f
11 hg add f
12 hg ci -m 1 -d'0 0'
13 echo
14
15 unix2dos f
16 hg ci -m 2 -d'0 0'
17 hg revert -a
18 echo
19
20 mkdir d
21 echo hello > d/f2
22 unix2dos d/f2
23 hg add d/f2
24 hg ci -m 3 -d'0 0'
25 hg revert -a
26 rm d/f2
27 echo
28
29 hg rem f
30 hg ci -m 4 -d'0 0'
31 echo
32
33 printf 'hello\x00\x0D\x0A' > bin
34 hg add bin
35 hg ci -m 5 -d'0 0'
36 hg log -v
37 echo
38
39 hg clone . dupe
40 echo
41 for x in a b c d; do echo content > dupe/$x; done
42 hg -R dupe add
43 unix2dos dupe/b dupe/c dupe/d
44 hg -R dupe ci -m a -d'0 0' dupe/a
45 hg -R dupe ci -m b/c -d'0 0' dupe/[bc]
46 hg -R dupe ci -m d -d'0 0' dupe/d
47 hg -R dupe log -v
48 echo
49
50 hg pull dupe
51 echo
52
53 hg log -v
54 echo
55
56 # XXX missing tests for encode/decode hooks
@@ -0,0 +1,157 b''
1 [hooks]
2 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
3 pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
4
5
6 Attempt to commit or push text file(s) using CRLF line endings
7 in b1aa5cde7ff4: f
8 transaction abort!
9 rollback completed
10 abort: pretxncommit.crlf hook failed
11 reverting f
12
13 Attempt to commit or push text file(s) using CRLF line endings
14 in 88b17af74937: d/f2
15 transaction abort!
16 rollback completed
17 abort: pretxncommit.crlf hook failed
18 forgetting d/f2
19
20
21 changeset: 2:a55cab36df04
22 tag: tip
23 user: test
24 date: Thu Jan 01 00:00:00 1970 +0000
25 files: bin
26 description:
27 5
28
29
30 changeset: 1:c72a7d1d0907
31 user: test
32 date: Thu Jan 01 00:00:00 1970 +0000
33 files: f
34 description:
35 4
36
37
38 changeset: 0:fcf06d5c4e1d
39 user: test
40 date: Thu Jan 01 00:00:00 1970 +0000
41 files: f
42 description:
43 1
44
45
46
47 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
48
49 adding dupe/a
50 adding dupe/b
51 adding dupe/c
52 adding dupe/d
53 changeset: 5:81c49ee61396
54 tag: tip
55 user: test
56 date: Thu Jan 01 00:00:00 1970 +0000
57 files: d
58 description:
59 d
60
61
62 changeset: 4:02184785bcac
63 user: test
64 date: Thu Jan 01 00:00:00 1970 +0000
65 files: b c
66 description:
67 b/c
68
69
70 changeset: 3:36e70ffe2c3d
71 user: test
72 date: Thu Jan 01 00:00:00 1970 +0000
73 files: a
74 description:
75 a
76
77
78 changeset: 2:a55cab36df04
79 user: test
80 date: Thu Jan 01 00:00:00 1970 +0000
81 files: bin
82 description:
83 5
84
85
86 changeset: 1:c72a7d1d0907
87 user: test
88 date: Thu Jan 01 00:00:00 1970 +0000
89 files: f
90 description:
91 4
92
93
94 changeset: 0:fcf06d5c4e1d
95 user: test
96 date: Thu Jan 01 00:00:00 1970 +0000
97 files: f
98 description:
99 1
100
101
102
103 pulling from dupe
104 searching for changes
105 adding changesets
106 adding manifests
107 adding file changes
108 added 3 changesets with 4 changes to 4 files
109 Attempt to commit or push text file(s) using CRLF line endings
110 in 02184785bcac: b
111 in 02184785bcac: c
112 in 81c49ee61396: d
113
114 To prevent this mistake in your local repository,
115 add to Mercurial.ini or .hg/hgrc:
116
117 [hooks]
118 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
119
120 and also consider adding:
121
122 [extensions]
123 hgext.win32text =
124 [encode]
125 ** = cleverencode:
126 [decode]
127 ** = cleverdecode:
128 transaction abort!
129 rollback completed
130 abort: pretxnchangegroup.crlf hook failed
131
132 changeset: 2:a55cab36df04
133 tag: tip
134 user: test
135 date: Thu Jan 01 00:00:00 1970 +0000
136 files: bin
137 description:
138 5
139
140
141 changeset: 1:c72a7d1d0907
142 user: test
143 date: Thu Jan 01 00:00:00 1970 +0000
144 files: f
145 description:
146 4
147
148
149 changeset: 0:fcf06d5c4e1d
150 user: test
151 date: Thu Jan 01 00:00:00 1970 +0000
152 files: f
153 description:
154 1
155
156
157
@@ -1,45 +1,101 b''
1 # win32text.py - LF <-> CRLF translation utilities for Windows users
2 #
3 # This software may be used and distributed according to the terms
4 # of the GNU General Public License, incorporated herein by reference.
5 #
6 # To perform automatic newline conversion, use:
7 #
8 # [extensions]
9 # hgext.win32text =
10 # [encode]
11 # ** = cleverencode:
12 # [decode]
13 # ** = cleverdecode:
14 #
15 # If not doing conversion, to make sure you do not commit CRLF by accident:
16 #
17 # [hooks]
18 # pretxncommit.crlf = python:hgext.win32text.forbidcrlf
19 #
20 # To do the same check on a server to prevent CRLF from being pushed or pulled:
21 #
22 # [hooks]
23 # pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
24
1 25 from mercurial import util, ui
2 26 from mercurial.i18n import gettext as _
27 from mercurial.node import *
3 28 import re
4 29
5 30 # regexp for single LF without CR preceding.
6 31 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
7 32
8 33 def dumbdecode(s, cmd):
9 34 # warn if already has CRLF in repository.
10 35 # it might cause unexpected eol conversion.
11 36 # see issue 302:
12 37 # http://www.selenic.com/mercurial/bts/issue302
13 38 if '\r\n' in s:
14 39 u = ui.ui()
15 40 u.warn(_('WARNING: file in repository already has CRLF line ending \n'
16 41 ' which does not need eol conversion by win32text plugin.\n'
17 42 ' Please reconsider encode/decode setting in'
18 43 ' mercurial.ini or .hg/hgrc\n'
19 44 ' before next commit.\n'))
20 45 # replace single LF to CRLF
21 46 return re_single_lf.sub('\\1\r\n', s)
22 47
23 48 def dumbencode(s, cmd):
24 49 return s.replace('\r\n', '\n')
25 50
26 51 def clevertest(s, cmd):
27 52 if '\0' in s: return False
28 53 return True
29 54
30 55 def cleverdecode(s, cmd):
31 56 if clevertest(s, cmd):
32 57 return dumbdecode(s, cmd)
33 58 return s
34 59
35 60 def cleverencode(s, cmd):
36 61 if clevertest(s, cmd):
37 62 return dumbencode(s, cmd)
38 63 return s
39 64
40 65 util.filtertable.update({
41 66 'dumbdecode:': dumbdecode,
42 67 'dumbencode:': dumbencode,
43 68 'cleverdecode:': cleverdecode,
44 69 'cleverencode:': cleverencode,
45 70 })
71
72 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
73 halt = False
74 for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()):
75 c = repo.changectx(rev)
76 for f in c.files():
77 if f not in c:
78 continue
79 data = c[f].data()
80 if '\0' not in data and '\r\n' in data:
81 if not halt:
82 ui.warn(_('Attempt to commit or push text file(s) '
83 'using CRLF line endings\n'))
84 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
85 halt = True
86 if halt and hooktype == 'pretxnchangegroup':
87 ui.warn(_('\nTo prevent this mistake in your local repository,\n'
88 'add to Mercurial.ini or .hg/hgrc:\n'
89 '\n'
90 '[hooks]\n'
91 'pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n'
92 '\n'
93 'and also consider adding:\n'
94 '\n'
95 '[extensions]\n'
96 'hgext.win32text =\n'
97 '[encode]\n'
98 '** = cleverencode:\n'
99 '[decode]\n'
100 '** = cleverdecode:\n'))
101 return halt
General Comments 0
You need to be logged in to leave comments. Login now