hgext/eol.py
author Martin Geisler <mg@lazybytes.net>
Sat, 13 Nov 2010 15:46:51 +0100
changeset 12979 733345a127ca
parent 12976 793563fd88c0
child 12981 df7c2f81afd5
permissions -rw-r--r--
eol: fix win32text encode/decode filter names
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     1
"""automatically manage newlines in repository files
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     2
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     3
This extension allows you to manage the type of line endings (CRLF or
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     4
LF) that are used in the repository and in the local working
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     5
directory. That way you can get CRLF line endings on Windows and LF on
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     6
Unix/Mac, thereby letting everybody use their OS native line endings.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     7
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     8
The extension reads its configuration from a versioned ``.hgeol``
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     9
configuration file every time you run an ``hg`` command. The
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    10
``.hgeol`` file use the same syntax as all other Mercurial
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    11
configuration files. It uses two sections, ``[patterns]`` and
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    12
``[repository]``.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    13
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    14
The ``[patterns]`` section specifies the line endings used in the
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    15
working directory. The format is specified by a file pattern. The
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    16
first match is used, so put more specific patterns first. The
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    17
available line endings are ``LF``, ``CRLF``, and ``BIN``.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    18
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    19
Files with the declared format of ``CRLF`` or ``LF`` are always
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    20
checked out in that format and files declared to be binary (``BIN``)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    21
are left unchanged. Additionally, ``native`` is an alias for the
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    22
platform's default line ending: ``LF`` on Unix (including Mac OS X)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    23
and ``CRLF`` on Windows. Note that ``BIN`` (do nothing to line
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    24
endings) is Mercurial's default behaviour; it is only needed if you
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    25
need to override a later, more general pattern.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    26
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    27
The optional ``[repository]`` section specifies the line endings to
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    28
use for files stored in the repository. It has a single setting,
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    29
``native``, which determines the storage line endings for files
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    30
declared as ``native`` in the ``[patterns]`` section. It can be set to
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    31
``LF`` or ``CRLF``. The default is ``LF``. For example, this means
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    32
that on Windows, files configured as ``native`` (``CRLF`` by default)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    33
will be converted to ``LF`` when stored in the repository. Files
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    34
declared as ``LF``, ``CRLF``, or ``BIN`` in the ``[patterns]`` section
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    35
are always stored as-is in the repository.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    36
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    37
Example versioned ``.hgeol`` file::
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    38
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    39
  [patterns]
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    40
  **.py = native
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    41
  **.vcproj = CRLF
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    42
  **.txt = native
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    43
  Makefile = LF
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    44
  **.jpg = BIN
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    45
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    46
  [repository]
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    47
  native = LF
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    48
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    49
The extension uses an optional ``[eol]`` section in your hgrc file
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    50
(not the ``.hgeol`` file) for settings that control the overall
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    51
behavior. There are two settings:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    52
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    53
- ``eol.native`` (default ``os.linesep``) can be set to ``LF`` or
12802
c82cd7b08158 eol: add missing word in module docstring
Georg Brandl <georg@python.org>
parents: 12308
diff changeset
    54
  ``CRLF`` to override the default interpretation of ``native`` for
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    55
  checkout. This can be used with :hg:`archive` on Unix, say, to
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    56
  generate an archive where files have line endings for Windows.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    57
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    58
- ``eol.only-consistent`` (default True) can be set to False to make
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    59
  the extension convert files with inconsistent EOLs. Inconsistent
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    60
  means that there is both ``CRLF`` and ``LF`` present in the file.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    61
  Such files are normally not touched under the assumption that they
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    62
  have mixed EOLs on purpose.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    63
12979
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
    64
The extension provides ``cleverencode:`` and ``cleverdecode:`` filters
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
    65
like the deprecated win32text extension does. This means that you can
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
    66
disable win32text and enable eol and your filters will still work. You
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
    67
only need to these filters until you have prepared a ``.hgeol`` file.
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
    68
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    69
See :hg:`help patterns` for more information about the glob patterns
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    70
used.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    71
"""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    72
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    73
from mercurial.i18n import _
12062
c327bfa5e831 cleanup: remove unused imports
Brodie Rao <brodie@bitheap.org>
parents: 11249
diff changeset
    74
from mercurial import util, config, extensions, match
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    75
import re, os
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    76
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    77
# Matches a lone LF, i.e., one that is not part of CRLF.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    78
singlelf = re.compile('(^|[^\r])\n')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    79
# Matches a single EOL which can either be a CRLF where repeated CR
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    80
# are removed or a LF. We do not care about old Machintosh files, so a
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    81
# stray CR is an error.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    82
eolre = re.compile('\r*\n')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    83
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    84
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    85
def inconsistenteol(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    86
    return '\r\n' in data and singlelf.search(data)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    87
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    88
def tolf(s, params, ui, **kwargs):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    89
    """Filter to convert to LF EOLs."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    90
    if util.binary(s):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    91
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    92
    if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    93
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    94
    return eolre.sub('\n', s)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    95
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    96
def tocrlf(s, params, ui, **kwargs):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    97
    """Filter to convert to CRLF EOLs."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    98
    if util.binary(s):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    99
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   100
    if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   101
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   102
    return eolre.sub('\r\n', s)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   103
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   104
def isbinary(s, params):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   105
    """Filter to do nothing with the file."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   106
    return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   107
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   108
filters = {
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   109
    'to-lf': tolf,
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   110
    'to-crlf': tocrlf,
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   111
    'is-binary': isbinary,
12975
278e3c9b939e eol: added filter aliases for backwards compatibility with win32text
Colin Caughie <c.caughie@indigovision.com>
parents: 12802
diff changeset
   112
    # The following provide backwards compatibility with win32text
12979
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
   113
    'cleverencode:': tolf,
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
   114
    'cleverdecode:': tocrlf
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   115
}
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   116
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   117
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   118
def hook(ui, repo, node, hooktype, **kwargs):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   119
    """verify that files have expected EOLs"""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   120
    files = set()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   121
    for rev in xrange(repo[node].rev(), len(repo)):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   122
        files.update(repo[rev].files())
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   123
    tip = repo['tip']
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   124
    for f in files:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   125
        if f not in tip:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   126
            continue
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   127
        for pattern, target in ui.configitems('encode'):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   128
            if match.match(repo.root, '', [pattern])(f):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   129
                data = tip[f].data()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   130
                if target == "to-lf" and "\r\n" in data:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   131
                    raise util.Abort(_("%s should not have CRLF line endings")
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   132
                                     % f)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   133
                elif target == "to-crlf" and singlelf.search(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   134
                    raise util.Abort(_("%s should not have LF line endings")
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   135
                                     % f)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   136
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   137
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   138
def preupdate(ui, repo, hooktype, parent1, parent2):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   139
    #print "preupdate for %s: %s -> %s" % (repo.root, parent1, parent2)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   140
    repo.readhgeol(parent1)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   141
    return False
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   142
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   143
def uisetup(ui):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   144
    ui.setconfig('hooks', 'preupdate.eol', preupdate)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   145
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   146
def extsetup(ui):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   147
    try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   148
        extensions.find('win32text')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   149
        raise util.Abort(_("the eol extension is incompatible with the "
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   150
                           "win32text extension"))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   151
    except KeyError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   152
        pass
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   153
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   154
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   155
def reposetup(ui, repo):
12307
0852da25a31b eol: setup the repo.ui in reposetup()
Steve Borho <steve@borho.org>
parents: 11249
diff changeset
   156
    uisetup(repo.ui)
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   157
    #print "reposetup for", repo.root
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   158
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   159
    if not repo.local():
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   160
        return
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   161
    for name, fn in filters.iteritems():
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   162
        repo.adddatafilter(name, fn)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   163
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   164
    ui.setconfig('patch', 'eol', 'auto')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   165
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   166
    class eolrepo(repo.__class__):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   167
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   168
        _decode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   169
        _encode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   170
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   171
        def readhgeol(self, node=None, data=None):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   172
            if data is None:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   173
                try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   174
                    if node is None:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   175
                        data = self.wfile('.hgeol').read()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   176
                    else:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   177
                        data = self[node]['.hgeol'].data()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   178
                except (IOError, LookupError):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   179
                    return None
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   180
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   181
            if self.ui.config('eol', 'native', os.linesep) in ('LF', '\n'):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   182
                self._decode['NATIVE'] = 'to-lf'
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   183
            else:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   184
                self._decode['NATIVE'] = 'to-crlf'
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   185
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   186
            eol = config.config()
12974
75e4fade4ad9 eol: exclude .hgtags file from eol translation (issue2493)
Colin Caughie <c.caughie@indigovision.com>
parents: 12802
diff changeset
   187
            # Our files should not be touched. The pattern must be
75e4fade4ad9 eol: exclude .hgtags file from eol translation (issue2493)
Colin Caughie <c.caughie@indigovision.com>
parents: 12802
diff changeset
   188
            # inserted first override a '** = native' pattern.
75e4fade4ad9 eol: exclude .hgtags file from eol translation (issue2493)
Colin Caughie <c.caughie@indigovision.com>
parents: 12802
diff changeset
   189
            eol.set('patterns', '.hg*', 'BIN')
75e4fade4ad9 eol: exclude .hgtags file from eol translation (issue2493)
Colin Caughie <c.caughie@indigovision.com>
parents: 12802
diff changeset
   190
            # We can then parse the user's patterns.
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   191
            eol.parse('.hgeol', data)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   192
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   193
            if eol.get('repository', 'native') == 'CRLF':
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   194
                self._encode['NATIVE'] = 'to-crlf'
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   195
            else:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   196
                self._encode['NATIVE'] = 'to-lf'
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   197
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   198
            for pattern, style in eol.items('patterns'):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   199
                key = style.upper()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   200
                try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   201
                    self.ui.setconfig('decode', pattern, self._decode[key])
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   202
                    self.ui.setconfig('encode', pattern, self._encode[key])
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   203
                except KeyError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   204
                    self.ui.warn(_("ignoring unknown EOL style '%s' from %s\n")
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   205
                                 % (style, eol.source('patterns', pattern)))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   206
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   207
            include = []
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   208
            exclude = []
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   209
            for pattern, style in eol.items('patterns'):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   210
                key = style.upper()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   211
                if key == 'BIN':
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   212
                    exclude.append(pattern)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   213
                else:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   214
                    include.append(pattern)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   215
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   216
            # This will match the files for which we need to care
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   217
            # about inconsistent newlines.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   218
            return match.match(self.root, '', [], include, exclude)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   219
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   220
        def _hgcleardirstate(self):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   221
            self._eolfile = self.readhgeol() or self.readhgeol('tip')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   222
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   223
            if not self._eolfile:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   224
                self._eolfile = util.never
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   225
                return
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   226
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   227
            try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   228
                cachemtime = os.path.getmtime(self.join("eol.cache"))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   229
            except OSError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   230
                cachemtime = 0
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   231
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   232
            try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   233
                eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   234
            except OSError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   235
                eolmtime = 0
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   236
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   237
            if eolmtime > cachemtime:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   238
                ui.debug("eol: detected change in .hgeol\n")
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   239
                # TODO: we could introduce a method for this in dirstate.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   240
                wlock = None
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   241
                try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   242
                    wlock = self.wlock()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   243
                    for f, e in self.dirstate._map.iteritems():
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   244
                        self.dirstate._map[f] = (e[0], e[1], -1, 0)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   245
                    self.dirstate._dirty = True
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   246
                    # Touch the cache to update mtime. TODO: are we sure this
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   247
                    # always enought to update the mtime, or should we write a
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   248
                    # bit to the file?
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   249
                    self.opener("eol.cache", "w").close()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   250
                finally:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   251
                    if wlock is not None:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   252
                        wlock.release()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   253
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   254
        def commitctx(self, ctx, error=False):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   255
            for f in sorted(ctx.added() + ctx.modified()):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   256
                if not self._eolfile(f):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   257
                    continue
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   258
                data = ctx[f].data()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   259
                if util.binary(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   260
                    # We should not abort here, since the user should
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   261
                    # be able to say "** = native" to automatically
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   262
                    # have all non-binary files taken care of.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   263
                    continue
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   264
                if inconsistenteol(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   265
                    raise util.Abort(_("inconsistent newline style "
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   266
                                       "in %s\n" % f))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   267
            return super(eolrepo, self).commitctx(ctx, error)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   268
    repo.__class__ = eolrepo
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   269
    repo._hgcleardirstate()