[PATCH] eol: hook should consider all changegroup heads (issue2666)
Antoine Pitrou
solipsis at pitrou.net
Tue Mar 1 02:46:30 CST 2011
# HG changeset patch
# User Antoine Pitrou <solipsis at pitrou.net>
# Date 1298968929 -3600
# Branch stable
# Node ID b9101359e4b0b0e218cb4508518d909dd86fb266
# Parent 4f5f54314720a20f58ce6167937496368b889330
eol: hook should consider all changegroup heads (issue2666)
If the eol hook only considers the tipmost changeset in the
changegroup, it is possible to first check in a file with a
bogus line ending, then create another head from a previous
changeset, and push the whole bunch without eol noticing.
By considering all heads in the changegroup, we fix this issue.
diff --git a/hgext/eol.py b/hgext/eol.py
--- a/hgext/eol.py
+++ b/hgext/eol.py
@@ -128,26 +128,39 @@
}
+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 hook(ui, repo, node, hooktype, **kwargs):
"""verify that files have expected EOLs"""
+ start = repo[node].rev()
files = set()
- for rev in xrange(repo[node].rev(), len(repo)):
+ heads = set([start])
+ for rev in xrange(start, len(repo)):
+ for p in repo.changelog.parentrevs(rev):
+ heads.discard(p)
+ heads.add(rev)
files.update(repo[rev].files())
- tip = repo['tip']
- 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
+ for head in heads:
+ ctx = repo[head]
+ for f in files:
+ if f not in ctx:
+ continue
+ target = checkfile(ui, repo, ctx, 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):
diff --git a/tests/test-eol-hook.t b/tests/test-eol-hook.t
--- a/tests/test-eol-hook.t
+++ b/tests/test-eol-hook.t
@@ -88,3 +88,50 @@
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
+
+ $ printf "first\r\nsecond" > b.txt
+ $ hg add b.txt
+ $ hg commit -m 'CRLF b.txt'
+ $ hg push ../main
+ pushing to ../main
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files
+ error: pretxnchangegroup hook failed: b.txt should not have CRLF line endings
+ transaction abort!
+ rollback completed
+ abort: b.txt should not have CRLF line endings
+ [255]
+
+ $ hg up -r -2
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ printf "some\nother\nfile" > c.txt
+ $ hg add c.txt
+ $ hg commit -m "LF c.txt, b.txt doesn't exist here"
+ created new head
+ $ hg push -f ../main
+ pushing to ../main
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 2 changesets with 2 changes to 2 files (+1 heads)
+ error: pretxnchangegroup hook failed: b.txt should not have CRLF line endings
+ transaction abort!
+ rollback completed
+ abort: b.txt should not have CRLF line endings
+ [255]
+
+ $ hg up -r -2
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ printf "first\nsecond" > b.txt
+ $ hg commit -m 'LF b.txt (fixed)'
+ $ hg push -f ../main
+ pushing to ../main
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 3 changesets with 3 changes to 2 files (+1 heads)
More information about the Mercurial-devel
mailing list