Mercurial > hg
comparison hgext/win32text.py @ 6481:e837dded56c7
win32text: Add macencode/macdecode
author | OHASHI Hideya <ohachige@gmail.com> |
---|---|
date | Thu, 03 Apr 2008 20:41:31 +0900 |
parents | 7f4257b5cbfc |
children | 0a803195bb29 |
comparison
equal
deleted
inserted
replaced
6472:8c4cd80afd3e | 6481:e837dded56c7 |
---|---|
1 # win32text.py - LF <-> CRLF translation utilities for Windows users | 1 # win32text.py - LF <-> CRLF/CR translation utilities for Windows/Mac users |
2 # | 2 # |
3 # This software may be used and distributed according to the terms | 3 # This software may be used and distributed according to the terms |
4 # of the GNU General Public License, incorporated herein by reference. | 4 # of the GNU General Public License, incorporated herein by reference. |
5 # | 5 # |
6 # To perform automatic newline conversion, use: | 6 # To perform automatic newline conversion, use: |
7 # | 7 # |
8 # [extensions] | 8 # [extensions] |
9 # hgext.win32text = | 9 # hgext.win32text = |
10 # [encode] | 10 # [encode] |
11 # ** = cleverencode: | 11 # ** = cleverencode: |
12 # # or ** = macencode: | |
12 # [decode] | 13 # [decode] |
13 # ** = cleverdecode: | 14 # ** = cleverdecode: |
15 # # or ** = macdecode: | |
14 # | 16 # |
15 # If not doing conversion, to make sure you do not commit CRLF by accident: | 17 # If not doing conversion, to make sure you do not commit CRLF/CR by accident: |
16 # | 18 # |
17 # [hooks] | 19 # [hooks] |
18 # pretxncommit.crlf = python:hgext.win32text.forbidcrlf | 20 # pretxncommit.crlf = python:hgext.win32text.forbidcrlf |
21 # # or pretxncommit.cr = python:hgext.win32text.forbidcr | |
19 # | 22 # |
20 # To do the same check on a server to prevent CRLF from being pushed or pulled: | 23 # To do the same check on a server to prevent CRLF/CR from being pushed or |
24 # pulled: | |
21 # | 25 # |
22 # [hooks] | 26 # [hooks] |
23 # pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf | 27 # pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf |
28 # # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr | |
24 | 29 |
25 from mercurial import util | 30 from mercurial import util |
26 from mercurial.i18n import gettext as _ | 31 from mercurial.i18n import gettext as _ |
27 from mercurial.node import bin, short | 32 from mercurial.node import bin, short |
28 import re | 33 import re |
29 | 34 |
30 # regexp for single LF without CR preceding. | 35 # regexp for single LF without CR preceding. |
31 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE) | 36 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE) |
32 | 37 |
33 def dumbdecode(s, cmd, ui=None, repo=None, filename=None, **kwargs): | 38 newlinestr = {'\r\n': 'CRLF', '\r': 'CR'} |
34 # warn if already has CRLF in repository. | 39 filterstr = {'\r\n': 'clever', '\r': 'mac'} |
40 | |
41 def checknewline(s, newline, ui=None, repo=None, filename=None): | |
42 # warn if already has 'newline' in repository. | |
35 # it might cause unexpected eol conversion. | 43 # it might cause unexpected eol conversion. |
36 # see issue 302: | 44 # see issue 302: |
37 # http://www.selenic.com/mercurial/bts/issue302 | 45 # http://www.selenic.com/mercurial/bts/issue302 |
38 if '\r\n' in s and ui and filename and repo: | 46 if newline in s and ui and filename and repo: |
39 ui.warn(_('WARNING: %s already has CRLF line endings\n' | 47 ui.warn(_('WARNING: %s already has %s line endings\n' |
40 'and does not need EOL conversion by the win32text plugin.\n' | 48 'and does not need EOL conversion by the win32text plugin.\n' |
41 'Before your next commit, please reconsider your ' | 49 'Before your next commit, please reconsider your ' |
42 'encode/decode settings in \nMercurial.ini or %s.\n') % | 50 'encode/decode settings in \nMercurial.ini or %s.\n') % |
43 (filename, repo.join('hgrc'))) | 51 (filename, newlinestr[newline], repo.join('hgrc'))) |
52 | |
53 def dumbdecode(s, cmd, **kwargs): | |
54 checknewline(s, '\r\n', **kwargs) | |
44 # replace single LF to CRLF | 55 # replace single LF to CRLF |
45 return re_single_lf.sub('\\1\r\n', s) | 56 return re_single_lf.sub('\\1\r\n', s) |
46 | 57 |
47 def dumbencode(s, cmd): | 58 def dumbencode(s, cmd): |
48 return s.replace('\r\n', '\n') | 59 return s.replace('\r\n', '\n') |
60 | |
61 def macdumbdecode(s, cmd, **kwargs): | |
62 checknewline(s, '\r', **kwargs) | |
63 return s.replace('\n', '\r') | |
64 | |
65 def macdumbencode(s, cmd): | |
66 return s.replace('\r', '\n') | |
49 | 67 |
50 def cleverdecode(s, cmd, **kwargs): | 68 def cleverdecode(s, cmd, **kwargs): |
51 if util.binary(s): | 69 if util.binary(s): |
52 return s | 70 return s |
53 return dumbdecode(s, cmd, **kwargs) | 71 return dumbdecode(s, cmd, **kwargs) |
55 def cleverencode(s, cmd): | 73 def cleverencode(s, cmd): |
56 if util.binary(s): | 74 if util.binary(s): |
57 return s | 75 return s |
58 return dumbencode(s, cmd) | 76 return dumbencode(s, cmd) |
59 | 77 |
78 def macdecode(s, cmd, **kwargs): | |
79 if util.binary(s): | |
80 return s | |
81 return macdumbdecode(s, cmd, **kwargs) | |
82 | |
83 def macencode(s, cmd): | |
84 if util.binary(s): | |
85 return s | |
86 return macdumbencode(s, cmd) | |
87 | |
60 _filters = { | 88 _filters = { |
61 'dumbdecode:': dumbdecode, | 89 'dumbdecode:': dumbdecode, |
62 'dumbencode:': dumbencode, | 90 'dumbencode:': dumbencode, |
63 'cleverdecode:': cleverdecode, | 91 'cleverdecode:': cleverdecode, |
64 'cleverencode:': cleverencode, | 92 'cleverencode:': cleverencode, |
93 'macdumbdecode:': macdumbdecode, | |
94 'macdumbencode:': macdumbencode, | |
95 'macdecode:': macdecode, | |
96 'macencode:': macencode, | |
65 } | 97 } |
66 | 98 |
67 def forbidcrlf(ui, repo, hooktype, node, **kwargs): | 99 def forbidcrlforcr(ui, repo, hooktype, node, newline, **kwargs): |
68 halt = False | 100 halt = False |
69 for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()): | 101 for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()): |
70 c = repo.changectx(rev) | 102 c = repo.changectx(rev) |
71 for f in c.files(): | 103 for f in c.files(): |
72 if f not in c: | 104 if f not in c: |
73 continue | 105 continue |
74 data = c[f].data() | 106 data = c[f].data() |
75 if not util.binary(data) and '\r\n' in data: | 107 if not util.binary(data) and newline in data: |
76 if not halt: | 108 if not halt: |
77 ui.warn(_('Attempt to commit or push text file(s) ' | 109 ui.warn(_('Attempt to commit or push text file(s) ' |
78 'using CRLF line endings\n')) | 110 'using %s line endings\n') % |
111 newlinestr[newline]) | |
79 ui.warn(_('in %s: %s\n') % (short(c.node()), f)) | 112 ui.warn(_('in %s: %s\n') % (short(c.node()), f)) |
80 halt = True | 113 halt = True |
81 if halt and hooktype == 'pretxnchangegroup': | 114 if halt and hooktype == 'pretxnchangegroup': |
115 crlf = newlinestr[newline].lower() | |
116 filter = filterstr[newline] | |
82 ui.warn(_('\nTo prevent this mistake in your local repository,\n' | 117 ui.warn(_('\nTo prevent this mistake in your local repository,\n' |
83 'add to Mercurial.ini or .hg/hgrc:\n' | 118 'add to Mercurial.ini or .hg/hgrc:\n' |
84 '\n' | 119 '\n' |
85 '[hooks]\n' | 120 '[hooks]\n' |
86 'pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n' | 121 'pretxncommit.%s = python:hgext.win32text.forbid%s\n' |
87 '\n' | 122 '\n' |
88 'and also consider adding:\n' | 123 'and also consider adding:\n' |
89 '\n' | 124 '\n' |
90 '[extensions]\n' | 125 '[extensions]\n' |
91 'hgext.win32text =\n' | 126 'hgext.win32text =\n' |
92 '[encode]\n' | 127 '[encode]\n' |
93 '** = cleverencode:\n' | 128 '** = %sencode:\n' |
94 '[decode]\n' | 129 '[decode]\n' |
95 '** = cleverdecode:\n')) | 130 '** = %sdecode:\n') % (crlf, crlf, filter, filter)) |
96 return halt | 131 return halt |
132 | |
133 def forbidcrlf(ui, repo, hooktype, node, **kwargs): | |
134 return forbidcrlforcr(ui, repo, hooktype, node, '\r\n', **kwargs) | |
135 | |
136 def forbidcr(ui, repo, hooktype, node, **kwargs): | |
137 return forbidcrlforcr(ui, repo, hooktype, node, '\r', **kwargs) | |
97 | 138 |
98 def reposetup(ui, repo): | 139 def reposetup(ui, repo): |
99 if not repo.local(): | 140 if not repo.local(): |
100 return | 141 return |
101 for name, fn in _filters.iteritems(): | 142 for name, fn in _filters.iteritems(): |