hgext/eol.py
author Martin Geisler <mg@aragost.com>
Fri, 04 May 2012 14:39:37 +0200
changeset 16580 80da0352a037
parent 16273 12e3f93b1cbc
child 16683 525fdb738975
permissions -rw-r--r--
test-largefiles: sort output to ensure test stability
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``
13471
bffa00360e13 eol: clarify where the .hgeol file is located
Martin Geisler <mg@aragost.com>
parents: 13127
diff changeset
     9
configuration file found in the root of the working copy. The
11249
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
13124
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    14
The ``[patterns]`` section specifies how line endings should be
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    15
converted between the working copy and the repository. The format is
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    16
specified by a file pattern. The first match is used, so put more
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    17
specific patterns first. The available line endings are ``LF``,
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    18
``CRLF``, and ``BIN``.
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    19
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    20
Files with the declared format of ``CRLF`` or ``LF`` are always
13124
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    21
checked out and stored in the repository in that format and files
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    22
declared to be binary (``BIN``) are left unchanged. Additionally,
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    23
``native`` is an alias for checking out in the platform's default line
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    24
ending: ``LF`` on Unix (including Mac OS X) and ``CRLF`` on
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    25
Windows. Note that ``BIN`` (do nothing to line endings) is Mercurial's
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    26
default behaviour; it is only needed if you need to override a later,
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    27
more general pattern.
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    28
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    29
The optional ``[repository]`` section specifies the line endings to
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    30
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
    31
``native``, which determines the storage line endings for files
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    32
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
    33
``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
    34
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
    35
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
    36
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
    37
are always stored as-is in the repository.
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
Example versioned ``.hgeol`` file::
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    40
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    41
  [patterns]
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    42
  **.py = native
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    43
  **.vcproj = CRLF
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    44
  **.txt = native
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    45
  Makefile = LF
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    46
  **.jpg = BIN
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    47
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    48
  [repository]
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    49
  native = LF
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    50
13124
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    51
.. note::
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    52
   The rules will first apply when files are touched in the working
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    53
   copy, e.g. by updating to null and back to tip to touch all files.
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    54
14856
9f5cd6b6d758 eol: document new eol.fix-trailing-newline setting
Martin Geisler <mg@aragost.com>
parents: 14855
diff changeset
    55
The extension uses an optional ``[eol]`` section read from both the
9f5cd6b6d758 eol: document new eol.fix-trailing-newline setting
Martin Geisler <mg@aragost.com>
parents: 14855
diff changeset
    56
normal Mercurial configuration files and the ``.hgeol`` file, with the
9f5cd6b6d758 eol: document new eol.fix-trailing-newline setting
Martin Geisler <mg@aragost.com>
parents: 14855
diff changeset
    57
latter overriding the former. You can use that section to control the
9f5cd6b6d758 eol: document new eol.fix-trailing-newline setting
Martin Geisler <mg@aragost.com>
parents: 14855
diff changeset
    58
overall behavior. There are three settings:
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    59
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    60
- ``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
    61
  ``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
    62
  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
    63
  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
    64
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    65
- ``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
    66
  the extension convert files with inconsistent EOLs. Inconsistent
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    67
  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
    68
  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
    69
  have mixed EOLs on purpose.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    70
14856
9f5cd6b6d758 eol: document new eol.fix-trailing-newline setting
Martin Geisler <mg@aragost.com>
parents: 14855
diff changeset
    71
- ``eol.fix-trailing-newline`` (default False) can be set to True to
14857
5b46c16e7121 eol: fix silly test-gendoc breakage by escaping control characters
Matt Mackall <mpm@selenic.com>
parents: 14856
diff changeset
    72
  ensure that converted files end with a EOL character (either ``\\n``
5b46c16e7121 eol: fix silly test-gendoc breakage by escaping control characters
Matt Mackall <mpm@selenic.com>
parents: 14856
diff changeset
    73
  or ``\\r\\n`` as per the configured patterns).
14856
9f5cd6b6d758 eol: document new eol.fix-trailing-newline setting
Martin Geisler <mg@aragost.com>
parents: 14855
diff changeset
    74
12979
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
    75
The extension provides ``cleverencode:`` and ``cleverdecode:`` filters
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
    76
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
    77
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
    78
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
    79
12980
20974e51383a eol: mention the hook in the module docstring
Martin Geisler <mg@lazybytes.net>
parents: 12974
diff changeset
    80
The ``win32text.forbid*`` hooks provided by the win32text extension
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
    81
have been unified into a single hook named ``eol.checkheadshook``. The
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
    82
hook will lookup the expected line endings from the ``.hgeol`` file,
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
    83
which means you must migrate to a ``.hgeol`` file first before using
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
    84
the hook. ``eol.checkheadshook`` only checks heads, intermediate
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
    85
invalid revisions will be pushed. To forbid them completely, use the
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
    86
``eol.checkallhook`` hook. These hooks are best used as
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
    87
``pretxnchangegroup`` hooks.
12980
20974e51383a eol: mention the hook in the module docstring
Martin Geisler <mg@lazybytes.net>
parents: 12974
diff changeset
    88
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    89
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
    90
used.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    91
"""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    92
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    93
from mercurial.i18n import _
13475
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
    94
from mercurial import util, config, extensions, match, error
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    95
import re, os
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    96
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    97
# 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
    98
singlelf = re.compile('(^|[^\r])\n')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    99
# 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
   100
# 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
   101
# stray CR is an error.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   102
eolre = re.compile('\r*\n')
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
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   105
def inconsistenteol(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   106
    return '\r\n' in data and singlelf.search(data)
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
def tolf(s, params, ui, **kwargs):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   109
    """Filter to convert to LF EOLs."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   110
    if util.binary(s):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   111
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   112
    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
   113
        return s
14855
f33579435378 eol: fix missing trailing newlines in comitted files
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 14854
diff changeset
   114
    if ui.configbool('eol', 'fix-trailing-newline', False) and s and s[-1] != '\n':
f33579435378 eol: fix missing trailing newlines in comitted files
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 14854
diff changeset
   115
        s = s + '\n'
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   116
    return eolre.sub('\n', s)
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 tocrlf(s, params, ui, **kwargs):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   119
    """Filter to convert to CRLF EOLs."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   120
    if util.binary(s):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   121
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   122
    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
   123
        return s
14855
f33579435378 eol: fix missing trailing newlines in comitted files
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 14854
diff changeset
   124
    if ui.configbool('eol', 'fix-trailing-newline', False) and s and s[-1] != '\n':
f33579435378 eol: fix missing trailing newlines in comitted files
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 14854
diff changeset
   125
        s = s + '\n'
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   126
    return eolre.sub('\r\n', s)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   127
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   128
def isbinary(s, params):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   129
    """Filter to do nothing with the file."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   130
    return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   131
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   132
filters = {
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   133
    'to-lf': tolf,
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   134
    'to-crlf': tocrlf,
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   135
    'is-binary': isbinary,
12975
278e3c9b939e eol: added filter aliases for backwards compatibility with win32text
Colin Caughie <c.caughie@indigovision.com>
parents: 12802
diff changeset
   136
    # 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
   137
    'cleverencode:': tolf,
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
   138
    'cleverdecode:': tocrlf
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   139
}
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   140
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   141
class eolfile(object):
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   142
    def __init__(self, ui, root, data):
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   143
        self._decode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   144
        self._encode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   145
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   146
        self.cfg = config.config()
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   147
        # Our files should not be touched. The pattern must be
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   148
        # inserted first override a '** = native' pattern.
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   149
        self.cfg.set('patterns', '.hg*', 'BIN')
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   150
        # We can then parse the user's patterns.
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   151
        self.cfg.parse('.hgeol', data)
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   152
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   153
        isrepolf = self.cfg.get('repository', 'native') != 'CRLF'
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   154
        self._encode['NATIVE'] = isrepolf and 'to-lf' or 'to-crlf'
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   155
        iswdlf = ui.config('eol', 'native', os.linesep) in ('LF', '\n')
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   156
        self._decode['NATIVE'] = iswdlf and 'to-lf' or 'to-crlf'
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   157
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   158
        include = []
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   159
        exclude = []
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   160
        for pattern, style in self.cfg.items('patterns'):
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   161
            key = style.upper()
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   162
            if key == 'BIN':
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   163
                exclude.append(pattern)
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   164
            else:
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   165
                include.append(pattern)
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   166
        # This will match the files for which we need to care
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   167
        # about inconsistent newlines.
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   168
        self.match = match.match(root, '', [], include, exclude)
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   169
14854
23c2d7d25329 eol: eol.only-consistent can now be specified in .hgeol
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 13650
diff changeset
   170
    def copytoui(self, ui):
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   171
        for pattern, style in self.cfg.items('patterns'):
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   172
            key = style.upper()
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   173
            try:
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   174
                ui.setconfig('decode', pattern, self._decode[key])
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   175
                ui.setconfig('encode', pattern, self._encode[key])
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   176
            except KeyError:
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   177
                ui.warn(_("ignoring unknown EOL style '%s' from %s\n")
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   178
                        % (style, self.cfg.source('patterns', pattern)))
14854
23c2d7d25329 eol: eol.only-consistent can now be specified in .hgeol
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 13650
diff changeset
   179
        # eol.only-consistent can be specified in ~/.hgrc or .hgeol
23c2d7d25329 eol: eol.only-consistent can now be specified in .hgeol
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 13650
diff changeset
   180
        for k, v in self.cfg.items('eol'):
23c2d7d25329 eol: eol.only-consistent can now be specified in .hgeol
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 13650
diff changeset
   181
            ui.setconfig('eol', k, v)
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   182
13615
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   183
    def checkrev(self, repo, ctx, files):
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   184
        failed = []
13650
56e71e7d2ba2 eol: no need to accumulate files when checking all changesets
Patrick Mezard <pmezard@gmail.com>
parents: 13649
diff changeset
   185
        for f in (files or ctx.files()):
13615
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   186
            if f not in ctx:
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   187
                continue
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   188
            for pattern, style in self.cfg.items('patterns'):
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   189
                if not match.match(repo.root, '', [pattern])(f):
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   190
                    continue
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   191
                target = self._encode[style.upper()]
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   192
                data = ctx[f].data()
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   193
                if (target == "to-lf" and "\r\n" in data
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   194
                    or target == "to-crlf" and singlelf.search(data)):
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   195
                    failed.append((str(ctx), target, f))
13501
50b825c1adb1 eol: stop after first matched rule in hook (issue2660)
Antoine Pitrou <solipsis@pitrou.net>
parents: 13475
diff changeset
   196
                break
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   197
        return failed
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   198
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   199
def parseeol(ui, repo, nodes):
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   200
    try:
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   201
        for node in nodes:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   202
            try:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   203
                if node is None:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   204
                    # Cannot use workingctx.data() since it would load
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   205
                    # and cache the filters before we configure them.
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   206
                    data = repo.wfile('.hgeol').read()
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   207
                else:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   208
                    data = repo[node]['.hgeol'].data()
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   209
                return eolfile(ui, repo.root, data)
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   210
            except (IOError, LookupError):
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   211
                pass
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   212
    except error.ParseError, inst:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   213
        ui.warn(_("warning: ignoring .hgeol file due to parse error "
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   214
                  "at %s: %s\n") % (inst.args[1], inst.args[0]))
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   215
    return None
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   216
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   217
def _checkhook(ui, repo, node, headsonly):
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   218
    # Get revisions to check and touched files at the same time
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   219
    files = set()
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   220
    revs = set()
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   221
    for rev in xrange(repo[node].rev(), len(repo)):
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   222
        revs.add(rev)
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   223
        if headsonly:
13650
56e71e7d2ba2 eol: no need to accumulate files when checking all changesets
Patrick Mezard <pmezard@gmail.com>
parents: 13649
diff changeset
   224
            ctx = repo[rev]
56e71e7d2ba2 eol: no need to accumulate files when checking all changesets
Patrick Mezard <pmezard@gmail.com>
parents: 13649
diff changeset
   225
            files.update(ctx.files())
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   226
            for pctx in ctx.parents():
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   227
                revs.discard(pctx.rev())
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   228
    failed = []
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   229
    for rev in revs:
13616
e6f93ca9ce86 eol: make the hook check all new heads, not only tip (issue2666)
Patrick Mezard <pmezard@gmail.com>
parents: 13615
diff changeset
   230
        ctx = repo[rev]
e6f93ca9ce86 eol: make the hook check all new heads, not only tip (issue2666)
Patrick Mezard <pmezard@gmail.com>
parents: 13615
diff changeset
   231
        eol = parseeol(ui, repo, [ctx.node()])
e6f93ca9ce86 eol: make the hook check all new heads, not only tip (issue2666)
Patrick Mezard <pmezard@gmail.com>
parents: 13615
diff changeset
   232
        if eol:
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   233
            failed.extend(eol.checkrev(repo, ctx, files))
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   234
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   235
    if failed:
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   236
        eols = {'to-lf': 'CRLF', 'to-crlf': 'LF'}
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   237
        msgs = []
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   238
        for node, target, f in failed:
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   239
            msgs.append(_("  %s in %s should not have %s line endings") %
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   240
                        (f, node, eols[target]))
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   241
        raise util.Abort(_("end-of-line check failed:\n") + "\n".join(msgs))
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   242
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   243
def checkallhook(ui, repo, node, hooktype, **kwargs):
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   244
    """verify that files have expected EOLs"""
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   245
    _checkhook(ui, repo, node, False)
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   246
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   247
def checkheadshook(ui, repo, node, hooktype, **kwargs):
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   248
    """verify that files have expected EOLs"""
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   249
    _checkhook(ui, repo, node, True)
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   250
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   251
# "checkheadshook" used to be called "hook"
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   252
hook = checkheadshook
11249
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 preupdate(ui, repo, hooktype, parent1, parent2):
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   255
    repo.loadeol([parent1])
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   256
    return False
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   257
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   258
def uisetup(ui):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   259
    ui.setconfig('hooks', 'preupdate.eol', preupdate)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   260
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   261
def extsetup(ui):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   262
    try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   263
        extensions.find('win32text')
13624
78cc35e75ecc eol: do not abort when win32text is found, only warn
Steve Borho <steve@borho.org>
parents: 13581
diff changeset
   264
        ui.warn(_("the eol extension is incompatible with the "
78cc35e75ecc eol: do not abort when win32text is found, only warn
Steve Borho <steve@borho.org>
parents: 13581
diff changeset
   265
                  "win32text extension\n"))
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   266
    except KeyError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   267
        pass
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   268
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   269
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   270
def reposetup(ui, repo):
12307
0852da25a31b eol: setup the repo.ui in reposetup()
Steve Borho <steve@borho.org>
parents: 11249
diff changeset
   271
    uisetup(repo.ui)
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   272
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   273
    if not repo.local():
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   274
        return
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   275
    for name, fn in filters.iteritems():
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   276
        repo.adddatafilter(name, fn)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   277
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   278
    ui.setconfig('patch', 'eol', 'auto')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   279
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   280
    class eolrepo(repo.__class__):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   281
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   282
        def loadeol(self, nodes):
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   283
            eol = parseeol(self.ui, self, nodes)
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   284
            if eol is None:
13612
21367c3da8aa eol: remove unused argument in readhgeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13611
diff changeset
   285
                return None
14854
23c2d7d25329 eol: eol.only-consistent can now be specified in .hgeol
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 13650
diff changeset
   286
            eol.copytoui(self.ui)
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   287
            return eol.match
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   288
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   289
        def _hgcleardirstate(self):
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   290
            self._eolfile = self.loadeol([None, 'tip'])
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   291
            if not self._eolfile:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   292
                self._eolfile = util.never
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   293
                return
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   294
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   295
            try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   296
                cachemtime = os.path.getmtime(self.join("eol.cache"))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   297
            except OSError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   298
                cachemtime = 0
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   299
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   300
            try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   301
                eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   302
            except OSError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   303
                eolmtime = 0
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   304
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   305
            if eolmtime > cachemtime:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   306
                ui.debug("eol: detected change in .hgeol\n")
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   307
                wlock = None
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   308
                try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   309
                    wlock = self.wlock()
13581
b30a488762e1 eol: use dirstate methods to clear dirstate
Martin Geisler <mg@lazybytes.net>
parents: 13505
diff changeset
   310
                    for f in self.dirstate:
b30a488762e1 eol: use dirstate methods to clear dirstate
Martin Geisler <mg@lazybytes.net>
parents: 13505
diff changeset
   311
                        if self.dirstate[f] == 'n':
b30a488762e1 eol: use dirstate methods to clear dirstate
Martin Geisler <mg@lazybytes.net>
parents: 13505
diff changeset
   312
                            # all normal files need to be looked at
b30a488762e1 eol: use dirstate methods to clear dirstate
Martin Geisler <mg@lazybytes.net>
parents: 13505
diff changeset
   313
                            # again since the new .hgeol file might no
b30a488762e1 eol: use dirstate methods to clear dirstate
Martin Geisler <mg@lazybytes.net>
parents: 13505
diff changeset
   314
                            # longer match a file it matched before
b30a488762e1 eol: use dirstate methods to clear dirstate
Martin Geisler <mg@lazybytes.net>
parents: 13505
diff changeset
   315
                            self.dirstate.normallookup(f)
16272
f97e7c378349 eol: document why os.utime doesn't work here
Martin Geisler <mg@aragost.com>
parents: 14866
diff changeset
   316
                    # Create or touch the cache to update mtime
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   317
                    self.opener("eol.cache", "w").close()
13475
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   318
                    wlock.release()
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   319
                except error.LockUnavailable:
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   320
                    # If we cannot lock the repository and clear the
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   321
                    # dirstate, then a commit might not see all files
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   322
                    # as modified. But if we cannot lock the
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   323
                    # repository, then we can also not make a commit,
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   324
                    # so ignore the error.
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   325
                    pass
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   326
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   327
        def commitctx(self, ctx, error=False):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   328
            for f in sorted(ctx.added() + ctx.modified()):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   329
                if not self._eolfile(f):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   330
                    continue
14862
abf915f537be eol: ignore IOError from deleted files in commitctx
Nicholas Riley <njriley@illinois.edu>
parents: 13650
diff changeset
   331
                try:
abf915f537be eol: ignore IOError from deleted files in commitctx
Nicholas Riley <njriley@illinois.edu>
parents: 13650
diff changeset
   332
                    data = ctx[f].data()
abf915f537be eol: ignore IOError from deleted files in commitctx
Nicholas Riley <njriley@illinois.edu>
parents: 13650
diff changeset
   333
                except IOError:
abf915f537be eol: ignore IOError from deleted files in commitctx
Nicholas Riley <njriley@illinois.edu>
parents: 13650
diff changeset
   334
                    continue
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   335
                if util.binary(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   336
                    # We should not abort here, since the user should
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   337
                    # be able to say "** = native" to automatically
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   338
                    # have all non-binary files taken care of.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   339
                    continue
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   340
                if inconsistenteol(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   341
                    raise util.Abort(_("inconsistent newline style "
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   342
                                       "in %s\n" % f))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   343
            return super(eolrepo, self).commitctx(ctx, error)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   344
    repo.__class__ = eolrepo
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   345
    repo._hgcleardirstate()