hgext/eol.py
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
Tue, 28 Mar 2017 06:08:12 +0200
changeset 31710 510267cf6c58
parent 31417 4cffaf8c4853
child 31775 8181f378b073
permissions -rw-r--r--
tags: extract tags computation from fnodes into its own function I'm about to introduce code that needs to perform such computation on "arbitrary" nodes. The logic is extracted into its own function for reuse.
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``
24367
aba1916c1b23 eol: replace "working copy" with "working directory" in extension help
Yuya Nishihara <yuya@tcha.org>
parents: 23877
diff changeset
     9
configuration file found in the root of the working directory. 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
24367
aba1916c1b23 eol: replace "working copy" with "working directory" in extension help
Yuya Nishihara <yuya@tcha.org>
parents: 23877
diff changeset
    15
converted between the working directory and the repository. The format is
13124
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
26098
ce26928cbe41 spelling: behaviour -> behavior
timeless@mozdev.org
parents: 25660
diff changeset
    26
default behavior; it is only needed if you need to override a later,
13124
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::
19997
de16c673455b documentation: add an extra newline after note directive
Simon Heimberg <simohe@besonet.ch>
parents: 17955
diff changeset
    52
13124
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    53
   The rules will first apply when files are touched in the working
24367
aba1916c1b23 eol: replace "working copy" with "working directory" in extension help
Yuya Nishihara <yuya@tcha.org>
parents: 23877
diff changeset
    54
   directory, e.g. by updating to null and back to tip to touch all files.
13124
cc5f0c0c19bc eol: improve help on whether EOLs are changed in working copy or repository
Erik Zielke <ez@aragost.com>
parents: 12980
diff changeset
    55
14856
9f5cd6b6d758 eol: document new eol.fix-trailing-newline setting
Martin Geisler <mg@aragost.com>
parents: 14855
diff changeset
    56
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
    57
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
    58
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
    59
overall behavior. There are three settings:
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    60
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    61
- ``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
    62
  ``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
    63
  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
    64
  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
    65
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    66
- ``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
    67
  the extension convert files with inconsistent EOLs. Inconsistent
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    68
  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
    69
  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
    70
  have mixed EOLs on purpose.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    71
14856
9f5cd6b6d758 eol: document new eol.fix-trailing-newline setting
Martin Geisler <mg@aragost.com>
parents: 14855
diff changeset
    72
- ``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
    73
  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
    74
  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
    75
12979
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
    76
The extension provides ``cleverencode:`` and ``cleverdecode:`` filters
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
    77
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
    78
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
    79
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
    80
12980
20974e51383a eol: mention the hook in the module docstring
Martin Geisler <mg@lazybytes.net>
parents: 12974
diff changeset
    81
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
    82
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
    83
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
    84
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
    85
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
    86
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
    87
``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
    88
``pretxnchangegroup`` hooks.
12980
20974e51383a eol: mention the hook in the module docstring
Martin Geisler <mg@lazybytes.net>
parents: 12974
diff changeset
    89
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    90
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
    91
used.
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
28969
cca011fd1ea7 py3: make eol use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27524
diff changeset
    94
from __future__ import absolute_import
cca011fd1ea7 py3: make eol use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27524
diff changeset
    95
cca011fd1ea7 py3: make eol use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27524
diff changeset
    96
import os
cca011fd1ea7 py3: make eol use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27524
diff changeset
    97
import re
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    98
from mercurial.i18n import _
28969
cca011fd1ea7 py3: make eol use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27524
diff changeset
    99
from mercurial import (
cca011fd1ea7 py3: make eol use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27524
diff changeset
   100
    config,
cca011fd1ea7 py3: make eol use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27524
diff changeset
   101
    error,
cca011fd1ea7 py3: make eol use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27524
diff changeset
   102
    extensions,
cca011fd1ea7 py3: make eol use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27524
diff changeset
   103
    match,
cca011fd1ea7 py3: make eol use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27524
diff changeset
   104
    util,
cca011fd1ea7 py3: make eol use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27524
diff changeset
   105
)
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   106
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 28969
diff changeset
   107
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
25186
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 24367
diff changeset
   108
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 24367
diff changeset
   109
# be specifying the version(s) of Mercurial they are tested with, or
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 24367
diff changeset
   110
# leave the attribute unspecified.
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 28969
diff changeset
   111
testedwith = 'ships-with-hg-core'
16743
38caf405d010 hgext: mark all first-party extensions as such
Augie Fackler <raf@durin42.com>
parents: 16683
diff changeset
   112
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   113
# 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
   114
singlelf = re.compile('(^|[^\r])\n')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   115
# Matches a single EOL which can either be a CRLF where repeated CR
17501
26dd532456cf spelling: Macintosh
timeless@mozdev.org
parents: 16743
diff changeset
   116
# 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
   117
# stray CR is an error.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   118
eolre = re.compile('\r*\n')
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   119
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 inconsistenteol(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   122
    return '\r\n' in data and singlelf.search(data)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   123
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   124
def tolf(s, params, ui, **kwargs):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   125
    """Filter to convert to LF EOLs."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   126
    if util.binary(s):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   127
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   128
    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
   129
        return s
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16273
diff changeset
   130
    if (ui.configbool('eol', 'fix-trailing-newline', False)
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16273
diff changeset
   131
        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
   132
        s = s + '\n'
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   133
    return eolre.sub('\n', s)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   134
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   135
def tocrlf(s, params, ui, **kwargs):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   136
    """Filter to convert to CRLF EOLs."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   137
    if util.binary(s):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   138
        return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   139
    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
   140
        return s
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16273
diff changeset
   141
    if (ui.configbool('eol', 'fix-trailing-newline', False)
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16273
diff changeset
   142
        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
   143
        s = s + '\n'
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   144
    return eolre.sub('\r\n', s)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   145
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   146
def isbinary(s, params):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   147
    """Filter to do nothing with the file."""
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   148
    return s
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   149
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   150
filters = {
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   151
    'to-lf': tolf,
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   152
    'to-crlf': tocrlf,
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   153
    'is-binary': isbinary,
12975
278e3c9b939e eol: added filter aliases for backwards compatibility with win32text
Colin Caughie <c.caughie@indigovision.com>
parents: 12802
diff changeset
   154
    # 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
   155
    'cleverencode:': tolf,
733345a127ca eol: fix win32text encode/decode filter names
Martin Geisler <mg@lazybytes.net>
parents: 12976
diff changeset
   156
    'cleverdecode:': tocrlf
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   157
}
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   158
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   159
class eolfile(object):
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   160
    def __init__(self, ui, root, data):
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   161
        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
   162
        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
   163
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   164
        self.cfg = config.config()
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   165
        # 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
   166
        # inserted first override a '** = native' pattern.
20790
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 19997
diff changeset
   167
        self.cfg.set('patterns', '.hg*', 'BIN', 'eol')
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   168
        # 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
   169
        self.cfg.parse('.hgeol', data)
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   170
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   171
        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
   172
        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
   173
        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
   174
        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
   175
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   176
        include = []
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   177
        exclude = []
30114
ad43458d3529 eol: store and reuse pattern matchers instead of creating in tight loop
Mads Kiilerich <madski@unity3d.com>
parents: 30113
diff changeset
   178
        self.patterns = []
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   179
        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
   180
            key = style.upper()
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   181
            if key == 'BIN':
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   182
                exclude.append(pattern)
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   183
            else:
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   184
                include.append(pattern)
30114
ad43458d3529 eol: store and reuse pattern matchers instead of creating in tight loop
Mads Kiilerich <madski@unity3d.com>
parents: 30113
diff changeset
   185
            m = match.match(root, '', [pattern])
ad43458d3529 eol: store and reuse pattern matchers instead of creating in tight loop
Mads Kiilerich <madski@unity3d.com>
parents: 30113
diff changeset
   186
            self.patterns.append((pattern, key, m))
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   187
        # 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
   188
        # about inconsistent newlines.
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   189
        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
   190
14854
23c2d7d25329 eol: eol.only-consistent can now be specified in .hgeol
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 13650
diff changeset
   191
    def copytoui(self, ui):
30114
ad43458d3529 eol: store and reuse pattern matchers instead of creating in tight loop
Mads Kiilerich <madski@unity3d.com>
parents: 30113
diff changeset
   192
        for pattern, key, m in self.patterns:
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   193
            try:
20790
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 19997
diff changeset
   194
                ui.setconfig('decode', pattern, self._decode[key], 'eol')
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 19997
diff changeset
   195
                ui.setconfig('encode', pattern, self._encode[key], 'eol')
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   196
            except KeyError:
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   197
                ui.warn(_("ignoring unknown EOL style '%s' from %s\n")
30114
ad43458d3529 eol: store and reuse pattern matchers instead of creating in tight loop
Mads Kiilerich <madski@unity3d.com>
parents: 30113
diff changeset
   198
                        % (key, 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
   199
        # 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
   200
        for k, v in self.cfg.items('eol'):
20790
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 19997
diff changeset
   201
            ui.setconfig('eol', k, v, 'eol')
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   202
13615
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   203
    def checkrev(self, repo, ctx, files):
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   204
        failed = []
13650
56e71e7d2ba2 eol: no need to accumulate files when checking all changesets
Patrick Mezard <pmezard@gmail.com>
parents: 13649
diff changeset
   205
        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
   206
            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
   207
                continue
30114
ad43458d3529 eol: store and reuse pattern matchers instead of creating in tight loop
Mads Kiilerich <madski@unity3d.com>
parents: 30113
diff changeset
   208
            for pattern, key, m in self.patterns:
ad43458d3529 eol: store and reuse pattern matchers instead of creating in tight loop
Mads Kiilerich <madski@unity3d.com>
parents: 30113
diff changeset
   209
                if not m(f):
13615
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   210
                    continue
30114
ad43458d3529 eol: store and reuse pattern matchers instead of creating in tight loop
Mads Kiilerich <madski@unity3d.com>
parents: 30113
diff changeset
   211
                target = self._encode[key]
13615
686dec753b52 eol: the hook no longer requires the extension to be loaded
Patrick Mezard <pmezard@gmail.com>
parents: 13614
diff changeset
   212
                data = ctx[f].data()
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   213
                if (target == "to-lf" and "\r\n" in data
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   214
                    or target == "to-crlf" and singlelf.search(data)):
27524
f5b6b4e574c1 eol: make output stable
Bryan O'Sullivan <bos@serpentine.com>
parents: 26587
diff changeset
   215
                    failed.append((f, target, str(ctx)))
13501
50b825c1adb1 eol: stop after first matched rule in hook (issue2660)
Antoine Pitrou <solipsis@pitrou.net>
parents: 13475
diff changeset
   216
                break
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   217
        return failed
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   218
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   219
def parseeol(ui, repo, nodes):
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   220
    try:
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   221
        for node in nodes:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   222
            try:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   223
                if node is None:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   224
                    # 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
   225
                    # and cache the filters before we configure them.
31417
4cffaf8c4853 eol: use 'wvfs' instead of 'wfile'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31328
diff changeset
   226
                    data = repo.wvfs('.hgeol').read()
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   227
                else:
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   228
                    data = repo[node]['.hgeol'].data()
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   229
                return eolfile(ui, repo.root, data)
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   230
            except (IOError, LookupError):
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   231
                pass
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25186
diff changeset
   232
    except error.ParseError as inst:
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   233
        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
   234
                  "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
   235
    return None
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   236
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   237
def _checkhook(ui, repo, node, headsonly):
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   238
    # 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
   239
    files = set()
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   240
    revs = set()
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   241
    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
   242
        revs.add(rev)
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   243
        if headsonly:
13650
56e71e7d2ba2 eol: no need to accumulate files when checking all changesets
Patrick Mezard <pmezard@gmail.com>
parents: 13649
diff changeset
   244
            ctx = repo[rev]
56e71e7d2ba2 eol: no need to accumulate files when checking all changesets
Patrick Mezard <pmezard@gmail.com>
parents: 13649
diff changeset
   245
            files.update(ctx.files())
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   246
            for pctx in ctx.parents():
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   247
                revs.discard(pctx.rev())
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   248
    failed = []
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   249
    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
   250
        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
   251
        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
   252
        if eol:
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   253
            failed.extend(eol.checkrev(repo, ctx, files))
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   254
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   255
    if failed:
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   256
        eols = {'to-lf': 'CRLF', 'to-crlf': 'LF'}
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   257
        msgs = []
27524
f5b6b4e574c1 eol: make output stable
Bryan O'Sullivan <bos@serpentine.com>
parents: 26587
diff changeset
   258
        for f, target, node in sorted(failed):
13649
328ce8a405ac eol: improve hook failure output
Patrick Mezard <pmezard@gmail.com>
parents: 13625
diff changeset
   259
            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
   260
                        (f, node, eols[target]))
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26586
diff changeset
   261
        raise error.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
   262
13617
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   263
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
   264
    """verify that files have expected EOLs"""
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   265
    _checkhook(ui, repo, node, False)
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   266
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   267
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
   268
    """verify that files have expected EOLs"""
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   269
    _checkhook(ui, repo, node, True)
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   270
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   271
# "checkheadshook" used to be called "hook"
9cb1a42cd4b3 eol: rename hook into checkheadshook, add checkallhook (issue2665)
Patrick Mezard <pmezard@gmail.com>
parents: 13616
diff changeset
   272
hook = checkheadshook
11249
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 preupdate(ui, repo, hooktype, parent1, parent2):
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   275
    repo.loadeol([parent1])
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   276
    return False
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
def uisetup(ui):
20790
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 19997
diff changeset
   279
    ui.setconfig('hooks', 'preupdate.eol', preupdate, 'eol')
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   280
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   281
def extsetup(ui):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   282
    try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   283
        extensions.find('win32text')
13624
78cc35e75ecc eol: do not abort when win32text is found, only warn
Steve Borho <steve@borho.org>
parents: 13581
diff changeset
   284
        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
   285
                  "win32text extension\n"))
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   286
    except KeyError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   287
        pass
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
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   290
def reposetup(ui, repo):
12307
0852da25a31b eol: setup the repo.ui in reposetup()
Steve Borho <steve@borho.org>
parents: 11249
diff changeset
   291
    uisetup(repo.ui)
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
    if not repo.local():
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   294
        return
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   295
    for name, fn in filters.iteritems():
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   296
        repo.adddatafilter(name, fn)
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   297
20790
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 19997
diff changeset
   298
    ui.setconfig('patch', 'eol', 'auto', 'eol')
11249
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
    class eolrepo(repo.__class__):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   301
13614
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   302
        def loadeol(self, nodes):
40d0cf79cb2c eol: extract parsing error handling in parseeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13613
diff changeset
   303
            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
   304
            if eol is None:
13612
21367c3da8aa eol: remove unused argument in readhgeol()
Patrick Mezard <pmezard@gmail.com>
parents: 13611
diff changeset
   305
                return None
14854
23c2d7d25329 eol: eol.only-consistent can now be specified in .hgeol
Stepan Koltsov <stepancheg@yandex-team.ru>
parents: 13650
diff changeset
   306
            eol.copytoui(self.ui)
13613
85b80261ca10 eol: separate .hgeol parsing from merge in ui
Patrick Mezard <pmezard@gmail.com>
parents: 13612
diff changeset
   307
            return eol.match
11249
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
        def _hgcleardirstate(self):
30113
ffb682412b98 eol: fix variable naming - call it _eolmatch instead of _eolfile
Mads Kiilerich <madski@unity3d.com>
parents: 29841
diff changeset
   310
            self._eolmatch = self.loadeol([None, 'tip'])
ffb682412b98 eol: fix variable naming - call it _eolmatch instead of _eolfile
Mads Kiilerich <madski@unity3d.com>
parents: 29841
diff changeset
   311
            if not self._eolmatch:
ffb682412b98 eol: fix variable naming - call it _eolmatch instead of _eolfile
Mads Kiilerich <madski@unity3d.com>
parents: 29841
diff changeset
   312
                self._eolmatch = util.never
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   313
                return
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   314
30140
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   315
            oldeol = None
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   316
            try:
31328
ab45421285d0 eol: directly use repo.vfs.join
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30164
diff changeset
   317
                cachemtime = os.path.getmtime(self.vfs.join("eol.cache"))
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   318
            except OSError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   319
                cachemtime = 0
30140
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   320
            else:
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   321
                olddata = self.vfs.read("eol.cache")
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   322
                if olddata:
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   323
                    oldeol = eolfile(self.ui, self.root, olddata)
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   324
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   325
            try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   326
                eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   327
            except OSError:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   328
                eolmtime = 0
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   329
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   330
            if eolmtime > cachemtime:
17955
4ae21a7568f3 eol: don't refer to a random name-captured ui object
Bryan O'Sullivan <bryano@fb.com>
parents: 17501
diff changeset
   331
                self.ui.debug("eol: detected change in .hgeol\n")
30140
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   332
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   333
                hgeoldata = self.wvfs.read('.hgeol')
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   334
                neweol = eolfile(self.ui, self.root, hgeoldata)
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   335
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   336
                wlock = None
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   337
                try:
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   338
                    wlock = self.wlock()
13581
b30a488762e1 eol: use dirstate methods to clear dirstate
Martin Geisler <mg@lazybytes.net>
parents: 13505
diff changeset
   339
                    for f in self.dirstate:
30140
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   340
                        if self.dirstate[f] != 'n':
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   341
                            continue
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   342
                        if oldeol is not None:
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   343
                            if not oldeol.match(f) and not neweol.match(f):
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   344
                                continue
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   345
                            oldkey = None
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   346
                            for pattern, key, m in oldeol.patterns:
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   347
                                if m(f):
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   348
                                    oldkey = key
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   349
                                    break
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   350
                            newkey = None
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   351
                            for pattern, key, m in neweol.patterns:
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   352
                                if m(f):
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   353
                                    newkey = key
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   354
                                    break
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   355
                            if oldkey == newkey:
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   356
                                continue
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   357
                        # all normal files need to be looked at again since
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   358
                        # the new .hgeol file specify a different filter
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   359
                        self.dirstate.normallookup(f)
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   360
                    # Write the cache to update mtime and cache .hgeol
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   361
                    with self.vfs("eol.cache", "w") as f:
747e546c561f eol: on update, only re-check files if filtering changed
Mads Kiilerich <madski@unity3d.com>
parents: 30114
diff changeset
   362
                        f.write(hgeoldata)
13475
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   363
                except error.LockUnavailable:
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   364
                    # If we cannot lock the repository and clear the
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   365
                    # dirstate, then a commit might not see all files
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   366
                    # as modified. But if we cannot lock the
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   367
                    # repository, then we can also not make a commit,
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   368
                    # so ignore the error.
c7bef25ca393 eol: handle LockUnavailable error (issue2569)
Martin Geisler <mg@aragost.com>
parents: 13471
diff changeset
   369
                    pass
30164
1c518d69d994 eol: make sure we always release the wlock when writing cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30140
diff changeset
   370
                finally:
1c518d69d994 eol: make sure we always release the wlock when writing cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30140
diff changeset
   371
                    if wlock is not None:
1c518d69d994 eol: make sure we always release the wlock when writing cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30140
diff changeset
   372
                        wlock.release()
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   373
26586
d51c658d3f04 eol: rename 'error' to 'haserror'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26098
diff changeset
   374
        def commitctx(self, ctx, haserror=False):
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   375
            for f in sorted(ctx.added() + ctx.modified()):
30113
ffb682412b98 eol: fix variable naming - call it _eolmatch instead of _eolfile
Mads Kiilerich <madski@unity3d.com>
parents: 29841
diff changeset
   376
                if not self._eolmatch(f):
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   377
                    continue
23068
fb3e63c603e8 eol: fix crash when handling removed files
Mads Kiilerich <madski@unity3d.com>
parents: 20870
diff changeset
   378
                fctx = ctx[f]
fb3e63c603e8 eol: fix crash when handling removed files
Mads Kiilerich <madski@unity3d.com>
parents: 20870
diff changeset
   379
                if fctx is None:
14862
abf915f537be eol: ignore IOError from deleted files in commitctx
Nicholas Riley <njriley@illinois.edu>
parents: 13650
diff changeset
   380
                    continue
23068
fb3e63c603e8 eol: fix crash when handling removed files
Mads Kiilerich <madski@unity3d.com>
parents: 20870
diff changeset
   381
                data = fctx.data()
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   382
                if util.binary(data):
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   383
                    # We should not abort here, since the user should
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   384
                    # be able to say "** = native" to automatically
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   385
                    # have all non-binary files taken care of.
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   386
                    continue
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   387
                if inconsistenteol(data):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26586
diff changeset
   388
                    raise error.Abort(_("inconsistent newline style "
20869
9658a79968c6 i18n: fix "% inside _()" problems
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19997
diff changeset
   389
                                       "in %s\n") % f)
26586
d51c658d3f04 eol: rename 'error' to 'haserror'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26098
diff changeset
   390
            return super(eolrepo, self).commitctx(ctx, haserror)
11249
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   391
    repo.__class__ = eolrepo
0bb67503ad4b eol: extension for managing file EOLs
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   392
    repo._hgcleardirstate()