##// END OF EJS Templates
win32text: use util.binary to detect \0
Christian Ebert -
r6247:7f4257b5 default
parent child Browse files
Show More
@@ -1,106 +1,103 b''
1 # win32text.py - LF <-> CRLF translation utilities for Windows users
1 # win32text.py - LF <-> CRLF translation utilities for Windows users
2 #
2 #
3 # This software may be used and distributed according to the terms
3 # This software may be used and distributed according to the terms
4 # of the GNU General Public License, incorporated herein by reference.
4 # of the GNU General Public License, incorporated herein by reference.
5 #
5 #
6 # To perform automatic newline conversion, use:
6 # To perform automatic newline conversion, use:
7 #
7 #
8 # [extensions]
8 # [extensions]
9 # hgext.win32text =
9 # hgext.win32text =
10 # [encode]
10 # [encode]
11 # ** = cleverencode:
11 # ** = cleverencode:
12 # [decode]
12 # [decode]
13 # ** = cleverdecode:
13 # ** = cleverdecode:
14 #
14 #
15 # If not doing conversion, to make sure you do not commit CRLF by accident:
15 # If not doing conversion, to make sure you do not commit CRLF by accident:
16 #
16 #
17 # [hooks]
17 # [hooks]
18 # pretxncommit.crlf = python:hgext.win32text.forbidcrlf
18 # pretxncommit.crlf = python:hgext.win32text.forbidcrlf
19 #
19 #
20 # To do the same check on a server to prevent CRLF from being pushed or pulled:
20 # To do the same check on a server to prevent CRLF from being pushed or pulled:
21 #
21 #
22 # [hooks]
22 # [hooks]
23 # pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
23 # pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
24
24
25 from mercurial import util
25 from mercurial.i18n import gettext as _
26 from mercurial.i18n import gettext as _
26 from mercurial.node import bin, short
27 from mercurial.node import bin, short
27 import re
28 import re
28
29
29 # regexp for single LF without CR preceding.
30 # regexp for single LF without CR preceding.
30 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
31 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
31
32
32 def dumbdecode(s, cmd, ui=None, repo=None, filename=None, **kwargs):
33 def dumbdecode(s, cmd, ui=None, repo=None, filename=None, **kwargs):
33 # warn if already has CRLF in repository.
34 # warn if already has CRLF in repository.
34 # it might cause unexpected eol conversion.
35 # it might cause unexpected eol conversion.
35 # see issue 302:
36 # see issue 302:
36 # http://www.selenic.com/mercurial/bts/issue302
37 # http://www.selenic.com/mercurial/bts/issue302
37 if '\r\n' in s and ui and filename and repo:
38 if '\r\n' in s and ui and filename and repo:
38 ui.warn(_('WARNING: %s already has CRLF line endings\n'
39 ui.warn(_('WARNING: %s already has CRLF line endings\n'
39 'and does not need EOL conversion by the win32text plugin.\n'
40 'and does not need EOL conversion by the win32text plugin.\n'
40 'Before your next commit, please reconsider your '
41 'Before your next commit, please reconsider your '
41 'encode/decode settings in \nMercurial.ini or %s.\n') %
42 'encode/decode settings in \nMercurial.ini or %s.\n') %
42 (filename, repo.join('hgrc')))
43 (filename, repo.join('hgrc')))
43 # replace single LF to CRLF
44 # replace single LF to CRLF
44 return re_single_lf.sub('\\1\r\n', s)
45 return re_single_lf.sub('\\1\r\n', s)
45
46
46 def dumbencode(s, cmd):
47 def dumbencode(s, cmd):
47 return s.replace('\r\n', '\n')
48 return s.replace('\r\n', '\n')
48
49
49 def clevertest(s, cmd):
50 if '\0' in s: return False
51 return True
52
53 def cleverdecode(s, cmd, **kwargs):
50 def cleverdecode(s, cmd, **kwargs):
54 if clevertest(s, cmd):
51 if util.binary(s):
52 return s
55 return dumbdecode(s, cmd, **kwargs)
53 return dumbdecode(s, cmd, **kwargs)
56 return s
57
54
58 def cleverencode(s, cmd):
55 def cleverencode(s, cmd):
59 if clevertest(s, cmd):
56 if util.binary(s):
57 return s
60 return dumbencode(s, cmd)
58 return dumbencode(s, cmd)
61 return s
62
59
63 _filters = {
60 _filters = {
64 'dumbdecode:': dumbdecode,
61 'dumbdecode:': dumbdecode,
65 'dumbencode:': dumbencode,
62 'dumbencode:': dumbencode,
66 'cleverdecode:': cleverdecode,
63 'cleverdecode:': cleverdecode,
67 'cleverencode:': cleverencode,
64 'cleverencode:': cleverencode,
68 }
65 }
69
66
70 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
67 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
71 halt = False
68 halt = False
72 for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()):
69 for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()):
73 c = repo.changectx(rev)
70 c = repo.changectx(rev)
74 for f in c.files():
71 for f in c.files():
75 if f not in c:
72 if f not in c:
76 continue
73 continue
77 data = c[f].data()
74 data = c[f].data()
78 if '\0' not in data and '\r\n' in data:
75 if not util.binary(data) and '\r\n' in data:
79 if not halt:
76 if not halt:
80 ui.warn(_('Attempt to commit or push text file(s) '
77 ui.warn(_('Attempt to commit or push text file(s) '
81 'using CRLF line endings\n'))
78 'using CRLF line endings\n'))
82 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
79 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
83 halt = True
80 halt = True
84 if halt and hooktype == 'pretxnchangegroup':
81 if halt and hooktype == 'pretxnchangegroup':
85 ui.warn(_('\nTo prevent this mistake in your local repository,\n'
82 ui.warn(_('\nTo prevent this mistake in your local repository,\n'
86 'add to Mercurial.ini or .hg/hgrc:\n'
83 'add to Mercurial.ini or .hg/hgrc:\n'
87 '\n'
84 '\n'
88 '[hooks]\n'
85 '[hooks]\n'
89 'pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n'
86 'pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n'
90 '\n'
87 '\n'
91 'and also consider adding:\n'
88 'and also consider adding:\n'
92 '\n'
89 '\n'
93 '[extensions]\n'
90 '[extensions]\n'
94 'hgext.win32text =\n'
91 'hgext.win32text =\n'
95 '[encode]\n'
92 '[encode]\n'
96 '** = cleverencode:\n'
93 '** = cleverencode:\n'
97 '[decode]\n'
94 '[decode]\n'
98 '** = cleverdecode:\n'))
95 '** = cleverdecode:\n'))
99 return halt
96 return halt
100
97
101 def reposetup(ui, repo):
98 def reposetup(ui, repo):
102 if not repo.local():
99 if not repo.local():
103 return
100 return
104 for name, fn in _filters.iteritems():
101 for name, fn in _filters.iteritems():
105 repo.adddatafilter(name, fn)
102 repo.adddatafilter(name, fn)
106
103
General Comments 0
You need to be logged in to leave comments. Login now