GIT hooks and CC4M
Automated Code Checks with Git Hooks
Published: 2025-07-25

Using Git Hooks to Ensure Code Quality.
To maintain high code quality in your repository, it's helpful to run a static code checker before committing changes. In this blog post, we’ll show how you can automate this process for MATLAB code stored in a Git repository.
We'll integrate CC4M (Code Checker for MATLAB) into a Git pre-commit hook to automatically verify code compliance with the guidelines before allowing it to be committed. Here’s how it works:
- When you commit changes, the pre-commit hook first runs CC4M.
- If no issues are found, the commit proceeds.
- If violations are detected, the commit is blocked, and the CC4M HTML report is opened to highlight the violations.
In the sections below, we’ll walk through setting up the pre-commit hook and the script that triggers CC4M. The example is created on a Windows machine. Both the pre-commit bash script and the called MATLAB function are availabe from GitHub.
The pre-commit hook
The hook performs four main steps:
Define the context
To run MATLAB and CC4M from the hook, the script first defines the environment:
#!/bin/sh
# file: pre-commit
#
# A hook script to verify MATLAB code using CC4M.
# Called by "git commit" with no arguments.
## Generic settings
matlabExe="matlab"
# only rules with sevirty level equal to or hight than "severityLevelBoundary" will be included
severityLevelBoundary=3
# From the predefined configurations, use the "MonkeyProof Coding Standard for MATLAB"
configFile=MonkeyProofMATLABCodingStandard
# List of extensions to include
supportedExtensions="\.m$|\.mlx$|\.slx$|\.mlapp$|\.mdl$"
# Git repository root folder
gitRootFolder=$(git rev-parse --show-toplevel)
# Initialize variables
gitFullFiles=
count=0
By default, the first MATLAB installation found in the path is used. To use a specific version:
# file: pre-commit
## Specific MATLAB version
matlabRoot="/c/Program Files/MATLAB/R2025a"
matlabExe="$matlabRoot/bin/matlab"
Select the relevant files
Next, the script collects all staged MATLAB files. If none are found, it exits with status 0, allowing the commit.
# file: pre-commit
# Loop over files to commit, just keep files to check
for file in $(git diff --cached --name-only --diff-filter=ACM); do
if echo "$file" | grep -qE "$supportedExtensions"; then
echo "$file contains MATLAB code."
if [ 1 -eq $count ]
then
gitFullFiles=''$gitFullFiles,''
fi
gitFullFiles=$gitFullFiles''"$gitRootFolder/$file"''
count=1
else
echo "$file not checked."
fi
done
if test $count -eq 0
then
echo "no MATLAB files to check"
exit 0
fi
Check the files
The hook then calls a MATLAB wrapper function precommit_example
, which uses CC4M to check the files.
# file: pre-commit
matlabOutput=$("$matlabExe" -batch "cd('$gitRootFolder');precommit_example('$gitFullFiles', '$configFile', $severityLevelBoundary)")
errorlevel=$?
The corresponding MATLAB wrapper function:
% file: precommit_example.m
function precommit_example(filestring, configFile, severityBoundary, doOpenReport, isVerbose)
% PRECOMMIT_EXAMPLE The MATLAB side of the Git pre-commit hook example
%
% Requires CC4M >= v2.18.2
%
% Inputs - required:
%
% * filestring (char) Comma-separated list of all the files to be checked.
%
% Inputs - optional
% * configFile (char) (File)name of CC4M configuration (default: 'MonkeyProofMATLABCodingStandard')
% * severityBoundary (double) Lowest severity that blocks a commit (default:3)
% * doOpenReport (boolean) If true (default), opens a the HTML report of the detected violations.
% * isVerbose (boolean) If true (default), shows some more information in the shell.
% Copyright 2025 Monkeyproof Solutions BV
arguments
filestring char
configFile char = 'MonkeyProofMATLABCodingStandard'
severityBoundary (1, 1) double = 3
doOpenReport (1, 1) logical = true
isVerbose (1, 1) logical = true
end
files = strsplit(filestring, ',');
[cc4mReportUrl, cc4mSummary] = monkeyproof.cc4m.start(...
'file', files, ...
'configFile', configFile, ...
'runSeverities', severityBoundary);
%% When to fail
% HERE define when to fail for this repository
failCondition = cc4mSummary.Results.NrViolations > 0; % violations found
if isVerbose
disp(cc4mReportUrl)
disp(cc4mSummary.Results)
end
if failCondition
if doOpenReport
% Make sure files analysed are on the path in order to make the links from the report work.
folders = {}; % cell array with project path
% Command to adapt the path.
addpathCmd = ['addpath(''', strjoin(folders, ''', '''), ''')'];
% Start new matlab session to open the report - a new session is
% used so that commit action can be finished immediately.
system(['matlab -r ', addpathCmd, ',web(''', cc4mReportUrl, ''') &']);
end
exit(1)
else
exit(0)
end
end
Commit or abort
Finally, the shell script determines whether to allow the commit:
# file: pre-commit
if test $errorlevel -eq 0
then
exit 0
else
echo "Commit blocked: One or more files violate critical coding guidelines. Please review and resolve the reported issues before committing."
echo $matlabOutput
exit 1
fi
Conclusion and discussion
This example shows how to set up a Git pre-commit hook to block commits if CC4M finds violations with a severity of 3 or higher.
While this approach uses local Git hooks, you can also version control your hook logic or include it in shared developer tooling to ensure consistency across teams.
Additionally, developers often want the option to override the blocking behavior. This can be implemented by adding a "Proceed?" (Yes/No) prompt — either within the MATLAB code (see section)) or in the Commit or abort section of the shell script. An example of this approach, with a Question Dialog included in the MATLAB code, is available in the GitHub repository.
If you have feedback, suggestions, or questions — feel free to contact us