##// END OF EJS Templates
Merge with crew-stable
Patrick Mezard -
r6475:93e4bb8c merge default
parent child Browse files
Show More
@@ -1,103 +1,106 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
26 from mercurial.i18n import gettext as _
25 from mercurial.i18n import gettext as _
27 from mercurial.node import bin, short
26 from mercurial.node import bin, short
28 import re
27 import re
29
28
30 # regexp for single LF without CR preceding.
29 # regexp for single LF without CR preceding.
31 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
30 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
32
31
33 def dumbdecode(s, cmd, ui=None, repo=None, filename=None, **kwargs):
32 def dumbdecode(s, cmd, ui=None, repo=None, filename=None, **kwargs):
34 # warn if already has CRLF in repository.
33 # warn if already has CRLF in repository.
35 # it might cause unexpected eol conversion.
34 # it might cause unexpected eol conversion.
36 # see issue 302:
35 # see issue 302:
37 # http://www.selenic.com/mercurial/bts/issue302
36 # http://www.selenic.com/mercurial/bts/issue302
38 if '\r\n' in s and ui and filename and repo:
37 if '\r\n' in s and ui and filename and repo:
39 ui.warn(_('WARNING: %s already has CRLF line endings\n'
38 ui.warn(_('WARNING: %s already has CRLF line endings\n'
40 'and does not need EOL conversion by the win32text plugin.\n'
39 'and does not need EOL conversion by the win32text plugin.\n'
41 'Before your next commit, please reconsider your '
40 'Before your next commit, please reconsider your '
42 'encode/decode settings in \nMercurial.ini or %s.\n') %
41 'encode/decode settings in \nMercurial.ini or %s.\n') %
43 (filename, repo.join('hgrc')))
42 (filename, repo.join('hgrc')))
44 # replace single LF to CRLF
43 # replace single LF to CRLF
45 return re_single_lf.sub('\\1\r\n', s)
44 return re_single_lf.sub('\\1\r\n', s)
46
45
47 def dumbencode(s, cmd):
46 def dumbencode(s, cmd):
48 return s.replace('\r\n', '\n')
47 return s.replace('\r\n', '\n')
49
48
49 def clevertest(s, cmd):
50 if '\0' in s: return False
51 return True
52
50 def cleverdecode(s, cmd, **kwargs):
53 def cleverdecode(s, cmd, **kwargs):
51 if util.binary(s):
54 if clevertest(s, cmd):
52 return s
55 return dumbdecode(s, cmd, **kwargs)
53 return dumbdecode(s, cmd, **kwargs)
56 return s
54
57
55 def cleverencode(s, cmd):
58 def cleverencode(s, cmd):
56 if util.binary(s):
59 if clevertest(s, cmd):
57 return s
60 return dumbencode(s, cmd)
58 return dumbencode(s, cmd)
61 return s
59
62
60 _filters = {
63 _filters = {
61 'dumbdecode:': dumbdecode,
64 'dumbdecode:': dumbdecode,
62 'dumbencode:': dumbencode,
65 'dumbencode:': dumbencode,
63 'cleverdecode:': cleverdecode,
66 'cleverdecode:': cleverdecode,
64 'cleverencode:': cleverencode,
67 'cleverencode:': cleverencode,
65 }
68 }
66
69
67 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
70 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
68 halt = False
71 halt = False
69 for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()):
72 for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()):
70 c = repo.changectx(rev)
73 c = repo.changectx(rev)
71 for f in c.files():
74 for f in c.files():
72 if f not in c:
75 if f not in c:
73 continue
76 continue
74 data = c[f].data()
77 data = c[f].data()
75 if not util.binary(data) and '\r\n' in data:
78 if '\0' not in data and '\r\n' in data:
76 if not halt:
79 if not halt:
77 ui.warn(_('Attempt to commit or push text file(s) '
80 ui.warn(_('Attempt to commit or push text file(s) '
78 'using CRLF line endings\n'))
81 'using CRLF line endings\n'))
79 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
82 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
80 halt = True
83 halt = True
81 if halt and hooktype == 'pretxnchangegroup':
84 if halt and hooktype == 'pretxnchangegroup':
82 ui.warn(_('\nTo prevent this mistake in your local repository,\n'
85 ui.warn(_('\nTo prevent this mistake in your local repository,\n'
83 'add to Mercurial.ini or .hg/hgrc:\n'
86 'add to Mercurial.ini or .hg/hgrc:\n'
84 '\n'
87 '\n'
85 '[hooks]\n'
88 '[hooks]\n'
86 'pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n'
89 'pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n'
87 '\n'
90 '\n'
88 'and also consider adding:\n'
91 'and also consider adding:\n'
89 '\n'
92 '\n'
90 '[extensions]\n'
93 '[extensions]\n'
91 'hgext.win32text =\n'
94 'hgext.win32text =\n'
92 '[encode]\n'
95 '[encode]\n'
93 '** = cleverencode:\n'
96 '** = cleverencode:\n'
94 '[decode]\n'
97 '[decode]\n'
95 '** = cleverdecode:\n'))
98 '** = cleverdecode:\n'))
96 return halt
99 return halt
97
100
98 def reposetup(ui, repo):
101 def reposetup(ui, repo):
99 if not repo.local():
102 if not repo.local():
100 return
103 return
101 for name, fn in _filters.iteritems():
104 for name, fn in _filters.iteritems():
102 repo.adddatafilter(name, fn)
105 repo.adddatafilter(name, fn)
103
106
General Comments 0
You need to be logged in to leave comments. Login now