##// END OF EJS Templates
eol: the hook no longer requires the extension to be loaded...
Patrick Mezard -
r13615:686dec75 default
parent child Browse files
Show More
@@ -1,299 +1,303 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.hook``. The hook will
76 have been unified into a single hook named ``eol.hook``. The hook will
77 lookup the expected line endings from the ``.hgeol`` file, which means
77 lookup the expected line endings from the ``.hgeol`` file, which means
78 you must migrate to a ``.hgeol`` file first before using the hook.
78 you must migrate to a ``.hgeol`` file first before using the hook.
79 Remember to enable the eol extension in the repository where you
80 install the hook.
81
79
82 See :hg:`help patterns` for more information about the glob patterns
80 See :hg:`help patterns` for more information about the glob patterns
83 used.
81 used.
84 """
82 """
85
83
86 from mercurial.i18n import _
84 from mercurial.i18n import _
87 from mercurial import util, config, extensions, match, error
85 from mercurial import util, config, extensions, match, error
88 import re, os
86 import re, os
89
87
90 # Matches a lone LF, i.e., one that is not part of CRLF.
88 # Matches a lone LF, i.e., one that is not part of CRLF.
91 singlelf = re.compile('(^|[^\r])\n')
89 singlelf = re.compile('(^|[^\r])\n')
92 # Matches a single EOL which can either be a CRLF where repeated CR
90 # Matches a single EOL which can either be a CRLF where repeated CR
93 # are removed or a LF. We do not care about old Machintosh files, so a
91 # are removed or a LF. We do not care about old Machintosh files, so a
94 # stray CR is an error.
92 # stray CR is an error.
95 eolre = re.compile('\r*\n')
93 eolre = re.compile('\r*\n')
96
94
97
95
98 def inconsistenteol(data):
96 def inconsistenteol(data):
99 return '\r\n' in data and singlelf.search(data)
97 return '\r\n' in data and singlelf.search(data)
100
98
101 def tolf(s, params, ui, **kwargs):
99 def tolf(s, params, ui, **kwargs):
102 """Filter to convert to LF EOLs."""
100 """Filter to convert to LF EOLs."""
103 if util.binary(s):
101 if util.binary(s):
104 return s
102 return s
105 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
103 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
106 return s
104 return s
107 return eolre.sub('\n', s)
105 return eolre.sub('\n', s)
108
106
109 def tocrlf(s, params, ui, **kwargs):
107 def tocrlf(s, params, ui, **kwargs):
110 """Filter to convert to CRLF EOLs."""
108 """Filter to convert to CRLF EOLs."""
111 if util.binary(s):
109 if util.binary(s):
112 return s
110 return s
113 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
111 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
114 return s
112 return s
115 return eolre.sub('\r\n', s)
113 return eolre.sub('\r\n', s)
116
114
117 def isbinary(s, params):
115 def isbinary(s, params):
118 """Filter to do nothing with the file."""
116 """Filter to do nothing with the file."""
119 return s
117 return s
120
118
121 filters = {
119 filters = {
122 'to-lf': tolf,
120 'to-lf': tolf,
123 'to-crlf': tocrlf,
121 'to-crlf': tocrlf,
124 'is-binary': isbinary,
122 'is-binary': isbinary,
125 # The following provide backwards compatibility with win32text
123 # The following provide backwards compatibility with win32text
126 'cleverencode:': tolf,
124 'cleverencode:': tolf,
127 'cleverdecode:': tocrlf
125 'cleverdecode:': tocrlf
128 }
126 }
129
127
130 class eolfile(object):
128 class eolfile(object):
131 def __init__(self, ui, root, data):
129 def __init__(self, ui, root, data):
132 self._decode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
130 self._decode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
133 self._encode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
131 self._encode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
134
132
135 self.cfg = config.config()
133 self.cfg = config.config()
136 # Our files should not be touched. The pattern must be
134 # Our files should not be touched. The pattern must be
137 # inserted first override a '** = native' pattern.
135 # inserted first override a '** = native' pattern.
138 self.cfg.set('patterns', '.hg*', 'BIN')
136 self.cfg.set('patterns', '.hg*', 'BIN')
139 # We can then parse the user's patterns.
137 # We can then parse the user's patterns.
140 self.cfg.parse('.hgeol', data)
138 self.cfg.parse('.hgeol', data)
141
139
142 isrepolf = self.cfg.get('repository', 'native') != 'CRLF'
140 isrepolf = self.cfg.get('repository', 'native') != 'CRLF'
143 self._encode['NATIVE'] = isrepolf and 'to-lf' or 'to-crlf'
141 self._encode['NATIVE'] = isrepolf and 'to-lf' or 'to-crlf'
144 iswdlf = ui.config('eol', 'native', os.linesep) in ('LF', '\n')
142 iswdlf = ui.config('eol', 'native', os.linesep) in ('LF', '\n')
145 self._decode['NATIVE'] = iswdlf and 'to-lf' or 'to-crlf'
143 self._decode['NATIVE'] = iswdlf and 'to-lf' or 'to-crlf'
146
144
147 include = []
145 include = []
148 exclude = []
146 exclude = []
149 for pattern, style in self.cfg.items('patterns'):
147 for pattern, style in self.cfg.items('patterns'):
150 key = style.upper()
148 key = style.upper()
151 if key == 'BIN':
149 if key == 'BIN':
152 exclude.append(pattern)
150 exclude.append(pattern)
153 else:
151 else:
154 include.append(pattern)
152 include.append(pattern)
155 # This will match the files for which we need to care
153 # This will match the files for which we need to care
156 # about inconsistent newlines.
154 # about inconsistent newlines.
157 self.match = match.match(root, '', [], include, exclude)
155 self.match = match.match(root, '', [], include, exclude)
158
156
159 def setfilters(self, ui):
157 def setfilters(self, ui):
160 for pattern, style in self.cfg.items('patterns'):
158 for pattern, style in self.cfg.items('patterns'):
161 key = style.upper()
159 key = style.upper()
162 try:
160 try:
163 ui.setconfig('decode', pattern, self._decode[key])
161 ui.setconfig('decode', pattern, self._decode[key])
164 ui.setconfig('encode', pattern, self._encode[key])
162 ui.setconfig('encode', pattern, self._encode[key])
165 except KeyError:
163 except KeyError:
166 ui.warn(_("ignoring unknown EOL style '%s' from %s\n")
164 ui.warn(_("ignoring unknown EOL style '%s' from %s\n")
167 % (style, self.cfg.source('patterns', pattern)))
165 % (style, self.cfg.source('patterns', pattern)))
168
166
167 def checkrev(self, repo, ctx, files):
168 for f in files:
169 if f not in ctx:
170 continue
171 for pattern, style in self.cfg.items('patterns'):
172 if not match.match(repo.root, '', [pattern])(f):
173 continue
174 target = self._encode[style.upper()]
175 data = ctx[f].data()
176 if target == "to-lf" and "\r\n" in data:
177 raise util.Abort(_("%s should not have CRLF line endings")
178 % f)
179 elif target == "to-crlf" and singlelf.search(data):
180 raise util.Abort(_("%s should not have LF line endings")
181 % f)
182 # Ignore other rules for this file
183 break
184
169 def parseeol(ui, repo, nodes):
185 def parseeol(ui, repo, nodes):
170 try:
186 try:
171 for node in nodes:
187 for node in nodes:
172 try:
188 try:
173 if node is None:
189 if node is None:
174 # Cannot use workingctx.data() since it would load
190 # Cannot use workingctx.data() since it would load
175 # and cache the filters before we configure them.
191 # and cache the filters before we configure them.
176 data = repo.wfile('.hgeol').read()
192 data = repo.wfile('.hgeol').read()
177 else:
193 else:
178 data = repo[node]['.hgeol'].data()
194 data = repo[node]['.hgeol'].data()
179 return eolfile(ui, repo.root, data)
195 return eolfile(ui, repo.root, data)
180 except (IOError, LookupError):
196 except (IOError, LookupError):
181 pass
197 pass
182 except error.ParseError, inst:
198 except error.ParseError, inst:
183 ui.warn(_("warning: ignoring .hgeol file due to parse error "
199 ui.warn(_("warning: ignoring .hgeol file due to parse error "
184 "at %s: %s\n") % (inst.args[1], inst.args[0]))
200 "at %s: %s\n") % (inst.args[1], inst.args[0]))
185 return None
201 return None
186
202
187 def hook(ui, repo, node, hooktype, **kwargs):
203 def hook(ui, repo, node, hooktype, **kwargs):
188 """verify that files have expected EOLs"""
204 """verify that files have expected EOLs"""
189 files = set()
205 files = set()
190 for rev in xrange(repo[node].rev(), len(repo)):
206 for rev in xrange(repo[node].rev(), len(repo)):
191 files.update(repo[rev].files())
207 files.update(repo[rev].files())
192 tip = repo['tip']
208 tip = repo['tip']
193 for f in files:
209 eol = parseeol(ui, repo, [tip.node()])
194 if f not in tip:
210 if eol:
195 continue
211 eol.checkrev(repo, tip, files)
196 for pattern, target in ui.configitems('encode'):
197 if match.match(repo.root, '', [pattern])(f):
198 data = tip[f].data()
199 if target == "to-lf" and "\r\n" in data:
200 raise util.Abort(_("%s should not have CRLF line endings")
201 % f)
202 elif target == "to-crlf" and singlelf.search(data):
203 raise util.Abort(_("%s should not have LF line endings")
204 % f)
205 # Ignore other rules for this file
206 break
207
208
212
209 def preupdate(ui, repo, hooktype, parent1, parent2):
213 def preupdate(ui, repo, hooktype, parent1, parent2):
210 #print "preupdate for %s: %s -> %s" % (repo.root, parent1, parent2)
214 #print "preupdate for %s: %s -> %s" % (repo.root, parent1, parent2)
211 repo.loadeol([parent1])
215 repo.loadeol([parent1])
212 return False
216 return False
213
217
214 def uisetup(ui):
218 def uisetup(ui):
215 ui.setconfig('hooks', 'preupdate.eol', preupdate)
219 ui.setconfig('hooks', 'preupdate.eol', preupdate)
216
220
217 def extsetup(ui):
221 def extsetup(ui):
218 try:
222 try:
219 extensions.find('win32text')
223 extensions.find('win32text')
220 raise util.Abort(_("the eol extension is incompatible with the "
224 raise util.Abort(_("the eol extension is incompatible with the "
221 "win32text extension"))
225 "win32text extension"))
222 except KeyError:
226 except KeyError:
223 pass
227 pass
224
228
225
229
226 def reposetup(ui, repo):
230 def reposetup(ui, repo):
227 uisetup(repo.ui)
231 uisetup(repo.ui)
228 #print "reposetup for", repo.root
232 #print "reposetup for", repo.root
229
233
230 if not repo.local():
234 if not repo.local():
231 return
235 return
232 for name, fn in filters.iteritems():
236 for name, fn in filters.iteritems():
233 repo.adddatafilter(name, fn)
237 repo.adddatafilter(name, fn)
234
238
235 ui.setconfig('patch', 'eol', 'auto')
239 ui.setconfig('patch', 'eol', 'auto')
236
240
237 class eolrepo(repo.__class__):
241 class eolrepo(repo.__class__):
238
242
239 def loadeol(self, nodes):
243 def loadeol(self, nodes):
240 eol = parseeol(self.ui, self, nodes)
244 eol = parseeol(self.ui, self, nodes)
241 if eol is None:
245 if eol is None:
242 return None
246 return None
243 eol.setfilters(self.ui)
247 eol.setfilters(self.ui)
244 return eol.match
248 return eol.match
245
249
246 def _hgcleardirstate(self):
250 def _hgcleardirstate(self):
247 self._eolfile = self.loadeol([None, 'tip'])
251 self._eolfile = self.loadeol([None, 'tip'])
248 if not self._eolfile:
252 if not self._eolfile:
249 self._eolfile = util.never
253 self._eolfile = util.never
250 return
254 return
251
255
252 try:
256 try:
253 cachemtime = os.path.getmtime(self.join("eol.cache"))
257 cachemtime = os.path.getmtime(self.join("eol.cache"))
254 except OSError:
258 except OSError:
255 cachemtime = 0
259 cachemtime = 0
256
260
257 try:
261 try:
258 eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
262 eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
259 except OSError:
263 except OSError:
260 eolmtime = 0
264 eolmtime = 0
261
265
262 if eolmtime > cachemtime:
266 if eolmtime > cachemtime:
263 ui.debug("eol: detected change in .hgeol\n")
267 ui.debug("eol: detected change in .hgeol\n")
264 wlock = None
268 wlock = None
265 try:
269 try:
266 wlock = self.wlock()
270 wlock = self.wlock()
267 for f in self.dirstate:
271 for f in self.dirstate:
268 if self.dirstate[f] == 'n':
272 if self.dirstate[f] == 'n':
269 # all normal files need to be looked at
273 # all normal files need to be looked at
270 # again since the new .hgeol file might no
274 # again since the new .hgeol file might no
271 # longer match a file it matched before
275 # longer match a file it matched before
272 self.dirstate.normallookup(f)
276 self.dirstate.normallookup(f)
273 # Touch the cache to update mtime.
277 # Touch the cache to update mtime.
274 self.opener("eol.cache", "w").close()
278 self.opener("eol.cache", "w").close()
275 wlock.release()
279 wlock.release()
276 except error.LockUnavailable:
280 except error.LockUnavailable:
277 # If we cannot lock the repository and clear the
281 # If we cannot lock the repository and clear the
278 # dirstate, then a commit might not see all files
282 # dirstate, then a commit might not see all files
279 # as modified. But if we cannot lock the
283 # as modified. But if we cannot lock the
280 # repository, then we can also not make a commit,
284 # repository, then we can also not make a commit,
281 # so ignore the error.
285 # so ignore the error.
282 pass
286 pass
283
287
284 def commitctx(self, ctx, error=False):
288 def commitctx(self, ctx, error=False):
285 for f in sorted(ctx.added() + ctx.modified()):
289 for f in sorted(ctx.added() + ctx.modified()):
286 if not self._eolfile(f):
290 if not self._eolfile(f):
287 continue
291 continue
288 data = ctx[f].data()
292 data = ctx[f].data()
289 if util.binary(data):
293 if util.binary(data):
290 # We should not abort here, since the user should
294 # We should not abort here, since the user should
291 # be able to say "** = native" to automatically
295 # be able to say "** = native" to automatically
292 # have all non-binary files taken care of.
296 # have all non-binary files taken care of.
293 continue
297 continue
294 if inconsistenteol(data):
298 if inconsistenteol(data):
295 raise util.Abort(_("inconsistent newline style "
299 raise util.Abort(_("inconsistent newline style "
296 "in %s\n" % f))
300 "in %s\n" % f))
297 return super(eolrepo, self).commitctx(ctx, error)
301 return super(eolrepo, self).commitctx(ctx, error)
298 repo.__class__ = eolrepo
302 repo.__class__ = eolrepo
299 repo._hgcleardirstate()
303 repo._hgcleardirstate()
@@ -1,86 +1,83 b''
1 Test the EOL hook
1 Test the EOL hook
2
2
3 $ hg init main
3 $ hg init main
4 $ cat > main/.hg/hgrc <<EOF
4 $ cat > main/.hg/hgrc <<EOF
5 > [extensions]
6 > eol =
7 >
8 > [hooks]
5 > [hooks]
9 > pretxnchangegroup = python:hgext.eol.hook
6 > pretxnchangegroup = python:hgext.eol.hook
10 > EOF
7 > EOF
11 $ hg clone main fork
8 $ hg clone main fork
12 updating to branch default
9 updating to branch default
13 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
10 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 $ cd fork
11 $ cd fork
15
12
16 Create repo
13 Create repo
17 $ cat > .hgeol <<EOF
14 $ cat > .hgeol <<EOF
18 > [patterns]
15 > [patterns]
19 > mixed.txt = BIN
16 > mixed.txt = BIN
20 > crlf.txt = CRLF
17 > crlf.txt = CRLF
21 > **.txt = native
18 > **.txt = native
22 > EOF
19 > EOF
23 $ hg add .hgeol
20 $ hg add .hgeol
24 $ hg commit -m 'Commit .hgeol'
21 $ hg commit -m 'Commit .hgeol'
25
22
26 $ printf "first\nsecond\nthird\n" > a.txt
23 $ printf "first\nsecond\nthird\n" > a.txt
27 $ hg add a.txt
24 $ hg add a.txt
28 $ hg commit -m 'LF a.txt'
25 $ hg commit -m 'LF a.txt'
29 $ hg push ../main
26 $ hg push ../main
30 pushing to ../main
27 pushing to ../main
31 searching for changes
28 searching for changes
32 adding changesets
29 adding changesets
33 adding manifests
30 adding manifests
34 adding file changes
31 adding file changes
35 added 2 changesets with 2 changes to 2 files
32 added 2 changesets with 2 changes to 2 files
36
33
37 $ printf "first\r\nsecond\r\nthird\n" > a.txt
34 $ printf "first\r\nsecond\r\nthird\n" > a.txt
38 $ hg commit -m 'CRLF a.txt'
35 $ hg commit -m 'CRLF a.txt'
39 $ hg push ../main
36 $ hg push ../main
40 pushing to ../main
37 pushing to ../main
41 searching for changes
38 searching for changes
42 adding changesets
39 adding changesets
43 adding manifests
40 adding manifests
44 adding file changes
41 adding file changes
45 added 1 changesets with 1 changes to 1 files
42 added 1 changesets with 1 changes to 1 files
46 error: pretxnchangegroup hook failed: a.txt should not have CRLF line endings
43 error: pretxnchangegroup hook failed: a.txt should not have CRLF line endings
47 transaction abort!
44 transaction abort!
48 rollback completed
45 rollback completed
49 abort: a.txt should not have CRLF line endings
46 abort: a.txt should not have CRLF line endings
50 [255]
47 [255]
51
48
52 $ printf "first\nsecond\nthird\n" > a.txt
49 $ printf "first\nsecond\nthird\n" > a.txt
53 $ hg commit -m 'LF a.txt (fixed)'
50 $ hg commit -m 'LF a.txt (fixed)'
54 $ hg push ../main
51 $ hg push ../main
55 pushing to ../main
52 pushing to ../main
56 searching for changes
53 searching for changes
57 adding changesets
54 adding changesets
58 adding manifests
55 adding manifests
59 adding file changes
56 adding file changes
60 added 2 changesets with 2 changes to 1 files
57 added 2 changesets with 2 changes to 1 files
61
58
62 $ printf "first\nsecond\nthird\n" > crlf.txt
59 $ printf "first\nsecond\nthird\n" > crlf.txt
63 $ hg add crlf.txt
60 $ hg add crlf.txt
64 $ hg commit -m 'LF crlf.txt'
61 $ hg commit -m 'LF crlf.txt'
65 $ hg push ../main
62 $ hg push ../main
66 pushing to ../main
63 pushing to ../main
67 searching for changes
64 searching for changes
68 adding changesets
65 adding changesets
69 adding manifests
66 adding manifests
70 adding file changes
67 adding file changes
71 added 1 changesets with 1 changes to 1 files
68 added 1 changesets with 1 changes to 1 files
72 error: pretxnchangegroup hook failed: crlf.txt should not have LF line endings
69 error: pretxnchangegroup hook failed: crlf.txt should not have LF line endings
73 transaction abort!
70 transaction abort!
74 rollback completed
71 rollback completed
75 abort: crlf.txt should not have LF line endings
72 abort: crlf.txt should not have LF line endings
76 [255]
73 [255]
77
74
78 $ printf "first\r\nsecond\r\nthird\r\n" > crlf.txt
75 $ printf "first\r\nsecond\r\nthird\r\n" > crlf.txt
79 $ hg commit -m 'CRLF crlf.txt (fixed)'
76 $ hg commit -m 'CRLF crlf.txt (fixed)'
80 $ hg push ../main
77 $ hg push ../main
81 pushing to ../main
78 pushing to ../main
82 searching for changes
79 searching for changes
83 adding changesets
80 adding changesets
84 adding manifests
81 adding manifests
85 adding file changes
82 adding file changes
86 added 2 changesets with 2 changes to 1 files
83 added 2 changesets with 2 changes to 1 files
General Comments 0
You need to be logged in to leave comments. Login now