hgext/eol.py
author Thomas Arendsen Hein <thomas@intevation.de>
Sun, 05 Sep 2010 22:32:11 +0200
branchstable
changeset 12170 581066a319e5
parent 11249 0bb67503ad4b
child 12062 c327bfa5e831
child 12307 0852da25a31b
permissions -rw-r--r--
verify: fix "missing revlog!" errors for revlog format v0 and add test With revlog format v0 the .d files are empty if the only revision stored is an empty file. Since Mercurial can no longer create format v0 repositories, but still use it, add a script which creates a repository with a single empty file. This can be used in other tests if wanted.
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
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    54
  ``CRLF`` override the default interpretation of ``native`` for
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
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    64
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
    65
used.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    66
"""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    67
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    68
from mercurial.i18n import _
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    69
from mercurial import util, config, extensions, commands, match, cmdutil
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    70
import re, os
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
# 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
    73
singlelf = re.compile('(^|[^\r])\n')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    74
# 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
    75
# 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
    76
# stray CR is an error.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    77
eolre = re.compile('\r*\n')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    78
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    79
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    80
def inconsistenteol(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    81
    return '\r\n' in data and singlelf.search(data)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    82
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    83
def tolf(s, params, ui, **kwargs):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    84
    """Filter to convert to LF EOLs."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    85
    if util.binary(s):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    86
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    87
    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
    88
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    89
    return eolre.sub('\n', s)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    90
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    91
def tocrlf(s, params, ui, **kwargs):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    92
    """Filter to convert to CRLF EOLs."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    93
    if util.binary(s):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    94
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    95
    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
    96
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    97
    return eolre.sub('\r\n', s)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    98
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    99
def isbinary(s, params):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   100
    """Filter to do nothing with the file."""
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
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   103
filters = {
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   104
    'to-lf': tolf,
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   105
    'to-crlf': tocrlf,
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   106
    'is-binary': isbinary,
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
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   109
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   110
def hook(ui, repo, node, hooktype, **kwargs):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   111
    """verify that files have expected EOLs"""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   112
    files = set()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   113
    for rev in xrange(repo[node].rev(), len(repo)):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   114
        files.update(repo[rev].files())
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   115
    tip = repo['tip']
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   116
    for f in files:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   117
        if f not in tip:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   118
            continue
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   119
        for pattern, target in ui.configitems('encode'):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   120
            if match.match(repo.root, '', [pattern])(f):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   121
                data = tip[f].data()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   122
                if target == "to-lf" and "\r\n" in data:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   123
                    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
   124
                                     % f)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   125
                elif target == "to-crlf" and singlelf.search(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   126
                    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
   127
                                     % f)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   128
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   129
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   130
def preupdate(ui, repo, hooktype, parent1, parent2):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   131
    #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
   132
    repo.readhgeol(parent1)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   133
    return False
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   134
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   135
def uisetup(ui):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   136
    ui.setconfig('hooks', 'preupdate.eol', preupdate)
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 extsetup(ui):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   139
    try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   140
        extensions.find('win32text')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   141
        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
   142
                           "win32text extension"))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   143
    except KeyError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   144
        pass
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
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   147
def reposetup(ui, repo):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   148
    #print "reposetup for", repo.root
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   149
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   150
    if not repo.local():
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   151
        return
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   152
    for name, fn in filters.iteritems():
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   153
        repo.adddatafilter(name, fn)
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
    ui.setconfig('patch', 'eol', 'auto')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   156
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   157
    class eolrepo(repo.__class__):
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
        _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
   160
        _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
   161
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   162
        def readhgeol(self, node=None, data=None):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   163
            if data is None:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   164
                try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   165
                    if node is None:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   166
                        data = self.wfile('.hgeol').read()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   167
                    else:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   168
                        data = self[node]['.hgeol'].data()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   169
                except (IOError, LookupError):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   170
                    return None
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   171
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   172
            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
   173
                self._decode['NATIVE'] = 'to-lf'
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   174
            else:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   175
                self._decode['NATIVE'] = 'to-crlf'
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   176
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   177
            eol = config.config()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   178
            eol.parse('.hgeol', data)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   179
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   180
            if eol.get('repository', 'native') == 'CRLF':
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   181
                self._encode['NATIVE'] = 'to-crlf'
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   182
            else:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   183
                self._encode['NATIVE'] = 'to-lf'
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   184
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   185
            for pattern, style in eol.items('patterns'):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   186
                key = style.upper()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   187
                try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   188
                    self.ui.setconfig('decode', pattern, self._decode[key])
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   189
                    self.ui.setconfig('encode', pattern, self._encode[key])
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   190
                except KeyError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   191
                    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
   192
                                 % (style, eol.source('patterns', pattern)))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   193
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   194
            include = []
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   195
            exclude = []
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   196
            for pattern, style in eol.items('patterns'):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   197
                key = style.upper()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   198
                if key == 'BIN':
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   199
                    exclude.append(pattern)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   200
                else:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   201
                    include.append(pattern)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   202
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   203
            # 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
   204
            # about inconsistent newlines.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   205
            return match.match(self.root, '', [], include, exclude)
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
        def _hgcleardirstate(self):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   208
            self._eolfile = self.readhgeol() or self.readhgeol('tip')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   209
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   210
            if not self._eolfile:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   211
                self._eolfile = util.never
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   212
                return
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   213
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   214
            try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   215
                cachemtime = os.path.getmtime(self.join("eol.cache"))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   216
            except OSError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   217
                cachemtime = 0
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   218
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   219
            try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   220
                eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   221
            except OSError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   222
                eolmtime = 0
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   223
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   224
            if eolmtime > cachemtime:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   225
                ui.debug("eol: detected change in .hgeol\n")
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   226
                # 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
   227
                wlock = None
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   228
                try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   229
                    wlock = self.wlock()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   230
                    for f, e in self.dirstate._map.iteritems():
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   231
                        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
   232
                    self.dirstate._dirty = True
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   233
                    # 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
   234
                    # 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
   235
                    # bit to the file?
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   236
                    self.opener("eol.cache", "w").close()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   237
                finally:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   238
                    if wlock is not None:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   239
                        wlock.release()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   240
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   241
        def commitctx(self, ctx, error=False):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   242
            for f in sorted(ctx.added() + ctx.modified()):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   243
                if not self._eolfile(f):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   244
                    continue
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   245
                data = ctx[f].data()
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   246
                if util.binary(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   247
                    # We should not abort here, since the user should
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   248
                    # be able to say "** = native" to automatically
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   249
                    # have all non-binary files taken care of.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   250
                    continue
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   251
                if inconsistenteol(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   252
                    raise util.Abort(_("inconsistent newline style "
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   253
                                       "in %s\n" % f))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   254
            return super(eolrepo, self).commitctx(ctx, error)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   255
    repo.__class__ = eolrepo
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   256
    repo._hgcleardirstate()