##// END OF EJS Templates
copies: properly match result during changeset centric copy tracing...
copies: properly match result during changeset centric copy tracing By filtering "during" the iteration we were excluding rename information that were not in the matched set but that file served as base information for the matched set. We now do all copy tracing matching at the end of the process to ensure we raise proper result. If we were aggregating information top down instead of bottom up we could do filtering during processing. However, we don't. Differential Revision: https://phab.mercurial-scm.org/D9585

File last commit:

r46434:c102b704 default
r46774:92905484 default
Show More
check-commit
115 lines | 3.2 KiB | text/plain | TextLexer
Gregory Szorc
global: use python3 in shebangs...
r46434 #!/usr/bin/env python3
Matt Mackall
contrib: add check-commit hook script to sanity-check commits
r22043 #
# Copyright 2014 Matt Mackall <mpm@selenic.com>
#
# A tool/hook to run basic sanity checks on commits/patches for
# submission to Mercurial. Install by adding the following to your
# .hg/hgrc:
#
# [hooks]
# pretxncommit = contrib/check-commit
#
# The hook can be temporarily bypassed with:
#
# $ BYPASS= hg commit
#
Matt Mackall
urls: bulk-change primary website URLs
r26421 # See also: https://mercurial-scm.org/wiki/ContributingChanges
Matt Mackall
contrib: add check-commit hook script to sanity-check commits
r22043
Pulkit Goyal
py3: make contrib/check-commit use print_function
r29164 from __future__ import absolute_import, print_function
Pulkit Goyal
py3: make contrib/check-commit use absolute_import
r29163
import os
import re
import sys
Matt Mackall
contrib: add check-commit hook script to sanity-check commits
r22043
timeless
check-commit: try to fix multiline handling...
r27782 commitheader = r"^(?:# [^\n]*\n)*"
afterheader = commitheader + r"(?!#)"
beforepatch = afterheader + r"(?!\n(?!@@))"
Matt Mackall
contrib: add check-commit hook script to sanity-check commits
r22043 errors = [
timeless
check-commit: try to fix multiline handling...
r27782 (beforepatch + r".*[(]bc[)]", "(BC) needs to be uppercase"),
Gregory Szorc
black: blacken scripts...
r44058 (
beforepatch + r".*[(]issue \d\d\d",
"no space allowed between issue and number",
),
timeless
check-commit: try to fix multiline handling...
r27782 (beforepatch + r".*[(]bug(\d|\s)", "use (issueDDDD) instead of bug"),
(commitheader + r"# User [^@\n]+\n", "username is not an email address"),
Gregory Szorc
black: blacken scripts...
r44058 (
commitheader + r"(?!merge with )[^#]\S+[^:] ",
"summary line doesn't start with 'topic: '",
),
timeless
check-commit: try to fix multiline handling...
r27782 (afterheader + r"[A-Z][a-z]\S+", "don't capitalize summary lines"),
Martin von Zweigbergk
check-commit: disallow capitalization only right after topic...
r40988 (afterheader + r"^\S+: *[A-Z][a-z]\S+", "don't capitalize summary lines"),
Gregory Szorc
black: blacken scripts...
r44058 (
afterheader + r"\S*[^A-Za-z0-9-_]\S*: ",
"summary keyword should be most user-relevant one-word command or topic",
),
timeless
check-commit: try to fix multiline handling...
r27782 (afterheader + r".*\.\s*\n", "don't add trailing period on summary line"),
(afterheader + r".{79,}", "summary line too long (limit is 78)"),
Matt Mackall
contrib: add check-commit hook script to sanity-check commits
r22043 ]
Gregory Szorc
check-commit: use raw string for regular expression...
r41680 word = re.compile(r'\S')
Gregory Szorc
black: blacken scripts...
r44058
timeless
check-commit: try to fix multiline handling...
r27782 def nonempty(first, second):
if word.search(first):
return first
return second
Gregory Szorc
black: blacken scripts...
r44058
FUJIWARA Katsunori
check-commit: omit whitespace...
r28043 def checkcommit(commit, node=None):
timeless
check-commit: modularize
r27780 exitcode = 0
timeless
check-commit: support REVs as commandline arguments...
r27781 printed = node is None
timeless
check-commit: sort errors by line number
r27783 hits = []
Gregory Szorc
black: blacken scripts...
r44058 signtag = (
afterheader + r'Added (tag [^ ]+|signature) for changeset [a-f0-9]{12}'
)
Augie Fackler
contrib: fix check-commit to not reject commits from `hg sign` and `hg tag`...
r30843 if re.search(signtag, commit):
return 0
timeless
check-commit: modularize
r27780 for exp, msg in errors:
Matt Mackall
check-commit: scan for multiple instances of error patterns
r28012 for m in re.finditer(exp, commit):
timeless
check-commit: try to fix multiline handling...
r27782 end = m.end()
trailing = re.search(r'(\\n)+$', exp)
if trailing:
end -= len(trailing.group()) / 2
timeless
check-commit: sort errors by line number
r27783 hits.append((end, exp, msg))
if hits:
hits.sort()
pos = 0
last = ''
for n, l in enumerate(commit.splitlines(True)):
pos += len(l)
while len(hits):
end, exp, msg = hits[0]
timeless
check-commit: try to fix multiline handling...
r27782 if pos < end:
timeless
check-commit: modularize
r27780 break
timeless
check-commit: sort errors by line number
r27783 if not printed:
printed = True
Pulkit Goyal
py3: make contrib/check-commit use print_function
r29164 print("node: %s" % node)
print("%d: %s" % (n, msg))
print(" %s" % nonempty(l, last)[:-1])
timeless
check-commit: sort errors by line number
r27783 if "BYPASS" not in os.environ:
exitcode = 1
del hits[0]
last = nonempty(l, last)
timeless
check-commit: modularize
r27780 return exitcode
Matt Mackall
contrib: add check-commit hook script to sanity-check commits
r22043
Gregory Szorc
black: blacken scripts...
r44058
timeless
check-commit: modularize
r27780 def readcommit(node):
return os.popen("hg export %s" % node).read()
Gregory Szorc
black: blacken scripts...
r44058
timeless
check-commit: modularize
r27780 if __name__ == "__main__":
timeless
check-commit: support REVs as commandline arguments...
r27781 exitcode = 0
timeless
check-commit: modularize
r27780 node = os.environ.get("HG_NODE")
Matt Mackall
contrib: add check-commit hook script to sanity-check commits
r22043
timeless
check-commit: modularize
r27780 if node:
commit = readcommit(node)
timeless
check-commit: support REVs as commandline arguments...
r27781 exitcode = checkcommit(commit)
elif sys.argv[1:]:
for node in sys.argv[1:]:
exitcode |= checkcommit(readcommit(node), node)
timeless
check-commit: modularize
r27780 else:
commit = sys.stdin.read()
timeless
check-commit: support REVs as commandline arguments...
r27781 exitcode = checkcommit(commit)
timeless
check-commit: modularize
r27780 sys.exit(exitcode)