Mercurial > hg-stable
annotate contrib/check-commit @ 44794:2dc5ae953c4a stable
graft: fix --base value to be saved in state file
'True' just works because it is treated as an integer revision '1' and
only the truthiness of the basectx is important. If multiple source revisions
were supported with --base, the resumed graft operation would go wrong.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Tue, 02 Jun 2020 20:40:06 +0900 |
parents | 99e231afc29c |
children | c102b704edb5 |
rev | line source |
---|---|
22043
1274ff3f20a8
contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
1 #!/usr/bin/env python |
1274ff3f20a8
contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
2 # |
1274ff3f20a8
contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
3 # Copyright 2014 Matt Mackall <mpm@selenic.com> |
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 |
29164
91f35b1a34cf
py3: make contrib/check-commit use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29163
diff
changeset
|
18 from __future__ import absolute_import, print_function |
29163
bf7fd815b083
py3: make contrib/check-commit use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
28043
diff
changeset
|
19 |
bf7fd815b083
py3: make contrib/check-commit use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
28043
diff
changeset
|
20 import os |
bf7fd815b083
py3: make contrib/check-commit use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
28043
diff
changeset
|
21 import re |
bf7fd815b083
py3: make contrib/check-commit use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
28043
diff
changeset
|
22 import sys |
22043
1274ff3f20a8
contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
23 |
27782
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
24 commitheader = r"^(?:# [^\n]*\n)*" |
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
25 afterheader = commitheader + r"(?!#)" |
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
26 beforepatch = afterheader + r"(?!\n(?!@@))" |
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
27 |
22043
1274ff3f20a8
contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
28 errors = [ |
27782
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
29 (beforepatch + r".*[(]bc[)]", "(BC) needs to be uppercase"), |
43703
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
30 ( |
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
31 beforepatch + r".*[(]issue \d\d\d", |
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
32 "no space allowed between issue and number", |
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
33 ), |
27782
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
34 (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
|
35 (commitheader + r"# User [^@\n]+\n", "username is not an email address"), |
43703
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
36 ( |
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
37 commitheader + r"(?!merge with )[^#]\S+[^:] ", |
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
38 "summary line doesn't start with 'topic: '", |
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
39 ), |
27782
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
40 (afterheader + r"[A-Z][a-z]\S+", "don't capitalize summary lines"), |
40965
811f772b44aa
check-commit: disallow capitalization only right after topic
Martin von Zweigbergk <martinvonz@google.com>
parents:
40308
diff
changeset
|
41 (afterheader + r"^\S+: *[A-Z][a-z]\S+", "don't capitalize summary lines"), |
43703
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
42 ( |
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
43 afterheader + r"\S*[^A-Za-z0-9-_]\S*: ", |
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
44 "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
|
45 ), |
27782
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
46 (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
|
47 (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
|
48 ] |
1274ff3f20a8
contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
49 |
41553
45a4789d3ff2
check-commit: use raw string for regular expression
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40965
diff
changeset
|
50 word = re.compile(r'\S') |
43703
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
51 |
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
52 |
27782
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
53 def nonempty(first, second): |
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
54 if word.search(first): |
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
55 return first |
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
56 return second |
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
57 |
43703
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
58 |
28043
ac4684c21f73
check-commit: omit whitespace
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28042
diff
changeset
|
59 def checkcommit(commit, node=None): |
27780 | 60 exitcode = 0 |
27781
2af351bd289c
check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents:
27780
diff
changeset
|
61 printed = node is None |
27783
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
62 hits = [] |
43703
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
63 signtag = ( |
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
64 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
|
65 ) |
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
|
66 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
|
67 return 0 |
27780 | 68 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
|
69 for m in re.finditer(exp, commit): |
27782
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
70 end = m.end() |
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
71 trailing = re.search(r'(\\n)+$', exp) |
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
72 if trailing: |
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
73 end -= len(trailing.group()) / 2 |
27783
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
74 hits.append((end, exp, msg)) |
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
75 if hits: |
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
76 hits.sort() |
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
77 pos = 0 |
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
78 last = '' |
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
79 for n, l in enumerate(commit.splitlines(True)): |
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
80 pos += len(l) |
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
81 while len(hits): |
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
82 end, exp, msg = hits[0] |
27782
7291c8165e33
check-commit: try to fix multiline handling
timeless <timeless@mozdev.org>
parents:
27781
diff
changeset
|
83 if pos < end: |
27780 | 84 break |
27783
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
85 if not printed: |
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
86 printed = True |
29164
91f35b1a34cf
py3: make contrib/check-commit use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29163
diff
changeset
|
87 print("node: %s" % node) |
91f35b1a34cf
py3: make contrib/check-commit use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29163
diff
changeset
|
88 print("%d: %s" % (n, msg)) |
91f35b1a34cf
py3: make contrib/check-commit use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29163
diff
changeset
|
89 print(" %s" % nonempty(l, last)[:-1]) |
27783
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
90 if "BYPASS" not in os.environ: |
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
91 exitcode = 1 |
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
92 del hits[0] |
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
93 last = nonempty(l, last) |
1d095371de47
check-commit: sort errors by line number
timeless <timeless@mozdev.org>
parents:
27782
diff
changeset
|
94 |
27780 | 95 return exitcode |
22043
1274ff3f20a8
contrib: add check-commit hook script to sanity-check commits
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
96 |
43703
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
97 |
27780 | 98 def readcommit(node): |
99 return os.popen("hg export %s" % node).read() | |
100 | |
43703
99e231afc29c
black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43112
diff
changeset
|
101 |
27780 | 102 if __name__ == "__main__": |
27781
2af351bd289c
check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents:
27780
diff
changeset
|
103 exitcode = 0 |
27780 | 104 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
|
105 |
27780 | 106 if node: |
107 commit = readcommit(node) | |
27781
2af351bd289c
check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents:
27780
diff
changeset
|
108 exitcode = checkcommit(commit) |
2af351bd289c
check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents:
27780
diff
changeset
|
109 elif sys.argv[1:]: |
2af351bd289c
check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents:
27780
diff
changeset
|
110 for node in sys.argv[1:]: |
2af351bd289c
check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents:
27780
diff
changeset
|
111 exitcode |= checkcommit(readcommit(node), node) |
27780 | 112 else: |
113 commit = sys.stdin.read() | |
27781
2af351bd289c
check-commit: support REVs as commandline arguments
timeless <timeless@mozdev.org>
parents:
27780
diff
changeset
|
114 exitcode = checkcommit(commit) |
27780 | 115 sys.exit(exitcode) |