Mercurial > hg-stable
view hgext/win32text.py @ 7513:fed8f75f29ce
convert-cvs: correctly handle Removed replies, fixes bug 1427
author | Frank Kingswood <frank@kingswood-consulting.co.uk> |
---|---|
date | Thu, 11 Dec 2008 13:33:35 +0000 |
parents | 59b4ae211584 |
children | 4a4c7f6a5912 |
line wrap: on
line source
# 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. # # To perform automatic newline conversion, use: # # [extensions] # hgext.win32text = # [encode] # ** = cleverencode: # # or ** = macencode: # [decode] # ** = cleverdecode: # # or ** = macdecode: # # 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/CR from being pushed or # pulled: # # [hooks] # pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf # # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr from mercurial.i18n import _ from mercurial.node import bin, short from mercurial import util import re # regexp for single LF without CR preceding. re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE) 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 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, 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 not util.binary(s): return dumbdecode(s, cmd, **kwargs) return s def cleverencode(s, cmd): if not util.binary(s): return dumbencode(s, cmd) return s def macdecode(s, cmd, **kwargs): if not util.binary(s): return macdumbdecode(s, cmd, **kwargs) return s def macencode(s, cmd): if not util.binary(s): return macdumbencode(s, cmd) return s _filters = { 'dumbdecode:': dumbdecode, 'dumbencode:': dumbencode, 'cleverdecode:': cleverdecode, 'cleverencode:': cleverencode, 'macdumbdecode:': macdumbdecode, 'macdumbencode:': macdumbencode, 'macdecode:': macdecode, 'macencode:': macencode, } def forbidnewline(ui, repo, hooktype, node, newline, **kwargs): halt = False for rev in xrange(repo[node].rev(), len(repo)): c = repo[rev] for f in c.files(): if f not in c: continue data = c[f].data() if not util.binary(data) and newline in data: if not halt: ui.warn(_('Attempt to commit or push text file(s) ' '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.%s = python:hgext.win32text.forbid%s\n' '\n' 'and also consider adding:\n' '\n' '[extensions]\n' 'hgext.win32text =\n' '[encode]\n' '** = %sencode:\n' '[decode]\n' '** = %sdecode:\n') % (crlf, crlf, filter, filter)) return halt def forbidcrlf(ui, repo, hooktype, node, **kwargs): return forbidnewline(ui, repo, hooktype, node, '\r\n', **kwargs) def forbidcr(ui, repo, hooktype, node, **kwargs): return forbidnewline(ui, repo, hooktype, node, '\r', **kwargs) def reposetup(ui, repo): if not repo.local(): return for name, fn in _filters.iteritems(): repo.adddatafilter(name, fn)