##// END OF EJS Templates
eol: fix variable naming - call it _eolmatch instead of _eolfile...
Mads Kiilerich -
r30113:ffb68241 default
parent child Browse files
Show More
@@ -1,363 +1,363 b''
1 """automatically manage newlines in repository files
1 """automatically manage newlines in repository files
2
2
3 This extension allows you to manage the type of line endings (CRLF or
3 This extension allows you to manage the type of line endings (CRLF or
4 LF) that are used in the repository and in the local working
4 LF) that are used in the repository and in the local working
5 directory. That way you can get CRLF line endings on Windows and LF on
5 directory. That way you can get CRLF line endings on Windows and LF on
6 Unix/Mac, thereby letting everybody use their OS native line endings.
6 Unix/Mac, thereby letting everybody use their OS native line endings.
7
7
8 The extension reads its configuration from a versioned ``.hgeol``
8 The extension reads its configuration from a versioned ``.hgeol``
9 configuration file found in the root of the working directory. The
9 configuration file found in the root of the working directory. The
10 ``.hgeol`` file use the same syntax as all other Mercurial
10 ``.hgeol`` file use the same syntax as all other Mercurial
11 configuration files. It uses two sections, ``[patterns]`` and
11 configuration files. It uses two sections, ``[patterns]`` and
12 ``[repository]``.
12 ``[repository]``.
13
13
14 The ``[patterns]`` section specifies how line endings should be
14 The ``[patterns]`` section specifies how line endings should be
15 converted between the working directory and the repository. The format is
15 converted between the working directory and the repository. The format is
16 specified by a file pattern. The first match is used, so put more
16 specified by a file pattern. The first match is used, so put more
17 specific patterns first. The available line endings are ``LF``,
17 specific patterns first. The available line endings are ``LF``,
18 ``CRLF``, and ``BIN``.
18 ``CRLF``, and ``BIN``.
19
19
20 Files with the declared format of ``CRLF`` or ``LF`` are always
20 Files with the declared format of ``CRLF`` or ``LF`` are always
21 checked out and stored in the repository in that format and files
21 checked out and stored in the repository in that format and files
22 declared to be binary (``BIN``) are left unchanged. Additionally,
22 declared to be binary (``BIN``) are left unchanged. Additionally,
23 ``native`` is an alias for checking out in the platform's default line
23 ``native`` is an alias for checking out in the platform's default line
24 ending: ``LF`` on Unix (including Mac OS X) and ``CRLF`` on
24 ending: ``LF`` on Unix (including Mac OS X) and ``CRLF`` on
25 Windows. Note that ``BIN`` (do nothing to line endings) is Mercurial's
25 Windows. Note that ``BIN`` (do nothing to line endings) is Mercurial's
26 default behavior; it is only needed if you need to override a later,
26 default behavior; it is only needed if you need to override a later,
27 more general pattern.
27 more general pattern.
28
28
29 The optional ``[repository]`` section specifies the line endings to
29 The optional ``[repository]`` section specifies the line endings to
30 use for files stored in the repository. It has a single setting,
30 use for files stored in the repository. It has a single setting,
31 ``native``, which determines the storage line endings for files
31 ``native``, which determines the storage line endings for files
32 declared as ``native`` in the ``[patterns]`` section. It can be set to
32 declared as ``native`` in the ``[patterns]`` section. It can be set to
33 ``LF`` or ``CRLF``. The default is ``LF``. For example, this means
33 ``LF`` or ``CRLF``. The default is ``LF``. For example, this means
34 that on Windows, files configured as ``native`` (``CRLF`` by default)
34 that on Windows, files configured as ``native`` (``CRLF`` by default)
35 will be converted to ``LF`` when stored in the repository. Files
35 will be converted to ``LF`` when stored in the repository. Files
36 declared as ``LF``, ``CRLF``, or ``BIN`` in the ``[patterns]`` section
36 declared as ``LF``, ``CRLF``, or ``BIN`` in the ``[patterns]`` section
37 are always stored as-is in the repository.
37 are always stored as-is in the repository.
38
38
39 Example versioned ``.hgeol`` file::
39 Example versioned ``.hgeol`` file::
40
40
41 [patterns]
41 [patterns]
42 **.py = native
42 **.py = native
43 **.vcproj = CRLF
43 **.vcproj = CRLF
44 **.txt = native
44 **.txt = native
45 Makefile = LF
45 Makefile = LF
46 **.jpg = BIN
46 **.jpg = BIN
47
47
48 [repository]
48 [repository]
49 native = LF
49 native = LF
50
50
51 .. note::
51 .. note::
52
52
53 The rules will first apply when files are touched in the working
53 The rules will first apply when files are touched in the working
54 directory, e.g. by updating to null and back to tip to touch all files.
54 directory, e.g. by updating to null and back to tip to touch all files.
55
55
56 The extension uses an optional ``[eol]`` section read from both the
56 The extension uses an optional ``[eol]`` section read from both the
57 normal Mercurial configuration files and the ``.hgeol`` file, with the
57 normal Mercurial configuration files and the ``.hgeol`` file, with the
58 latter overriding the former. You can use that section to control the
58 latter overriding the former. You can use that section to control the
59 overall behavior. There are three settings:
59 overall behavior. There are three settings:
60
60
61 - ``eol.native`` (default ``os.linesep``) can be set to ``LF`` or
61 - ``eol.native`` (default ``os.linesep``) can be set to ``LF`` or
62 ``CRLF`` to override the default interpretation of ``native`` for
62 ``CRLF`` to override the default interpretation of ``native`` for
63 checkout. This can be used with :hg:`archive` on Unix, say, to
63 checkout. This can be used with :hg:`archive` on Unix, say, to
64 generate an archive where files have line endings for Windows.
64 generate an archive where files have line endings for Windows.
65
65
66 - ``eol.only-consistent`` (default True) can be set to False to make
66 - ``eol.only-consistent`` (default True) can be set to False to make
67 the extension convert files with inconsistent EOLs. Inconsistent
67 the extension convert files with inconsistent EOLs. Inconsistent
68 means that there is both ``CRLF`` and ``LF`` present in the file.
68 means that there is both ``CRLF`` and ``LF`` present in the file.
69 Such files are normally not touched under the assumption that they
69 Such files are normally not touched under the assumption that they
70 have mixed EOLs on purpose.
70 have mixed EOLs on purpose.
71
71
72 - ``eol.fix-trailing-newline`` (default False) can be set to True to
72 - ``eol.fix-trailing-newline`` (default False) can be set to True to
73 ensure that converted files end with a EOL character (either ``\\n``
73 ensure that converted files end with a EOL character (either ``\\n``
74 or ``\\r\\n`` as per the configured patterns).
74 or ``\\r\\n`` as per the configured patterns).
75
75
76 The extension provides ``cleverencode:`` and ``cleverdecode:`` filters
76 The extension provides ``cleverencode:`` and ``cleverdecode:`` filters
77 like the deprecated win32text extension does. This means that you can
77 like the deprecated win32text extension does. This means that you can
78 disable win32text and enable eol and your filters will still work. You
78 disable win32text and enable eol and your filters will still work. You
79 only need to these filters until you have prepared a ``.hgeol`` file.
79 only need to these filters until you have prepared a ``.hgeol`` file.
80
80
81 The ``win32text.forbid*`` hooks provided by the win32text extension
81 The ``win32text.forbid*`` hooks provided by the win32text extension
82 have been unified into a single hook named ``eol.checkheadshook``. The
82 have been unified into a single hook named ``eol.checkheadshook``. The
83 hook will lookup the expected line endings from the ``.hgeol`` file,
83 hook will lookup the expected line endings from the ``.hgeol`` file,
84 which means you must migrate to a ``.hgeol`` file first before using
84 which means you must migrate to a ``.hgeol`` file first before using
85 the hook. ``eol.checkheadshook`` only checks heads, intermediate
85 the hook. ``eol.checkheadshook`` only checks heads, intermediate
86 invalid revisions will be pushed. To forbid them completely, use the
86 invalid revisions will be pushed. To forbid them completely, use the
87 ``eol.checkallhook`` hook. These hooks are best used as
87 ``eol.checkallhook`` hook. These hooks are best used as
88 ``pretxnchangegroup`` hooks.
88 ``pretxnchangegroup`` hooks.
89
89
90 See :hg:`help patterns` for more information about the glob patterns
90 See :hg:`help patterns` for more information about the glob patterns
91 used.
91 used.
92 """
92 """
93
93
94 from __future__ import absolute_import
94 from __future__ import absolute_import
95
95
96 import os
96 import os
97 import re
97 import re
98 from mercurial.i18n import _
98 from mercurial.i18n import _
99 from mercurial import (
99 from mercurial import (
100 config,
100 config,
101 error,
101 error,
102 extensions,
102 extensions,
103 match,
103 match,
104 util,
104 util,
105 )
105 )
106
106
107 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
107 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
108 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
108 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
109 # be specifying the version(s) of Mercurial they are tested with, or
109 # be specifying the version(s) of Mercurial they are tested with, or
110 # leave the attribute unspecified.
110 # leave the attribute unspecified.
111 testedwith = 'ships-with-hg-core'
111 testedwith = 'ships-with-hg-core'
112
112
113 # Matches a lone LF, i.e., one that is not part of CRLF.
113 # Matches a lone LF, i.e., one that is not part of CRLF.
114 singlelf = re.compile('(^|[^\r])\n')
114 singlelf = re.compile('(^|[^\r])\n')
115 # Matches a single EOL which can either be a CRLF where repeated CR
115 # Matches a single EOL which can either be a CRLF where repeated CR
116 # are removed or a LF. We do not care about old Macintosh files, so a
116 # are removed or a LF. We do not care about old Macintosh files, so a
117 # stray CR is an error.
117 # stray CR is an error.
118 eolre = re.compile('\r*\n')
118 eolre = re.compile('\r*\n')
119
119
120
120
121 def inconsistenteol(data):
121 def inconsistenteol(data):
122 return '\r\n' in data and singlelf.search(data)
122 return '\r\n' in data and singlelf.search(data)
123
123
124 def tolf(s, params, ui, **kwargs):
124 def tolf(s, params, ui, **kwargs):
125 """Filter to convert to LF EOLs."""
125 """Filter to convert to LF EOLs."""
126 if util.binary(s):
126 if util.binary(s):
127 return s
127 return s
128 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
128 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
129 return s
129 return s
130 if (ui.configbool('eol', 'fix-trailing-newline', False)
130 if (ui.configbool('eol', 'fix-trailing-newline', False)
131 and s and s[-1] != '\n'):
131 and s and s[-1] != '\n'):
132 s = s + '\n'
132 s = s + '\n'
133 return eolre.sub('\n', s)
133 return eolre.sub('\n', s)
134
134
135 def tocrlf(s, params, ui, **kwargs):
135 def tocrlf(s, params, ui, **kwargs):
136 """Filter to convert to CRLF EOLs."""
136 """Filter to convert to CRLF EOLs."""
137 if util.binary(s):
137 if util.binary(s):
138 return s
138 return s
139 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
139 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
140 return s
140 return s
141 if (ui.configbool('eol', 'fix-trailing-newline', False)
141 if (ui.configbool('eol', 'fix-trailing-newline', False)
142 and s and s[-1] != '\n'):
142 and s and s[-1] != '\n'):
143 s = s + '\n'
143 s = s + '\n'
144 return eolre.sub('\r\n', s)
144 return eolre.sub('\r\n', s)
145
145
146 def isbinary(s, params):
146 def isbinary(s, params):
147 """Filter to do nothing with the file."""
147 """Filter to do nothing with the file."""
148 return s
148 return s
149
149
150 filters = {
150 filters = {
151 'to-lf': tolf,
151 'to-lf': tolf,
152 'to-crlf': tocrlf,
152 'to-crlf': tocrlf,
153 'is-binary': isbinary,
153 'is-binary': isbinary,
154 # The following provide backwards compatibility with win32text
154 # The following provide backwards compatibility with win32text
155 'cleverencode:': tolf,
155 'cleverencode:': tolf,
156 'cleverdecode:': tocrlf
156 'cleverdecode:': tocrlf
157 }
157 }
158
158
159 class eolfile(object):
159 class eolfile(object):
160 def __init__(self, ui, root, data):
160 def __init__(self, ui, root, data):
161 self._decode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
161 self._decode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
162 self._encode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
162 self._encode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
163
163
164 self.cfg = config.config()
164 self.cfg = config.config()
165 # Our files should not be touched. The pattern must be
165 # Our files should not be touched. The pattern must be
166 # inserted first override a '** = native' pattern.
166 # inserted first override a '** = native' pattern.
167 self.cfg.set('patterns', '.hg*', 'BIN', 'eol')
167 self.cfg.set('patterns', '.hg*', 'BIN', 'eol')
168 # We can then parse the user's patterns.
168 # We can then parse the user's patterns.
169 self.cfg.parse('.hgeol', data)
169 self.cfg.parse('.hgeol', data)
170
170
171 isrepolf = self.cfg.get('repository', 'native') != 'CRLF'
171 isrepolf = self.cfg.get('repository', 'native') != 'CRLF'
172 self._encode['NATIVE'] = isrepolf and 'to-lf' or 'to-crlf'
172 self._encode['NATIVE'] = isrepolf and 'to-lf' or 'to-crlf'
173 iswdlf = ui.config('eol', 'native', os.linesep) in ('LF', '\n')
173 iswdlf = ui.config('eol', 'native', os.linesep) in ('LF', '\n')
174 self._decode['NATIVE'] = iswdlf and 'to-lf' or 'to-crlf'
174 self._decode['NATIVE'] = iswdlf and 'to-lf' or 'to-crlf'
175
175
176 include = []
176 include = []
177 exclude = []
177 exclude = []
178 for pattern, style in self.cfg.items('patterns'):
178 for pattern, style in self.cfg.items('patterns'):
179 key = style.upper()
179 key = style.upper()
180 if key == 'BIN':
180 if key == 'BIN':
181 exclude.append(pattern)
181 exclude.append(pattern)
182 else:
182 else:
183 include.append(pattern)
183 include.append(pattern)
184 # This will match the files for which we need to care
184 # This will match the files for which we need to care
185 # about inconsistent newlines.
185 # about inconsistent newlines.
186 self.match = match.match(root, '', [], include, exclude)
186 self.match = match.match(root, '', [], include, exclude)
187
187
188 def copytoui(self, ui):
188 def copytoui(self, ui):
189 for pattern, style in self.cfg.items('patterns'):
189 for pattern, style in self.cfg.items('patterns'):
190 key = style.upper()
190 key = style.upper()
191 try:
191 try:
192 ui.setconfig('decode', pattern, self._decode[key], 'eol')
192 ui.setconfig('decode', pattern, self._decode[key], 'eol')
193 ui.setconfig('encode', pattern, self._encode[key], 'eol')
193 ui.setconfig('encode', pattern, self._encode[key], 'eol')
194 except KeyError:
194 except KeyError:
195 ui.warn(_("ignoring unknown EOL style '%s' from %s\n")
195 ui.warn(_("ignoring unknown EOL style '%s' from %s\n")
196 % (style, self.cfg.source('patterns', pattern)))
196 % (style, self.cfg.source('patterns', pattern)))
197 # eol.only-consistent can be specified in ~/.hgrc or .hgeol
197 # eol.only-consistent can be specified in ~/.hgrc or .hgeol
198 for k, v in self.cfg.items('eol'):
198 for k, v in self.cfg.items('eol'):
199 ui.setconfig('eol', k, v, 'eol')
199 ui.setconfig('eol', k, v, 'eol')
200
200
201 def checkrev(self, repo, ctx, files):
201 def checkrev(self, repo, ctx, files):
202 failed = []
202 failed = []
203 for f in (files or ctx.files()):
203 for f in (files or ctx.files()):
204 if f not in ctx:
204 if f not in ctx:
205 continue
205 continue
206 for pattern, style in self.cfg.items('patterns'):
206 for pattern, style in self.cfg.items('patterns'):
207 if not match.match(repo.root, '', [pattern])(f):
207 if not match.match(repo.root, '', [pattern])(f):
208 continue
208 continue
209 target = self._encode[style.upper()]
209 target = self._encode[style.upper()]
210 data = ctx[f].data()
210 data = ctx[f].data()
211 if (target == "to-lf" and "\r\n" in data
211 if (target == "to-lf" and "\r\n" in data
212 or target == "to-crlf" and singlelf.search(data)):
212 or target == "to-crlf" and singlelf.search(data)):
213 failed.append((f, target, str(ctx)))
213 failed.append((f, target, str(ctx)))
214 break
214 break
215 return failed
215 return failed
216
216
217 def parseeol(ui, repo, nodes):
217 def parseeol(ui, repo, nodes):
218 try:
218 try:
219 for node in nodes:
219 for node in nodes:
220 try:
220 try:
221 if node is None:
221 if node is None:
222 # Cannot use workingctx.data() since it would load
222 # Cannot use workingctx.data() since it would load
223 # and cache the filters before we configure them.
223 # and cache the filters before we configure them.
224 data = repo.wfile('.hgeol').read()
224 data = repo.wfile('.hgeol').read()
225 else:
225 else:
226 data = repo[node]['.hgeol'].data()
226 data = repo[node]['.hgeol'].data()
227 return eolfile(ui, repo.root, data)
227 return eolfile(ui, repo.root, data)
228 except (IOError, LookupError):
228 except (IOError, LookupError):
229 pass
229 pass
230 except error.ParseError as inst:
230 except error.ParseError as inst:
231 ui.warn(_("warning: ignoring .hgeol file due to parse error "
231 ui.warn(_("warning: ignoring .hgeol file due to parse error "
232 "at %s: %s\n") % (inst.args[1], inst.args[0]))
232 "at %s: %s\n") % (inst.args[1], inst.args[0]))
233 return None
233 return None
234
234
235 def _checkhook(ui, repo, node, headsonly):
235 def _checkhook(ui, repo, node, headsonly):
236 # Get revisions to check and touched files at the same time
236 # Get revisions to check and touched files at the same time
237 files = set()
237 files = set()
238 revs = set()
238 revs = set()
239 for rev in xrange(repo[node].rev(), len(repo)):
239 for rev in xrange(repo[node].rev(), len(repo)):
240 revs.add(rev)
240 revs.add(rev)
241 if headsonly:
241 if headsonly:
242 ctx = repo[rev]
242 ctx = repo[rev]
243 files.update(ctx.files())
243 files.update(ctx.files())
244 for pctx in ctx.parents():
244 for pctx in ctx.parents():
245 revs.discard(pctx.rev())
245 revs.discard(pctx.rev())
246 failed = []
246 failed = []
247 for rev in revs:
247 for rev in revs:
248 ctx = repo[rev]
248 ctx = repo[rev]
249 eol = parseeol(ui, repo, [ctx.node()])
249 eol = parseeol(ui, repo, [ctx.node()])
250 if eol:
250 if eol:
251 failed.extend(eol.checkrev(repo, ctx, files))
251 failed.extend(eol.checkrev(repo, ctx, files))
252
252
253 if failed:
253 if failed:
254 eols = {'to-lf': 'CRLF', 'to-crlf': 'LF'}
254 eols = {'to-lf': 'CRLF', 'to-crlf': 'LF'}
255 msgs = []
255 msgs = []
256 for f, target, node in sorted(failed):
256 for f, target, node in sorted(failed):
257 msgs.append(_(" %s in %s should not have %s line endings") %
257 msgs.append(_(" %s in %s should not have %s line endings") %
258 (f, node, eols[target]))
258 (f, node, eols[target]))
259 raise error.Abort(_("end-of-line check failed:\n") + "\n".join(msgs))
259 raise error.Abort(_("end-of-line check failed:\n") + "\n".join(msgs))
260
260
261 def checkallhook(ui, repo, node, hooktype, **kwargs):
261 def checkallhook(ui, repo, node, hooktype, **kwargs):
262 """verify that files have expected EOLs"""
262 """verify that files have expected EOLs"""
263 _checkhook(ui, repo, node, False)
263 _checkhook(ui, repo, node, False)
264
264
265 def checkheadshook(ui, repo, node, hooktype, **kwargs):
265 def checkheadshook(ui, repo, node, hooktype, **kwargs):
266 """verify that files have expected EOLs"""
266 """verify that files have expected EOLs"""
267 _checkhook(ui, repo, node, True)
267 _checkhook(ui, repo, node, True)
268
268
269 # "checkheadshook" used to be called "hook"
269 # "checkheadshook" used to be called "hook"
270 hook = checkheadshook
270 hook = checkheadshook
271
271
272 def preupdate(ui, repo, hooktype, parent1, parent2):
272 def preupdate(ui, repo, hooktype, parent1, parent2):
273 repo.loadeol([parent1])
273 repo.loadeol([parent1])
274 return False
274 return False
275
275
276 def uisetup(ui):
276 def uisetup(ui):
277 ui.setconfig('hooks', 'preupdate.eol', preupdate, 'eol')
277 ui.setconfig('hooks', 'preupdate.eol', preupdate, 'eol')
278
278
279 def extsetup(ui):
279 def extsetup(ui):
280 try:
280 try:
281 extensions.find('win32text')
281 extensions.find('win32text')
282 ui.warn(_("the eol extension is incompatible with the "
282 ui.warn(_("the eol extension is incompatible with the "
283 "win32text extension\n"))
283 "win32text extension\n"))
284 except KeyError:
284 except KeyError:
285 pass
285 pass
286
286
287
287
288 def reposetup(ui, repo):
288 def reposetup(ui, repo):
289 uisetup(repo.ui)
289 uisetup(repo.ui)
290
290
291 if not repo.local():
291 if not repo.local():
292 return
292 return
293 for name, fn in filters.iteritems():
293 for name, fn in filters.iteritems():
294 repo.adddatafilter(name, fn)
294 repo.adddatafilter(name, fn)
295
295
296 ui.setconfig('patch', 'eol', 'auto', 'eol')
296 ui.setconfig('patch', 'eol', 'auto', 'eol')
297
297
298 class eolrepo(repo.__class__):
298 class eolrepo(repo.__class__):
299
299
300 def loadeol(self, nodes):
300 def loadeol(self, nodes):
301 eol = parseeol(self.ui, self, nodes)
301 eol = parseeol(self.ui, self, nodes)
302 if eol is None:
302 if eol is None:
303 return None
303 return None
304 eol.copytoui(self.ui)
304 eol.copytoui(self.ui)
305 return eol.match
305 return eol.match
306
306
307 def _hgcleardirstate(self):
307 def _hgcleardirstate(self):
308 self._eolfile = self.loadeol([None, 'tip'])
308 self._eolmatch = self.loadeol([None, 'tip'])
309 if not self._eolfile:
309 if not self._eolmatch:
310 self._eolfile = util.never
310 self._eolmatch = util.never
311 return
311 return
312
312
313 try:
313 try:
314 cachemtime = os.path.getmtime(self.join("eol.cache"))
314 cachemtime = os.path.getmtime(self.join("eol.cache"))
315 except OSError:
315 except OSError:
316 cachemtime = 0
316 cachemtime = 0
317
317
318 try:
318 try:
319 eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
319 eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
320 except OSError:
320 except OSError:
321 eolmtime = 0
321 eolmtime = 0
322
322
323 if eolmtime > cachemtime:
323 if eolmtime > cachemtime:
324 self.ui.debug("eol: detected change in .hgeol\n")
324 self.ui.debug("eol: detected change in .hgeol\n")
325 wlock = None
325 wlock = None
326 try:
326 try:
327 wlock = self.wlock()
327 wlock = self.wlock()
328 for f in self.dirstate:
328 for f in self.dirstate:
329 if self.dirstate[f] == 'n':
329 if self.dirstate[f] == 'n':
330 # all normal files need to be looked at
330 # all normal files need to be looked at
331 # again since the new .hgeol file might no
331 # again since the new .hgeol file might no
332 # longer match a file it matched before
332 # longer match a file it matched before
333 self.dirstate.normallookup(f)
333 self.dirstate.normallookup(f)
334 # Create or touch the cache to update mtime
334 # Create or touch the cache to update mtime
335 self.vfs("eol.cache", "w").close()
335 self.vfs("eol.cache", "w").close()
336 wlock.release()
336 wlock.release()
337 except error.LockUnavailable:
337 except error.LockUnavailable:
338 # If we cannot lock the repository and clear the
338 # If we cannot lock the repository and clear the
339 # dirstate, then a commit might not see all files
339 # dirstate, then a commit might not see all files
340 # as modified. But if we cannot lock the
340 # as modified. But if we cannot lock the
341 # repository, then we can also not make a commit,
341 # repository, then we can also not make a commit,
342 # so ignore the error.
342 # so ignore the error.
343 pass
343 pass
344
344
345 def commitctx(self, ctx, haserror=False):
345 def commitctx(self, ctx, haserror=False):
346 for f in sorted(ctx.added() + ctx.modified()):
346 for f in sorted(ctx.added() + ctx.modified()):
347 if not self._eolfile(f):
347 if not self._eolmatch(f):
348 continue
348 continue
349 fctx = ctx[f]
349 fctx = ctx[f]
350 if fctx is None:
350 if fctx is None:
351 continue
351 continue
352 data = fctx.data()
352 data = fctx.data()
353 if util.binary(data):
353 if util.binary(data):
354 # We should not abort here, since the user should
354 # We should not abort here, since the user should
355 # be able to say "** = native" to automatically
355 # be able to say "** = native" to automatically
356 # have all non-binary files taken care of.
356 # have all non-binary files taken care of.
357 continue
357 continue
358 if inconsistenteol(data):
358 if inconsistenteol(data):
359 raise error.Abort(_("inconsistent newline style "
359 raise error.Abort(_("inconsistent newline style "
360 "in %s\n") % f)
360 "in %s\n") % f)
361 return super(eolrepo, self).commitctx(ctx, haserror)
361 return super(eolrepo, self).commitctx(ctx, haserror)
362 repo.__class__ = eolrepo
362 repo.__class__ = eolrepo
363 repo._hgcleardirstate()
363 repo._hgcleardirstate()
General Comments 0
You need to be logged in to leave comments. Login now