Bug 2665 - An eol hool to validate all changesets
Summary: An eol hool to validate all changesets
Status: RESOLVED FIXED
Alias: None
Product: Mercurial
Classification: Unclassified
Component: Mercurial (show other bugs)
Version: unspecified
Hardware: All All
: normal feature
Assignee: Bugzilla
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-27 12:15 UTC by Antoine Pitrou
Modified: 2012-05-13 04:59 UTC (History)
6 users (show)

See Also:
Python Version: ---


Attachments
(34 bytes, text/plain)
2011-02-27 12:15 UTC, Antoine Pitrou
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Antoine Pitrou 2011-02-27 12:15 UTC
The current eol hook validates the final changeset in the push changegroup.

However, if you don't want history to be polluted with whitespace-fixing
commits, you might prefer a hook which validates all incoming changesets.
Here is one.

(note this might not apply cleanly without the issue2660 patch)
Comment 1 Matt Mackall 2011-02-27 12:37 UTC
Unlike the Python community, we find the BTS to be a poor tool for managing
and reviewing patches. Please don't post patches here - they will be lost.
Comment 2 Martin Geisler 2011-02-28 02:52 UTC
Matt: the patch is simple and correct, it consists of a simple refactoring
and the new hook. Since it does not change existing functionality, I suggest
we include it with Mercurial 1.8, if Antoine can update it and document it
in the docstring.

Antoine: in any case, please send it to mercurial-devel@selenic.com as a
proper patch with a changeset message.

Three small comments on the part of the patch that affects eol.py:

diff --git a/hgext/eol.py b/hgext/eol.py
--- a/hgext/eol.py
+++ b/hgext/eol.py
@@ -128,6 +128,41 @@
 }
 
 
+def checkfile(ui, repo, node, file):
+    """check that a file in the given node has expected EOLs"""
+    for pattern, target in ui.configitems('encode'):
+        if match.match(repo.root, '', [pattern])(file):
+            data = node[file].data()
+            if ((target == "to-lf" and "\r\n" in data) or
+                (target == "to-crlf" and singlelf.search(data))):
+                return target
+            # Ignore other rules for this file
+            break
+
+def allcsethook(ui, repo, node, hooktype, **kwargs):
+    """verify that files in all new csets have expected EOLs"""
+    failed = {}
+    for rev in xrange(repo[node].rev(), len(repo)):
+        node = repo[rev]

This should be

  ctx = repo[rev]

+        files = repo[rev].files()
+        for f in files:
+            if f not in node:
+                continue

and these four lines should be

  for f in ctx

+            target = checkfile(ui, repo, node, f)
+            if target:
+                failed.setdefault(node, []).append((f, target))
+    if failed:
+        msgs = []
+        for node, files in failed.items():

A dictionary is not so good here since we want deterministic output (for our
tests).

+            for f, target in files:
+                if target == "to-lf":
+                    msgs.append(_("%s in %s should not have CRLF line endings")
+                                % (f, node))
+                elif target == "to-crlf":
+                    msgs.append(_("%s in %s should not have LF line endings")
+                                % (f, node))
+        raise util.Abort("\n".join(msgs))
+

 def hook(ui, repo, node, hooktype, **kwargs):
     """verify that files have expected EOLs"""
     files = set()
@@ -137,18 +172,13 @@
     for f in files:
         if f not in tip:
             continue
-        for pattern, target in ui.configitems('encode'):
-            if match.match(repo.root, '', [pattern])(f):
-                data = tip[f].data()
-                if target == "to-lf" and "\r\n" in data:
-                    raise util.Abort(_("%s should not have CRLF line endings")
-                                     % f)
-                elif target == "to-crlf" and singlelf.search(data):
-                    raise util.Abort(_("%s should not have LF line endings")
-                                     % f)
-                # Ignore other rules for this file
-                break
-
+        target = checkfile(ui, repo, tip, f)
+        if target == "to-lf":
+            raise util.Abort(_("%s should not have CRLF line endings")
+                             % f)
+        elif target == "to-crlf":
+            raise util.Abort(_("%s should not have LF line endings")
+                             % f)
 
 def preupdate(ui, repo, hooktype, parent1, parent2):
     #print "preupdate for %s: %s -> %s" % (repo.root, parent1, parent2)
Comment 3 Patrick Mézard 2011-03-13 08:12 UTC
Should be fixed by http://hg.intevation.org/mercurial/crew/rev/9cb1a42cd4b3

See checkallhook
Comment 4 Antoine Pitrou 2011-03-13 08:23 UTC
Any reason you didn't consider
http://www.selenic.com/pipermail/mercurial-devel/2011-February/028586.html?

It included changeset ids as part of the error message, which can be useful.
Comment 5 Patrick Mézard 2011-03-13 08:47 UTC
No good reason, I started to work on this before reading the issue and did
not pay enough attention to what you did. But Martin noticed it too when
reviewing my changes and we just agreed to update the hook output afterwards.
Comment 6 HG Bot 2011-03-14 15:00 UTC
Fixed by http://selenic.com/repo/hg/rev/9cb1a42cd4b3
Patrick Mezard <pmezard@gmail.com>
eol: rename hook into checkheadshook, add checkallhook (issue2665)

(please test the fix)
Comment 7 Bugzilla 2012-05-12 09:17 UTC

--- Bug imported by bugzilla@serpentine.com 2012-05-12 09:17 EDT  ---

This bug was previously known as _bug_ 2665 at http://mercurial.selenic.com/bts/issue2665
Imported an attachment (id=1528)