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