##// END OF EJS Templates
eol: eol.only-consistent can now be specified in .hgeol
Stepan Koltsov -
r14854:23c2d7d2 default
parent child Browse files
Show More
@@ -1,332 +1,335 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 copy. The
9 configuration file found in the root of the working copy. 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 copy and the repository. The format is
15 converted between the working copy 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 behaviour; it is only needed if you need to override a later,
26 default behaviour; 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 The rules will first apply when files are touched in the working
52 The rules will first apply when files are touched in the working
53 copy, e.g. by updating to null and back to tip to touch all files.
53 copy, e.g. by updating to null and back to tip to touch all files.
54
54
55 The extension uses an optional ``[eol]`` section in your hgrc file
55 The extension uses an optional ``[eol]`` section in your hgrc file
56 (not the ``.hgeol`` file) for settings that control the overall
56 (not the ``.hgeol`` file) for settings that control the overall
57 behavior. There are two settings:
57 behavior. There are two settings:
58
58
59 - ``eol.native`` (default ``os.linesep``) can be set to ``LF`` or
59 - ``eol.native`` (default ``os.linesep``) can be set to ``LF`` or
60 ``CRLF`` to override the default interpretation of ``native`` for
60 ``CRLF`` to override the default interpretation of ``native`` for
61 checkout. This can be used with :hg:`archive` on Unix, say, to
61 checkout. This can be used with :hg:`archive` on Unix, say, to
62 generate an archive where files have line endings for Windows.
62 generate an archive where files have line endings for Windows.
63
63
64 - ``eol.only-consistent`` (default True) can be set to False to make
64 - ``eol.only-consistent`` (default True) can be set to False to make
65 the extension convert files with inconsistent EOLs. Inconsistent
65 the extension convert files with inconsistent EOLs. Inconsistent
66 means that there is both ``CRLF`` and ``LF`` present in the file.
66 means that there is both ``CRLF`` and ``LF`` present in the file.
67 Such files are normally not touched under the assumption that they
67 Such files are normally not touched under the assumption that they
68 have mixed EOLs on purpose.
68 have mixed EOLs on purpose.
69
69
70 The extension provides ``cleverencode:`` and ``cleverdecode:`` filters
70 The extension provides ``cleverencode:`` and ``cleverdecode:`` filters
71 like the deprecated win32text extension does. This means that you can
71 like the deprecated win32text extension does. This means that you can
72 disable win32text and enable eol and your filters will still work. You
72 disable win32text and enable eol and your filters will still work. You
73 only need to these filters until you have prepared a ``.hgeol`` file.
73 only need to these filters until you have prepared a ``.hgeol`` file.
74
74
75 The ``win32text.forbid*`` hooks provided by the win32text extension
75 The ``win32text.forbid*`` hooks provided by the win32text extension
76 have been unified into a single hook named ``eol.checkheadshook``. The
76 have been unified into a single hook named ``eol.checkheadshook``. The
77 hook will lookup the expected line endings from the ``.hgeol`` file,
77 hook will lookup the expected line endings from the ``.hgeol`` file,
78 which means you must migrate to a ``.hgeol`` file first before using
78 which means you must migrate to a ``.hgeol`` file first before using
79 the hook. ``eol.checkheadshook`` only checks heads, intermediate
79 the hook. ``eol.checkheadshook`` only checks heads, intermediate
80 invalid revisions will be pushed. To forbid them completely, use the
80 invalid revisions will be pushed. To forbid them completely, use the
81 ``eol.checkallhook`` hook. These hooks are best used as
81 ``eol.checkallhook`` hook. These hooks are best used as
82 ``pretxnchangegroup`` hooks.
82 ``pretxnchangegroup`` hooks.
83
83
84 See :hg:`help patterns` for more information about the glob patterns
84 See :hg:`help patterns` for more information about the glob patterns
85 used.
85 used.
86 """
86 """
87
87
88 from mercurial.i18n import _
88 from mercurial.i18n import _
89 from mercurial import util, config, extensions, match, error
89 from mercurial import util, config, extensions, match, error
90 import re, os
90 import re, os
91
91
92 # Matches a lone LF, i.e., one that is not part of CRLF.
92 # Matches a lone LF, i.e., one that is not part of CRLF.
93 singlelf = re.compile('(^|[^\r])\n')
93 singlelf = re.compile('(^|[^\r])\n')
94 # Matches a single EOL which can either be a CRLF where repeated CR
94 # Matches a single EOL which can either be a CRLF where repeated CR
95 # are removed or a LF. We do not care about old Machintosh files, so a
95 # are removed or a LF. We do not care about old Machintosh files, so a
96 # stray CR is an error.
96 # stray CR is an error.
97 eolre = re.compile('\r*\n')
97 eolre = re.compile('\r*\n')
98
98
99
99
100 def inconsistenteol(data):
100 def inconsistenteol(data):
101 return '\r\n' in data and singlelf.search(data)
101 return '\r\n' in data and singlelf.search(data)
102
102
103 def tolf(s, params, ui, **kwargs):
103 def tolf(s, params, ui, **kwargs):
104 """Filter to convert to LF EOLs."""
104 """Filter to convert to LF EOLs."""
105 if util.binary(s):
105 if util.binary(s):
106 return s
106 return s
107 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
107 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
108 return s
108 return s
109 return eolre.sub('\n', s)
109 return eolre.sub('\n', s)
110
110
111 def tocrlf(s, params, ui, **kwargs):
111 def tocrlf(s, params, ui, **kwargs):
112 """Filter to convert to CRLF EOLs."""
112 """Filter to convert to CRLF EOLs."""
113 if util.binary(s):
113 if util.binary(s):
114 return s
114 return s
115 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
115 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
116 return s
116 return s
117 return eolre.sub('\r\n', s)
117 return eolre.sub('\r\n', s)
118
118
119 def isbinary(s, params):
119 def isbinary(s, params):
120 """Filter to do nothing with the file."""
120 """Filter to do nothing with the file."""
121 return s
121 return s
122
122
123 filters = {
123 filters = {
124 'to-lf': tolf,
124 'to-lf': tolf,
125 'to-crlf': tocrlf,
125 'to-crlf': tocrlf,
126 'is-binary': isbinary,
126 'is-binary': isbinary,
127 # The following provide backwards compatibility with win32text
127 # The following provide backwards compatibility with win32text
128 'cleverencode:': tolf,
128 'cleverencode:': tolf,
129 'cleverdecode:': tocrlf
129 'cleverdecode:': tocrlf
130 }
130 }
131
131
132 class eolfile(object):
132 class eolfile(object):
133 def __init__(self, ui, root, data):
133 def __init__(self, ui, root, data):
134 self._decode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
134 self._decode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
135 self._encode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
135 self._encode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
136
136
137 self.cfg = config.config()
137 self.cfg = config.config()
138 # Our files should not be touched. The pattern must be
138 # Our files should not be touched. The pattern must be
139 # inserted first override a '** = native' pattern.
139 # inserted first override a '** = native' pattern.
140 self.cfg.set('patterns', '.hg*', 'BIN')
140 self.cfg.set('patterns', '.hg*', 'BIN')
141 # We can then parse the user's patterns.
141 # We can then parse the user's patterns.
142 self.cfg.parse('.hgeol', data)
142 self.cfg.parse('.hgeol', data)
143
143
144 isrepolf = self.cfg.get('repository', 'native') != 'CRLF'
144 isrepolf = self.cfg.get('repository', 'native') != 'CRLF'
145 self._encode['NATIVE'] = isrepolf and 'to-lf' or 'to-crlf'
145 self._encode['NATIVE'] = isrepolf and 'to-lf' or 'to-crlf'
146 iswdlf = ui.config('eol', 'native', os.linesep) in ('LF', '\n')
146 iswdlf = ui.config('eol', 'native', os.linesep) in ('LF', '\n')
147 self._decode['NATIVE'] = iswdlf and 'to-lf' or 'to-crlf'
147 self._decode['NATIVE'] = iswdlf and 'to-lf' or 'to-crlf'
148
148
149 include = []
149 include = []
150 exclude = []
150 exclude = []
151 for pattern, style in self.cfg.items('patterns'):
151 for pattern, style in self.cfg.items('patterns'):
152 key = style.upper()
152 key = style.upper()
153 if key == 'BIN':
153 if key == 'BIN':
154 exclude.append(pattern)
154 exclude.append(pattern)
155 else:
155 else:
156 include.append(pattern)
156 include.append(pattern)
157 # This will match the files for which we need to care
157 # This will match the files for which we need to care
158 # about inconsistent newlines.
158 # about inconsistent newlines.
159 self.match = match.match(root, '', [], include, exclude)
159 self.match = match.match(root, '', [], include, exclude)
160
160
161 def setfilters(self, ui):
161 def copytoui(self, ui):
162 for pattern, style in self.cfg.items('patterns'):
162 for pattern, style in self.cfg.items('patterns'):
163 key = style.upper()
163 key = style.upper()
164 try:
164 try:
165 ui.setconfig('decode', pattern, self._decode[key])
165 ui.setconfig('decode', pattern, self._decode[key])
166 ui.setconfig('encode', pattern, self._encode[key])
166 ui.setconfig('encode', pattern, self._encode[key])
167 except KeyError:
167 except KeyError:
168 ui.warn(_("ignoring unknown EOL style '%s' from %s\n")
168 ui.warn(_("ignoring unknown EOL style '%s' from %s\n")
169 % (style, self.cfg.source('patterns', pattern)))
169 % (style, self.cfg.source('patterns', pattern)))
170 # eol.only-consistent can be specified in ~/.hgrc or .hgeol
171 for k, v in self.cfg.items('eol'):
172 ui.setconfig('eol', k, v)
170
173
171 def checkrev(self, repo, ctx, files):
174 def checkrev(self, repo, ctx, files):
172 failed = []
175 failed = []
173 for f in (files or ctx.files()):
176 for f in (files or ctx.files()):
174 if f not in ctx:
177 if f not in ctx:
175 continue
178 continue
176 for pattern, style in self.cfg.items('patterns'):
179 for pattern, style in self.cfg.items('patterns'):
177 if not match.match(repo.root, '', [pattern])(f):
180 if not match.match(repo.root, '', [pattern])(f):
178 continue
181 continue
179 target = self._encode[style.upper()]
182 target = self._encode[style.upper()]
180 data = ctx[f].data()
183 data = ctx[f].data()
181 if (target == "to-lf" and "\r\n" in data
184 if (target == "to-lf" and "\r\n" in data
182 or target == "to-crlf" and singlelf.search(data)):
185 or target == "to-crlf" and singlelf.search(data)):
183 failed.append((str(ctx), target, f))
186 failed.append((str(ctx), target, f))
184 break
187 break
185 return failed
188 return failed
186
189
187 def parseeol(ui, repo, nodes):
190 def parseeol(ui, repo, nodes):
188 try:
191 try:
189 for node in nodes:
192 for node in nodes:
190 try:
193 try:
191 if node is None:
194 if node is None:
192 # Cannot use workingctx.data() since it would load
195 # Cannot use workingctx.data() since it would load
193 # and cache the filters before we configure them.
196 # and cache the filters before we configure them.
194 data = repo.wfile('.hgeol').read()
197 data = repo.wfile('.hgeol').read()
195 else:
198 else:
196 data = repo[node]['.hgeol'].data()
199 data = repo[node]['.hgeol'].data()
197 return eolfile(ui, repo.root, data)
200 return eolfile(ui, repo.root, data)
198 except (IOError, LookupError):
201 except (IOError, LookupError):
199 pass
202 pass
200 except error.ParseError, inst:
203 except error.ParseError, inst:
201 ui.warn(_("warning: ignoring .hgeol file due to parse error "
204 ui.warn(_("warning: ignoring .hgeol file due to parse error "
202 "at %s: %s\n") % (inst.args[1], inst.args[0]))
205 "at %s: %s\n") % (inst.args[1], inst.args[0]))
203 return None
206 return None
204
207
205 def _checkhook(ui, repo, node, headsonly):
208 def _checkhook(ui, repo, node, headsonly):
206 # Get revisions to check and touched files at the same time
209 # Get revisions to check and touched files at the same time
207 files = set()
210 files = set()
208 revs = set()
211 revs = set()
209 for rev in xrange(repo[node].rev(), len(repo)):
212 for rev in xrange(repo[node].rev(), len(repo)):
210 revs.add(rev)
213 revs.add(rev)
211 if headsonly:
214 if headsonly:
212 ctx = repo[rev]
215 ctx = repo[rev]
213 files.update(ctx.files())
216 files.update(ctx.files())
214 for pctx in ctx.parents():
217 for pctx in ctx.parents():
215 revs.discard(pctx.rev())
218 revs.discard(pctx.rev())
216 failed = []
219 failed = []
217 for rev in revs:
220 for rev in revs:
218 ctx = repo[rev]
221 ctx = repo[rev]
219 eol = parseeol(ui, repo, [ctx.node()])
222 eol = parseeol(ui, repo, [ctx.node()])
220 if eol:
223 if eol:
221 failed.extend(eol.checkrev(repo, ctx, files))
224 failed.extend(eol.checkrev(repo, ctx, files))
222
225
223 if failed:
226 if failed:
224 eols = {'to-lf': 'CRLF', 'to-crlf': 'LF'}
227 eols = {'to-lf': 'CRLF', 'to-crlf': 'LF'}
225 msgs = []
228 msgs = []
226 for node, target, f in failed:
229 for node, target, f in failed:
227 msgs.append(_(" %s in %s should not have %s line endings") %
230 msgs.append(_(" %s in %s should not have %s line endings") %
228 (f, node, eols[target]))
231 (f, node, eols[target]))
229 raise util.Abort(_("end-of-line check failed:\n") + "\n".join(msgs))
232 raise util.Abort(_("end-of-line check failed:\n") + "\n".join(msgs))
230
233
231 def checkallhook(ui, repo, node, hooktype, **kwargs):
234 def checkallhook(ui, repo, node, hooktype, **kwargs):
232 """verify that files have expected EOLs"""
235 """verify that files have expected EOLs"""
233 _checkhook(ui, repo, node, False)
236 _checkhook(ui, repo, node, False)
234
237
235 def checkheadshook(ui, repo, node, hooktype, **kwargs):
238 def checkheadshook(ui, repo, node, hooktype, **kwargs):
236 """verify that files have expected EOLs"""
239 """verify that files have expected EOLs"""
237 _checkhook(ui, repo, node, True)
240 _checkhook(ui, repo, node, True)
238
241
239 # "checkheadshook" used to be called "hook"
242 # "checkheadshook" used to be called "hook"
240 hook = checkheadshook
243 hook = checkheadshook
241
244
242 def preupdate(ui, repo, hooktype, parent1, parent2):
245 def preupdate(ui, repo, hooktype, parent1, parent2):
243 #print "preupdate for %s: %s -> %s" % (repo.root, parent1, parent2)
246 #print "preupdate for %s: %s -> %s" % (repo.root, parent1, parent2)
244 repo.loadeol([parent1])
247 repo.loadeol([parent1])
245 return False
248 return False
246
249
247 def uisetup(ui):
250 def uisetup(ui):
248 ui.setconfig('hooks', 'preupdate.eol', preupdate)
251 ui.setconfig('hooks', 'preupdate.eol', preupdate)
249
252
250 def extsetup(ui):
253 def extsetup(ui):
251 try:
254 try:
252 extensions.find('win32text')
255 extensions.find('win32text')
253 ui.warn(_("the eol extension is incompatible with the "
256 ui.warn(_("the eol extension is incompatible with the "
254 "win32text extension\n"))
257 "win32text extension\n"))
255 except KeyError:
258 except KeyError:
256 pass
259 pass
257
260
258
261
259 def reposetup(ui, repo):
262 def reposetup(ui, repo):
260 uisetup(repo.ui)
263 uisetup(repo.ui)
261 #print "reposetup for", repo.root
264 #print "reposetup for", repo.root
262
265
263 if not repo.local():
266 if not repo.local():
264 return
267 return
265 for name, fn in filters.iteritems():
268 for name, fn in filters.iteritems():
266 repo.adddatafilter(name, fn)
269 repo.adddatafilter(name, fn)
267
270
268 ui.setconfig('patch', 'eol', 'auto')
271 ui.setconfig('patch', 'eol', 'auto')
269
272
270 class eolrepo(repo.__class__):
273 class eolrepo(repo.__class__):
271
274
272 def loadeol(self, nodes):
275 def loadeol(self, nodes):
273 eol = parseeol(self.ui, self, nodes)
276 eol = parseeol(self.ui, self, nodes)
274 if eol is None:
277 if eol is None:
275 return None
278 return None
276 eol.setfilters(self.ui)
279 eol.copytoui(self.ui)
277 return eol.match
280 return eol.match
278
281
279 def _hgcleardirstate(self):
282 def _hgcleardirstate(self):
280 self._eolfile = self.loadeol([None, 'tip'])
283 self._eolfile = self.loadeol([None, 'tip'])
281 if not self._eolfile:
284 if not self._eolfile:
282 self._eolfile = util.never
285 self._eolfile = util.never
283 return
286 return
284
287
285 try:
288 try:
286 cachemtime = os.path.getmtime(self.join("eol.cache"))
289 cachemtime = os.path.getmtime(self.join("eol.cache"))
287 except OSError:
290 except OSError:
288 cachemtime = 0
291 cachemtime = 0
289
292
290 try:
293 try:
291 eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
294 eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
292 except OSError:
295 except OSError:
293 eolmtime = 0
296 eolmtime = 0
294
297
295 if eolmtime > cachemtime:
298 if eolmtime > cachemtime:
296 ui.debug("eol: detected change in .hgeol\n")
299 ui.debug("eol: detected change in .hgeol\n")
297 wlock = None
300 wlock = None
298 try:
301 try:
299 wlock = self.wlock()
302 wlock = self.wlock()
300 for f in self.dirstate:
303 for f in self.dirstate:
301 if self.dirstate[f] == 'n':
304 if self.dirstate[f] == 'n':
302 # all normal files need to be looked at
305 # all normal files need to be looked at
303 # again since the new .hgeol file might no
306 # again since the new .hgeol file might no
304 # longer match a file it matched before
307 # longer match a file it matched before
305 self.dirstate.normallookup(f)
308 self.dirstate.normallookup(f)
306 # Touch the cache to update mtime.
309 # Touch the cache to update mtime.
307 self.opener("eol.cache", "w").close()
310 self.opener("eol.cache", "w").close()
308 wlock.release()
311 wlock.release()
309 except error.LockUnavailable:
312 except error.LockUnavailable:
310 # If we cannot lock the repository and clear the
313 # If we cannot lock the repository and clear the
311 # dirstate, then a commit might not see all files
314 # dirstate, then a commit might not see all files
312 # as modified. But if we cannot lock the
315 # as modified. But if we cannot lock the
313 # repository, then we can also not make a commit,
316 # repository, then we can also not make a commit,
314 # so ignore the error.
317 # so ignore the error.
315 pass
318 pass
316
319
317 def commitctx(self, ctx, error=False):
320 def commitctx(self, ctx, error=False):
318 for f in sorted(ctx.added() + ctx.modified()):
321 for f in sorted(ctx.added() + ctx.modified()):
319 if not self._eolfile(f):
322 if not self._eolfile(f):
320 continue
323 continue
321 data = ctx[f].data()
324 data = ctx[f].data()
322 if util.binary(data):
325 if util.binary(data):
323 # We should not abort here, since the user should
326 # We should not abort here, since the user should
324 # be able to say "** = native" to automatically
327 # be able to say "** = native" to automatically
325 # have all non-binary files taken care of.
328 # have all non-binary files taken care of.
326 continue
329 continue
327 if inconsistenteol(data):
330 if inconsistenteol(data):
328 raise util.Abort(_("inconsistent newline style "
331 raise util.Abort(_("inconsistent newline style "
329 "in %s\n" % f))
332 "in %s\n" % f))
330 return super(eolrepo, self).commitctx(ctx, error)
333 return super(eolrepo, self).commitctx(ctx, error)
331 repo.__class__ = eolrepo
334 repo.__class__ = eolrepo
332 repo._hgcleardirstate()
335 repo._hgcleardirstate()
@@ -1,443 +1,465 b''
1 Test EOL extension
1 Test EOL extension
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [diff]
4 > [diff]
5 > git = True
5 > git = True
6 > EOF
6 > EOF
7
7
8 Set up helpers
8 Set up helpers
9
9
10 $ cat > switch-eol.py <<EOF
10 $ cat > switch-eol.py <<EOF
11 > import sys
11 > import sys
12 > try:
12 > try:
13 > import os, msvcrt
13 > import os, msvcrt
14 > msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
14 > msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
15 > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
15 > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
16 > except ImportError:
16 > except ImportError:
17 > pass
17 > pass
18 > (old, new) = sys.argv[1] == 'LF' and ('\n', '\r\n') or ('\r\n', '\n')
18 > (old, new) = sys.argv[1] == 'LF' and ('\n', '\r\n') or ('\r\n', '\n')
19 > print "%% switching encoding from %r to %r" % (old, new)
19 > print "%% switching encoding from %r to %r" % (old, new)
20 > for path in sys.argv[2:]:
20 > for path in sys.argv[2:]:
21 > data = file(path, 'rb').read()
21 > data = file(path, 'rb').read()
22 > data = data.replace(old, new)
22 > data = data.replace(old, new)
23 > file(path, 'wb').write(data)
23 > file(path, 'wb').write(data)
24 > EOF
24 > EOF
25
25
26 $ seteol () {
26 $ seteol () {
27 > if [ $1 = "LF" ]; then
27 > if [ $1 = "LF" ]; then
28 > EOL='\n'
28 > EOL='\n'
29 > else
29 > else
30 > EOL='\r\n'
30 > EOL='\r\n'
31 > fi
31 > fi
32 > }
32 > }
33
33
34 $ makerepo () {
34 $ makerepo () {
35 > seteol $1
35 > seteol $1
36 > echo "% setup $1 repository"
36 > echo "% setup $1 repository"
37 > hg init repo
37 > hg init repo
38 > cd repo
38 > cd repo
39 > cat > .hgeol <<EOF
39 > cat > .hgeol <<EOF
40 > [repository]
40 > [repository]
41 > native = $1
41 > native = $1
42 > [patterns]
42 > [patterns]
43 > mixed.txt = BIN
43 > mixed.txt = BIN
44 > **.txt = native
44 > **.txt = native
45 > EOF
45 > EOF
46 > printf "first${EOL}second${EOL}third${EOL}" > a.txt
46 > printf "first${EOL}second${EOL}third${EOL}" > a.txt
47 > hg commit --addremove -m 'checkin'
47 > hg commit --addremove -m 'checkin'
48 > echo
48 > echo
49 > cd ..
49 > cd ..
50 > }
50 > }
51
51
52 $ dotest () {
52 $ dotest () {
53 > seteol $1
53 > seteol $1
54 > echo "% hg clone repo repo-$1"
54 > echo "% hg clone repo repo-$1"
55 > hg clone --noupdate repo repo-$1
55 > hg clone --noupdate repo repo-$1
56 > cd repo-$1
56 > cd repo-$1
57 > cat > .hg/hgrc <<EOF
57 > cat > .hg/hgrc <<EOF
58 > [extensions]
58 > [extensions]
59 > eol =
59 > eol =
60 > [eol]
60 > [eol]
61 > native = $1
61 > native = $1
62 > EOF
62 > EOF
63 > hg update
63 > hg update
64 > echo '% a.txt'
64 > echo '% a.txt'
65 > cat a.txt
65 > cat a.txt
66 > echo '% hg cat a.txt'
66 > echo '% hg cat a.txt'
67 > hg cat a.txt
67 > hg cat a.txt
68 > printf "fourth${EOL}" >> a.txt
68 > printf "fourth${EOL}" >> a.txt
69 > echo '% a.txt'
69 > echo '% a.txt'
70 > cat a.txt
70 > cat a.txt
71 > hg diff
71 > hg diff
72 > python ../switch-eol.py $1 a.txt
72 > python ../switch-eol.py $1 a.txt
73 > echo '% hg diff only reports a single changed line:'
73 > echo '% hg diff only reports a single changed line:'
74 > hg diff
74 > hg diff
75 > echo "% reverting back to $1 format"
75 > echo "% reverting back to $1 format"
76 > hg revert a.txt
76 > hg revert a.txt
77 > cat a.txt
77 > cat a.txt
78 > printf "first\r\nsecond\n" > mixed.txt
78 > printf "first\r\nsecond\n" > mixed.txt
79 > hg add mixed.txt
79 > hg add mixed.txt
80 > echo "% hg commit of inconsistent .txt file marked as binary (should work)"
80 > echo "% hg commit of inconsistent .txt file marked as binary (should work)"
81 > hg commit -m 'binary file'
81 > hg commit -m 'binary file'
82 > echo "% hg commit of inconsistent .txt file marked as native (should fail)"
82 > echo "% hg commit of inconsistent .txt file marked as native (should fail)"
83 > printf "first\nsecond\r\nthird\nfourth\r\n" > a.txt
83 > printf "first\nsecond\r\nthird\nfourth\r\n" > a.txt
84 > hg commit -m 'inconsistent file'
84 > hg commit -m 'inconsistent file'
85 > echo "% hg commit --config eol.only-consistent=False (should work)"
85 > echo "% hg commit --config eol.only-consistent=False (should work)"
86 > hg commit --config eol.only-consistent=False -m 'inconsistent file'
86 > hg commit --config eol.only-consistent=False -m 'inconsistent file'
87 > echo "% hg commit of binary .txt file marked as native (binary files always okay)"
87 > echo "% hg commit of binary .txt file marked as native (binary files always okay)"
88 > printf "first${EOL}\0${EOL}third${EOL}" > a.txt
88 > printf "first${EOL}\0${EOL}third${EOL}" > a.txt
89 > hg commit -m 'binary file'
89 > hg commit -m 'binary file'
90 > cd ..
90 > cd ..
91 > rm -r repo-$1
91 > rm -r repo-$1
92 > }
92 > }
93
93
94 $ makemixedrepo () {
94 $ makemixedrepo () {
95 > echo
95 > echo
96 > echo "# setup $1 repository"
96 > echo "# setup $1 repository"
97 > hg init mixed
97 > hg init mixed
98 > cd mixed
98 > cd mixed
99 > printf "foo\r\nbar\r\nbaz\r\n" > win.txt
99 > printf "foo\r\nbar\r\nbaz\r\n" > win.txt
100 > printf "foo\nbar\nbaz\n" > unix.txt
100 > printf "foo\nbar\nbaz\n" > unix.txt
101 > #printf "foo\r\nbar\nbaz\r\n" > mixed.txt
101 > #printf "foo\r\nbar\nbaz\r\n" > mixed.txt
102 > hg commit --addremove -m 'created mixed files'
102 > hg commit --addremove -m 'created mixed files'
103 > echo "# setting repository-native EOLs to $1"
103 > echo "# setting repository-native EOLs to $1"
104 > cat > .hgeol <<EOF
104 > cat > .hgeol <<EOF
105 > [repository]
105 > [repository]
106 > native = $1
106 > native = $1
107 > [patterns]
107 > [patterns]
108 > **.txt = native
108 > **.txt = native
109 > EOF
109 > EOF
110 > hg commit --addremove -m 'added .hgeol'
110 > hg commit --addremove -m 'added .hgeol'
111 > cd ..
111 > cd ..
112 > }
112 > }
113
113
114 $ testmixed () {
114 $ testmixed () {
115 > echo
115 > echo
116 > echo "% hg clone mixed mixed-$1"
116 > echo "% hg clone mixed mixed-$1"
117 > hg clone mixed mixed-$1
117 > hg clone mixed mixed-$1
118 > cd mixed-$1
118 > cd mixed-$1
119 > echo '% hg status (eol extension not yet activated)'
119 > echo '% hg status (eol extension not yet activated)'
120 > hg status
120 > hg status
121 > cat > .hg/hgrc <<EOF
121 > cat > .hg/hgrc <<EOF
122 > [extensions]
122 > [extensions]
123 > eol =
123 > eol =
124 > [eol]
124 > [eol]
125 > native = $1
125 > native = $1
126 > EOF
126 > EOF
127 > echo '% hg status (eol activated)'
127 > echo '% hg status (eol activated)'
128 > hg status
128 > hg status
129 > echo '% hg commit'
129 > echo '% hg commit'
130 > hg commit -m 'synchronized EOLs'
130 > hg commit -m 'synchronized EOLs'
131 > echo '% hg status'
131 > echo '% hg status'
132 > hg status
132 > hg status
133 > cd ..
133 > cd ..
134 > rm -r mixed-$1
134 > rm -r mixed-$1
135 > }
135 > }
136
136
137 Basic tests
137 Basic tests
138
138
139 $ makerepo LF
139 $ makerepo LF
140 % setup LF repository
140 % setup LF repository
141 adding .hgeol
141 adding .hgeol
142 adding a.txt
142 adding a.txt
143
143
144 $ dotest LF
144 $ dotest LF
145 % hg clone repo repo-LF
145 % hg clone repo repo-LF
146 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
146 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
147 % a.txt
147 % a.txt
148 first
148 first
149 second
149 second
150 third
150 third
151 % hg cat a.txt
151 % hg cat a.txt
152 first
152 first
153 second
153 second
154 third
154 third
155 % a.txt
155 % a.txt
156 first
156 first
157 second
157 second
158 third
158 third
159 fourth
159 fourth
160 diff --git a/a.txt b/a.txt
160 diff --git a/a.txt b/a.txt
161 --- a/a.txt
161 --- a/a.txt
162 +++ b/a.txt
162 +++ b/a.txt
163 @@ -1,3 +1,4 @@
163 @@ -1,3 +1,4 @@
164 first
164 first
165 second
165 second
166 third
166 third
167 +fourth
167 +fourth
168 % switching encoding from '\n' to '\r\n'
168 % switching encoding from '\n' to '\r\n'
169 % hg diff only reports a single changed line:
169 % hg diff only reports a single changed line:
170 diff --git a/a.txt b/a.txt
170 diff --git a/a.txt b/a.txt
171 --- a/a.txt
171 --- a/a.txt
172 +++ b/a.txt
172 +++ b/a.txt
173 @@ -1,3 +1,4 @@
173 @@ -1,3 +1,4 @@
174 first
174 first
175 second
175 second
176 third
176 third
177 +fourth
177 +fourth
178 % reverting back to LF format
178 % reverting back to LF format
179 first
179 first
180 second
180 second
181 third
181 third
182 % hg commit of inconsistent .txt file marked as binary (should work)
182 % hg commit of inconsistent .txt file marked as binary (should work)
183 % hg commit of inconsistent .txt file marked as native (should fail)
183 % hg commit of inconsistent .txt file marked as native (should fail)
184 abort: inconsistent newline style in a.txt
184 abort: inconsistent newline style in a.txt
185
185
186 % hg commit --config eol.only-consistent=False (should work)
186 % hg commit --config eol.only-consistent=False (should work)
187 % hg commit of binary .txt file marked as native (binary files always okay)
187 % hg commit of binary .txt file marked as native (binary files always okay)
188 $ dotest CRLF
188 $ dotest CRLF
189 % hg clone repo repo-CRLF
189 % hg clone repo repo-CRLF
190 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
190 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 % a.txt
191 % a.txt
192 first\r (esc)
192 first\r (esc)
193 second\r (esc)
193 second\r (esc)
194 third\r (esc)
194 third\r (esc)
195 % hg cat a.txt
195 % hg cat a.txt
196 first
196 first
197 second
197 second
198 third
198 third
199 % a.txt
199 % a.txt
200 first\r (esc)
200 first\r (esc)
201 second\r (esc)
201 second\r (esc)
202 third\r (esc)
202 third\r (esc)
203 fourth\r (esc)
203 fourth\r (esc)
204 diff --git a/a.txt b/a.txt
204 diff --git a/a.txt b/a.txt
205 --- a/a.txt
205 --- a/a.txt
206 +++ b/a.txt
206 +++ b/a.txt
207 @@ -1,3 +1,4 @@
207 @@ -1,3 +1,4 @@
208 first
208 first
209 second
209 second
210 third
210 third
211 +fourth
211 +fourth
212 % switching encoding from '\r\n' to '\n'
212 % switching encoding from '\r\n' to '\n'
213 % hg diff only reports a single changed line:
213 % hg diff only reports a single changed line:
214 diff --git a/a.txt b/a.txt
214 diff --git a/a.txt b/a.txt
215 --- a/a.txt
215 --- a/a.txt
216 +++ b/a.txt
216 +++ b/a.txt
217 @@ -1,3 +1,4 @@
217 @@ -1,3 +1,4 @@
218 first
218 first
219 second
219 second
220 third
220 third
221 +fourth
221 +fourth
222 % reverting back to CRLF format
222 % reverting back to CRLF format
223 first\r (esc)
223 first\r (esc)
224 second\r (esc)
224 second\r (esc)
225 third\r (esc)
225 third\r (esc)
226 % hg commit of inconsistent .txt file marked as binary (should work)
226 % hg commit of inconsistent .txt file marked as binary (should work)
227 % hg commit of inconsistent .txt file marked as native (should fail)
227 % hg commit of inconsistent .txt file marked as native (should fail)
228 abort: inconsistent newline style in a.txt
228 abort: inconsistent newline style in a.txt
229
229
230 % hg commit --config eol.only-consistent=False (should work)
230 % hg commit --config eol.only-consistent=False (should work)
231 % hg commit of binary .txt file marked as native (binary files always okay)
231 % hg commit of binary .txt file marked as native (binary files always okay)
232 $ rm -r repo
232 $ rm -r repo
233 $ makerepo CRLF
233 $ makerepo CRLF
234 % setup CRLF repository
234 % setup CRLF repository
235 adding .hgeol
235 adding .hgeol
236 adding a.txt
236 adding a.txt
237
237
238 $ dotest LF
238 $ dotest LF
239 % hg clone repo repo-LF
239 % hg clone repo repo-LF
240 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
240 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
241 % a.txt
241 % a.txt
242 first
242 first
243 second
243 second
244 third
244 third
245 % hg cat a.txt
245 % hg cat a.txt
246 first\r (esc)
246 first\r (esc)
247 second\r (esc)
247 second\r (esc)
248 third\r (esc)
248 third\r (esc)
249 % a.txt
249 % a.txt
250 first
250 first
251 second
251 second
252 third
252 third
253 fourth
253 fourth
254 diff --git a/a.txt b/a.txt
254 diff --git a/a.txt b/a.txt
255 --- a/a.txt
255 --- a/a.txt
256 +++ b/a.txt
256 +++ b/a.txt
257 @@ -1,3 +1,4 @@
257 @@ -1,3 +1,4 @@
258 first\r (esc)
258 first\r (esc)
259 second\r (esc)
259 second\r (esc)
260 third\r (esc)
260 third\r (esc)
261 +fourth\r (esc)
261 +fourth\r (esc)
262 % switching encoding from '\n' to '\r\n'
262 % switching encoding from '\n' to '\r\n'
263 % hg diff only reports a single changed line:
263 % hg diff only reports a single changed line:
264 diff --git a/a.txt b/a.txt
264 diff --git a/a.txt b/a.txt
265 --- a/a.txt
265 --- a/a.txt
266 +++ b/a.txt
266 +++ b/a.txt
267 @@ -1,3 +1,4 @@
267 @@ -1,3 +1,4 @@
268 first\r (esc)
268 first\r (esc)
269 second\r (esc)
269 second\r (esc)
270 third\r (esc)
270 third\r (esc)
271 +fourth\r (esc)
271 +fourth\r (esc)
272 % reverting back to LF format
272 % reverting back to LF format
273 first
273 first
274 second
274 second
275 third
275 third
276 % hg commit of inconsistent .txt file marked as binary (should work)
276 % hg commit of inconsistent .txt file marked as binary (should work)
277 % hg commit of inconsistent .txt file marked as native (should fail)
277 % hg commit of inconsistent .txt file marked as native (should fail)
278 abort: inconsistent newline style in a.txt
278 abort: inconsistent newline style in a.txt
279
279
280 % hg commit --config eol.only-consistent=False (should work)
280 % hg commit --config eol.only-consistent=False (should work)
281 % hg commit of binary .txt file marked as native (binary files always okay)
281 % hg commit of binary .txt file marked as native (binary files always okay)
282 $ dotest CRLF
282 $ dotest CRLF
283 % hg clone repo repo-CRLF
283 % hg clone repo repo-CRLF
284 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
284 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
285 % a.txt
285 % a.txt
286 first\r (esc)
286 first\r (esc)
287 second\r (esc)
287 second\r (esc)
288 third\r (esc)
288 third\r (esc)
289 % hg cat a.txt
289 % hg cat a.txt
290 first\r (esc)
290 first\r (esc)
291 second\r (esc)
291 second\r (esc)
292 third\r (esc)
292 third\r (esc)
293 % a.txt
293 % a.txt
294 first\r (esc)
294 first\r (esc)
295 second\r (esc)
295 second\r (esc)
296 third\r (esc)
296 third\r (esc)
297 fourth\r (esc)
297 fourth\r (esc)
298 diff --git a/a.txt b/a.txt
298 diff --git a/a.txt b/a.txt
299 --- a/a.txt
299 --- a/a.txt
300 +++ b/a.txt
300 +++ b/a.txt
301 @@ -1,3 +1,4 @@
301 @@ -1,3 +1,4 @@
302 first\r (esc)
302 first\r (esc)
303 second\r (esc)
303 second\r (esc)
304 third\r (esc)
304 third\r (esc)
305 +fourth\r (esc)
305 +fourth\r (esc)
306 % switching encoding from '\r\n' to '\n'
306 % switching encoding from '\r\n' to '\n'
307 % hg diff only reports a single changed line:
307 % hg diff only reports a single changed line:
308 diff --git a/a.txt b/a.txt
308 diff --git a/a.txt b/a.txt
309 --- a/a.txt
309 --- a/a.txt
310 +++ b/a.txt
310 +++ b/a.txt
311 @@ -1,3 +1,4 @@
311 @@ -1,3 +1,4 @@
312 first\r (esc)
312 first\r (esc)
313 second\r (esc)
313 second\r (esc)
314 third\r (esc)
314 third\r (esc)
315 +fourth\r (esc)
315 +fourth\r (esc)
316 % reverting back to CRLF format
316 % reverting back to CRLF format
317 first\r (esc)
317 first\r (esc)
318 second\r (esc)
318 second\r (esc)
319 third\r (esc)
319 third\r (esc)
320 % hg commit of inconsistent .txt file marked as binary (should work)
320 % hg commit of inconsistent .txt file marked as binary (should work)
321 % hg commit of inconsistent .txt file marked as native (should fail)
321 % hg commit of inconsistent .txt file marked as native (should fail)
322 abort: inconsistent newline style in a.txt
322 abort: inconsistent newline style in a.txt
323
323
324 % hg commit --config eol.only-consistent=False (should work)
324 % hg commit --config eol.only-consistent=False (should work)
325 % hg commit of binary .txt file marked as native (binary files always okay)
325 % hg commit of binary .txt file marked as native (binary files always okay)
326 $ rm -r repo
326 $ rm -r repo
327
327
328 Mixed tests
328 Mixed tests
329
329
330 $ makemixedrepo LF
330 $ makemixedrepo LF
331
331
332 # setup LF repository
332 # setup LF repository
333 adding unix.txt
333 adding unix.txt
334 adding win.txt
334 adding win.txt
335 # setting repository-native EOLs to LF
335 # setting repository-native EOLs to LF
336 adding .hgeol
336 adding .hgeol
337 $ testmixed LF
337 $ testmixed LF
338
338
339 % hg clone mixed mixed-LF
339 % hg clone mixed mixed-LF
340 updating to branch default
340 updating to branch default
341 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
341 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
342 % hg status (eol extension not yet activated)
342 % hg status (eol extension not yet activated)
343 % hg status (eol activated)
343 % hg status (eol activated)
344 M win.txt
344 M win.txt
345 % hg commit
345 % hg commit
346 % hg status
346 % hg status
347 $ testmixed CRLF
347 $ testmixed CRLF
348
348
349 % hg clone mixed mixed-CRLF
349 % hg clone mixed mixed-CRLF
350 updating to branch default
350 updating to branch default
351 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
351 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
352 % hg status (eol extension not yet activated)
352 % hg status (eol extension not yet activated)
353 % hg status (eol activated)
353 % hg status (eol activated)
354 M win.txt
354 M win.txt
355 % hg commit
355 % hg commit
356 % hg status
356 % hg status
357 $ rm -r mixed
357 $ rm -r mixed
358 $ makemixedrepo CRLF
358 $ makemixedrepo CRLF
359
359
360 # setup CRLF repository
360 # setup CRLF repository
361 adding unix.txt
361 adding unix.txt
362 adding win.txt
362 adding win.txt
363 # setting repository-native EOLs to CRLF
363 # setting repository-native EOLs to CRLF
364 adding .hgeol
364 adding .hgeol
365 $ testmixed LF
365 $ testmixed LF
366
366
367 % hg clone mixed mixed-LF
367 % hg clone mixed mixed-LF
368 updating to branch default
368 updating to branch default
369 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
369 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
370 % hg status (eol extension not yet activated)
370 % hg status (eol extension not yet activated)
371 % hg status (eol activated)
371 % hg status (eol activated)
372 M unix.txt
372 M unix.txt
373 % hg commit
373 % hg commit
374 % hg status
374 % hg status
375 $ testmixed CRLF
375 $ testmixed CRLF
376
376
377 % hg clone mixed mixed-CRLF
377 % hg clone mixed mixed-CRLF
378 updating to branch default
378 updating to branch default
379 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
379 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
380 % hg status (eol extension not yet activated)
380 % hg status (eol extension not yet activated)
381 % hg status (eol activated)
381 % hg status (eol activated)
382 M unix.txt
382 M unix.txt
383 % hg commit
383 % hg commit
384 % hg status
384 % hg status
385 $ rm -r mixed
385 $ rm -r mixed
386
386
387 Test issue2569 -- eol extension takes write lock on reading:
387 Test issue2569 -- eol extension takes write lock on reading:
388
388
389 $ echo '[extensions]' >> $HGRCPATH
389 $ echo '[extensions]' >> $HGRCPATH
390 $ echo 'eol =' >> $HGRCPATH
390 $ echo 'eol =' >> $HGRCPATH
391 $ hg init repo
391 $ hg init repo
392 $ cd repo
392 $ cd repo
393 $ touch .hgeol
393 $ touch .hgeol
394 $ hg status
394 $ hg status
395 ? .hgeol
395 ? .hgeol
396 $ chmod -R -w .hg
396 $ chmod -R -w .hg
397 $ sleep 1
397 $ sleep 1
398 $ touch .hgeol
398 $ touch .hgeol
399 $ hg status --traceback
399 $ hg status --traceback
400 ? .hgeol
400 ? .hgeol
401 $ chmod -R u+w .hg
401 $ chmod -R u+w .hg
402 $ cd ..
402 $ cd ..
403
403
404 Test cleverencode: and cleverdecode: aliases for win32text extension
404 Test cleverencode: and cleverdecode: aliases for win32text extension
405
405
406 $ echo '[encode]' >> $HGRCPATH
406 $ echo '[encode]' >> $HGRCPATH
407 $ echo '**.txt = cleverencode:' >> $HGRCPATH
407 $ echo '**.txt = cleverencode:' >> $HGRCPATH
408 $ echo '[decode]' >> $HGRCPATH
408 $ echo '[decode]' >> $HGRCPATH
409 $ echo '**.txt = cleverdecode:' >> $HGRCPATH
409 $ echo '**.txt = cleverdecode:' >> $HGRCPATH
410
410
411 $ hg init win32compat
411 $ hg init win32compat
412 $ cd win32compat
412 $ cd win32compat
413 $ printf "foo\r\nbar\r\nbaz\r\n" > win.txt
413 $ printf "foo\r\nbar\r\nbaz\r\n" > win.txt
414 $ printf "foo\nbar\nbaz\n" > unix.txt
414 $ printf "foo\nbar\nbaz\n" > unix.txt
415 $ hg add
415 $ hg add
416 adding unix.txt
416 adding unix.txt
417 adding win.txt
417 adding win.txt
418 $ hg commit -m checkin
418 $ hg commit -m checkin
419
419
420 Check that both files have LF line-endings in the repository:
420 Check that both files have LF line-endings in the repository:
421
421
422 $ hg cat win.txt
422 $ hg cat win.txt
423 foo
423 foo
424 bar
424 bar
425 baz
425 baz
426 $ hg cat unix.txt
426 $ hg cat unix.txt
427 foo
427 foo
428 bar
428 bar
429 baz
429 baz
430
430
431 Test handling of a broken .hgeol file:
431 Test handling of a broken .hgeol file:
432
432
433 $ touch .hgeol
433 $ touch .hgeol
434 $ hg add .hgeol
434 $ hg add .hgeol
435 $ hg commit -m 'clean version'
435 $ hg commit -m 'clean version'
436 $ echo "bad" > .hgeol
436 $ echo "bad" > .hgeol
437 $ hg status
437 $ hg status
438 warning: ignoring .hgeol file due to parse error at .hgeol:1: bad
438 warning: ignoring .hgeol file due to parse error at .hgeol:1: bad
439 M .hgeol
439 M .hgeol
440 $ hg revert .hgeol
440 $ hg revert .hgeol
441 warning: ignoring .hgeol file due to parse error at .hgeol:1: bad
441 warning: ignoring .hgeol file due to parse error at .hgeol:1: bad
442 $ hg status
442 $ hg status
443 ? .hgeol.orig
443 ? .hgeol.orig
444
445 Test eol.only-consistent can be specified in .hgeol
446
447 $ cd $TESTTMP
448 $ hg init only-consistent
449 $ cd only-consistent
450 $ printf "first\nsecond\r\n" > a.txt
451 $ hg add a.txt
452 $ cat > .hgeol << EOF
453 > [eol]
454 > only-consistent = True
455 > EOF
456 $ hg commit -m 'inconsistent'
457 abort: inconsistent newline style in a.txt
458
459 [255]
460 $ cat > .hgeol << EOF
461 > [eol]
462 > only-consistent = False
463 > EOF
464 $ hg commit -m 'consistent'
465
General Comments 0
You need to be logged in to leave comments. Login now