disable all checks on revert commits

For QB08-047.
This commit is contained in:
Joel Brobecker
2017-11-09 07:54:22 -08:00
parent 1e1e4ec080
commit 087a8bcdf0
7 changed files with 151 additions and 1 deletions

View File

@@ -504,3 +504,22 @@ def diff_tree(*args, **kwargs):
filename))
return result
def is_revert_commit(rev):
"""Return True if the given commit appears to be a revert commit.
PARAMETERS
rev: A commit revision (string with the commit's SHA1 or reference
name).
"""
# We detect such commits by searching for specific patterns that
# the "git revert" command automatically includes in the default
# revision log of such commits, hoping that a user is not deleting
# them afterwards.
raw_revlog = git.log('-1', rev, pretty='format:%B')
if 'This reverts commit' in raw_revlog:
return True
# No recognizable pattern. Probably not a revert commit.
return False

View File

@@ -3,7 +3,7 @@
from config import git_config, SUBJECT_MAX_SUBJECT_CHARS
from errors import InvalidUpdate
from git import (git, get_object_type, is_null_rev, commit_parents,
commit_rev)
commit_rev, is_revert_commit)
from os.path import expanduser, isfile, getmtime
from pre_commit_checks import (check_revision_history, style_check_commit,
check_filename_collisions,
@@ -231,7 +231,18 @@ class AbstractUpdate(object):
# handled by the __no_cvs_check_user_override method.
return
# Create a list of commits that were added, but with revert
# commits being filtered out. We have decided that revert commits
# should not be subject to any check (QB08-047). This allows
# users to quickly revert a commit if need be, without having
# to worry about bumping into any check of any kind.
added = self.added_commits
for commit in added:
if is_revert_commit(commit.rev):
debug('revert commit detected,'
' all checks disabled for this commit: %s' % commit.rev)
added.remove(commit)
if not added:
# There are no new commits, so nothing further to check.
return

View File

@@ -0,0 +1,4 @@
[core]
repositoryformatversion = 0
filemode = true
bare = true

View File

@@ -0,0 +1,16 @@
#! /usr/bin/env python
"""A dummy cvs_check program that FAILs all files.
"""
import sys
# To help with testing, print a trace containing the name of the module
# and the names of the files being checked.
print "cvs_check: %s < %s" % (
' '.join(["`%s'" % arg for arg in sys.argv[1:]]),
' '.join(["`%s'" % arg for arg in sys.stdin.read().splitlines(False)]))
filenames = sys.stdin.read().splitlines(False)
print >> sys.stderr, \
'ERROR: %s: Copyright year in header is not up to date' % filenames[0]
sys.exit(1)

View File

@@ -0,0 +1,4 @@
[hooks]
from-domain = adacore.com
mailinglist = git-hooks-ci@example.com
tn-required = true

View File

@@ -0,0 +1,96 @@
from support import *
class TestRun(TestCase):
def test_push_commit_on_master(self):
"""Try pushing one single-file commit on master.
This is just to verify that revision-log checks are enabled,
and in particular that we get an error if the TN is missing.
That way, we know that our repository is correctly configured
in terms of requiring TNs in the revision log and should
normally reject commits that don't follow this rule.
"""
cd ('%s/repo' % TEST_DIR)
# Push master to the `origin' remote. The delta should be one
# commit with one file being modified.
p = Run('git push origin master'.split())
expected_out = """\
remote: *** The following commit is missing a ticket number inside
remote: *** its revision history. If the change is sufficiently
remote: *** minor that a ticket number is not meaningful, please use
remote: *** the word "no-tn-check" in place of a ticket number.
remote: ***
remote: *** commit a60540361d47901d3fe254271779f380d94645f7
remote: *** Subject: Updated a.
remote: error: hook declined to update refs/heads/master
To ../bare/repo.git
! [remote rejected] master -> master (hook declined)
error: failed to push some refs to '../bare/repo.git'
"""
self.assertNotEqual(p.status, 0, p.image)
self.assertRunOutputEqual(p, expected_out)
def test_push_commit_on_revert(self):
"""Try pushing one single-file commit on revert.
This verifies that all checks are disabled when pushing
a commit which has been created using "git revert". In
particular, this commit violates a number of requirements
in the revision log. And the cvs_check.py script is also
set up to always return an error, so this will allow us
to verify that no file is style-checked.
"""
cd ('%s/repo' % TEST_DIR)
# Push master to the `origin' remote. The delta should be one
# commit with one file being modified.
p = Run('git push origin revert'.split())
expected_out = """\
remote: DEBUG: Content-Type: text/plain; charset="us-ascii"
remote: MIME-Version: 1.0
remote: Content-Transfer-Encoding: 7bit
remote: From: Test Suite <testsuite@adacore.com>
remote: To: git-hooks-ci@example.com
remote: Bcc: file-ci@gnat.com
remote: Subject: [repo/revert] Revert "New file: a."
remote: X-Act-Checkin: repo
remote: X-Git-Author: Joel Brobecker <brobecker@adacore.com>
remote: X-Git-Refname: refs/heads/revert
remote: X-Git-Oldrev: d065089ff184d97934c010ccd0e7e8ed94cb7165
remote: X-Git-Newrev: d669d669fcbdeab1eedf9756ce1ef5a62c4f97db
remote:
remote: commit d669d669fcbdeab1eedf9756ce1ef5a62c4f97db
remote: Author: Joel Brobecker <brobecker@adacore.com>
remote: Date: Thu Nov 9 06:05:21 2017 -0800
remote:
remote: Revert "New file: a."
remote:
remote: This reverts commit d065089ff184d97934c010ccd0e7e8ed94cb7165.
remote:
remote: No TN included as we want to verify that revert commits don't go through any check of any kind (including lines too long like this one).
remote:
remote: Diff:
remote: ---
remote: a | 3 ---
remote: 1 file changed, 3 deletions(-)
remote:
remote: diff --git a/a b/a
remote: deleted file mode 100644
remote: index 01d0f12..0000000
remote: --- a/a
remote: +++ /dev/null
remote: @@ -1,3 +0,0 @@
remote: -Some file.
remote: -Second line.
remote: -Third line.
To ../bare/repo.git
d065089..d669d66 revert -> revert
"""
self.assertEqual(p.status, 0, p.image)
self.assertRunOutputEqual(p, expected_out)
if __name__ == '__main__':
runtests()