[PATCH] win32text: Add macencode/macdecode
OHASHI Hideya
ohachige at gmail.com
Thu Apr 3 11:42:50 UTC 2008
# HG changeset patch
# User OHASHI Hideya <ohachige at gmail.com>
# Date 1207222891 -32400
# Node ID 840b1f1a93a0461eb2b9ef60be7c4030c1c14fae
# Parent a5e7c5e15e9e4d5c0e7780978210a890a3348cd6
win32text: Add macencode/macdecode
diff -r a5e7c5e15e9e -r 840b1f1a93a0 hgext/win32text.py
--- a/hgext/win32text.py Thu Apr 03 13:30:47 2008 +0900
+++ b/hgext/win32text.py Thu Apr 03 20:41:31 2008 +0900
@@ -1,4 +1,4 @@
-# win32text.py - LF <-> CRLF translation utilities for Windows users
+# win32text.py - LF <-> CRLF/CR translation utilities for Windows/Mac users
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
@@ -9,18 +9,23 @@
# hgext.win32text =
# [encode]
# ** = cleverencode:
+# # or ** = macencode:
# [decode]
# ** = cleverdecode:
+# # or ** = macdecode:
#
-# If not doing conversion, to make sure you do not commit CRLF by accident:
+# If not doing conversion, to make sure you do not commit CRLF/CR by accident:
#
# [hooks]
# pretxncommit.crlf = python:hgext.win32text.forbidcrlf
+# # or pretxncommit.cr = python:hgext.win32text.forbidcr
#
-# To do the same check on a server to prevent CRLF from being pushed or pulled:
+# To do the same check on a server to prevent CRLF/CR from being pushed or
+# pulled:
#
# [hooks]
# pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
+# # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
from mercurial import util
from mercurial.i18n import gettext as _
@@ -30,22 +35,35 @@
# regexp for single LF without CR preceding.
re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
-def dumbdecode(s, cmd, ui=None, repo=None, filename=None, **kwargs):
- # warn if already has CRLF in repository.
+newlinestr = {'\r\n': 'CRLF', '\r': 'CR'}
+filterstr = {'\r\n': 'clever', '\r': 'mac'}
+
+def checknewline(s, newline, ui=None, repo=None, filename=None):
+ # warn if already has 'newline' in repository.
# it might cause unexpected eol conversion.
# see issue 302:
# http://www.selenic.com/mercurial/bts/issue302
- if '\r\n' in s and ui and filename and repo:
- ui.warn(_('WARNING: %s already has CRLF line endings\n'
+ if newline in s and ui and filename and repo:
+ ui.warn(_('WARNING: %s already has %s line endings\n'
'and does not need EOL conversion by the win32text plugin.\n'
'Before your next commit, please reconsider your '
'encode/decode settings in \nMercurial.ini or %s.\n') %
- (filename, repo.join('hgrc')))
+ (filename, newlinestr[newline], repo.join('hgrc')))
+
+def dumbdecode(s, cmd, **kwargs):
+ checknewline(s, '\r\n', **kwargs)
# replace single LF to CRLF
return re_single_lf.sub('\\1\r\n', s)
def dumbencode(s, cmd):
return s.replace('\r\n', '\n')
+
+def macdumbdecode(s, cmd, **kwargs):
+ checknewline(s, '\r', **kwargs)
+ return s.replace('\n', '\r')
+
+def macdumbencode(s, cmd):
+ return s.replace('\r', '\n')
def cleverdecode(s, cmd, **kwargs):
if util.binary(s):
@@ -57,14 +75,28 @@
return s
return dumbencode(s, cmd)
+def macdecode(s, cmd, **kwargs):
+ if util.binary(s):
+ return s
+ return macdumbdecode(s, cmd, **kwargs)
+
+def macencode(s, cmd):
+ if util.binary(s):
+ return s
+ return macdumbencode(s, cmd)
+
_filters = {
'dumbdecode:': dumbdecode,
'dumbencode:': dumbencode,
'cleverdecode:': cleverdecode,
'cleverencode:': cleverencode,
+ 'macdumbdecode:': macdumbdecode,
+ 'macdumbencode:': macdumbencode,
+ 'macdecode:': macdecode,
+ 'macencode:': macencode,
}
-def forbidcrlf(ui, repo, hooktype, node, **kwargs):
+def forbidcrlforcr(ui, repo, hooktype, node, newline, **kwargs):
halt = False
for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()):
c = repo.changectx(rev)
@@ -72,28 +104,37 @@
if f not in c:
continue
data = c[f].data()
- if not util.binary(data) and '\r\n' in data:
+ if not util.binary(data) and newline in data:
if not halt:
ui.warn(_('Attempt to commit or push text file(s) '
- 'using CRLF line endings\n'))
+ 'using %s line endings\n') %
+ newlinestr[newline])
ui.warn(_('in %s: %s\n') % (short(c.node()), f))
halt = True
if halt and hooktype == 'pretxnchangegroup':
+ crlf = newlinestr[newline].lower()
+ filter = filterstr[newline]
ui.warn(_('\nTo prevent this mistake in your local repository,\n'
'add to Mercurial.ini or .hg/hgrc:\n'
'\n'
'[hooks]\n'
- 'pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n'
+ 'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
'\n'
'and also consider adding:\n'
'\n'
'[extensions]\n'
'hgext.win32text =\n'
'[encode]\n'
- '** = cleverencode:\n'
+ '** = %sencode:\n'
'[decode]\n'
- '** = cleverdecode:\n'))
+ '** = %sdecode:\n') % (crlf, crlf, filter, filter))
return halt
+
+def forbidcrlf(ui, repo, hooktype, node, **kwargs):
+ return forbidcrlforcr(ui, repo, hooktype, node, '\r\n', **kwargs)
+
+def forbidcr(ui, repo, hooktype, node, **kwargs):
+ return forbidcrlforcr(ui, repo, hooktype, node, '\r', **kwargs)
def reposetup(ui, repo):
if not repo.local():
diff -r a5e7c5e15e9e -r 840b1f1a93a0 tests/test-mactext
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mactext Thu Apr 03 20:41:31 2008 +0900
@@ -0,0 +1,115 @@
+#!/bin/sh
+
+cat > unix2mac.py <<EOF
+import sys
+
+for path in sys.argv[1:]:
+ data = file(path, 'rb').read()
+ data = data.replace('\n', '\r')
+ file(path, 'wb').write(data)
+EOF
+
+cat > print.py <<EOF
+import sys
+print(sys.stdin.read().replace('\n', '<LF>').replace('\r', '<CR>').replace('\0', '<NUL>'))
+EOF
+
+hg init
+echo '[hooks]' >> .hg/hgrc
+echo 'pretxncommit.cr = python:hgext.win32text.forbidcr' >> .hg/hgrc
+echo 'pretxnchangegroup.cr = python:hgext.win32text.forbidcr' >> .hg/hgrc
+cat .hg/hgrc
+echo
+
+echo hello > f
+hg add f
+hg ci -m 1 -d'0 0'
+echo
+
+python unix2mac.py f
+hg ci -m 2 -d'0 0'
+hg revert -a
+echo
+
+mkdir d
+echo hello > d/f2
+python unix2mac.py d/f2
+hg add d/f2
+hg ci -m 3 -d'0 0'
+hg revert -a
+rm d/f2
+echo
+
+hg rem f
+hg ci -m 4 -d'0 0'
+echo
+
+python -c 'file("bin", "wb").write("hello\x00\x0D")'
+hg add bin
+hg ci -m 5 -d'0 0'
+hg log -v
+echo
+
+hg clone . dupe
+echo
+for x in a b c d; do echo content > dupe/$x; done
+hg -R dupe add
+python unix2mac.py dupe/b dupe/c dupe/d
+hg -R dupe ci -m a -d'0 0' dupe/a
+hg -R dupe ci -m b/c -d'0 0' dupe/[bc]
+hg -R dupe ci -m d -d'0 0' dupe/d
+hg -R dupe log -v
+echo
+
+hg pull dupe
+echo
+
+hg log -v
+echo
+
+rm .hg/hgrc
+(echo some; echo text) > f3
+python -c 'file("f4.bat", "wb").write("rem empty\x0D")'
+hg add f3 f4.bat
+hg ci -m 6 -d'0 0'
+
+python print.py < bin
+python print.py < f3
+python print.py < f4.bat
+echo
+
+echo '[extensions]' >> .hg/hgrc
+echo 'win32text = ' >> .hg/hgrc
+echo '[decode]' >> .hg/hgrc
+echo '** = macdecode:' >> .hg/hgrc
+echo '[encode]' >> .hg/hgrc
+echo '** = macencode:' >> .hg/hgrc
+cat .hg/hgrc
+echo
+
+rm f3 f4.bat bin
+hg co 2>&1 | python -c 'import sys, os; sys.stdout.write(sys.stdin.read().replace(os.getcwd(), "...."))'
+python print.py < bin
+python print.py < f3
+python print.py < f4.bat
+echo
+
+python -c 'file("f5.sh", "wb").write("# empty\x0D")'
+hg add f5.sh
+hg ci -m 7 -d'0 0'
+python print.py < f5.sh
+hg cat f5.sh | python print.py
+
+echo '% just linefeed' > linefeed
+hg ci -qAm 8 linefeed
+python print.py < linefeed
+hg cat linefeed | python print.py
+hg st -q
+hg revert -a linefeed
+python print.py < linefeed
+hg st -q
+echo modified >> linefeed
+hg st -q
+hg revert -a
+hg st -q
+python print.py < linefeed
diff -r a5e7c5e15e9e -r 840b1f1a93a0 tests/test-mactext.out
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mactext.out Thu Apr 03 20:41:31 2008 +0900
@@ -0,0 +1,187 @@
+[hooks]
+pretxncommit.cr = python:hgext.win32text.forbidcr
+pretxnchangegroup.cr = python:hgext.win32text.forbidcr
+
+
+Attempt to commit or push text file(s) using CR line endings
+in dea860dc51ec: f
+transaction abort!
+rollback completed
+abort: pretxncommit.cr hook failed
+reverting f
+
+Attempt to commit or push text file(s) using CR line endings
+in 8aa1d87b4e2f: d/f2
+transaction abort!
+rollback completed
+abort: pretxncommit.cr hook failed
+forgetting d/f2
+
+
+changeset: 2:d7599e43717c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+files: bin
+description:
+5
+
+
+changeset: 1:c72a7d1d0907
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+files: f
+description:
+4
+
+
+changeset: 0:fcf06d5c4e1d
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+files: f
+description:
+1
+
+
+
+updating working directory
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+adding dupe/a
+adding dupe/b
+adding dupe/c
+adding dupe/d
+changeset: 5:ebbcbe52b20e
+tag: tip
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+files: d
+description:
+d
+
+
+changeset: 4:ceeb93d6508a
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+files: b c
+description:
+b/c
+
+
+changeset: 3:c5404edbb872
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+files: a
+description:
+a
+
+
+changeset: 2:d7599e43717c
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+files: bin
+description:
+5
+
+
+changeset: 1:c72a7d1d0907
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+files: f
+description:
+4
+
+
+changeset: 0:fcf06d5c4e1d
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+files: f
+description:
+1
+
+
+
+pulling from dupe
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 3 changesets with 4 changes to 4 files
+Attempt to commit or push text file(s) using CR line endings
+in ceeb93d6508a: b
+in ceeb93d6508a: c
+in ebbcbe52b20e: d
+
+To prevent this mistake in your local repository,
+add to Mercurial.ini or .hg/hgrc:
+
+[hooks]
+pretxncommit.cr = python:hgext.win32text.forbidcr
+
+and also consider adding:
+
+[extensions]
+hgext.win32text =
+[encode]
+** = macencode:
+[decode]
+** = macdecode:
+transaction abort!
+rollback completed
+abort: pretxnchangegroup.cr hook failed
+
+changeset: 2:d7599e43717c
+tag: tip
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+files: bin
+description:
+5
+
+
+changeset: 1:c72a7d1d0907
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+files: f
+description:
+4
+
+
+changeset: 0:fcf06d5c4e1d
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+files: f
+description:
+1
+
+
+
+hello<NUL><CR>
+some<LF>text<LF>
+rem empty<CR>
+
+[extensions]
+win32text =
+[decode]
+** = macdecode:
+[encode]
+** = macencode:
+
+WARNING: f4.bat already has CR line endings
+and does not need EOL conversion by the win32text plugin.
+Before your next commit, please reconsider your encode/decode settings in
+Mercurial.ini or ..../.hg/hgrc.
+3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+hello<NUL><CR>
+some<CR>text<CR>
+rem empty<CR>
+
+# empty<CR>
+# empty<LF>
+% just linefeed<LF>
+% just linefeed<LF>
+no changes needed to linefeed
+% just linefeed<LF>
+M linefeed
+reverting linefeed
+% just linefeed<CR>
More information about the Mercurial-devel
mailing list