##// END OF EJS Templates
win32text: drop associated dirstate cache information on revert...
marmoute -
r49211:f5dea753 default
parent child Browse files
Show More
@@ -1,76 +1,76 b''
1 # narrowdirstate.py - extensions to mercurial dirstate to support narrow clones
1 # narrowdirstate.py - extensions to mercurial dirstate to support narrow clones
2 #
2 #
3 # Copyright 2017 Google, Inc.
3 # Copyright 2017 Google, Inc.
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 from mercurial.i18n import _
10 from mercurial.i18n import _
11 from mercurial import error
11 from mercurial import error
12
12
13
13
14 def wrapdirstate(repo, dirstate):
14 def wrapdirstate(repo, dirstate):
15 """Add narrow spec dirstate ignore, block changes outside narrow spec."""
15 """Add narrow spec dirstate ignore, block changes outside narrow spec."""
16
16
17 def _editfunc(fn):
17 def _editfunc(fn):
18 def _wrapper(self, *args, **kwargs):
18 def _wrapper(self, *args, **kwargs):
19 narrowmatch = repo.narrowmatch()
19 narrowmatch = repo.narrowmatch()
20 for f in args:
20 for f in args:
21 if f is not None and not narrowmatch(f) and f not in self:
21 if f is not None and not narrowmatch(f) and f not in self:
22 raise error.Abort(
22 raise error.Abort(
23 _(
23 _(
24 b"cannot track '%s' - it is outside "
24 b"cannot track '%s' - it is outside "
25 + b"the narrow clone"
25 + b"the narrow clone"
26 )
26 )
27 % f
27 % f
28 )
28 )
29 return fn(self, *args, **kwargs)
29 return fn(self, *args, **kwargs)
30
30
31 return _wrapper
31 return _wrapper
32
32
33 class narrowdirstate(dirstate.__class__):
33 class narrowdirstate(dirstate.__class__):
34 # Prevent adding/editing/copying/deleting files that are outside the
34 # Prevent adding/editing/copying/deleting files that are outside the
35 # sparse checkout
35 # sparse checkout
36 @_editfunc
36 @_editfunc
37 def normal(self, *args, **kwargs):
37 def normal(self, *args, **kwargs):
38 return super(narrowdirstate, self).normal(*args, **kwargs)
38 return super(narrowdirstate, self).normal(*args, **kwargs)
39
39
40 @_editfunc
40 @_editfunc
41 def set_tracked(self, *args):
41 def set_tracked(self, *args, **kwargs):
42 return super(narrowdirstate, self).set_tracked(*args)
42 return super(narrowdirstate, self).set_tracked(*args, **kwargs)
43
43
44 @_editfunc
44 @_editfunc
45 def set_untracked(self, *args):
45 def set_untracked(self, *args):
46 return super(narrowdirstate, self).set_untracked(*args)
46 return super(narrowdirstate, self).set_untracked(*args)
47
47
48 @_editfunc
48 @_editfunc
49 def add(self, *args):
49 def add(self, *args):
50 return super(narrowdirstate, self).add(*args)
50 return super(narrowdirstate, self).add(*args)
51
51
52 @_editfunc
52 @_editfunc
53 def normallookup(self, *args):
53 def normallookup(self, *args):
54 return super(narrowdirstate, self).normallookup(*args)
54 return super(narrowdirstate, self).normallookup(*args)
55
55
56 @_editfunc
56 @_editfunc
57 def copy(self, *args):
57 def copy(self, *args):
58 return super(narrowdirstate, self).copy(*args)
58 return super(narrowdirstate, self).copy(*args)
59
59
60 @_editfunc
60 @_editfunc
61 def remove(self, *args):
61 def remove(self, *args):
62 return super(narrowdirstate, self).remove(*args)
62 return super(narrowdirstate, self).remove(*args)
63
63
64 @_editfunc
64 @_editfunc
65 def merge(self, *args):
65 def merge(self, *args):
66 return super(narrowdirstate, self).merge(*args)
66 return super(narrowdirstate, self).merge(*args)
67
67
68 def rebuild(self, parent, allfiles, changedfiles=None):
68 def rebuild(self, parent, allfiles, changedfiles=None):
69 if changedfiles is None:
69 if changedfiles is None:
70 # Rebuilding entire dirstate, let's filter allfiles to match the
70 # Rebuilding entire dirstate, let's filter allfiles to match the
71 # narrowspec.
71 # narrowspec.
72 allfiles = [f for f in allfiles if repo.narrowmatch()(f)]
72 allfiles = [f for f in allfiles if repo.narrowmatch()(f)]
73 super(narrowdirstate, self).rebuild(parent, allfiles, changedfiles)
73 super(narrowdirstate, self).rebuild(parent, allfiles, changedfiles)
74
74
75 dirstate.__class__ = narrowdirstate
75 dirstate.__class__ = narrowdirstate
76 return dirstate
76 return dirstate
@@ -1,226 +1,246 b''
1 # win32text.py - LF <-> CRLF/CR translation utilities for Windows/Mac users
1 # win32text.py - LF <-> CRLF/CR translation utilities for Windows/Mac users
2 #
2 #
3 # Copyright 2005, 2007-2009 Olivia Mackall <olivia@selenic.com> and others
3 # Copyright 2005, 2007-2009 Olivia Mackall <olivia@selenic.com> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 '''perform automatic newline conversion (DEPRECATED)
8 '''perform automatic newline conversion (DEPRECATED)
9
9
10 Deprecation: The win32text extension requires each user to configure
10 Deprecation: The win32text extension requires each user to configure
11 the extension again and again for each clone since the configuration
11 the extension again and again for each clone since the configuration
12 is not copied when cloning.
12 is not copied when cloning.
13
13
14 We have therefore made the ``eol`` as an alternative. The ``eol``
14 We have therefore made the ``eol`` as an alternative. The ``eol``
15 uses a version controlled file for its configuration and each clone
15 uses a version controlled file for its configuration and each clone
16 will therefore use the right settings from the start.
16 will therefore use the right settings from the start.
17
17
18 To perform automatic newline conversion, use::
18 To perform automatic newline conversion, use::
19
19
20 [extensions]
20 [extensions]
21 win32text =
21 win32text =
22 [encode]
22 [encode]
23 ** = cleverencode:
23 ** = cleverencode:
24 # or ** = macencode:
24 # or ** = macencode:
25
25
26 [decode]
26 [decode]
27 ** = cleverdecode:
27 ** = cleverdecode:
28 # or ** = macdecode:
28 # or ** = macdecode:
29
29
30 If not doing conversion, to make sure you do not commit CRLF/CR by accident::
30 If not doing conversion, to make sure you do not commit CRLF/CR by accident::
31
31
32 [hooks]
32 [hooks]
33 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
33 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
34 # or pretxncommit.cr = python:hgext.win32text.forbidcr
34 # or pretxncommit.cr = python:hgext.win32text.forbidcr
35
35
36 To do the same check on a server to prevent CRLF/CR from being
36 To do the same check on a server to prevent CRLF/CR from being
37 pushed or pulled::
37 pushed or pulled::
38
38
39 [hooks]
39 [hooks]
40 pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
40 pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
41 # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
41 # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
42 '''
42 '''
43
43
44 from __future__ import absolute_import
44 from __future__ import absolute_import
45
45
46 import re
46 import re
47 from mercurial.i18n import _
47 from mercurial.i18n import _
48 from mercurial.node import short
48 from mercurial.node import short
49 from mercurial import (
49 from mercurial import (
50 cmdutil,
51 extensions,
50 pycompat,
52 pycompat,
51 registrar,
53 registrar,
52 )
54 )
53 from mercurial.utils import stringutil
55 from mercurial.utils import stringutil
54
56
55 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
57 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
56 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
58 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
57 # be specifying the version(s) of Mercurial they are tested with, or
59 # be specifying the version(s) of Mercurial they are tested with, or
58 # leave the attribute unspecified.
60 # leave the attribute unspecified.
59 testedwith = b'ships-with-hg-core'
61 testedwith = b'ships-with-hg-core'
60
62
61 configtable = {}
63 configtable = {}
62 configitem = registrar.configitem(configtable)
64 configitem = registrar.configitem(configtable)
63
65
64 configitem(
66 configitem(
65 b'win32text',
67 b'win32text',
66 b'warn',
68 b'warn',
67 default=True,
69 default=True,
68 )
70 )
69
71
70 # regexp for single LF without CR preceding.
72 # regexp for single LF without CR preceding.
71 re_single_lf = re.compile(b'(^|[^\r])\n', re.MULTILINE)
73 re_single_lf = re.compile(b'(^|[^\r])\n', re.MULTILINE)
72
74
73 newlinestr = {b'\r\n': b'CRLF', b'\r': b'CR'}
75 newlinestr = {b'\r\n': b'CRLF', b'\r': b'CR'}
74 filterstr = {b'\r\n': b'clever', b'\r': b'mac'}
76 filterstr = {b'\r\n': b'clever', b'\r': b'mac'}
75
77
76
78
77 def checknewline(s, newline, ui=None, repo=None, filename=None):
79 def checknewline(s, newline, ui=None, repo=None, filename=None):
78 # warn if already has 'newline' in repository.
80 # warn if already has 'newline' in repository.
79 # it might cause unexpected eol conversion.
81 # it might cause unexpected eol conversion.
80 # see issue 302:
82 # see issue 302:
81 # https://bz.mercurial-scm.org/302
83 # https://bz.mercurial-scm.org/302
82 if newline in s and ui and filename and repo:
84 if newline in s and ui and filename and repo:
83 ui.warn(
85 ui.warn(
84 _(
86 _(
85 b'WARNING: %s already has %s line endings\n'
87 b'WARNING: %s already has %s line endings\n'
86 b'and does not need EOL conversion by the win32text plugin.\n'
88 b'and does not need EOL conversion by the win32text plugin.\n'
87 b'Before your next commit, please reconsider your '
89 b'Before your next commit, please reconsider your '
88 b'encode/decode settings in \nMercurial.ini or %s.\n'
90 b'encode/decode settings in \nMercurial.ini or %s.\n'
89 )
91 )
90 % (filename, newlinestr[newline], repo.vfs.join(b'hgrc'))
92 % (filename, newlinestr[newline], repo.vfs.join(b'hgrc'))
91 )
93 )
92
94
93
95
94 def dumbdecode(s, cmd, **kwargs):
96 def dumbdecode(s, cmd, **kwargs):
95 checknewline(s, b'\r\n', **kwargs)
97 checknewline(s, b'\r\n', **kwargs)
96 # replace single LF to CRLF
98 # replace single LF to CRLF
97 return re_single_lf.sub(b'\\1\r\n', s)
99 return re_single_lf.sub(b'\\1\r\n', s)
98
100
99
101
100 def dumbencode(s, cmd):
102 def dumbencode(s, cmd):
101 return s.replace(b'\r\n', b'\n')
103 return s.replace(b'\r\n', b'\n')
102
104
103
105
104 def macdumbdecode(s, cmd, **kwargs):
106 def macdumbdecode(s, cmd, **kwargs):
105 checknewline(s, b'\r', **kwargs)
107 checknewline(s, b'\r', **kwargs)
106 return s.replace(b'\n', b'\r')
108 return s.replace(b'\n', b'\r')
107
109
108
110
109 def macdumbencode(s, cmd):
111 def macdumbencode(s, cmd):
110 return s.replace(b'\r', b'\n')
112 return s.replace(b'\r', b'\n')
111
113
112
114
113 def cleverdecode(s, cmd, **kwargs):
115 def cleverdecode(s, cmd, **kwargs):
114 if not stringutil.binary(s):
116 if not stringutil.binary(s):
115 return dumbdecode(s, cmd, **kwargs)
117 return dumbdecode(s, cmd, **kwargs)
116 return s
118 return s
117
119
118
120
119 def cleverencode(s, cmd):
121 def cleverencode(s, cmd):
120 if not stringutil.binary(s):
122 if not stringutil.binary(s):
121 return dumbencode(s, cmd)
123 return dumbencode(s, cmd)
122 return s
124 return s
123
125
124
126
125 def macdecode(s, cmd, **kwargs):
127 def macdecode(s, cmd, **kwargs):
126 if not stringutil.binary(s):
128 if not stringutil.binary(s):
127 return macdumbdecode(s, cmd, **kwargs)
129 return macdumbdecode(s, cmd, **kwargs)
128 return s
130 return s
129
131
130
132
131 def macencode(s, cmd):
133 def macencode(s, cmd):
132 if not stringutil.binary(s):
134 if not stringutil.binary(s):
133 return macdumbencode(s, cmd)
135 return macdumbencode(s, cmd)
134 return s
136 return s
135
137
136
138
137 _filters = {
139 _filters = {
138 b'dumbdecode:': dumbdecode,
140 b'dumbdecode:': dumbdecode,
139 b'dumbencode:': dumbencode,
141 b'dumbencode:': dumbencode,
140 b'cleverdecode:': cleverdecode,
142 b'cleverdecode:': cleverdecode,
141 b'cleverencode:': cleverencode,
143 b'cleverencode:': cleverencode,
142 b'macdumbdecode:': macdumbdecode,
144 b'macdumbdecode:': macdumbdecode,
143 b'macdumbencode:': macdumbencode,
145 b'macdumbencode:': macdumbencode,
144 b'macdecode:': macdecode,
146 b'macdecode:': macdecode,
145 b'macencode:': macencode,
147 b'macencode:': macencode,
146 }
148 }
147
149
148
150
149 def forbidnewline(ui, repo, hooktype, node, newline, **kwargs):
151 def forbidnewline(ui, repo, hooktype, node, newline, **kwargs):
150 halt = False
152 halt = False
151 seen = set()
153 seen = set()
152 # we try to walk changesets in reverse order from newest to
154 # we try to walk changesets in reverse order from newest to
153 # oldest, so that if we see a file multiple times, we take the
155 # oldest, so that if we see a file multiple times, we take the
154 # newest version as canonical. this prevents us from blocking a
156 # newest version as canonical. this prevents us from blocking a
155 # changegroup that contains an unacceptable commit followed later
157 # changegroup that contains an unacceptable commit followed later
156 # by a commit that fixes the problem.
158 # by a commit that fixes the problem.
157 tip = repo[b'tip']
159 tip = repo[b'tip']
158 for rev in pycompat.xrange(
160 for rev in pycompat.xrange(
159 repo.changelog.tiprev(), repo[node].rev() - 1, -1
161 repo.changelog.tiprev(), repo[node].rev() - 1, -1
160 ):
162 ):
161 c = repo[rev]
163 c = repo[rev]
162 for f in c.files():
164 for f in c.files():
163 if f in seen or f not in tip or f not in c:
165 if f in seen or f not in tip or f not in c:
164 continue
166 continue
165 seen.add(f)
167 seen.add(f)
166 data = c[f].data()
168 data = c[f].data()
167 if not stringutil.binary(data) and newline in data:
169 if not stringutil.binary(data) and newline in data:
168 if not halt:
170 if not halt:
169 ui.warn(
171 ui.warn(
170 _(
172 _(
171 b'attempt to commit or push text file(s) '
173 b'attempt to commit or push text file(s) '
172 b'using %s line endings\n'
174 b'using %s line endings\n'
173 )
175 )
174 % newlinestr[newline]
176 % newlinestr[newline]
175 )
177 )
176 ui.warn(_(b'in %s: %s\n') % (short(c.node()), f))
178 ui.warn(_(b'in %s: %s\n') % (short(c.node()), f))
177 halt = True
179 halt = True
178 if halt and hooktype == b'pretxnchangegroup':
180 if halt and hooktype == b'pretxnchangegroup':
179 crlf = newlinestr[newline].lower()
181 crlf = newlinestr[newline].lower()
180 filter = filterstr[newline]
182 filter = filterstr[newline]
181 ui.warn(
183 ui.warn(
182 _(
184 _(
183 b'\nTo prevent this mistake in your local repository,\n'
185 b'\nTo prevent this mistake in your local repository,\n'
184 b'add to Mercurial.ini or .hg/hgrc:\n'
186 b'add to Mercurial.ini or .hg/hgrc:\n'
185 b'\n'
187 b'\n'
186 b'[hooks]\n'
188 b'[hooks]\n'
187 b'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
189 b'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
188 b'\n'
190 b'\n'
189 b'and also consider adding:\n'
191 b'and also consider adding:\n'
190 b'\n'
192 b'\n'
191 b'[extensions]\n'
193 b'[extensions]\n'
192 b'win32text =\n'
194 b'win32text =\n'
193 b'[encode]\n'
195 b'[encode]\n'
194 b'** = %sencode:\n'
196 b'** = %sencode:\n'
195 b'[decode]\n'
197 b'[decode]\n'
196 b'** = %sdecode:\n'
198 b'** = %sdecode:\n'
197 )
199 )
198 % (crlf, crlf, filter, filter)
200 % (crlf, crlf, filter, filter)
199 )
201 )
200 return halt
202 return halt
201
203
202
204
203 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
205 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
204 return forbidnewline(ui, repo, hooktype, node, b'\r\n', **kwargs)
206 return forbidnewline(ui, repo, hooktype, node, b'\r\n', **kwargs)
205
207
206
208
207 def forbidcr(ui, repo, hooktype, node, **kwargs):
209 def forbidcr(ui, repo, hooktype, node, **kwargs):
208 return forbidnewline(ui, repo, hooktype, node, b'\r', **kwargs)
210 return forbidnewline(ui, repo, hooktype, node, b'\r', **kwargs)
209
211
210
212
211 def reposetup(ui, repo):
213 def reposetup(ui, repo):
212 if not repo.local():
214 if not repo.local():
213 return
215 return
214 for name, fn in pycompat.iteritems(_filters):
216 for name, fn in pycompat.iteritems(_filters):
215 repo.adddatafilter(name, fn)
217 repo.adddatafilter(name, fn)
216
218
217
219
220 def wrap_revert(orig, repo, ctx, names, uipathfn, actions, *args, **kwargs):
221 # reset dirstate cache for file we touch
222 ds = repo.dirstate
223 with ds.parentchange():
224 for filename in actions[b'revert'][0]:
225 entry = ds.get_entry(filename)
226 if entry is not None:
227 if entry.p1_tracked:
228 ds.update_file(
229 filename,
230 entry.tracked,
231 p1_tracked=True,
232 p2_info=entry.p2_info,
233 )
234 return orig(repo, ctx, names, uipathfn, actions, *args, **kwargs)
235
236
218 def extsetup(ui):
237 def extsetup(ui):
219 # deprecated config: win32text.warn
238 # deprecated config: win32text.warn
220 if ui.configbool(b'win32text', b'warn'):
239 if ui.configbool(b'win32text', b'warn'):
221 ui.warn(
240 ui.warn(
222 _(
241 _(
223 b"win32text is deprecated: "
242 b"win32text is deprecated: "
224 b"https://mercurial-scm.org/wiki/Win32TextExtension\n"
243 b"https://mercurial-scm.org/wiki/Win32TextExtension\n"
225 )
244 )
226 )
245 )
246 extensions.wrapfunction(cmdutil, '_performrevert', wrap_revert)
@@ -1,425 +1,424 b''
1
1
2 $ hg init t
2 $ hg init t
3 $ cd t
3 $ cd t
4 $ cat > unix2dos.py <<EOF
4 $ cat > unix2dos.py <<EOF
5 > import sys
5 > import sys
6 >
6 >
7 > for path in sys.argv[1:]:
7 > for path in sys.argv[1:]:
8 > data = open(path, 'rb').read()
8 > data = open(path, 'rb').read()
9 > data = data.replace(b'\n', b'\r\n')
9 > data = data.replace(b'\n', b'\r\n')
10 > open(path, 'wb').write(data)
10 > open(path, 'wb').write(data)
11 > EOF
11 > EOF
12 $ echo '[hooks]' >> .hg/hgrc
12 $ echo '[hooks]' >> .hg/hgrc
13 $ echo 'pretxncommit.crlf = python:hgext.win32text.forbidcrlf' >> .hg/hgrc
13 $ echo 'pretxncommit.crlf = python:hgext.win32text.forbidcrlf' >> .hg/hgrc
14 $ echo 'pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf' >> .hg/hgrc
14 $ echo 'pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf' >> .hg/hgrc
15 $ cat .hg/hgrc
15 $ cat .hg/hgrc
16 [hooks]
16 [hooks]
17 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
17 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
18 pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
18 pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
19
19
20 $ echo hello > f
20 $ echo hello > f
21 $ hg add f
21 $ hg add f
22
22
23 commit should succeed
23 commit should succeed
24
24
25 $ hg ci -m 1
25 $ hg ci -m 1
26
26
27 $ hg clone . ../zoz
27 $ hg clone . ../zoz
28 updating to branch default
28 updating to branch default
29 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
29 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
30 $ cp .hg/hgrc ../zoz/.hg
30 $ cp .hg/hgrc ../zoz/.hg
31 $ "$PYTHON" unix2dos.py f
31 $ "$PYTHON" unix2dos.py f
32
32
33 commit should fail
33 commit should fail
34
34
35 $ hg ci -m 2.1
35 $ hg ci -m 2.1
36 attempt to commit or push text file(s) using CRLF line endings
36 attempt to commit or push text file(s) using CRLF line endings
37 in f583ea08d42a: f
37 in f583ea08d42a: f
38 transaction abort!
38 transaction abort!
39 rollback completed
39 rollback completed
40 abort: pretxncommit.crlf hook failed
40 abort: pretxncommit.crlf hook failed
41 [40]
41 [40]
42
42
43 $ mv .hg/hgrc .hg/hgrc.bak
43 $ mv .hg/hgrc .hg/hgrc.bak
44
44
45 commits should succeed
45 commits should succeed
46
46
47 $ hg ci -m 2
47 $ hg ci -m 2
48 $ hg cp f g
48 $ hg cp f g
49 $ hg ci -m 2.2
49 $ hg ci -m 2.2
50
50
51 push should fail
51 push should fail
52
52
53 $ hg push ../zoz
53 $ hg push ../zoz
54 pushing to ../zoz
54 pushing to ../zoz
55 searching for changes
55 searching for changes
56 adding changesets
56 adding changesets
57 adding manifests
57 adding manifests
58 adding file changes
58 adding file changes
59 attempt to commit or push text file(s) using CRLF line endings
59 attempt to commit or push text file(s) using CRLF line endings
60 in bc2d09796734: g
60 in bc2d09796734: g
61 in b1aa5cde7ff4: f
61 in b1aa5cde7ff4: f
62
62
63 To prevent this mistake in your local repository,
63 To prevent this mistake in your local repository,
64 add to Mercurial.ini or .hg/hgrc:
64 add to Mercurial.ini or .hg/hgrc:
65
65
66 [hooks]
66 [hooks]
67 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
67 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
68
68
69 and also consider adding:
69 and also consider adding:
70
70
71 [extensions]
71 [extensions]
72 win32text =
72 win32text =
73 [encode]
73 [encode]
74 ** = cleverencode:
74 ** = cleverencode:
75 [decode]
75 [decode]
76 ** = cleverdecode:
76 ** = cleverdecode:
77 transaction abort!
77 transaction abort!
78 rollback completed
78 rollback completed
79 abort: pretxnchangegroup.crlf hook failed
79 abort: pretxnchangegroup.crlf hook failed
80 [40]
80 [40]
81
81
82 $ mv .hg/hgrc.bak .hg/hgrc
82 $ mv .hg/hgrc.bak .hg/hgrc
83 $ echo hello > f
83 $ echo hello > f
84 $ hg rm g
84 $ hg rm g
85
85
86 commit should succeed
86 commit should succeed
87
87
88 $ hg ci -m 2.3
88 $ hg ci -m 2.3
89
89
90 push should succeed
90 push should succeed
91
91
92 $ hg push ../zoz
92 $ hg push ../zoz
93 pushing to ../zoz
93 pushing to ../zoz
94 searching for changes
94 searching for changes
95 adding changesets
95 adding changesets
96 adding manifests
96 adding manifests
97 adding file changes
97 adding file changes
98 added 3 changesets with 3 changes to 2 files
98 added 3 changesets with 3 changes to 2 files
99
99
100 and now for something completely different
100 and now for something completely different
101
101
102 $ mkdir d
102 $ mkdir d
103 $ echo hello > d/f2
103 $ echo hello > d/f2
104 $ "$PYTHON" unix2dos.py d/f2
104 $ "$PYTHON" unix2dos.py d/f2
105 $ hg add d/f2
105 $ hg add d/f2
106 $ hg ci -m 3
106 $ hg ci -m 3
107 attempt to commit or push text file(s) using CRLF line endings
107 attempt to commit or push text file(s) using CRLF line endings
108 in 053ba1a3035a: d/f2
108 in 053ba1a3035a: d/f2
109 transaction abort!
109 transaction abort!
110 rollback completed
110 rollback completed
111 abort: pretxncommit.crlf hook failed
111 abort: pretxncommit.crlf hook failed
112 [40]
112 [40]
113 $ hg revert -a
113 $ hg revert -a
114 forgetting d/f2
114 forgetting d/f2
115 $ rm d/f2
115 $ rm d/f2
116
116
117 $ hg rem f
117 $ hg rem f
118 $ hg ci -m 4
118 $ hg ci -m 4
119
119
120 $ "$PYTHON" -c 'open("bin", "wb").write(b"hello\x00\x0D\x0A")'
120 $ "$PYTHON" -c 'open("bin", "wb").write(b"hello\x00\x0D\x0A")'
121 $ hg add bin
121 $ hg add bin
122 $ hg ci -m 5
122 $ hg ci -m 5
123 $ hg log -v
123 $ hg log -v
124 changeset: 5:f0b1c8d75fce
124 changeset: 5:f0b1c8d75fce
125 tag: tip
125 tag: tip
126 user: test
126 user: test
127 date: Thu Jan 01 00:00:00 1970 +0000
127 date: Thu Jan 01 00:00:00 1970 +0000
128 files: bin
128 files: bin
129 description:
129 description:
130 5
130 5
131
131
132
132
133 changeset: 4:77796dbcd4ad
133 changeset: 4:77796dbcd4ad
134 user: test
134 user: test
135 date: Thu Jan 01 00:00:00 1970 +0000
135 date: Thu Jan 01 00:00:00 1970 +0000
136 files: f
136 files: f
137 description:
137 description:
138 4
138 4
139
139
140
140
141 changeset: 3:7c1b5430b350
141 changeset: 3:7c1b5430b350
142 user: test
142 user: test
143 date: Thu Jan 01 00:00:00 1970 +0000
143 date: Thu Jan 01 00:00:00 1970 +0000
144 files: f g
144 files: f g
145 description:
145 description:
146 2.3
146 2.3
147
147
148
148
149 changeset: 2:bc2d09796734
149 changeset: 2:bc2d09796734
150 user: test
150 user: test
151 date: Thu Jan 01 00:00:00 1970 +0000
151 date: Thu Jan 01 00:00:00 1970 +0000
152 files: g
152 files: g
153 description:
153 description:
154 2.2
154 2.2
155
155
156
156
157 changeset: 1:b1aa5cde7ff4
157 changeset: 1:b1aa5cde7ff4
158 user: test
158 user: test
159 date: Thu Jan 01 00:00:00 1970 +0000
159 date: Thu Jan 01 00:00:00 1970 +0000
160 files: f
160 files: f
161 description:
161 description:
162 2
162 2
163
163
164
164
165 changeset: 0:fcf06d5c4e1d
165 changeset: 0:fcf06d5c4e1d
166 user: test
166 user: test
167 date: Thu Jan 01 00:00:00 1970 +0000
167 date: Thu Jan 01 00:00:00 1970 +0000
168 files: f
168 files: f
169 description:
169 description:
170 1
170 1
171
171
172
172
173 $ hg clone . dupe
173 $ hg clone . dupe
174 updating to branch default
174 updating to branch default
175 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
175 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
176
176
177 $ for x in a b c d; do echo content > dupe/$x; done
177 $ for x in a b c d; do echo content > dupe/$x; done
178 $ hg -R dupe add
178 $ hg -R dupe add
179 adding dupe/a
179 adding dupe/a
180 adding dupe/b
180 adding dupe/b
181 adding dupe/c
181 adding dupe/c
182 adding dupe/d
182 adding dupe/d
183 $ "$PYTHON" unix2dos.py dupe/b dupe/c dupe/d
183 $ "$PYTHON" unix2dos.py dupe/b dupe/c dupe/d
184 $ hg -R dupe ci -m a dupe/a
184 $ hg -R dupe ci -m a dupe/a
185 $ hg -R dupe ci -m b/c dupe/[bc]
185 $ hg -R dupe ci -m b/c dupe/[bc]
186 $ hg -R dupe ci -m d dupe/d
186 $ hg -R dupe ci -m d dupe/d
187 $ hg -R dupe log -v
187 $ hg -R dupe log -v
188 changeset: 8:67ac5962ab43
188 changeset: 8:67ac5962ab43
189 tag: tip
189 tag: tip
190 user: test
190 user: test
191 date: Thu Jan 01 00:00:00 1970 +0000
191 date: Thu Jan 01 00:00:00 1970 +0000
192 files: d
192 files: d
193 description:
193 description:
194 d
194 d
195
195
196
196
197 changeset: 7:68c127d1834e
197 changeset: 7:68c127d1834e
198 user: test
198 user: test
199 date: Thu Jan 01 00:00:00 1970 +0000
199 date: Thu Jan 01 00:00:00 1970 +0000
200 files: b c
200 files: b c
201 description:
201 description:
202 b/c
202 b/c
203
203
204
204
205 changeset: 6:adbf8bf7f31d
205 changeset: 6:adbf8bf7f31d
206 user: test
206 user: test
207 date: Thu Jan 01 00:00:00 1970 +0000
207 date: Thu Jan 01 00:00:00 1970 +0000
208 files: a
208 files: a
209 description:
209 description:
210 a
210 a
211
211
212
212
213 changeset: 5:f0b1c8d75fce
213 changeset: 5:f0b1c8d75fce
214 user: test
214 user: test
215 date: Thu Jan 01 00:00:00 1970 +0000
215 date: Thu Jan 01 00:00:00 1970 +0000
216 files: bin
216 files: bin
217 description:
217 description:
218 5
218 5
219
219
220
220
221 changeset: 4:77796dbcd4ad
221 changeset: 4:77796dbcd4ad
222 user: test
222 user: test
223 date: Thu Jan 01 00:00:00 1970 +0000
223 date: Thu Jan 01 00:00:00 1970 +0000
224 files: f
224 files: f
225 description:
225 description:
226 4
226 4
227
227
228
228
229 changeset: 3:7c1b5430b350
229 changeset: 3:7c1b5430b350
230 user: test
230 user: test
231 date: Thu Jan 01 00:00:00 1970 +0000
231 date: Thu Jan 01 00:00:00 1970 +0000
232 files: f g
232 files: f g
233 description:
233 description:
234 2.3
234 2.3
235
235
236
236
237 changeset: 2:bc2d09796734
237 changeset: 2:bc2d09796734
238 user: test
238 user: test
239 date: Thu Jan 01 00:00:00 1970 +0000
239 date: Thu Jan 01 00:00:00 1970 +0000
240 files: g
240 files: g
241 description:
241 description:
242 2.2
242 2.2
243
243
244
244
245 changeset: 1:b1aa5cde7ff4
245 changeset: 1:b1aa5cde7ff4
246 user: test
246 user: test
247 date: Thu Jan 01 00:00:00 1970 +0000
247 date: Thu Jan 01 00:00:00 1970 +0000
248 files: f
248 files: f
249 description:
249 description:
250 2
250 2
251
251
252
252
253 changeset: 0:fcf06d5c4e1d
253 changeset: 0:fcf06d5c4e1d
254 user: test
254 user: test
255 date: Thu Jan 01 00:00:00 1970 +0000
255 date: Thu Jan 01 00:00:00 1970 +0000
256 files: f
256 files: f
257 description:
257 description:
258 1
258 1
259
259
260
260
261 $ hg pull dupe
261 $ hg pull dupe
262 pulling from dupe
262 pulling from dupe
263 searching for changes
263 searching for changes
264 adding changesets
264 adding changesets
265 adding manifests
265 adding manifests
266 adding file changes
266 adding file changes
267 attempt to commit or push text file(s) using CRLF line endings
267 attempt to commit or push text file(s) using CRLF line endings
268 in 67ac5962ab43: d
268 in 67ac5962ab43: d
269 in 68c127d1834e: b
269 in 68c127d1834e: b
270 in 68c127d1834e: c
270 in 68c127d1834e: c
271
271
272 To prevent this mistake in your local repository,
272 To prevent this mistake in your local repository,
273 add to Mercurial.ini or .hg/hgrc:
273 add to Mercurial.ini or .hg/hgrc:
274
274
275 [hooks]
275 [hooks]
276 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
276 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
277
277
278 and also consider adding:
278 and also consider adding:
279
279
280 [extensions]
280 [extensions]
281 win32text =
281 win32text =
282 [encode]
282 [encode]
283 ** = cleverencode:
283 ** = cleverencode:
284 [decode]
284 [decode]
285 ** = cleverdecode:
285 ** = cleverdecode:
286 transaction abort!
286 transaction abort!
287 rollback completed
287 rollback completed
288 abort: pretxnchangegroup.crlf hook failed
288 abort: pretxnchangegroup.crlf hook failed
289 [40]
289 [40]
290
290
291 $ hg log -v
291 $ hg log -v
292 changeset: 5:f0b1c8d75fce
292 changeset: 5:f0b1c8d75fce
293 tag: tip
293 tag: tip
294 user: test
294 user: test
295 date: Thu Jan 01 00:00:00 1970 +0000
295 date: Thu Jan 01 00:00:00 1970 +0000
296 files: bin
296 files: bin
297 description:
297 description:
298 5
298 5
299
299
300
300
301 changeset: 4:77796dbcd4ad
301 changeset: 4:77796dbcd4ad
302 user: test
302 user: test
303 date: Thu Jan 01 00:00:00 1970 +0000
303 date: Thu Jan 01 00:00:00 1970 +0000
304 files: f
304 files: f
305 description:
305 description:
306 4
306 4
307
307
308
308
309 changeset: 3:7c1b5430b350
309 changeset: 3:7c1b5430b350
310 user: test
310 user: test
311 date: Thu Jan 01 00:00:00 1970 +0000
311 date: Thu Jan 01 00:00:00 1970 +0000
312 files: f g
312 files: f g
313 description:
313 description:
314 2.3
314 2.3
315
315
316
316
317 changeset: 2:bc2d09796734
317 changeset: 2:bc2d09796734
318 user: test
318 user: test
319 date: Thu Jan 01 00:00:00 1970 +0000
319 date: Thu Jan 01 00:00:00 1970 +0000
320 files: g
320 files: g
321 description:
321 description:
322 2.2
322 2.2
323
323
324
324
325 changeset: 1:b1aa5cde7ff4
325 changeset: 1:b1aa5cde7ff4
326 user: test
326 user: test
327 date: Thu Jan 01 00:00:00 1970 +0000
327 date: Thu Jan 01 00:00:00 1970 +0000
328 files: f
328 files: f
329 description:
329 description:
330 2
330 2
331
331
332
332
333 changeset: 0:fcf06d5c4e1d
333 changeset: 0:fcf06d5c4e1d
334 user: test
334 user: test
335 date: Thu Jan 01 00:00:00 1970 +0000
335 date: Thu Jan 01 00:00:00 1970 +0000
336 files: f
336 files: f
337 description:
337 description:
338 1
338 1
339
339
340
340
341 $ rm .hg/hgrc
341 $ rm .hg/hgrc
342 $ (echo some; echo text) > f3
342 $ (echo some; echo text) > f3
343 $ "$PYTHON" -c 'open("f4.bat", "wb").write(b"rem empty\x0D\x0A")'
343 $ "$PYTHON" -c 'open("f4.bat", "wb").write(b"rem empty\x0D\x0A")'
344 $ hg add f3 f4.bat
344 $ hg add f3 f4.bat
345 $ hg ci -m 6
345 $ hg ci -m 6
346 $ cat bin
346 $ cat bin
347 hello\x00\r (esc)
347 hello\x00\r (esc)
348 $ cat f3
348 $ cat f3
349 some
349 some
350 text
350 text
351 $ cat f4.bat
351 $ cat f4.bat
352 rem empty\r (esc)
352 rem empty\r (esc)
353
353
354 $ echo '[extensions]' >> .hg/hgrc
354 $ echo '[extensions]' >> .hg/hgrc
355 $ echo 'win32text = ' >> .hg/hgrc
355 $ echo 'win32text = ' >> .hg/hgrc
356 $ echo '[decode]' >> .hg/hgrc
356 $ echo '[decode]' >> .hg/hgrc
357 $ echo '** = cleverdecode:' >> .hg/hgrc
357 $ echo '** = cleverdecode:' >> .hg/hgrc
358 $ echo '[encode]' >> .hg/hgrc
358 $ echo '[encode]' >> .hg/hgrc
359 $ echo '** = cleverencode:' >> .hg/hgrc
359 $ echo '** = cleverencode:' >> .hg/hgrc
360 $ cat .hg/hgrc
360 $ cat .hg/hgrc
361 [extensions]
361 [extensions]
362 win32text =
362 win32text =
363 [decode]
363 [decode]
364 ** = cleverdecode:
364 ** = cleverdecode:
365 [encode]
365 [encode]
366 ** = cleverencode:
366 ** = cleverencode:
367
367
368 Trigger deprecation warning:
368 Trigger deprecation warning:
369
369
370 $ hg id -t
370 $ hg id -t
371 win32text is deprecated: https://mercurial-scm.org/wiki/Win32TextExtension
371 win32text is deprecated: https://mercurial-scm.org/wiki/Win32TextExtension
372 tip
372 tip
373
373
374 Disable warning:
374 Disable warning:
375
375
376 $ echo '[win32text]' >> .hg/hgrc
376 $ echo '[win32text]' >> .hg/hgrc
377 $ echo 'warn = no' >> .hg/hgrc
377 $ echo 'warn = no' >> .hg/hgrc
378 $ hg id -t
378 $ hg id -t
379 tip
379 tip
380
380
381 $ rm f3 f4.bat bin
381 $ rm f3 f4.bat bin
382 $ hg co -C
382 $ hg co -C
383 WARNING: f4.bat already has CRLF line endings
383 WARNING: f4.bat already has CRLF line endings
384 and does not need EOL conversion by the win32text plugin.
384 and does not need EOL conversion by the win32text plugin.
385 Before your next commit, please reconsider your encode/decode settings in
385 Before your next commit, please reconsider your encode/decode settings in
386 Mercurial.ini or $TESTTMP/t/.hg/hgrc.
386 Mercurial.ini or $TESTTMP/t/.hg/hgrc.
387 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
387 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
388 $ cat bin
388 $ cat bin
389 hello\x00\r (esc)
389 hello\x00\r (esc)
390 $ cat f3
390 $ cat f3
391 some\r (esc)
391 some\r (esc)
392 text\r (esc)
392 text\r (esc)
393 $ cat f4.bat
393 $ cat f4.bat
394 rem empty\r (esc)
394 rem empty\r (esc)
395
395
396 $ "$PYTHON" -c 'open("f5.sh", "wb").write(b"# empty\x0D\x0A")'
396 $ "$PYTHON" -c 'open("f5.sh", "wb").write(b"# empty\x0D\x0A")'
397 $ hg add f5.sh
397 $ hg add f5.sh
398 $ hg ci -m 7
398 $ hg ci -m 7
399 $ cat f5.sh
399 $ cat f5.sh
400 # empty\r (esc)
400 # empty\r (esc)
401 $ hg cat f5.sh
401 $ hg cat f5.sh
402 # empty
402 # empty
403 $ echo '% just linefeed' > linefeed
403 $ echo '% just linefeed' > linefeed
404 $ hg ci -qAm 8 linefeed
404 $ hg ci -qAm 8 linefeed
405 $ cat linefeed
405 $ cat linefeed
406 % just linefeed
406 % just linefeed
407 $ hg cat linefeed
407 $ hg cat linefeed
408 % just linefeed
408 % just linefeed
409 $ hg st -q
409 $ hg st -q
410 $ hg revert -a linefeed
410 $ hg revert -a linefeed
411 no changes needed to linefeed
411 no changes needed to linefeed
412 $ cat linefeed
412 $ cat linefeed
413 % just linefeed
413 % just linefeed
414 $ hg st -q
414 $ hg st -q
415 $ echo modified >> linefeed
415 $ echo modified >> linefeed
416 $ hg st -q
416 $ hg st -q
417 M linefeed
417 M linefeed
418 $ hg revert -a
418 $ hg revert -a
419 reverting linefeed
419 reverting linefeed
420 $ hg st -q
420 $ hg st -q
421 M linefeed (known-bad-output !)
422 $ cat linefeed
421 $ cat linefeed
423 % just linefeed\r (esc)
422 % just linefeed\r (esc)
424
423
425 $ cd ..
424 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now