54 |
54 |
55 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for |
55 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for |
56 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should |
56 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should |
57 # be specifying the version(s) of Mercurial they are tested with, or |
57 # be specifying the version(s) of Mercurial they are tested with, or |
58 # leave the attribute unspecified. |
58 # leave the attribute unspecified. |
59 testedwith = 'ships-with-hg-core' |
59 testedwith = b'ships-with-hg-core' |
60 |
60 |
61 configtable = {} |
61 configtable = {} |
62 configitem = registrar.configitem(configtable) |
62 configitem = registrar.configitem(configtable) |
63 |
63 |
64 configitem( |
64 configitem( |
65 'win32text', 'warn', default=True, |
65 b'win32text', b'warn', default=True, |
66 ) |
66 ) |
67 |
67 |
68 # regexp for single LF without CR preceding. |
68 # regexp for single LF without CR preceding. |
69 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE) |
69 re_single_lf = re.compile(b'(^|[^\r])\n', re.MULTILINE) |
70 |
70 |
71 newlinestr = {'\r\n': 'CRLF', '\r': 'CR'} |
71 newlinestr = {b'\r\n': b'CRLF', b'\r': b'CR'} |
72 filterstr = {'\r\n': 'clever', '\r': 'mac'} |
72 filterstr = {b'\r\n': b'clever', b'\r': b'mac'} |
73 |
73 |
74 |
74 |
75 def checknewline(s, newline, ui=None, repo=None, filename=None): |
75 def checknewline(s, newline, ui=None, repo=None, filename=None): |
76 # warn if already has 'newline' in repository. |
76 # warn if already has 'newline' in repository. |
77 # it might cause unexpected eol conversion. |
77 # it might cause unexpected eol conversion. |
78 # see issue 302: |
78 # see issue 302: |
79 # https://bz.mercurial-scm.org/302 |
79 # https://bz.mercurial-scm.org/302 |
80 if newline in s and ui and filename and repo: |
80 if newline in s and ui and filename and repo: |
81 ui.warn( |
81 ui.warn( |
82 _( |
82 _( |
83 'WARNING: %s already has %s line endings\n' |
83 b'WARNING: %s already has %s line endings\n' |
84 'and does not need EOL conversion by the win32text plugin.\n' |
84 b'and does not need EOL conversion by the win32text plugin.\n' |
85 'Before your next commit, please reconsider your ' |
85 b'Before your next commit, please reconsider your ' |
86 'encode/decode settings in \nMercurial.ini or %s.\n' |
86 b'encode/decode settings in \nMercurial.ini or %s.\n' |
87 ) |
87 ) |
88 % (filename, newlinestr[newline], repo.vfs.join('hgrc')) |
88 % (filename, newlinestr[newline], repo.vfs.join(b'hgrc')) |
89 ) |
89 ) |
90 |
90 |
91 |
91 |
92 def dumbdecode(s, cmd, **kwargs): |
92 def dumbdecode(s, cmd, **kwargs): |
93 checknewline(s, '\r\n', **kwargs) |
93 checknewline(s, b'\r\n', **kwargs) |
94 # replace single LF to CRLF |
94 # replace single LF to CRLF |
95 return re_single_lf.sub('\\1\r\n', s) |
95 return re_single_lf.sub(b'\\1\r\n', s) |
96 |
96 |
97 |
97 |
98 def dumbencode(s, cmd): |
98 def dumbencode(s, cmd): |
99 return s.replace('\r\n', '\n') |
99 return s.replace(b'\r\n', b'\n') |
100 |
100 |
101 |
101 |
102 def macdumbdecode(s, cmd, **kwargs): |
102 def macdumbdecode(s, cmd, **kwargs): |
103 checknewline(s, '\r', **kwargs) |
103 checknewline(s, b'\r', **kwargs) |
104 return s.replace('\n', '\r') |
104 return s.replace(b'\n', b'\r') |
105 |
105 |
106 |
106 |
107 def macdumbencode(s, cmd): |
107 def macdumbencode(s, cmd): |
108 return s.replace('\r', '\n') |
108 return s.replace(b'\r', b'\n') |
109 |
109 |
110 |
110 |
111 def cleverdecode(s, cmd, **kwargs): |
111 def cleverdecode(s, cmd, **kwargs): |
112 if not stringutil.binary(s): |
112 if not stringutil.binary(s): |
113 return dumbdecode(s, cmd, **kwargs) |
113 return dumbdecode(s, cmd, **kwargs) |
131 return macdumbencode(s, cmd) |
131 return macdumbencode(s, cmd) |
132 return s |
132 return s |
133 |
133 |
134 |
134 |
135 _filters = { |
135 _filters = { |
136 'dumbdecode:': dumbdecode, |
136 b'dumbdecode:': dumbdecode, |
137 'dumbencode:': dumbencode, |
137 b'dumbencode:': dumbencode, |
138 'cleverdecode:': cleverdecode, |
138 b'cleverdecode:': cleverdecode, |
139 'cleverencode:': cleverencode, |
139 b'cleverencode:': cleverencode, |
140 'macdumbdecode:': macdumbdecode, |
140 b'macdumbdecode:': macdumbdecode, |
141 'macdumbencode:': macdumbencode, |
141 b'macdumbencode:': macdumbencode, |
142 'macdecode:': macdecode, |
142 b'macdecode:': macdecode, |
143 'macencode:': macencode, |
143 b'macencode:': macencode, |
144 } |
144 } |
145 |
145 |
146 |
146 |
147 def forbidnewline(ui, repo, hooktype, node, newline, **kwargs): |
147 def forbidnewline(ui, repo, hooktype, node, newline, **kwargs): |
148 halt = False |
148 halt = False |
164 data = c[f].data() |
164 data = c[f].data() |
165 if not stringutil.binary(data) and newline in data: |
165 if not stringutil.binary(data) and newline in data: |
166 if not halt: |
166 if not halt: |
167 ui.warn( |
167 ui.warn( |
168 _( |
168 _( |
169 'attempt to commit or push text file(s) ' |
169 b'attempt to commit or push text file(s) ' |
170 'using %s line endings\n' |
170 b'using %s line endings\n' |
171 ) |
171 ) |
172 % newlinestr[newline] |
172 % newlinestr[newline] |
173 ) |
173 ) |
174 ui.warn(_('in %s: %s\n') % (short(c.node()), f)) |
174 ui.warn(_(b'in %s: %s\n') % (short(c.node()), f)) |
175 halt = True |
175 halt = True |
176 if halt and hooktype == 'pretxnchangegroup': |
176 if halt and hooktype == b'pretxnchangegroup': |
177 crlf = newlinestr[newline].lower() |
177 crlf = newlinestr[newline].lower() |
178 filter = filterstr[newline] |
178 filter = filterstr[newline] |
179 ui.warn( |
179 ui.warn( |
180 _( |
180 _( |
181 '\nTo prevent this mistake in your local repository,\n' |
181 b'\nTo prevent this mistake in your local repository,\n' |
182 'add to Mercurial.ini or .hg/hgrc:\n' |
182 b'add to Mercurial.ini or .hg/hgrc:\n' |
183 '\n' |
183 b'\n' |
184 '[hooks]\n' |
184 b'[hooks]\n' |
185 'pretxncommit.%s = python:hgext.win32text.forbid%s\n' |
185 b'pretxncommit.%s = python:hgext.win32text.forbid%s\n' |
186 '\n' |
186 b'\n' |
187 'and also consider adding:\n' |
187 b'and also consider adding:\n' |
188 '\n' |
188 b'\n' |
189 '[extensions]\n' |
189 b'[extensions]\n' |
190 'win32text =\n' |
190 b'win32text =\n' |
191 '[encode]\n' |
191 b'[encode]\n' |
192 '** = %sencode:\n' |
192 b'** = %sencode:\n' |
193 '[decode]\n' |
193 b'[decode]\n' |
194 '** = %sdecode:\n' |
194 b'** = %sdecode:\n' |
195 ) |
195 ) |
196 % (crlf, crlf, filter, filter) |
196 % (crlf, crlf, filter, filter) |
197 ) |
197 ) |
198 return halt |
198 return halt |
199 |
199 |
200 |
200 |
201 def forbidcrlf(ui, repo, hooktype, node, **kwargs): |
201 def forbidcrlf(ui, repo, hooktype, node, **kwargs): |
202 return forbidnewline(ui, repo, hooktype, node, '\r\n', **kwargs) |
202 return forbidnewline(ui, repo, hooktype, node, b'\r\n', **kwargs) |
203 |
203 |
204 |
204 |
205 def forbidcr(ui, repo, hooktype, node, **kwargs): |
205 def forbidcr(ui, repo, hooktype, node, **kwargs): |
206 return forbidnewline(ui, repo, hooktype, node, '\r', **kwargs) |
206 return forbidnewline(ui, repo, hooktype, node, b'\r', **kwargs) |
207 |
207 |
208 |
208 |
209 def reposetup(ui, repo): |
209 def reposetup(ui, repo): |
210 if not repo.local(): |
210 if not repo.local(): |
211 return |
211 return |