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