##// END OF EJS Templates
win32text: use reST syntax for literal blocks
Martin Geisler -
r9217:9cdb6964 default
parent child Browse files
Show More
@@ -1,158 +1,158 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 # Copyright 2005, 2007-2009 Matt Mackall <mpm@selenic.com> and others
3 # Copyright 2005, 2007-2009 Matt Mackall <mpm@selenic.com> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2, incorporated herein by reference.
6 # GNU General Public License version 2, incorporated herein by reference.
7
7
8 '''perform automatic newline conversion
8 '''perform automatic newline conversion
9
9
10 To perform automatic newline conversion, use:
10 To perform automatic newline conversion, use::
11
11
12 [extensions]
12 [extensions]
13 hgext.win32text =
13 hgext.win32text =
14 [encode]
14 [encode]
15 ** = cleverencode:
15 ** = cleverencode:
16 # or ** = macencode:
16 # or ** = macencode:
17
17
18 [decode]
18 [decode]
19 ** = cleverdecode:
19 ** = cleverdecode:
20 # or ** = macdecode:
20 # or ** = macdecode:
21
21
22 If not doing conversion, to make sure you do not commit CRLF/CR by accident:
22 If not doing conversion, to make sure you do not commit CRLF/CR by accident::
23
23
24 [hooks]
24 [hooks]
25 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
25 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
26 # or pretxncommit.cr = python:hgext.win32text.forbidcr
26 # or pretxncommit.cr = python:hgext.win32text.forbidcr
27
27
28 To do the same check on a server to prevent CRLF/CR from being
28 To do the same check on a server to prevent CRLF/CR from being
29 pushed or pulled:
29 pushed or pulled::
30
30
31 [hooks]
31 [hooks]
32 pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
32 pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
33 # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
33 # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
34 '''
34 '''
35
35
36 from mercurial.i18n import _
36 from mercurial.i18n import _
37 from mercurial.node import short
37 from mercurial.node import short
38 from mercurial import util
38 from mercurial import util
39 import re
39 import re
40
40
41 # regexp for single LF without CR preceding.
41 # regexp for single LF without CR preceding.
42 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
42 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
43
43
44 newlinestr = {'\r\n': 'CRLF', '\r': 'CR'}
44 newlinestr = {'\r\n': 'CRLF', '\r': 'CR'}
45 filterstr = {'\r\n': 'clever', '\r': 'mac'}
45 filterstr = {'\r\n': 'clever', '\r': 'mac'}
46
46
47 def checknewline(s, newline, ui=None, repo=None, filename=None):
47 def checknewline(s, newline, ui=None, repo=None, filename=None):
48 # warn if already has 'newline' in repository.
48 # warn if already has 'newline' in repository.
49 # it might cause unexpected eol conversion.
49 # it might cause unexpected eol conversion.
50 # see issue 302:
50 # see issue 302:
51 # http://mercurial.selenic.com/bts/issue302
51 # http://mercurial.selenic.com/bts/issue302
52 if newline in s and ui and filename and repo:
52 if newline in s and ui and filename and repo:
53 ui.warn(_('WARNING: %s already has %s line endings\n'
53 ui.warn(_('WARNING: %s already has %s line endings\n'
54 'and does not need EOL conversion by the win32text plugin.\n'
54 'and does not need EOL conversion by the win32text plugin.\n'
55 'Before your next commit, please reconsider your '
55 'Before your next commit, please reconsider your '
56 'encode/decode settings in \nMercurial.ini or %s.\n') %
56 'encode/decode settings in \nMercurial.ini or %s.\n') %
57 (filename, newlinestr[newline], repo.join('hgrc')))
57 (filename, newlinestr[newline], repo.join('hgrc')))
58
58
59 def dumbdecode(s, cmd, **kwargs):
59 def dumbdecode(s, cmd, **kwargs):
60 checknewline(s, '\r\n', **kwargs)
60 checknewline(s, '\r\n', **kwargs)
61 # replace single LF to CRLF
61 # replace single LF to CRLF
62 return re_single_lf.sub('\\1\r\n', s)
62 return re_single_lf.sub('\\1\r\n', s)
63
63
64 def dumbencode(s, cmd):
64 def dumbencode(s, cmd):
65 return s.replace('\r\n', '\n')
65 return s.replace('\r\n', '\n')
66
66
67 def macdumbdecode(s, cmd, **kwargs):
67 def macdumbdecode(s, cmd, **kwargs):
68 checknewline(s, '\r', **kwargs)
68 checknewline(s, '\r', **kwargs)
69 return s.replace('\n', '\r')
69 return s.replace('\n', '\r')
70
70
71 def macdumbencode(s, cmd):
71 def macdumbencode(s, cmd):
72 return s.replace('\r', '\n')
72 return s.replace('\r', '\n')
73
73
74 def cleverdecode(s, cmd, **kwargs):
74 def cleverdecode(s, cmd, **kwargs):
75 if not util.binary(s):
75 if not util.binary(s):
76 return dumbdecode(s, cmd, **kwargs)
76 return dumbdecode(s, cmd, **kwargs)
77 return s
77 return s
78
78
79 def cleverencode(s, cmd):
79 def cleverencode(s, cmd):
80 if not util.binary(s):
80 if not util.binary(s):
81 return dumbencode(s, cmd)
81 return dumbencode(s, cmd)
82 return s
82 return s
83
83
84 def macdecode(s, cmd, **kwargs):
84 def macdecode(s, cmd, **kwargs):
85 if not util.binary(s):
85 if not util.binary(s):
86 return macdumbdecode(s, cmd, **kwargs)
86 return macdumbdecode(s, cmd, **kwargs)
87 return s
87 return s
88
88
89 def macencode(s, cmd):
89 def macencode(s, cmd):
90 if not util.binary(s):
90 if not util.binary(s):
91 return macdumbencode(s, cmd)
91 return macdumbencode(s, cmd)
92 return s
92 return s
93
93
94 _filters = {
94 _filters = {
95 'dumbdecode:': dumbdecode,
95 'dumbdecode:': dumbdecode,
96 'dumbencode:': dumbencode,
96 'dumbencode:': dumbencode,
97 'cleverdecode:': cleverdecode,
97 'cleverdecode:': cleverdecode,
98 'cleverencode:': cleverencode,
98 'cleverencode:': cleverencode,
99 'macdumbdecode:': macdumbdecode,
99 'macdumbdecode:': macdumbdecode,
100 'macdumbencode:': macdumbencode,
100 'macdumbencode:': macdumbencode,
101 'macdecode:': macdecode,
101 'macdecode:': macdecode,
102 'macencode:': macencode,
102 'macencode:': macencode,
103 }
103 }
104
104
105 def forbidnewline(ui, repo, hooktype, node, newline, **kwargs):
105 def forbidnewline(ui, repo, hooktype, node, newline, **kwargs):
106 halt = False
106 halt = False
107 seen = set()
107 seen = set()
108 # we try to walk changesets in reverse order from newest to
108 # we try to walk changesets in reverse order from newest to
109 # oldest, so that if we see a file multiple times, we take the
109 # oldest, so that if we see a file multiple times, we take the
110 # newest version as canonical. this prevents us from blocking a
110 # newest version as canonical. this prevents us from blocking a
111 # changegroup that contains an unacceptable commit followed later
111 # changegroup that contains an unacceptable commit followed later
112 # by a commit that fixes the problem.
112 # by a commit that fixes the problem.
113 tip = repo['tip']
113 tip = repo['tip']
114 for rev in xrange(len(repo)-1, repo[node].rev()-1, -1):
114 for rev in xrange(len(repo)-1, repo[node].rev()-1, -1):
115 c = repo[rev]
115 c = repo[rev]
116 for f in c.files():
116 for f in c.files():
117 if f in seen or f not in tip or f not in c:
117 if f in seen or f not in tip or f not in c:
118 continue
118 continue
119 seen.add(f)
119 seen.add(f)
120 data = c[f].data()
120 data = c[f].data()
121 if not util.binary(data) and newline in data:
121 if not util.binary(data) and newline in data:
122 if not halt:
122 if not halt:
123 ui.warn(_('Attempt to commit or push text file(s) '
123 ui.warn(_('Attempt to commit or push text file(s) '
124 'using %s line endings\n') %
124 'using %s line endings\n') %
125 newlinestr[newline])
125 newlinestr[newline])
126 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
126 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
127 halt = True
127 halt = True
128 if halt and hooktype == 'pretxnchangegroup':
128 if halt and hooktype == 'pretxnchangegroup':
129 crlf = newlinestr[newline].lower()
129 crlf = newlinestr[newline].lower()
130 filter = filterstr[newline]
130 filter = filterstr[newline]
131 ui.warn(_('\nTo prevent this mistake in your local repository,\n'
131 ui.warn(_('\nTo prevent this mistake in your local repository,\n'
132 'add to Mercurial.ini or .hg/hgrc:\n'
132 'add to Mercurial.ini or .hg/hgrc:\n'
133 '\n'
133 '\n'
134 '[hooks]\n'
134 '[hooks]\n'
135 'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
135 'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
136 '\n'
136 '\n'
137 'and also consider adding:\n'
137 'and also consider adding:\n'
138 '\n'
138 '\n'
139 '[extensions]\n'
139 '[extensions]\n'
140 'hgext.win32text =\n'
140 'hgext.win32text =\n'
141 '[encode]\n'
141 '[encode]\n'
142 '** = %sencode:\n'
142 '** = %sencode:\n'
143 '[decode]\n'
143 '[decode]\n'
144 '** = %sdecode:\n') % (crlf, crlf, filter, filter))
144 '** = %sdecode:\n') % (crlf, crlf, filter, filter))
145 return halt
145 return halt
146
146
147 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
147 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
148 return forbidnewline(ui, repo, hooktype, node, '\r\n', **kwargs)
148 return forbidnewline(ui, repo, hooktype, node, '\r\n', **kwargs)
149
149
150 def forbidcr(ui, repo, hooktype, node, **kwargs):
150 def forbidcr(ui, repo, hooktype, node, **kwargs):
151 return forbidnewline(ui, repo, hooktype, node, '\r', **kwargs)
151 return forbidnewline(ui, repo, hooktype, node, '\r', **kwargs)
152
152
153 def reposetup(ui, repo):
153 def reposetup(ui, repo):
154 if not repo.local():
154 if not repo.local():
155 return
155 return
156 for name, fn in _filters.iteritems():
156 for name, fn in _filters.iteritems():
157 repo.adddatafilter(name, fn)
157 repo.adddatafilter(name, fn)
158
158
General Comments 0
You need to be logged in to leave comments. Login now