annotate contrib/check-commit @ 49680:40e24d82b513

delta-find: make sure we only use newer full snapshot as candidate The current code does not needs to protect against this, as there are no older snapshot in the current cache. However as we are getting ready to reuse this cache from one revision to another, we need the code to protect itself about what's coming.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Sun, 06 Nov 2022 17:55:55 -0500
parents 6000f5b25c9b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
45830
c102b704edb5 global: use python3 in shebangs
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43659
diff changeset
1 #!/usr/bin/env python3
22043
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 45830
diff changeset
3 # Copyright 2014 Olivia Mackall <olivia@selenic.com>
22043
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
5 # A tool/hook to run basic sanity checks on commits/patches for
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
6 # submission to Mercurial. Install by adding the following to your
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7 # .hg/hgrc:
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
8 #
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
9 # [hooks]
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
10 # pretxncommit = contrib/check-commit
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
11 #
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
12 # The hook can be temporarily bypassed with:
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
13 #
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
14 # $ BYPASS= hg commit
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
15 #
26421
4b0fc75f9403 urls: bulk-change primary website URLs
Matt Mackall <mpm@selenic.com>
parents: 25643
diff changeset
16 # See also: https://mercurial-scm.org/wiki/ContributingChanges
22043
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
17
29163
bf7fd815b083 py3: make contrib/check-commit use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28043
diff changeset
18
bf7fd815b083 py3: make contrib/check-commit use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28043
diff changeset
19 import os
bf7fd815b083 py3: make contrib/check-commit use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28043
diff changeset
20 import re
bf7fd815b083 py3: make contrib/check-commit use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28043
diff changeset
21 import sys
22043
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
22
27782
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
23 commitheader = r"^(?:# [^\n]*\n)*"
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
24 afterheader = commitheader + r"(?!#)"
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
25 beforepatch = afterheader + r"(?!\n(?!@@))"
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
26
22043
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
27 errors = [
27782
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
28 (beforepatch + r".*[(]bc[)]", "(BC) needs to be uppercase"),
43659
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
29 (
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
30 beforepatch + r".*[(]issue \d\d\d",
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
31 "no space allowed between issue and number",
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
32 ),
27782
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
33 (beforepatch + r".*[(]bug(\d|\s)", "use (issueDDDD) instead of bug"),
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
34 (commitheader + r"# User [^@\n]+\n", "username is not an email address"),
43659
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
35 (
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
36 commitheader + r"(?!merge with )[^#]\S+[^:] ",
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
37 "summary line doesn't start with 'topic: '",
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
38 ),
27782
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
39 (afterheader + r"[A-Z][a-z]\S+", "don't capitalize summary lines"),
40952
811f772b44aa check-commit: disallow capitalization only right after topic
Martin von Zweigbergk <martinvonz@google.com>
parents: 40308
diff changeset
40 (afterheader + r"^\S+: *[A-Z][a-z]\S+", "don't capitalize summary lines"),
43659
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
41 (
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
42 afterheader + r"\S*[^A-Za-z0-9-_]\S*: ",
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
43 "summary keyword should be most user-relevant one-word command or topic",
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
44 ),
27782
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
45 (afterheader + r".*\.\s*\n", "don't add trailing period on summary line"),
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
46 (afterheader + r".{79,}", "summary line too long (limit is 78)"),
22043
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
47 ]
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
48
41539
45a4789d3ff2 check-commit: use raw string for regular expression
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40952
diff changeset
49 word = re.compile(r'\S')
43659
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
50
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
51
27782
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
52 def nonempty(first, second):
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
53 if word.search(first):
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
54 return first
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
55 return second
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
56
43659
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
57
28043
ac4684c21f73 check-commit: omit whitespace
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28042
diff changeset
58 def checkcommit(commit, node=None):
27780
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
59 exitcode = 0
27781
2af351bd289c check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents: 27780
diff changeset
60 printed = node is None
27783
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
61 hits = []
43659
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
62 signtag = (
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
63 afterheader + r'Added (tag [^ ]+|signature) for changeset [a-f0-9]{12}'
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
64 )
30843
2fb3ae89e4e1 contrib: fix check-commit to not reject commits from `hg sign` and `hg tag`
Augie Fackler <augie@google.com>
parents: 30061
diff changeset
65 if re.search(signtag, commit):
2fb3ae89e4e1 contrib: fix check-commit to not reject commits from `hg sign` and `hg tag`
Augie Fackler <augie@google.com>
parents: 30061
diff changeset
66 return 0
27780
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
67 for exp, msg in errors:
28012
897b2fcf079f check-commit: scan for multiple instances of error patterns
Matt Mackall <mpm@selenic.com>
parents: 27783
diff changeset
68 for m in re.finditer(exp, commit):
27782
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
69 end = m.end()
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
70 trailing = re.search(r'(\\n)+$', exp)
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
71 if trailing:
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
72 end -= len(trailing.group()) / 2
27783
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
73 hits.append((end, exp, msg))
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
74 if hits:
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
75 hits.sort()
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
76 pos = 0
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
77 last = ''
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
78 for n, l in enumerate(commit.splitlines(True)):
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
79 pos += len(l)
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
80 while len(hits):
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
81 end, exp, msg = hits[0]
27782
7291c8165e33 check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents: 27781
diff changeset
82 if pos < end:
27780
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
83 break
27783
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
84 if not printed:
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
85 printed = True
29164
91f35b1a34cf py3: make contrib/check-commit use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29163
diff changeset
86 print("node: %s" % node)
91f35b1a34cf py3: make contrib/check-commit use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29163
diff changeset
87 print("%d: %s" % (n, msg))
91f35b1a34cf py3: make contrib/check-commit use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29163
diff changeset
88 print(" %s" % nonempty(l, last)[:-1])
27783
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
89 if "BYPASS" not in os.environ:
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
90 exitcode = 1
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
91 del hits[0]
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
92 last = nonempty(l, last)
1d095371de47 check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents: 27782
diff changeset
93
27780
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
94 return exitcode
22043
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
95
43659
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
96
27780
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
97 def readcommit(node):
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
98 return os.popen("hg export %s" % node).read()
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
99
43659
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43112
diff changeset
100
27780
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
101 if __name__ == "__main__":
27781
2af351bd289c check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents: 27780
diff changeset
102 exitcode = 0
27780
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
103 node = os.environ.get("HG_NODE")
22043
1274ff3f20a8 contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
104
27780
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
105 if node:
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
106 commit = readcommit(node)
27781
2af351bd289c check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents: 27780
diff changeset
107 exitcode = checkcommit(commit)
2af351bd289c check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents: 27780
diff changeset
108 elif sys.argv[1:]:
2af351bd289c check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents: 27780
diff changeset
109 for node in sys.argv[1:]:
2af351bd289c check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents: 27780
diff changeset
110 exitcode |= checkcommit(readcommit(node), node)
27780
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
111 else:
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
112 commit = sys.stdin.read()
27781
2af351bd289c check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents: 27780
diff changeset
113 exitcode = checkcommit(commit)
27780
f47185f09533 check-commit: modularize
timeless <timeless@mozdev.org>
parents: 27779
diff changeset
114 sys.exit(exitcode)