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