Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions hooks/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
"hooks.no-precommit-check": {"default": (), "type": tuple},
"hooks.no-rh-character-range-check": {"default": False, "type": bool},
"hooks.no-rh-style-checks": {"default": (), "type": tuple},
"hooks.no-rh-near-revert-check": {"default": False, "type": bool},
"hooks.no-style-checks": {"default": (), "type": tuple},
"hooks.pre-receive-hook": {"default": None},
"hooks.post-receive-hook": {"default": None},
Expand Down
24 changes: 24 additions & 0 deletions hooks/pre_commit_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,29 @@ def check_missing_ticket_number(commit):
)


def reject_almost_reversions(commit):
"""Raise InvalidUpdate if the commit's revlog contains "This reverts
commit" in it.

The GCC ChangeLog scripts expect a line that contains that sentence to also
contain a reference to the commit being reverted. If this line is altered,
therefore, they will fail.

PARAMETERS
commit: A CommitInfo object corresponding to the commit being checked.
"""
if git_config("hooks.no-rh-near-revert-check"):
return

if "This reverts commit" in commit.raw_revlog:
raise InvalidUpdate(
"Commit %s looks like it was intended as a revert." % commit.rev,
"",
"When reverting, you should leave the 'This reverts commit'",
"line unaltered.",
)


def check_revision_history(commit):
"""Apply pre-commit checks to the commit's revision history.

Expand All @@ -321,6 +344,7 @@ def check_revision_history(commit):
return

# Various checks on the revision history...
reject_almost_reversions(commit)
ensure_iso_8859_15_only(commit)
ensure_empty_line_after_subject(commit)
reject_lines_too_long(commit)
Expand Down
19 changes: 14 additions & 5 deletions hooks/updates/commits.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@
from io_utils import safe_decode
from updates.mailinglists import expanded_mailing_list
from utils import debug
import re


_REVERT_COMMIT_RE = re.compile(
r"^This reverts commit (?P<hash>[0-9a-f]+)\.$",
re.M
)
"""A regex that matches the same revert lines as ``revert_regex`` does in
``contrib/gcc-changelog/git_commit.py``.

Note that this regex is matched against an entire body of a commit rather than
each line in it, though.
"""


class CommitInfo(object):
Expand Down Expand Up @@ -235,11 +248,7 @@ def is_revert(self):
revision log of such commits, hoping that a user is not deleting
them afterwards.
"""
if "This reverts commit" in self.raw_revlog:
return True

# No recognizable pattern. Probably not a revert commit.
return False
return bool(_REVERT_COMMIT_RE.search(self.raw_revlog));

@classmethod
def __all_files_from_commit_rev(cls, rev):
Expand Down
Empty file.
Binary file not shown.
95 changes: 95 additions & 0 deletions testsuite/tests/GCC__stricter_revert_pattern/hooks_config
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
[hooks]
from-domain = gcc.gnu.org
mailinglist = true

# We do not want to force a maximum line length in commit
# revision logs, as they get in the way of copy-pasting
# debugging session, error messages, logs, etc.
max-rh-line-length = 0

# We allow a 0.5MiB email diff maximum.
max-email-diff-size = 524288

# Reject merge commits on a certain number of branches:
# - on master: We request that people rebase their changes
# before pushing instead (merge commits tend to confuse
# git newcomers).
# - on release: We apply the same policy to release branches
# as we have on master.
reject-merge-commits = refs/heads/master,refs/heads/trunk,refs/heads/releases/.*

# The URL where we can inspect the commit, inserted in the commit
# notification email, and also copy sent to the file-commit-cmd.
commit-url = "https://gcc.gnu.org/g:%(rev)s"

# This style checker does nothing at present.
# style-checker = /git/gcc.git/hooks-bin/style_checker

# Send a copy to bugzilla if a commit has a PR number in it.
# The script is a wrapper around
# /sourceware/infra/bin/email-to-bugzilla.
# file-commit-cmd = "/git/gcc.git/hooks-bin/email-to-bugzilla-filtered"

# Work around <https://github.com/AdaCore/git-hooks/issues/9>
# to allow larger merges.
max-commit-emails = 5000

# Allow deliberate merges to use the default commit message.
# Branches that do not allow merge commits are listed in
# reject-merge-commits.
disable-merge-commit-checks = true

# Do not send emails for commits that are already in the
# repository being added to development branches or user or
# vendor branches (through merges or rebases).
email-new-commits-only = refs/heads/devel/.*
email-new-commits-only = refs/users/.*
email-new-commits-only = refs/vendors/.*

# GCC-specific ref naming conventions for user and vendor
# branches.
branch-ref-namespace = refs/users/[^/]*/heads/.*
branch-ref-namespace = refs/vendors/[^/]*/heads/.*

# GCC-specific ref naming conventions for user and vendor
# tags.
tag-ref-namespace = refs/users/[^/]*/tags/.*
tag-ref-namespace = refs/vendors/[^/]*/tags/.*

# Branch deletion is disabled by default.
restrict-branch-deletion = true

# Branch deletion is allowed for user and vendor branches.
allow-delete-branch = refs/users/[^/]*/heads/.*
allow-delete-branch = refs/vendors/[^/]*/heads/.*

# Non-fast-forward updates are allowed in the user and vendor
# namespaces.
allow-non-fast-forward = refs/users/.*
allow-non-fast-forward = refs/vendors/.*

# Message to give for rejected branch deletion.
rejected-branch-deletion-tip = Branch deletion is only allowed for user and vendor branches. If another branch was created by mistake, contact an administrator to delete it on the server with git update-ref. If a development branch is dead, also contact an administrator to move it under refs/dead/heads/ rather than deleting it.

# Commit messages should not be restricted to ISO-8859-15.
no-rh-character-range-check = true

# Custom checker script for each new commit of each ref being
# updated. This makes several checks on the commit message,
# including for ChangeLog formatting and contents.
# commit-extra-checker = /git/gcc.git/hooks-bin/commit_checker

# Custom checker script for ref updates. This checks for
# branch naming conventions and not introducing new references
# to the git-svn history.
# update-hook = /git/gcc.git/hooks-bin/update_hook

# Custom email formatter. This inserts GCC monotonically
# increasing commit ids in the commit emails.
# commit-email-formatter = /git/gcc.git/hooks-bin/commit_email_formatter

# For GCC/Rust development that happens outside of GCC proper,
# <https://rust-gcc.github.io/>, the Git commit messages
# don't always adhere to standard GCC style; see
# <https://github.com/Rust-GCC/gccrs/issues/143>.
no-precommit-check = refs/heads/devel/rust/.*
52 changes: 52 additions & 0 deletions testsuite/tests/GCC__stricter_revert_pattern/run_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
def test_push_bad_revert_commit(testcase):
"""Try pushing trunk..."""
p = testcase.run("git push origin trunk".split())
testcase.assertNotEqual(p.status, 0, p.image)
testcase.assertRunOutputEqual(p, """\
remote: *** Commit df3a09266b6685060fb1e11268922b491e3e5cd8 looks like it was intended as a revert.
remote: ***
remote: *** When reverting, you should leave the 'This reverts commit'
remote: *** line unaltered.
remote: error: hook declined to update refs/heads/trunk
To ../bare/repo.git/
! [remote rejected] trunk -> trunk (hook declined)
error: failed to push some refs to '../bare/repo.git/'
""")


def test_push_good_revert_commit(testcase):
"""Try pushing trunk..."""
p = testcase.run("git push origin trunk-good:trunk".split())
testcase.assertEqual(p.status, 0, p.image)
testcase.assertRunOutputEqual(p, """\
remote: DEBUG: Content-Type: text/plain; charset="utf-8"
remote: MIME-Version: 1.0
remote: Content-Transfer-Encoding: quoted-printable
remote: From: Test Suite <testsuite@gcc.gnu.org>
remote: To: true
remote: Subject: [repo/trunk] Revert "rs6000: Disassemble opaque modes using subregs to allow optimizations"
remote: X-Act-Checkin: repo
remote: X-Git-Author: Surya Kumari Jangala <jskumari@linux.ibm.com>
remote: X-Git-Refname: refs/heads/trunk
remote: X-Git-Oldrev: dc366d741ae38b1dfb105a67176c1de93cf1ed55
remote: X-Git-Newrev: 12ec343fa812ffa793dd0f41ecb47d2d06109673
remote:
remote: https://gcc.gnu.org/g:12ec343fa812ffa793dd0f41ecb47d2d06109673
remote:
remote: commit 12ec343fa812ffa793dd0f41ecb47d2d06109673
remote: Author: Surya Kumari Jangala <jskumari@linux.ibm.com>
remote: Date: Sat Apr 11 12:19:45 2026 -0500
remote:
remote: Revert "rs6000: Disassemble opaque modes using subregs to allow optimizations"
remote:
remote: This reverts commit 69a2c243dd2cf9f77150c0eb86dfbc0931876bc1.
remote:
remote: This will resolve the issue reported in PR124804.
remote:
remote: Diff:
remote: ---
remote:
remote: hooks/post-update: line 5: exec: git-update-server-info: not found
To ../bare/repo.git/
dc366d7..12ec343 trunk-good -> trunk
""")