##// END OF EJS Templates
win32text: rename forbidcrlforcr() function
Patrick Mezard -
r6483:0a803195 default
parent child Browse files
Show More
@@ -1,144 +1,144 b''
1 # win32text.py - LF <-> CRLF/CR translation utilities for Windows/Mac users
1 # win32text.py - LF <-> CRLF/CR translation utilities for Windows/Mac 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 # # or ** = macencode:
12 # # or ** = macencode:
13 # [decode]
13 # [decode]
14 # ** = cleverdecode:
14 # ** = cleverdecode:
15 # # or ** = macdecode:
15 # # or ** = macdecode:
16 #
16 #
17 # If not doing conversion, to make sure you do not commit CRLF/CR by accident:
17 # If not doing conversion, to make sure you do not commit CRLF/CR by accident:
18 #
18 #
19 # [hooks]
19 # [hooks]
20 # pretxncommit.crlf = python:hgext.win32text.forbidcrlf
20 # pretxncommit.crlf = python:hgext.win32text.forbidcrlf
21 # # or pretxncommit.cr = python:hgext.win32text.forbidcr
21 # # or pretxncommit.cr = python:hgext.win32text.forbidcr
22 #
22 #
23 # To do the same check on a server to prevent CRLF/CR from being pushed or
23 # To do the same check on a server to prevent CRLF/CR from being pushed or
24 # pulled:
24 # pulled:
25 #
25 #
26 # [hooks]
26 # [hooks]
27 # pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
27 # pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
28 # # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
28 # # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
29
29
30 from mercurial import util
30 from mercurial import util
31 from mercurial.i18n import gettext as _
31 from mercurial.i18n import gettext as _
32 from mercurial.node import bin, short
32 from mercurial.node import bin, short
33 import re
33 import re
34
34
35 # regexp for single LF without CR preceding.
35 # regexp for single LF without CR preceding.
36 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
36 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
37
37
38 newlinestr = {'\r\n': 'CRLF', '\r': 'CR'}
38 newlinestr = {'\r\n': 'CRLF', '\r': 'CR'}
39 filterstr = {'\r\n': 'clever', '\r': 'mac'}
39 filterstr = {'\r\n': 'clever', '\r': 'mac'}
40
40
41 def checknewline(s, newline, ui=None, repo=None, filename=None):
41 def checknewline(s, newline, ui=None, repo=None, filename=None):
42 # warn if already has 'newline' in repository.
42 # warn if already has 'newline' in repository.
43 # it might cause unexpected eol conversion.
43 # it might cause unexpected eol conversion.
44 # see issue 302:
44 # see issue 302:
45 # http://www.selenic.com/mercurial/bts/issue302
45 # http://www.selenic.com/mercurial/bts/issue302
46 if newline in s and ui and filename and repo:
46 if newline in s and ui and filename and repo:
47 ui.warn(_('WARNING: %s already has %s line endings\n'
47 ui.warn(_('WARNING: %s already has %s line endings\n'
48 'and does not need EOL conversion by the win32text plugin.\n'
48 'and does not need EOL conversion by the win32text plugin.\n'
49 'Before your next commit, please reconsider your '
49 'Before your next commit, please reconsider your '
50 'encode/decode settings in \nMercurial.ini or %s.\n') %
50 'encode/decode settings in \nMercurial.ini or %s.\n') %
51 (filename, newlinestr[newline], repo.join('hgrc')))
51 (filename, newlinestr[newline], repo.join('hgrc')))
52
52
53 def dumbdecode(s, cmd, **kwargs):
53 def dumbdecode(s, cmd, **kwargs):
54 checknewline(s, '\r\n', **kwargs)
54 checknewline(s, '\r\n', **kwargs)
55 # replace single LF to CRLF
55 # replace single LF to CRLF
56 return re_single_lf.sub('\\1\r\n', s)
56 return re_single_lf.sub('\\1\r\n', s)
57
57
58 def dumbencode(s, cmd):
58 def dumbencode(s, cmd):
59 return s.replace('\r\n', '\n')
59 return s.replace('\r\n', '\n')
60
60
61 def macdumbdecode(s, cmd, **kwargs):
61 def macdumbdecode(s, cmd, **kwargs):
62 checknewline(s, '\r', **kwargs)
62 checknewline(s, '\r', **kwargs)
63 return s.replace('\n', '\r')
63 return s.replace('\n', '\r')
64
64
65 def macdumbencode(s, cmd):
65 def macdumbencode(s, cmd):
66 return s.replace('\r', '\n')
66 return s.replace('\r', '\n')
67
67
68 def cleverdecode(s, cmd, **kwargs):
68 def cleverdecode(s, cmd, **kwargs):
69 if util.binary(s):
69 if util.binary(s):
70 return s
70 return s
71 return dumbdecode(s, cmd, **kwargs)
71 return dumbdecode(s, cmd, **kwargs)
72
72
73 def cleverencode(s, cmd):
73 def cleverencode(s, cmd):
74 if util.binary(s):
74 if util.binary(s):
75 return s
75 return s
76 return dumbencode(s, cmd)
76 return dumbencode(s, cmd)
77
77
78 def macdecode(s, cmd, **kwargs):
78 def macdecode(s, cmd, **kwargs):
79 if util.binary(s):
79 if util.binary(s):
80 return s
80 return s
81 return macdumbdecode(s, cmd, **kwargs)
81 return macdumbdecode(s, cmd, **kwargs)
82
82
83 def macencode(s, cmd):
83 def macencode(s, cmd):
84 if util.binary(s):
84 if util.binary(s):
85 return s
85 return s
86 return macdumbencode(s, cmd)
86 return macdumbencode(s, cmd)
87
87
88 _filters = {
88 _filters = {
89 'dumbdecode:': dumbdecode,
89 'dumbdecode:': dumbdecode,
90 'dumbencode:': dumbencode,
90 'dumbencode:': dumbencode,
91 'cleverdecode:': cleverdecode,
91 'cleverdecode:': cleverdecode,
92 'cleverencode:': cleverencode,
92 'cleverencode:': cleverencode,
93 'macdumbdecode:': macdumbdecode,
93 'macdumbdecode:': macdumbdecode,
94 'macdumbencode:': macdumbencode,
94 'macdumbencode:': macdumbencode,
95 'macdecode:': macdecode,
95 'macdecode:': macdecode,
96 'macencode:': macencode,
96 'macencode:': macencode,
97 }
97 }
98
98
99 def forbidcrlforcr(ui, repo, hooktype, node, newline, **kwargs):
99 def forbidnewline(ui, repo, hooktype, node, newline, **kwargs):
100 halt = False
100 halt = False
101 for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()):
101 for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()):
102 c = repo.changectx(rev)
102 c = repo.changectx(rev)
103 for f in c.files():
103 for f in c.files():
104 if f not in c:
104 if f not in c:
105 continue
105 continue
106 data = c[f].data()
106 data = c[f].data()
107 if not util.binary(data) and newline in data:
107 if not util.binary(data) and newline in data:
108 if not halt:
108 if not halt:
109 ui.warn(_('Attempt to commit or push text file(s) '
109 ui.warn(_('Attempt to commit or push text file(s) '
110 'using %s line endings\n') %
110 'using %s line endings\n') %
111 newlinestr[newline])
111 newlinestr[newline])
112 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
112 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
113 halt = True
113 halt = True
114 if halt and hooktype == 'pretxnchangegroup':
114 if halt and hooktype == 'pretxnchangegroup':
115 crlf = newlinestr[newline].lower()
115 crlf = newlinestr[newline].lower()
116 filter = filterstr[newline]
116 filter = filterstr[newline]
117 ui.warn(_('\nTo prevent this mistake in your local repository,\n'
117 ui.warn(_('\nTo prevent this mistake in your local repository,\n'
118 'add to Mercurial.ini or .hg/hgrc:\n'
118 'add to Mercurial.ini or .hg/hgrc:\n'
119 '\n'
119 '\n'
120 '[hooks]\n'
120 '[hooks]\n'
121 'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
121 'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
122 '\n'
122 '\n'
123 'and also consider adding:\n'
123 'and also consider adding:\n'
124 '\n'
124 '\n'
125 '[extensions]\n'
125 '[extensions]\n'
126 'hgext.win32text =\n'
126 'hgext.win32text =\n'
127 '[encode]\n'
127 '[encode]\n'
128 '** = %sencode:\n'
128 '** = %sencode:\n'
129 '[decode]\n'
129 '[decode]\n'
130 '** = %sdecode:\n') % (crlf, crlf, filter, filter))
130 '** = %sdecode:\n') % (crlf, crlf, filter, filter))
131 return halt
131 return halt
132
132
133 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
133 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
134 return forbidcrlforcr(ui, repo, hooktype, node, '\r\n', **kwargs)
134 return forbidnewline(ui, repo, hooktype, node, '\r\n', **kwargs)
135
135
136 def forbidcr(ui, repo, hooktype, node, **kwargs):
136 def forbidcr(ui, repo, hooktype, node, **kwargs):
137 return forbidcrlforcr(ui, repo, hooktype, node, '\r', **kwargs)
137 return forbidnewline(ui, repo, hooktype, node, '\r', **kwargs)
138
138
139 def reposetup(ui, repo):
139 def reposetup(ui, repo):
140 if not repo.local():
140 if not repo.local():
141 return
141 return
142 for name, fn in _filters.iteritems():
142 for name, fn in _filters.iteritems():
143 repo.adddatafilter(name, fn)
143 repo.adddatafilter(name, fn)
144
144
General Comments 0
You need to be logged in to leave comments. Login now