##// END OF EJS Templates
eol: extension for managing file EOLs
Martin Geisler -
r11249:0bb67503 stable
parent child Browse files
Show More
@@ -0,0 +1,256 b''
1 """automatically manage newlines in repository files
2
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
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.
7
8 The extension reads its configuration from a versioned ``.hgeol``
9 configuration file every time you run an ``hg`` command. The
10 ``.hgeol`` file use the same syntax as all other Mercurial
11 configuration files. It uses two sections, ``[patterns]`` and
12 ``[repository]``.
13
14 The ``[patterns]`` section specifies the line endings used in the
15 working directory. The format is specified by a file pattern. The
16 first match is used, so put more specific patterns first. The
17 available line endings are ``LF``, ``CRLF``, and ``BIN``.
18
19 Files with the declared format of ``CRLF`` or ``LF`` are always
20 checked out in that format and files declared to be binary (``BIN``)
21 are left unchanged. Additionally, ``native`` is an alias for the
22 platform's default line ending: ``LF`` on Unix (including Mac OS X)
23 and ``CRLF`` on Windows. Note that ``BIN`` (do nothing to line
24 endings) is Mercurial's default behaviour; it is only needed if you
25 need to override a later, more general pattern.
26
27 The optional ``[repository]`` section specifies the line endings to
28 use for files stored in the repository. It has a single setting,
29 ``native``, which determines the storage line endings for files
30 declared as ``native`` in the ``[patterns]`` section. It can be set to
31 ``LF`` or ``CRLF``. The default is ``LF``. For example, this means
32 that on Windows, files configured as ``native`` (``CRLF`` by default)
33 will be converted to ``LF`` when stored in the repository. Files
34 declared as ``LF``, ``CRLF``, or ``BIN`` in the ``[patterns]`` section
35 are always stored as-is in the repository.
36
37 Example versioned ``.hgeol`` file::
38
39 [patterns]
40 **.py = native
41 **.vcproj = CRLF
42 **.txt = native
43 Makefile = LF
44 **.jpg = BIN
45
46 [repository]
47 native = LF
48
49 The extension uses an optional ``[eol]`` section in your hgrc file
50 (not the ``.hgeol`` file) for settings that control the overall
51 behavior. There are two settings:
52
53 - ``eol.native`` (default ``os.linesep``) can be set to ``LF`` or
54 ``CRLF`` override the default interpretation of ``native`` for
55 checkout. This can be used with :hg:`archive` on Unix, say, to
56 generate an archive where files have line endings for Windows.
57
58 - ``eol.only-consistent`` (default True) can be set to False to make
59 the extension convert files with inconsistent EOLs. Inconsistent
60 means that there is both ``CRLF`` and ``LF`` present in the file.
61 Such files are normally not touched under the assumption that they
62 have mixed EOLs on purpose.
63
64 See :hg:`help patterns` for more information about the glob patterns
65 used.
66 """
67
68 from mercurial.i18n import _
69 from mercurial import util, config, extensions, commands, match, cmdutil
70 import re, os
71
72 # Matches a lone LF, i.e., one that is not part of CRLF.
73 singlelf = re.compile('(^|[^\r])\n')
74 # Matches a single EOL which can either be a CRLF where repeated CR
75 # are removed or a LF. We do not care about old Machintosh files, so a
76 # stray CR is an error.
77 eolre = re.compile('\r*\n')
78
79
80 def inconsistenteol(data):
81 return '\r\n' in data and singlelf.search(data)
82
83 def tolf(s, params, ui, **kwargs):
84 """Filter to convert to LF EOLs."""
85 if util.binary(s):
86 return s
87 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
88 return s
89 return eolre.sub('\n', s)
90
91 def tocrlf(s, params, ui, **kwargs):
92 """Filter to convert to CRLF EOLs."""
93 if util.binary(s):
94 return s
95 if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
96 return s
97 return eolre.sub('\r\n', s)
98
99 def isbinary(s, params):
100 """Filter to do nothing with the file."""
101 return s
102
103 filters = {
104 'to-lf': tolf,
105 'to-crlf': tocrlf,
106 'is-binary': isbinary,
107 }
108
109
110 def hook(ui, repo, node, hooktype, **kwargs):
111 """verify that files have expected EOLs"""
112 files = set()
113 for rev in xrange(repo[node].rev(), len(repo)):
114 files.update(repo[rev].files())
115 tip = repo['tip']
116 for f in files:
117 if f not in tip:
118 continue
119 for pattern, target in ui.configitems('encode'):
120 if match.match(repo.root, '', [pattern])(f):
121 data = tip[f].data()
122 if target == "to-lf" and "\r\n" in data:
123 raise util.Abort(_("%s should not have CRLF line endings")
124 % f)
125 elif target == "to-crlf" and singlelf.search(data):
126 raise util.Abort(_("%s should not have LF line endings")
127 % f)
128
129
130 def preupdate(ui, repo, hooktype, parent1, parent2):
131 #print "preupdate for %s: %s -> %s" % (repo.root, parent1, parent2)
132 repo.readhgeol(parent1)
133 return False
134
135 def uisetup(ui):
136 ui.setconfig('hooks', 'preupdate.eol', preupdate)
137
138 def extsetup(ui):
139 try:
140 extensions.find('win32text')
141 raise util.Abort(_("the eol extension is incompatible with the "
142 "win32text extension"))
143 except KeyError:
144 pass
145
146
147 def reposetup(ui, repo):
148 #print "reposetup for", repo.root
149
150 if not repo.local():
151 return
152 for name, fn in filters.iteritems():
153 repo.adddatafilter(name, fn)
154
155 ui.setconfig('patch', 'eol', 'auto')
156
157 class eolrepo(repo.__class__):
158
159 _decode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
160 _encode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
161
162 def readhgeol(self, node=None, data=None):
163 if data is None:
164 try:
165 if node is None:
166 data = self.wfile('.hgeol').read()
167 else:
168 data = self[node]['.hgeol'].data()
169 except (IOError, LookupError):
170 return None
171
172 if self.ui.config('eol', 'native', os.linesep) in ('LF', '\n'):
173 self._decode['NATIVE'] = 'to-lf'
174 else:
175 self._decode['NATIVE'] = 'to-crlf'
176
177 eol = config.config()
178 eol.parse('.hgeol', data)
179
180 if eol.get('repository', 'native') == 'CRLF':
181 self._encode['NATIVE'] = 'to-crlf'
182 else:
183 self._encode['NATIVE'] = 'to-lf'
184
185 for pattern, style in eol.items('patterns'):
186 key = style.upper()
187 try:
188 self.ui.setconfig('decode', pattern, self._decode[key])
189 self.ui.setconfig('encode', pattern, self._encode[key])
190 except KeyError:
191 self.ui.warn(_("ignoring unknown EOL style '%s' from %s\n")
192 % (style, eol.source('patterns', pattern)))
193
194 include = []
195 exclude = []
196 for pattern, style in eol.items('patterns'):
197 key = style.upper()
198 if key == 'BIN':
199 exclude.append(pattern)
200 else:
201 include.append(pattern)
202
203 # This will match the files for which we need to care
204 # about inconsistent newlines.
205 return match.match(self.root, '', [], include, exclude)
206
207 def _hgcleardirstate(self):
208 self._eolfile = self.readhgeol() or self.readhgeol('tip')
209
210 if not self._eolfile:
211 self._eolfile = util.never
212 return
213
214 try:
215 cachemtime = os.path.getmtime(self.join("eol.cache"))
216 except OSError:
217 cachemtime = 0
218
219 try:
220 eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
221 except OSError:
222 eolmtime = 0
223
224 if eolmtime > cachemtime:
225 ui.debug("eol: detected change in .hgeol\n")
226 # TODO: we could introduce a method for this in dirstate.
227 wlock = None
228 try:
229 wlock = self.wlock()
230 for f, e in self.dirstate._map.iteritems():
231 self.dirstate._map[f] = (e[0], e[1], -1, 0)
232 self.dirstate._dirty = True
233 # Touch the cache to update mtime. TODO: are we sure this
234 # always enought to update the mtime, or should we write a
235 # bit to the file?
236 self.opener("eol.cache", "w").close()
237 finally:
238 if wlock is not None:
239 wlock.release()
240
241 def commitctx(self, ctx, error=False):
242 for f in sorted(ctx.added() + ctx.modified()):
243 if not self._eolfile(f):
244 continue
245 data = ctx[f].data()
246 if util.binary(data):
247 # We should not abort here, since the user should
248 # be able to say "** = native" to automatically
249 # have all non-binary files taken care of.
250 continue
251 if inconsistenteol(data):
252 raise util.Abort(_("inconsistent newline style "
253 "in %s\n" % f))
254 return super(eolrepo, self).commitctx(ctx, error)
255 repo.__class__ = eolrepo
256 repo._hgcleardirstate()
@@ -0,0 +1,180 b''
1 #!/bin/sh
2
3 cat > $HGRCPATH <<EOF
4 [diff]
5 git = True
6 EOF
7
8 cat > switch-eol.py <<EOF
9 import sys
10
11 try:
12 import os, msvcrt
13 msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
14 msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
15 except ImportError:
16 pass
17
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)
20 for path in sys.argv[2:]:
21 data = file(path, 'rb').read()
22 data = data.replace(old, new)
23 file(path, 'wb').write(data)
24 EOF
25
26 seteol () {
27 if [ $1 = "LF" ]; then
28 EOL='\n'
29 else
30 EOL='\r\n'
31 fi
32 }
33
34 makerepo () {
35 seteol $1
36 echo "% setup $1 repository"
37 hg init repo
38 cd repo
39
40 cat > .hgeol <<EOF
41 [repository]
42 native = $1
43
44 [patterns]
45 mixed.txt = BIN
46 **.txt = native
47 EOF
48
49 printf "first${EOL}second${EOL}third${EOL}" > a.txt
50 hg commit --addremove -m 'checkin'
51 echo
52 cd ..
53 }
54
55 dotest () {
56 seteol $1
57 echo "% hg clone repo repo-$1"
58 hg clone --noupdate repo repo-$1
59 cd repo-$1
60
61 cat > .hg/hgrc <<EOF
62 [extensions]
63 eol =
64
65 [eol]
66 native = $1
67 EOF
68
69 hg update
70 echo '% printrepr.py a.txt'
71 python $TESTDIR/printrepr.py < a.txt
72 echo '% hg cat a.txt'
73 hg cat a.txt | python $TESTDIR/printrepr.py
74
75 printf "fourth${EOL}" >> a.txt
76 echo '% printrepr.py a.txt'
77 python $TESTDIR/printrepr.py < a.txt
78 hg diff | python $TESTDIR/printrepr.py
79
80 python ../switch-eol.py $1 a.txt
81 echo '% hg diff only reports a single changed line:'
82 hg diff | python $TESTDIR/printrepr.py
83
84 echo "% reverting back to $1 format"
85 hg revert a.txt
86 python $TESTDIR/printrepr.py < a.txt
87
88 printf "first\r\nsecond\n" > mixed.txt
89 hg add mixed.txt
90 echo "% hg commit of inconsistent .txt file marked as binary (should work)"
91 hg commit -m 'binary file'
92
93 echo "% hg commit of inconsistent .txt file marked as native (should fail)"
94 printf "first\nsecond\r\nthird\nfourth\r\n" > a.txt
95 hg commit -m 'inconsistent file'
96
97 echo "% hg commit --config eol.only-consistent=False (should work)"
98 hg commit --config eol.only-consistent=False -m 'inconsistent file'
99
100 echo "% hg commit of binary .txt file marked as native (binary files always okay)"
101 printf "first${EOL}\0${EOL}third${EOL}" > a.txt
102 hg commit -m 'binary file'
103
104 cd ..
105 rm -r repo-$1
106 }
107
108 makerepo LF
109 dotest LF
110 dotest CRLF
111 rm -r repo
112
113 makerepo CRLF
114 dotest LF
115 dotest CRLF
116 rm -r repo
117
118
119 makemixedrepo () {
120 echo
121 echo "# setup $1 repository"
122 hg init mixed
123 cd mixed
124 printf "foo\r\nbar\r\nbaz\r\n" > win.txt
125 printf "foo\nbar\nbaz\n" > unix.txt
126 #printf "foo\r\nbar\nbaz\r\n" > mixed.txt
127
128 hg commit --addremove -m 'created mixed files'
129
130 echo "# setting repository-native EOLs to $1"
131 cat > .hgeol <<EOF
132 [repository]
133 native = $1
134
135 [patterns]
136 **.txt = native
137 EOF
138 hg commit --addremove -m 'added .hgeol'
139 cd ..
140 }
141
142 testmixed () {
143 echo
144 echo "% hg clone mixed mixed-$1"
145 hg clone mixed mixed-$1
146 cd mixed-$1
147
148 echo '% hg status (eol extension not yet activated)'
149 hg status
150
151 cat > .hg/hgrc <<EOF
152 [extensions]
153 eol =
154
155 [eol]
156 native = $1
157 EOF
158
159 echo '% hg status (eol activated)'
160 hg status
161 echo '% hg commit'
162 hg commit -m 'synchronized EOLs'
163
164 echo '% hg status'
165 hg status
166
167 cd ..
168 rm -r mixed-$1
169 }
170
171 makemixedrepo LF
172 testmixed LF
173 testmixed CRLF
174 rm -r mixed
175
176 makemixedrepo CRLF
177 testmixed LF
178 testmixed CRLF
179 rm -r mixed
180
@@ -0,0 +1,73 b''
1 #!/bin/sh
2
3 cat > $HGRCPATH <<EOF
4 [diff]
5 git = 1
6 EOF
7
8 seteol () {
9 if [ $1 = "LF" ]; then
10 EOL='\n'
11 else
12 EOL='\r\n'
13 fi
14 }
15
16 makerepo () {
17 echo
18 echo "# ==== setup repository ===="
19 echo '% hg init'
20 hg init repo
21 cd repo
22
23 printf "first\nsecond\nthird\n" > a.txt
24 hg commit -d '100 0' --addremove -m 'LF commit'
25 cd ..
26 }
27
28 dotest () {
29 seteol $1
30
31 echo
32 echo "% hg clone repo repo-$1"
33 hg clone repo repo-$1
34 cd repo-$1
35
36 cat > .hg/hgrc <<EOF
37 [extensions]
38 eol =
39
40 [eol]
41 native = LF
42 EOF
43
44 cat > .hgeol <<EOF
45 [patterns]
46 **.txt = native
47
48 [repository]
49 native = $1
50 EOF
51
52 echo '% hg add .hgeol'
53 hg add .hgeol
54 echo '% hg status'
55 hg status
56
57 echo '% hg commit'
58 hg commit -d '200 0' -m 'Added .hgeol file'
59
60 echo '% hg status'
61 hg status
62
63 echo '% hg tip -p'
64 hg tip -p | python $TESTDIR/printrepr.py
65
66 cd ..
67 rm -r repo-$1
68 }
69
70 makerepo
71 dotest LF
72 dotest CRLF
73 rm -r repo
@@ -0,0 +1,69 b''
1
2 # ==== setup repository ====
3 % hg init
4 adding a.txt
5
6 % hg clone repo repo-LF
7 updating to branch default
8 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
9 % hg add .hgeol
10 % hg status
11 A .hgeol
12 % hg commit
13 % hg status
14 % hg tip -p
15 changeset: 1:34614fc6dc02
16 tag: tip
17 user: test
18 date: Thu Jan 01 00:03:20 1970 +0000
19 summary: Added .hgeol file
20
21 diff --git a/.hgeol b/.hgeol
22 new file mode 100644
23 --- /dev/null
24 +++ b/.hgeol
25 @@ -0,0 +1,5 @@
26 +[patterns]
27 +**.txt = native
28 +
29 +[repository]
30 +native = LF
31
32
33 % hg clone repo repo-CRLF
34 updating to branch default
35 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
36 % hg add .hgeol
37 % hg status
38 M a.txt
39 A .hgeol
40 % hg commit
41 % hg status
42 % hg tip -p
43 changeset: 1:4bbdacd3fe39
44 tag: tip
45 user: test
46 date: Thu Jan 01 00:03:20 1970 +0000
47 summary: Added .hgeol file
48
49 diff --git a/.hgeol b/.hgeol
50 new file mode 100644
51 --- /dev/null
52 +++ b/.hgeol
53 @@ -0,0 +1,5 @@
54 +[patterns]
55 +**.txt = native
56 +
57 +[repository]
58 +native = CRLF
59 diff --git a/a.txt b/a.txt
60 --- a/a.txt
61 +++ b/a.txt
62 @@ -1,3 +1,3 @@
63 -first
64 -second
65 -third
66 +first\r
67 +second\r
68 +third\r
69
@@ -0,0 +1,63 b''
1 #!/bin/sh
2
3 cat > $HGRCPATH <<EOF
4 [diff]
5 git = True
6
7 [extensions]
8 eol =
9
10 [eol]
11 native = CRLF
12 EOF
13
14 echo "% setup repository"
15 hg init repo
16 cd repo
17
18 cat > .hgeol <<EOF
19 [patterns]
20 **.txt = native
21 EOF
22
23 printf "first\r\nsecond\r\nthird\r\n" > a.txt
24 hg commit --addremove -m 'checkin'
25 cd ..
26
27 echo "% hg clone repo repo-2"
28 hg clone repo repo-2
29 cd repo-2
30
31 echo '% printrepr.py a.txt'
32 python $TESTDIR/printrepr.py < a.txt
33 echo '% hg cat a.txt'
34 hg cat a.txt | python $TESTDIR/printrepr.py
35
36 hg remove .hgeol
37 hg commit -m 'remove eol'
38 hg push --quiet
39
40 cd ..
41
42 # Test clone of repo with .hgeol in working dir, but no .hgeol in tip
43 echo "% hg clone repo repo-3"
44 hg clone repo repo-3
45 cd repo-3
46
47 echo '% printrepr.py a.txt'
48 python $TESTDIR/printrepr.py < a.txt
49
50 cd ..
51
52 # Test clone of revision with .hgeol
53 echo "% hg clone -r 1 repo repo-4"
54 hg clone -r 0 repo repo-4
55 cd repo-4
56
57 echo '% cat .hgeol'
58 cat .hgeol
59
60 echo '% printrepr.py a.txt'
61 python $TESTDIR/printrepr.py < a.txt
62
63 cd ..
@@ -0,0 +1,36 b''
1 % setup repository
2 adding .hgeol
3 adding a.txt
4 % hg clone repo repo-2
5 updating to branch default
6 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
7 % printrepr.py a.txt
8 first\r
9 second\r
10 third\r
11 % hg cat a.txt
12 first
13 second
14 third
15 % hg clone repo repo-3
16 updating to branch default
17 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
18 % printrepr.py a.txt
19 first
20 second
21 third
22 % hg clone -r 1 repo repo-4
23 requesting all changes
24 adding changesets
25 adding manifests
26 adding file changes
27 added 1 changesets with 2 changes to 2 files
28 updating to branch default
29 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
30 % cat .hgeol
31 [patterns]
32 **.txt = native
33 % printrepr.py a.txt
34 first\r
35 second\r
36 third\r
@@ -0,0 +1,47 b''
1 #!/bin/sh
2
3 cat > $HGRCPATH <<EOF
4 [diff]
5 git = True
6 EOF
7
8 hg init main
9 cat > main/.hg/hgrc <<EOF
10 [extensions]
11 eol =
12
13 [hooks]
14 pretxnchangegroup = python:hgext.eol.hook
15 EOF
16
17 hg clone main fork
18
19 cd fork
20 cat > .hgeol <<EOF
21 [patterns]
22 mixed.txt = BIN
23 **.txt = native
24 EOF
25
26 hg add .hgeol
27 hg commit -m 'Commit .hgeol'
28
29 printf "first\nsecond\nthird\n" > a.txt
30 hg add a.txt
31 echo "% hg commit (LF a.txt)"
32 hg commit -m 'LF a.txt'
33 echo "% hg push"
34 hg push ../main
35
36 printf "first\r\nsecond\r\nthird\n" > a.txt
37 echo "% hg commit (CRLF a.txt)"
38 hg commit -m 'CRLF a.txt'
39 echo "% hg push"
40 hg push ../main
41
42
43 echo "% hg commit (LF a.txt)"
44 printf "first\nsecond\nthird\n" > a.txt
45 hg commit -m 'LF a.txt (fixed)'
46 echo "% hg push"
47 hg push ../main
@@ -0,0 +1,30 b''
1 updating to branch default
2 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 % hg commit (LF a.txt)
4 % hg push
5 pushing to ../main
6 searching for changes
7 adding changesets
8 adding manifests
9 adding file changes
10 added 2 changesets with 2 changes to 2 files
11 % hg commit (CRLF a.txt)
12 % hg push
13 pushing to ../main
14 searching for changes
15 adding changesets
16 adding manifests
17 adding file changes
18 added 1 changesets with 1 changes to 1 files
19 error: pretxnchangegroup hook failed: a.txt should not have CRLF line endings
20 transaction abort!
21 rollback completed
22 abort: a.txt should not have CRLF line endings
23 % hg commit (LF a.txt)
24 % hg push
25 pushing to ../main
26 searching for changes
27 adding changesets
28 adding manifests
29 adding file changes
30 added 2 changesets with 2 changes to 1 files
@@ -0,0 +1,103 b''
1 #!/bin/sh
2
3 cat > $HGRCPATH <<EOF
4 [diff]
5 git = 1
6 EOF
7
8 seteol () {
9 if [ $1 = "LF" ]; then
10 EOL='\n'
11 else
12 EOL='\r\n'
13 fi
14 }
15
16 makerepo () {
17 seteol $1
18 echo
19 echo "# ==== setup $1 repository ===="
20 echo '% hg init'
21 hg init repo
22 cd repo
23
24 cat > .hgeol <<EOF
25 [repository]
26 native = $1
27
28 [patterns]
29 unix.txt = LF
30 win.txt = CRLF
31 **.txt = native
32 EOF
33
34 printf "first\r\nsecond\r\nthird\r\n" > win.txt
35 printf "first\nsecond\nthird\n" > unix.txt
36 printf "first${EOL}second${EOL}third${EOL}" > native.txt
37 hg commit --addremove -m 'checkin'
38 cd ..
39 }
40
41 dotest () {
42 seteol $1
43
44 echo
45 echo "% hg clone repo repo-$1"
46 hg clone --noupdate repo repo-$1
47 cd repo-$1
48
49 cat > .hg/hgrc <<EOF
50 [extensions]
51 eol =
52
53 [eol]
54 native = $1
55 EOF
56
57 hg update
58 echo '% printrepr.py native.txt'
59 python $TESTDIR/printrepr.py < native.txt
60
61 echo '% printrepr.py unix.txt'
62 python $TESTDIR/printrepr.py < unix.txt
63
64 echo '% printrepr.py win.txt'
65 python $TESTDIR/printrepr.py < win.txt
66
67 printf "first${EOL}third${EOL}" > native.txt
68 printf "first\r\nthird\r\n" > win.txt
69 printf "first\nthird\n" > unix.txt
70
71 echo '% hg diff'
72 hg diff > p
73 python $TESTDIR/printrepr.py < p
74
75 echo '% hg revert'
76 hg revert --all
77
78 echo '% hg import'
79 hg import -m 'patch' p
80
81 echo '% printrepr.py native.txt'
82 python $TESTDIR/printrepr.py < native.txt
83 echo '% printrepr.py unix.txt'
84 python $TESTDIR/printrepr.py < unix.txt
85 echo '% printrepr.py win.txt'
86 python $TESTDIR/printrepr.py < win.txt
87
88 echo '% hg diff -c tip'
89 hg diff -c tip | python $TESTDIR/printrepr.py
90
91 cd ..
92 rm -r repo-$1
93 }
94
95 makerepo LF
96 dotest LF
97 dotest CRLF
98 rm -r repo
99
100 makerepo CRLF
101 dotest LF
102 dotest CRLF
103 rm -r repo
@@ -0,0 +1,310 b''
1
2 # ==== setup LF repository ====
3 % hg init
4 adding .hgeol
5 adding native.txt
6 adding unix.txt
7 adding win.txt
8
9 % hg clone repo repo-LF
10 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
11 % printrepr.py native.txt
12 first
13 second
14 third
15 % printrepr.py unix.txt
16 first
17 second
18 third
19 % printrepr.py win.txt
20 first\r
21 second\r
22 third\r
23 % hg diff
24 diff --git a/native.txt b/native.txt
25 --- a/native.txt
26 +++ b/native.txt
27 @@ -1,3 +1,2 @@
28 first
29 -second
30 third
31 diff --git a/unix.txt b/unix.txt
32 --- a/unix.txt
33 +++ b/unix.txt
34 @@ -1,3 +1,2 @@
35 first
36 -second
37 third
38 diff --git a/win.txt b/win.txt
39 --- a/win.txt
40 +++ b/win.txt
41 @@ -1,3 +1,2 @@
42 first\r
43 -second\r
44 third\r
45 % hg revert
46 reverting native.txt
47 reverting unix.txt
48 reverting win.txt
49 % hg import
50 applying p
51 % printrepr.py native.txt
52 first
53 third
54 % printrepr.py unix.txt
55 first
56 third
57 % printrepr.py win.txt
58 first\r
59 third\r
60 % hg diff -c tip
61 diff --git a/native.txt b/native.txt
62 --- a/native.txt
63 +++ b/native.txt
64 @@ -1,3 +1,2 @@
65 first
66 -second
67 third
68 diff --git a/unix.txt b/unix.txt
69 --- a/unix.txt
70 +++ b/unix.txt
71 @@ -1,3 +1,2 @@
72 first
73 -second
74 third
75 diff --git a/win.txt b/win.txt
76 --- a/win.txt
77 +++ b/win.txt
78 @@ -1,3 +1,2 @@
79 first\r
80 -second\r
81 third\r
82
83 % hg clone repo repo-CRLF
84 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
85 % printrepr.py native.txt
86 first\r
87 second\r
88 third\r
89 % printrepr.py unix.txt
90 first
91 second
92 third
93 % printrepr.py win.txt
94 first\r
95 second\r
96 third\r
97 % hg diff
98 diff --git a/native.txt b/native.txt
99 --- a/native.txt
100 +++ b/native.txt
101 @@ -1,3 +1,2 @@
102 first
103 -second
104 third
105 diff --git a/unix.txt b/unix.txt
106 --- a/unix.txt
107 +++ b/unix.txt
108 @@ -1,3 +1,2 @@
109 first
110 -second
111 third
112 diff --git a/win.txt b/win.txt
113 --- a/win.txt
114 +++ b/win.txt
115 @@ -1,3 +1,2 @@
116 first\r
117 -second\r
118 third\r
119 % hg revert
120 reverting native.txt
121 reverting unix.txt
122 reverting win.txt
123 % hg import
124 applying p
125 % printrepr.py native.txt
126 first\r
127 third\r
128 % printrepr.py unix.txt
129 first
130 third
131 % printrepr.py win.txt
132 first\r
133 third\r
134 % hg diff -c tip
135 diff --git a/native.txt b/native.txt
136 --- a/native.txt
137 +++ b/native.txt
138 @@ -1,3 +1,2 @@
139 first
140 -second
141 third
142 diff --git a/unix.txt b/unix.txt
143 --- a/unix.txt
144 +++ b/unix.txt
145 @@ -1,3 +1,2 @@
146 first
147 -second
148 third
149 diff --git a/win.txt b/win.txt
150 --- a/win.txt
151 +++ b/win.txt
152 @@ -1,3 +1,2 @@
153 first\r
154 -second\r
155 third\r
156
157 # ==== setup CRLF repository ====
158 % hg init
159 adding .hgeol
160 adding native.txt
161 adding unix.txt
162 adding win.txt
163
164 % hg clone repo repo-LF
165 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
166 % printrepr.py native.txt
167 first
168 second
169 third
170 % printrepr.py unix.txt
171 first
172 second
173 third
174 % printrepr.py win.txt
175 first\r
176 second\r
177 third\r
178 % hg diff
179 diff --git a/native.txt b/native.txt
180 --- a/native.txt
181 +++ b/native.txt
182 @@ -1,3 +1,2 @@
183 first\r
184 -second\r
185 third\r
186 diff --git a/unix.txt b/unix.txt
187 --- a/unix.txt
188 +++ b/unix.txt
189 @@ -1,3 +1,2 @@
190 first
191 -second
192 third
193 diff --git a/win.txt b/win.txt
194 --- a/win.txt
195 +++ b/win.txt
196 @@ -1,3 +1,2 @@
197 first\r
198 -second\r
199 third\r
200 % hg revert
201 reverting native.txt
202 reverting unix.txt
203 reverting win.txt
204 % hg import
205 applying p
206 % printrepr.py native.txt
207 first
208 third
209 % printrepr.py unix.txt
210 first
211 third
212 % printrepr.py win.txt
213 first\r
214 third\r
215 % hg diff -c tip
216 diff --git a/native.txt b/native.txt
217 --- a/native.txt
218 +++ b/native.txt
219 @@ -1,3 +1,2 @@
220 first\r
221 -second\r
222 third\r
223 diff --git a/unix.txt b/unix.txt
224 --- a/unix.txt
225 +++ b/unix.txt
226 @@ -1,3 +1,2 @@
227 first
228 -second
229 third
230 diff --git a/win.txt b/win.txt
231 --- a/win.txt
232 +++ b/win.txt
233 @@ -1,3 +1,2 @@
234 first\r
235 -second\r
236 third\r
237
238 % hg clone repo repo-CRLF
239 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
240 % printrepr.py native.txt
241 first\r
242 second\r
243 third\r
244 % printrepr.py unix.txt
245 first
246 second
247 third
248 % printrepr.py win.txt
249 first\r
250 second\r
251 third\r
252 % hg diff
253 diff --git a/native.txt b/native.txt
254 --- a/native.txt
255 +++ b/native.txt
256 @@ -1,3 +1,2 @@
257 first\r
258 -second\r
259 third\r
260 diff --git a/unix.txt b/unix.txt
261 --- a/unix.txt
262 +++ b/unix.txt
263 @@ -1,3 +1,2 @@
264 first
265 -second
266 third
267 diff --git a/win.txt b/win.txt
268 --- a/win.txt
269 +++ b/win.txt
270 @@ -1,3 +1,2 @@
271 first\r
272 -second\r
273 third\r
274 % hg revert
275 reverting native.txt
276 reverting unix.txt
277 reverting win.txt
278 % hg import
279 applying p
280 % printrepr.py native.txt
281 first\r
282 third\r
283 % printrepr.py unix.txt
284 first
285 third
286 % printrepr.py win.txt
287 first\r
288 third\r
289 % hg diff -c tip
290 diff --git a/native.txt b/native.txt
291 --- a/native.txt
292 +++ b/native.txt
293 @@ -1,3 +1,2 @@
294 first\r
295 -second\r
296 third\r
297 diff --git a/unix.txt b/unix.txt
298 --- a/unix.txt
299 +++ b/unix.txt
300 @@ -1,3 +1,2 @@
301 first
302 -second
303 third
304 diff --git a/win.txt b/win.txt
305 --- a/win.txt
306 +++ b/win.txt
307 @@ -1,3 +1,2 @@
308 first\r
309 -second\r
310 third\r
@@ -0,0 +1,83 b''
1 #!/bin/sh
2
3 cat > $HGRCPATH <<EOF
4 [diff]
5 git = 1
6 EOF
7
8 seteol () {
9 if [ $1 = "LF" ]; then
10 EOL='\n'
11 else
12 EOL='\r\n'
13 fi
14 }
15
16 makerepo () {
17 echo
18 echo "# ==== setup repository ===="
19 echo '% hg init'
20 hg init repo
21 cd repo
22
23 cat > .hgeol <<EOF
24 [patterns]
25 **.txt = LF
26 EOF
27
28 printf "first\nsecond\nthird\n" > a.txt
29 hg commit --addremove -m 'LF commit'
30
31 cat > .hgeol <<EOF
32 [patterns]
33 **.txt = CRLF
34 EOF
35
36 printf "first\r\nsecond\r\nthird\r\n" > a.txt
37 hg commit -m 'CRLF commit'
38
39 cd ..
40 }
41
42 dotest () {
43 seteol $1
44
45 echo
46 echo "% hg clone repo repo-$1"
47 hg clone --noupdate repo repo-$1
48 cd repo-$1
49
50 cat > .hg/hgrc <<EOF
51 [extensions]
52 eol =
53 EOF
54
55 hg update
56
57 echo '% printrepr.py a.txt (before)'
58 python $TESTDIR/printrepr.py < a.txt
59
60 printf "first${EOL}third${EOL}" > a.txt
61
62 echo '% printrepr.py a.txt (after)'
63 python $TESTDIR/printrepr.py < a.txt
64 echo '% hg diff'
65 hg diff | python $TESTDIR/printrepr.py
66
67 echo '% hg update 0'
68 hg update 0
69
70 echo '% printrepr.py a.txt'
71 python $TESTDIR/printrepr.py < a.txt
72 echo '% hg diff'
73 hg diff | python $TESTDIR/printrepr.py
74
75
76 cd ..
77 rm -r repo-$1
78 }
79
80 makerepo
81 dotest LF
82 dotest CRLF
83 rm -r repo
@@ -0,0 +1,69 b''
1
2 # ==== setup repository ====
3 % hg init
4 adding .hgeol
5 adding a.txt
6
7 % hg clone repo repo-LF
8 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
9 % printrepr.py a.txt (before)
10 first\r
11 second\r
12 third\r
13 % printrepr.py a.txt (after)
14 first
15 third
16 % hg diff
17 diff --git a/a.txt b/a.txt
18 --- a/a.txt
19 +++ b/a.txt
20 @@ -1,3 +1,2 @@
21 first\r
22 -second\r
23 third\r
24 % hg update 0
25 merging a.txt
26 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
27 % printrepr.py a.txt
28 first\r
29 third\r
30 % hg diff
31 diff --git a/a.txt b/a.txt
32 --- a/a.txt
33 +++ b/a.txt
34 @@ -1,3 +1,2 @@
35 first
36 -second
37 third
38
39 % hg clone repo repo-CRLF
40 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
41 % printrepr.py a.txt (before)
42 first\r
43 second\r
44 third\r
45 % printrepr.py a.txt (after)
46 first\r
47 third\r
48 % hg diff
49 diff --git a/a.txt b/a.txt
50 --- a/a.txt
51 +++ b/a.txt
52 @@ -1,3 +1,2 @@
53 first\r
54 -second\r
55 third\r
56 % hg update 0
57 merging a.txt
58 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
59 % printrepr.py a.txt
60 first\r
61 third\r
62 % hg diff
63 diff --git a/a.txt b/a.txt
64 --- a/a.txt
65 +++ b/a.txt
66 @@ -1,3 +1,2 @@
67 first
68 -second
69 third
@@ -0,0 +1,228 b''
1 % setup LF repository
2 adding .hgeol
3 adding a.txt
4
5 % hg clone repo repo-LF
6 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
7 % printrepr.py a.txt
8 first
9 second
10 third
11 % hg cat a.txt
12 first
13 second
14 third
15 % printrepr.py a.txt
16 first
17 second
18 third
19 fourth
20 diff --git a/a.txt b/a.txt
21 --- a/a.txt
22 +++ b/a.txt
23 @@ -1,3 +1,4 @@
24 first
25 second
26 third
27 +fourth
28 % switching encoding from '\n' to '\r\n'
29 % hg diff only reports a single changed line:
30 diff --git a/a.txt b/a.txt
31 --- a/a.txt
32 +++ b/a.txt
33 @@ -1,3 +1,4 @@
34 first
35 second
36 third
37 +fourth
38 % reverting back to LF format
39 first
40 second
41 third
42 % hg commit of inconsistent .txt file marked as binary (should work)
43 % hg commit of inconsistent .txt file marked as native (should fail)
44 abort: inconsistent newline style in a.txt
45
46 % hg commit --config eol.only-consistent=False (should work)
47 % hg commit of binary .txt file marked as native (binary files always okay)
48 % hg clone repo repo-CRLF
49 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
50 % printrepr.py a.txt
51 first\r
52 second\r
53 third\r
54 % hg cat a.txt
55 first
56 second
57 third
58 % printrepr.py a.txt
59 first\r
60 second\r
61 third\r
62 fourth\r
63 diff --git a/a.txt b/a.txt
64 --- a/a.txt
65 +++ b/a.txt
66 @@ -1,3 +1,4 @@
67 first
68 second
69 third
70 +fourth
71 % switching encoding from '\r\n' to '\n'
72 % hg diff only reports a single changed line:
73 diff --git a/a.txt b/a.txt
74 --- a/a.txt
75 +++ b/a.txt
76 @@ -1,3 +1,4 @@
77 first
78 second
79 third
80 +fourth
81 % reverting back to CRLF format
82 first\r
83 second\r
84 third\r
85 % hg commit of inconsistent .txt file marked as binary (should work)
86 % hg commit of inconsistent .txt file marked as native (should fail)
87 abort: inconsistent newline style in a.txt
88
89 % hg commit --config eol.only-consistent=False (should work)
90 % hg commit of binary .txt file marked as native (binary files always okay)
91 % setup CRLF repository
92 adding .hgeol
93 adding a.txt
94
95 % hg clone repo repo-LF
96 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
97 % printrepr.py a.txt
98 first
99 second
100 third
101 % hg cat a.txt
102 first\r
103 second\r
104 third\r
105 % printrepr.py a.txt
106 first
107 second
108 third
109 fourth
110 diff --git a/a.txt b/a.txt
111 --- a/a.txt
112 +++ b/a.txt
113 @@ -1,3 +1,4 @@
114 first\r
115 second\r
116 third\r
117 +fourth\r
118 % switching encoding from '\n' to '\r\n'
119 % hg diff only reports a single changed line:
120 diff --git a/a.txt b/a.txt
121 --- a/a.txt
122 +++ b/a.txt
123 @@ -1,3 +1,4 @@
124 first\r
125 second\r
126 third\r
127 +fourth\r
128 % reverting back to LF format
129 first
130 second
131 third
132 % hg commit of inconsistent .txt file marked as binary (should work)
133 % hg commit of inconsistent .txt file marked as native (should fail)
134 abort: inconsistent newline style in a.txt
135
136 % hg commit --config eol.only-consistent=False (should work)
137 % hg commit of binary .txt file marked as native (binary files always okay)
138 % hg clone repo repo-CRLF
139 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 % printrepr.py a.txt
141 first\r
142 second\r
143 third\r
144 % hg cat a.txt
145 first\r
146 second\r
147 third\r
148 % printrepr.py a.txt
149 first\r
150 second\r
151 third\r
152 fourth\r
153 diff --git a/a.txt b/a.txt
154 --- a/a.txt
155 +++ b/a.txt
156 @@ -1,3 +1,4 @@
157 first\r
158 second\r
159 third\r
160 +fourth\r
161 % switching encoding from '\r\n' to '\n'
162 % hg diff only reports a single changed line:
163 diff --git a/a.txt b/a.txt
164 --- a/a.txt
165 +++ b/a.txt
166 @@ -1,3 +1,4 @@
167 first\r
168 second\r
169 third\r
170 +fourth\r
171 % reverting back to CRLF format
172 first\r
173 second\r
174 third\r
175 % hg commit of inconsistent .txt file marked as binary (should work)
176 % hg commit of inconsistent .txt file marked as native (should fail)
177 abort: inconsistent newline style in a.txt
178
179 % hg commit --config eol.only-consistent=False (should work)
180 % hg commit of binary .txt file marked as native (binary files always okay)
181
182 # setup LF repository
183 adding unix.txt
184 adding win.txt
185 # setting repository-native EOLs to LF
186 adding .hgeol
187
188 % hg clone mixed mixed-LF
189 updating to branch default
190 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 % hg status (eol extension not yet activated)
192 % hg status (eol activated)
193 M win.txt
194 % hg commit
195 % hg status
196
197 % hg clone mixed mixed-CRLF
198 updating to branch default
199 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
200 % hg status (eol extension not yet activated)
201 % hg status (eol activated)
202 M win.txt
203 % hg commit
204 % hg status
205
206 # setup CRLF repository
207 adding unix.txt
208 adding win.txt
209 # setting repository-native EOLs to CRLF
210 adding .hgeol
211
212 % hg clone mixed mixed-LF
213 updating to branch default
214 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
215 % hg status (eol extension not yet activated)
216 % hg status (eol activated)
217 M unix.txt
218 % hg commit
219 % hg status
220
221 % hg clone mixed mixed-CRLF
222 updating to branch default
223 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
224 % hg status (eol extension not yet activated)
225 % hg status (eol activated)
226 M unix.txt
227 % hg commit
228 % hg status
General Comments 0
You need to be logged in to leave comments. Login now