hgext/eol.py
author timeless@mozdev.org
Fri, 17 Aug 2012 13:58:18 -0700
changeset 17501 26dd532456cf
parent 16743 38caf405d010
child 17955 4ae21a7568f3
permissions -rw-r--r--
spelling: Macintosh
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
16743
38caf405d010 hgext: mark all first-party extensions as such
Augie Fackler <raf@durin42.com>
parents: 16683
diff changeset
    97
testedwith = 'internal'
38caf405d010 hgext: mark all first-party extensions as such
Augie Fackler <raf@durin42.com>
parents: 16683
diff changeset
    98
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    99
# 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
   100
singlelf = re.compile('(^|[^\r])\n')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   101
# Matches a single EOL which can either be a CRLF where repeated CR
17501
26dd532456cf spelling: Macintosh
timeless@mozdev.org
parents: 16743
diff changeset
   102
# are removed or a LF. We do not care about old Macintosh files, so a
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   103
# stray CR is an error.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   104
eolre = re.compile('\r*\n')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   105
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   106
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   107
def inconsistenteol(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   108
    return '\r\n' in data and singlelf.search(data)
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 tolf(s, params, ui, **kwargs):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   111
    """Filter to convert to LF EOLs."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   112
    if util.binary(s):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   113
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   114
    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
   115
        return s
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16273
diff changeset
   116
    if (ui.configbool('eol', 'fix-trailing-newline', False)
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16273
diff changeset
   117
        and s and s[-1] != '\n'):
14855
f33579435378 eol: fix missing trailing newlines in comitted files
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 14854
diff changeset
   118
        s = s + '\n'
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   119
    return eolre.sub('\n', s)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   120
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   121
def tocrlf(s, params, ui, **kwargs):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   122
    """Filter to convert to CRLF EOLs."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   123
    if util.binary(s):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   124
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   125
    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
   126
        return s
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16273
diff changeset
   127
    if (ui.configbool('eol', 'fix-trailing-newline', False)
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16273
diff changeset
   128
        and s and s[-1] != '\n'):
14855
f33579435378 eol: fix missing trailing newlines in comitted files
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 14854
diff changeset
   129
        s = s + '\n'
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   130
    return eolre.sub('\r\n', 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
def isbinary(s, params):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   133
    """Filter to do nothing with the file."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   134
    return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   135
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   136
filters = {
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   137
    'to-lf': tolf,
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   138
    'to-crlf': tocrlf,
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   139
    'is-binary': isbinary,
12975
278e3c9b939e eol: added filter aliases for backwards compatibility with win32text
Colin Caughie <c.caughie@indigovision.com>
parents: 12802
diff changeset
   140
    # 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
   141
    'cleverencode:': tolf,
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
   142
    'cleverdecode:': tocrlf
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   143
}
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   144
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   145
class eolfile(object):
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   146
    def __init__(self, ui, root, data):
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   147
        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
   148
        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
   149
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   150
        self.cfg = config.config()
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   151
        # 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
   152
        # inserted first override a '** = native' pattern.
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   153
        self.cfg.set('patterns', '.hg*', 'BIN')
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   154
        # 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
   155
        self.cfg.parse('.hgeol', data)
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   156
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   157
        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
   158
        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
   159
        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
   160
        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
   161
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   162
        include = []
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   163
        exclude = []
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   164
        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
   165
            key = style.upper()
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   166
            if key == 'BIN':
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   167
                exclude.append(pattern)
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   168
            else:
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   169
                include.append(pattern)
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   170
        # 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
   171
        # about inconsistent newlines.
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   172
        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
   173
14854
23c2d7d25329 eol: eol.only-consistent can now be specified in .hgeol
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 13650
diff changeset
   174
    def copytoui(self, ui):
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   175
        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
   176
            key = style.upper()
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   177
            try:
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   178
                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
   179
                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
   180
            except KeyError:
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   181
                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
   182
                        % (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
   183
        # 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
   184
        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
   185
            ui.setconfig('eol', k, v)
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   186
13615
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   187
    def checkrev(self, repo, ctx, files):
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   188
        failed = []
13650
56e71e7d2ba2 eol: no need to accumulate files when checking all changesets
Patrick Mezard <pmezard@gmail.com>
parents: 13649
diff changeset
   189
        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
   190
            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
   191
                continue
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   192
            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
   193
                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
   194
                    continue
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   195
                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
   196
                data = ctx[f].data()
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   197
                if (target == "to-lf" and "\r\n" in data
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   198
                    or target == "to-crlf" and singlelf.search(data)):
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   199
                    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
   200
                break
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   201
        return failed
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   202
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   203
def parseeol(ui, repo, nodes):
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   204
    try:
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   205
        for node in nodes:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   206
            try:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   207
                if node is None:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   208
                    # 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
   209
                    # 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
   210
                    data = repo.wfile('.hgeol').read()
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   211
                else:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   212
                    data = repo[node]['.hgeol'].data()
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   213
                return eolfile(ui, repo.root, data)
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   214
            except (IOError, LookupError):
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   215
                pass
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   216
    except error.ParseError, inst:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   217
        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
   218
                  "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
   219
    return None
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   220
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   221
def _checkhook(ui, repo, node, headsonly):
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   222
    # 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
   223
    files = set()
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   224
    revs = set()
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   225
    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
   226
        revs.add(rev)
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   227
        if headsonly:
13650
56e71e7d2ba2 eol: no need to accumulate files when checking all changesets
Patrick Mezard <pmezard@gmail.com>
parents: 13649
diff changeset
   228
            ctx = repo[rev]
56e71e7d2ba2 eol: no need to accumulate files when checking all changesets
Patrick Mezard <pmezard@gmail.com>
parents: 13649
diff changeset
   229
            files.update(ctx.files())
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   230
            for pctx in ctx.parents():
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   231
                revs.discard(pctx.rev())
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   232
    failed = []
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   233
    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
   234
        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
   235
        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
   236
        if eol:
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   237
            failed.extend(eol.checkrev(repo, ctx, files))
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   238
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   239
    if failed:
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   240
        eols = {'to-lf': 'CRLF', 'to-crlf': 'LF'}
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   241
        msgs = []
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   242
        for node, target, f in failed:
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   243
            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
   244
                        (f, node, eols[target]))
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   245
        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
   246
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   247
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
   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, False)
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
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
   252
    """verify that files have expected EOLs"""
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   253
    _checkhook(ui, repo, node, True)
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   254
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   255
# "checkheadshook" used to be called "hook"
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   256
hook = checkheadshook
11249
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 preupdate(ui, repo, hooktype, parent1, parent2):
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   259
    repo.loadeol([parent1])
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   260
    return False
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   261
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   262
def uisetup(ui):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   263
    ui.setconfig('hooks', 'preupdate.eol', preupdate)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   264
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   265
def extsetup(ui):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   266
    try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   267
        extensions.find('win32text')
13624
78cc35e75ecc eol: do not abort when win32text is found, only warn
Steve Borho <steve@borho.org>
parents: 13581
diff changeset
   268
        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
   269
                  "win32text extension\n"))
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   270
    except KeyError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   271
        pass
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
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   274
def reposetup(ui, repo):
12307
0852da25a31b eol: setup the repo.ui in reposetup()
Steve Borho <steve@borho.org>
parents: 11249
diff changeset
   275
    uisetup(repo.ui)
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   276
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   277
    if not repo.local():
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   278
        return
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   279
    for name, fn in filters.iteritems():
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   280
        repo.adddatafilter(name, fn)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   281
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   282
    ui.setconfig('patch', 'eol', 'auto')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   283
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   284
    class eolrepo(repo.__class__):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   285
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   286
        def loadeol(self, nodes):
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   287
            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
   288
            if eol is None:
13612
21367c3da8aa eol: remove unused argument in readhgeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13611
diff changeset
   289
                return None
14854
23c2d7d25329 eol: eol.only-consistent can now be specified in .hgeol
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 13650
diff changeset
   290
            eol.copytoui(self.ui)
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   291
            return eol.match
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   292
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   293
        def _hgcleardirstate(self):
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   294
            self._eolfile = self.loadeol([None, 'tip'])
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   295
            if not self._eolfile:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   296
                self._eolfile = util.never
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   297
                return
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   298
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   299
            try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   300
                cachemtime = os.path.getmtime(self.join("eol.cache"))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   301
            except OSError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   302
                cachemtime = 0
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   303
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   304
            try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   305
                eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   306
            except OSError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   307
                eolmtime = 0
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   308
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   309
            if eolmtime > cachemtime:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   310
                ui.debug("eol: detected change in .hgeol\n")
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   311
                wlock = None
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   312
                try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   313
                    wlock = self.wlock()
13581
b30a488762e1 eol: use dirstate methods to clear dirstate
Martin Geisler <mg@lazybytes.net>
parents: 13505
diff changeset
   314
                    for f in self.dirstate:
b30a488762e1 eol: use dirstate methods to clear dirstate
Martin Geisler <mg@lazybytes.net>
parents: 13505
diff changeset
   315
                        if self.dirstate[f] == 'n':
b30a488762e1 eol: use dirstate methods to clear dirstate
Martin Geisler <mg@lazybytes.net>
parents: 13505
diff changeset
   316
                            # 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
   317
                            # 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
   318
                            # longer match a file it matched before
b30a488762e1 eol: use dirstate methods to clear dirstate
Martin Geisler <mg@lazybytes.net>
parents: 13505
diff changeset
   319
                            self.dirstate.normallookup(f)
16272
f97e7c378349 eol: document why os.utime doesn't work here
Martin Geisler <mg@aragost.com>
parents: 14866
diff changeset
   320
                    # Create or touch the cache to update mtime
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   321
                    self.opener("eol.cache", "w").close()
13475
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   322
                    wlock.release()
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   323
                except error.LockUnavailable:
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   324
                    # If we cannot lock the repository and clear the
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   325
                    # dirstate, then a commit might not see all files
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   326
                    # as modified. But if we cannot lock the
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   327
                    # repository, then we can also not make a commit,
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   328
                    # so ignore the error.
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   329
                    pass
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   330
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   331
        def commitctx(self, ctx, error=False):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   332
            for f in sorted(ctx.added() + ctx.modified()):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   333
                if not self._eolfile(f):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   334
                    continue
14862
abf915f537be eol: ignore IOError from deleted files in commitctx
Nicholas Riley <njriley@illinois.edu>
parents: 13650
diff changeset
   335
                try:
abf915f537be eol: ignore IOError from deleted files in commitctx
Nicholas Riley <njriley@illinois.edu>
parents: 13650
diff changeset
   336
                    data = ctx[f].data()
abf915f537be eol: ignore IOError from deleted files in commitctx
Nicholas Riley <njriley@illinois.edu>
parents: 13650
diff changeset
   337
                except IOError:
abf915f537be eol: ignore IOError from deleted files in commitctx
Nicholas Riley <njriley@illinois.edu>
parents: 13650
diff changeset
   338
                    continue
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   339
                if util.binary(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   340
                    # We should not abort here, since the user should
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   341
                    # be able to say "** = native" to automatically
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   342
                    # have all non-binary files taken care of.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   343
                    continue
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   344
                if inconsistenteol(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   345
                    raise util.Abort(_("inconsistent newline style "
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   346
                                       "in %s\n" % f))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   347
            return super(eolrepo, self).commitctx(ctx, error)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   348
    repo.__class__ = eolrepo
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   349
    repo._hgcleardirstate()