Build a Shareable Commit Quality Gate

Build shareable pre-commit checks that catch bad Git commits before they land.

Introduction

30 Second Summary

Small formatting mistakes can travel with a code change. They distract reviewers from the work that matters.

In this project, you will build a commit quality gate that stops broken staged content before it enters your Git history. A native Git hook demonstrates local protection before a shareable pre-commit configuration makes the checks repeatable across clones.

What You'll Build

Picture a broken YAML file stopping at your quality gate before its clean replacement passes every check.

By the end of this project, you'll have:

  • A blocked commit attempt that shows staged trailing whitespace cannot enter the repository history.
  • A fresh clone test that proves installed client-side hooks stay local to one repository.
  • A shareable check suite that reports invalid YAML. Its formatting hooks repair final newlines plus trailing whitespace before your clean commit.
  • Secret Mission: Add a repository-local pattern check that rejects DO NOT COMMIT markers.

Are there any prerequisites?

You should already feel comfortable creating Git commits. You'll need internet access for Windows downloads plus the first hook installation, with Step 1 verifying Python 3.11 or newer.

Before We Start

This first checkpoint gives every failure in the project a clear purpose. You are building a local commit quality gate that catches bad staged content before it becomes a Git commit.

Set Up a Cross-Platform Git Workspace

Hook behavior is hard to compare when each repository runs in a different shell. Git also needs a known author identity before it can create a useful baseline.

Bash gives Linux and Windows the same command flow inside Visual Studio Code. Python 3.11 or newer supports the framework you install later.

In this step, get ready to:
  • Verify the required development tools.
  • Configure your Git commit identity.
  • Create an initialized repository with its starter files.
Prepare tools for your operating system

Your operating system changes how you access the tools. The project commands remain Bash commands on both platforms.

Linux

Your Linux environment already includes Git, Python 3, and Visual Studio Code. Start by checking the two command-line tools.

  • Press the Super key to open application search.
  • Type Terminal into application search.
  • Press Enter to open the terminal.
  • Check your Git installation by running this command:
git --version

What should I see?

Git prints its installed version. This confirms that your Bash shell can find Git.

  • Check your Python version by running this command:
python3 --version

What should I see?

Python prints its installed version. Note whether the version is 3.11 or newer.

Windows

Git for Windows supplies Git Bash. The installers may ask you to approve changes to your computer.

  • Download Git-2.56.0.2-64-bit.exe from the Git for Windows release page.
  • Run the Git for Windows installer.
  • Keep the recommended installer options.
  • Install Python 3.15.1 through the Python Install Manager from the Python downloads page.
  • Install Visual Studio Code 1.143.0 with the recommended User setup from the Windows setup guide.
  • Restart Visual Studio Code after installation.

What do these installations provide?

  • Git for Windows provides Git plus the Git Bash shell used throughout this project.
  • Python provides the runtime required by the framework you install later.
  • Visual Studio Code provides the workspace plus its integrated terminal.
  • Press the Windows key to open application search.
  • Type Git Bash into application search.
  • Press Enter to open Git Bash.
  • Check your Git installation by running this command:
git --version

What should I see?

Git prints its installed version. This confirms that Git Bash can find Git.

  • Check your Python version by running this command:
py --version

What should I see?

Python prints its installed version. Note whether the version is 3.11 or newer.

Why use Bash on both systems?

Bash keeps the project commands consistent across Linux and Windows. Git Bash supplies that command environment on Windows.

✔️ I see version 3.11 or higher

That clears the compatibility hurdle. Your Python runtime can support the framework used later in the project.

ⓧ I see an older version

Your installed Python version is below the project requirement. Choose your operating system to upgrade it before continuing.

Linux

  • Install a current Python 3 release through your Linux distribution.
  • Verify the upgraded version by running this command:
python3 --version
What should I see?

Python now reports version 3.11 or newer.

Windows

  • Install Python 3.15.1 through the Python downloads page.
  • Verify the upgraded version in Git Bash by running this command:
py --version
What should I see?

Python now reports version 3.11 or newer.

ⓧ Command not found

Your shell cannot find Python yet. Choose your operating system to install it before repeating the check.

Linux

  • Install a current Python 3 release through your Linux distribution.
  • Confirm the installation by running this command:
python3 --version
What should I see?

Python prints version 3.11 or newer.

Windows

  • Install Python 3.15.1 through the Python downloads page.
  • Confirm the installation in Git Bash by running this command:
py --version
What should I see?

Python prints version 3.11 or newer.

Git check failed?

  • Install Git through your Linux distribution if the Linux shell cannot find it.
  • Run the Git for Windows installer again if Git Bash cannot find Git.

Still stuck? Help me diagnose why Git is unavailable.

Open Bash and confirm your Git identity

Every Git commit records an author name. It also records an author email.

  • Press the Super key on Linux or the Windows key on Windows to open application search.
  • Type Visual Studio Code into application search.
  • Press Enter to open Visual Studio Code.

Linux

  • Click Terminal in the Visual Studio Code top menu.
  • Select New Terminal.
  • Confirm that the terminal profile label shows Bash.

The integrated terminal now uses your normal Linux Bash shell.

Windows

  • Run Terminal: Select Default Profile from the Visual Studio Code command field.
  • Select Git Bash.
  • Click Terminal in the Visual Studio Code top menu.
  • Select New Terminal.
  • Confirm that the terminal profile label shows Git Bash.

The integrated terminal now uses Git Bash for the project commands.

  • Read your current Git identity by running these commands:
git config user.name
git config user.email

What do these commands show?

  • The first command prints the author name Git attaches to commits.
  • The second command prints the author email Git attaches to commits.

✔️ Both values are shown

Your commit identity is ready. Git can attach both author values to future commits.

ⓧ One or both values are blank

  • Replace the example name with your author name.
  • Replace the example email with your author email.
  • Set both identity values by running these commands:
git config --global user.name "Your Name Comes Here"
git config --global user.email you@yourdomain.example.com

What does this change?

The global settings make your identity available to repositories owned by your user account. Your commits can now record the correct author details.

  • Confirm both identity values by running the checks again:
git config user.name
git config user.email

What should I see?

Git prints your author name on the first line. It prints your author email on the second line.

Identity still blank?

Check that you replaced both example values before running the global configuration commands.

Still blank? Help me fix my Git identity.

Create the repository baseline

A repository needs Git metadata before it can track files. Its starter files describe the lab and exclude the project environment from future commits.

  • Click File in the Visual Studio Code top menu.
  • Select Open Folder.
  • Navigate to your Desktop in the folder picker.
  • Use the folder-creation control to create commit-quality-gate.
  • Select the commit-quality-gate folder.
  • Confirm the folder selection to open it in Visual Studio Code.
  • Open a Bash terminal from the Terminal menu.
  • Initialize the open folder as a Git repository by running this command:
git init

What does this command do?

Git creates the hidden metadata used to track repository history. The new repository starts with no commits.

  • Use the new-file control in the Explorer sidebar to create README.md.
  • Paste the following content into README.md:
# Commit Quality Gate

This repository demonstrates shareable checks that run before a Git commit.

What does this file establish?

The heading names the repository. The description records the purpose of its shared checks.

  • Save README.md.
  • Confirm that README.md appears in the Explorer sidebar.

README missing from the Explorer?

Confirm that the file is named README.md inside the open commit-quality-gate folder.

Still missing? Help me find my README file.

  • Use the new-file control in the Explorer sidebar to create .gitignore.
  • Paste the following content into .gitignore:
.venv/

What does this file establish?

The exclusion keeps the project-specific virtual environment out of future commits. You create that environment in a later step.

  • Save .gitignore.
  • Confirm that .gitignore appears in the Explorer sidebar.

Gitignore missing from the Explorer?

Confirm that the filename starts with a dot. Check that your editor did not add another file extension.

Still missing? Help me check my gitignore filename.

✔️ Awesome, I've got everything!

Your two starter files match the project baseline. Double-check that both files are saved.

ⓧ I'd like to double check the full code

Your README.md should match this file exactly.

# Commit Quality Gate

This repository demonstrates shareable checks that run before a Git commit.

What should I compare?

Check the heading plus the repository description. Keep one blank line between them.

Your .gitignore should match this file exactly.

.venv/

What should I compare?

Confirm that the file contains the virtual environment directory name with its trailing slash.

Before you run the final check, predict whether Git already knows about a commit.

  • Inspect the repository state by running this command:
git status

What should I see?

Git reports that the repository has no commits. It lists README.md plus .gitignore as untracked files.

Files missing from Git status?

Confirm that the terminal is inside the commit-quality-gate folder. Check that both filenames match the Explorer sidebar.

Still missing a file? Help me diagnose my repository setup.

Your cross-platform workspace is ready for commits. Next, you will enable Git's native sample hook and watch it reject staged trailing whitespace.

Make a Native Hook Block a Commit

Your initialized repository has the files it needs. Its history still needs a safe starting point before you test commit behavior.

A Git hook can inspect staged content before Git creates a commit. In this step, you will enable Git's supplied sample hook so you can watch a real rejection happen.

In this step, get ready to:
  • Create a baseline commit for the hook lab.
  • Enable Git's supplied native pre-commit hook.
  • Trigger the hook with staged trailing whitespace.
Create the baseline commit

A baseline commit gives you a known-good snapshot. The later history check can then prove whether the rejected draft created another commit.

  • Create the baseline snapshot by running these commands:
git add .
git commit -m "Create hook lab"
git log --oneline

What do these commands do?

  • The first command adds the current repository files to Git's staging area.
  • The second command records that staged snapshot with the message Create hook lab.
  • The final command displays the repository history in a compact format.
  • Confirm that the log contains one commit with the message Create hook lab.

Your repository now has a clean baseline. That single history entry gives the hook test a clear reference point.

Commit missing from the history?

Check that the terminal is still inside the original commit-quality-gate repository. Confirm that the commit command completed before reading the log.

If the baseline still does not appear, help me diagnose the missing Git commit.

Enable the native hook

Traditional Git hooks live inside .git/hooks. Git ignores a hook that does not have executable permission.

  • Install the supplied sample at the active hook path by running these commands:
cp .git/hooks/pre-commit.sample .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

What do these commands do?

  • The copy command creates .git/hooks/pre-commit from Git's disabled sample file.
  • The permission command allows Git to execute the copied hook.
  • The enabled sample checks staged content for trailing whitespace before Git creates a commit.
  • Confirm that the terminal returned to its prompt without reporting an error.

The native hook is now installed in this repository. The next commit attempt provides the visible proof that Git can execute it.

Hook installation command failed?

Confirm that the terminal path belongs to commit-quality-gate. The sample file exists only inside an initialized repository's .git/hooks directory.

If the commands still fail, help me install the sample pre-commit hook.

Trigger the planned rejection

The hook checks the staged version of a file. Your draft line must therefore be saved before you add it to Git's staging area.

  • Select README.md from the Visual Studio Code Explorer sidebar.
  • Click the empty line beneath the existing repository description.
  • Enter the text Draft note with exactly three spaces after note.
  • Save README.md with Cmd+S on macOS or Ctrl+S on Windows.
  • Stage the draft line and inspect its state by running these commands:
git add README.md
git status

What does staging prove?

The first command adds the saved version of README.md to Git's index. The status check confirms that the file is ready for the next commit attempt.

  • Check the status output for README.md among the staged changes.

Before you run the commit, do you expect Git to create it or stop first?

  • Attempt the draft commit by running this command:
git commit -m "Add draft note"

What happened?

The hook reports trailing whitespace in README.md. Its non-zero exit stops Git before the draft commit is created.

That rejection is the result you wanted. You have direct evidence that the native hook is guarding this repository.

Did the draft commit succeed?

Trailing spaces are easy for an editor to remove automatically. Temporarily disable the setting that removes trailing whitespace before saving files.

Restore the three spaces after Draft note. Stage README.md again before repeating the commit attempt.

If the hook still allows the commit, help me diagnose why my native pre-commit hook did not run.

Before you inspect the history, how many commits do you expect the log to contain?

  • Verify that the rejected change created no commit by running this command:
git log --oneline

What should the history show?

You should see only the baseline commit with the message Create hook lab. The staged draft remains available for the next part of the project.

✔️ Awesome, I've got everything!

Your baseline commit remains the only history entry. Your staged draft is ready for the next experiment.

ⓧ I'd like to double check the full code

Compare your staged README.md with this complete file. The final line contains exactly three trailing spaces.

# Commit Quality Gate

This repository demonstrates shareable checks that run before a Git commit.

Draft note   

What should match?

The heading stays at the top. The repository description is followed by a blank line before the staged draft.

Your .gitignore file remains unchanged.

.venv/

Why keep this file?

This tracked rule keeps the later project environment out of Git. It already belongs to the baseline commit.

Your native hook now blocks bad staged content before it reaches the history. Next, you will test whether that protection follows the repository into a fresh clone.

Clone the Repository and Expose the Gap

The native Git hook just blocked a bad commit in your original repository. That result proves local protection works in that one working directory.

This step tests whether that protection follows a fresh clone. The clone will hold deliberately invalid YAML when you test its commit gate.

In this step, get ready to:
  • Create a local clone from the committed baseline.
  • Add an intentionally invalid config.yaml file.
  • Test whether the clone accepts the invalid file.
Clone the committed snapshot

A clone is a second working directory built from committed history. It gives you a clean test of what another contributor receives.

  • Create the sibling clone from your original repository by running this command:
git clone . ../commit-quality-gate-clone

What does this command do?

The command copies the committed repository into a sibling folder named commit-quality-gate-clone. The staged README draft is absent because it never became part of the baseline commit.

Your original repository keeps its staged draft unchanged. The clone receives the clean committed version of README.md.

  • Select File from the top menu in Visual Studio Code.
  • Select Open Folder....
  • Choose the sibling commit-quality-gate-clone folder.
  • Select Open on macOS or Select Folder on Windows or Linux.
  • Confirm the Workspace Trust prompt with Yes, I trust the authors if it appears.
  • Select Terminal from the top menu.
  • Select New Terminal.
  • Open README.md from the Explorer sidebar.

You should see the committed baseline text without the rejected draft line. Your new Bash terminal now belongs to the clone.

Clone missing or showing the draft?

Check that you selected the sibling commit-quality-gate-clone folder. Opening the original repository shows its staged draft instead.

If the clone command failed, confirm that a folder with the same name does not already exist. Help me debug the local clone.

Create the invalid YAML file

The clone needs content that a quality gate should reject. This file deliberately leaves a YAML sequence unfinished.

  • Use the file creation control at the top of the Explorer sidebar to create config.yaml inside commit-quality-gate-clone.
  • Replace the editor contents with this intentionally invalid configuration:
project:
  name: commit-quality-gate
  enabled: [true

Why is this YAML invalid?

  • The project mapping groups the repository settings.
  • The value [true starts a sequence without closing it.
  • A YAML syntax check should reject this unfinished structure.
  • Save config.yaml.
  • Read the final line in the editor.

You should see enabled: [true with no closing bracket. That visible defect is the test case for the clone.

File missing or corrected?

Confirm that config.yaml sits beside README.md in the clone. Keep the unfinished final line exactly as shown for this test.

If the editor changed the content while saving, paste the three lines again. Help me preserve the invalid YAML test file.

✔️ Awesome, I've got everything!

Your clone contains the clean baseline files plus the intentionally invalid config.yaml test file.

ⓧ I'd like to double check the full code

  • Compare .gitignore with this reference:
.venv/

This file remains unchanged from the baseline commit.

  • Compare README.md with this reference:
# Commit Quality Gate

This repository demonstrates shareable checks that run before a Git commit.

This is the clean README from the baseline commit. The rejected draft remains staged only in the original repository.

  • Compare config.yaml with this reference:
project:
  name: commit-quality-gate
  enabled: [true

The unfinished sequence matches the planned invalid YAML test case.

Commit the unchecked YAML

A pre-commit event is the moment when a client-side hook can inspect staged content before Git creates a commit. This attempt tests whether the clone has that protection.

Before you run these commands, do you expect the clone to reject the invalid YAML or record it in history?

  • Test the clone's commit gate by running these commands:
git add config.yaml
git commit -m "Add unchecked YAML"
git log --oneline

What just happened?

The commit succeeds even though config.yaml contains invalid YAML. The final command shows Add unchecked YAML at the top of the history.

The clone came from committed Git data. Installed client-side hooks were not copied into it.

You caught the distribution gap. A safeguard that stays inside one .git/hooks directory cannot protect a fresh clone.

Commit rejected or missing?

Confirm that the active Visual Studio Code workspace is commit-quality-gate-clone. Committing from the original repository runs its installed native hook.

If Git reports that there are no changes to commit, save config.yaml before running the commands again. Help me debug the clone's commit result.

Your clone has exposed the distribution gap in local hooks. Next, you'll add a tracked pre-commit configuration that every clone can reuse.

Add a Shareable pre-commit Configuration

Your clone accepted broken YAML because the original repository's native Git hook stayed behind. That successful bad commit exposed the sharing problem.

A tracked pre-commit configuration gives every clone the same named checks after one setup command. You will add that configuration in Visual Studio Code before testing it against the invalid file.

In this step, get ready to:
  • Track the pinned package plus the shared hook configuration.
  • Install pre-commit inside an isolated project environment.
  • Run all three checks against the invalid YAML.
Create the shared configuration files

The requirements-dev.txt file records the exact development package. The .pre-commit-config.yaml file records the checks available to every clone.

Why use a tracked configuration?

The native hook lived only inside the original repository's .git directory. A tracked configuration travels with the project through Git.

Each developer still installs a local launcher once. After that setup, every clone runs the same named checks.

  • Use the new-file control in the Visual Studio Code file sidebar.
  • Create requirements-dev.txt directly inside commit-quality-gate-clone.

You'll see an empty requirements-dev.txt editor tab inside the clone.

  • Add the pinned dependency by copying this line into requirements-dev.txt:
pre-commit==4.7.0

What Does This File Do?

  • The file gives another clone a repeatable development dependency list.
  • The pre-commit==4.7.0 pin selects the exact package release used by this project.
  • Save requirements-dev.txt.
  • Confirm requirements-dev.txt appears directly beneath commit-quality-gate-clone in the file sidebar.

Can't See requirements-dev.txt?

Check that the file sits directly inside commit-quality-gate-clone. Confirm that its name ends with .txt.

If the file is still missing, help me locate requirements-dev.txt in Visual Studio Code.

The shared configuration pins the hook repository to v6.0.0. It selects one syntax check plus two text-formatting checks.

  • Use the new-file control in the Visual Studio Code file sidebar.
  • Create .pre-commit-config.yaml directly inside commit-quality-gate-clone.

You'll see an empty .pre-commit-config.yaml editor tab inside the clone.

  • Add the shared checks by copying this configuration into .pre-commit-config.yaml:
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: check-yaml
      - id: end-of-file-fixer
      - id: trailing-whitespace

What Does This Configuration Do?

  • The repo entry identifies the repository that supplies the hooks.
  • The rev entry locks those hooks to v6.0.0.
  • The check-yaml hook checks YAML files for parseable syntax.
  • The end-of-file-fixer hook keeps final newlines consistent.
  • The trailing-whitespace hook removes spaces left at the ends of lines.
  • Save .pre-commit-config.yaml.
  • Confirm .pre-commit-config.yaml appears directly beneath commit-quality-gate-clone in the file sidebar.

Configuration File Missing?

Check that the filename begins with a dot. Confirm that it ends with .yaml.

If the file still looks different, help me compare my pre-commit configuration.

✔️ Awesome, I've got everything!

Your clone now contains both shared setup files. Confirm that you saved each file before continuing.

ⓧ I'd like to double check the full code

Compare the tracked files in commit-quality-gate-clone with these exact versions. The config.yaml file remains intentionally invalid for the planned check.

.venv/
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: check-yaml
      - id: end-of-file-fixer
      - id: trailing-whitespace
# Commit Quality Gate

This repository demonstrates shareable checks that run before a Git commit.
project:
  name: commit-quality-gate
  enabled: [true
pre-commit==4.7.0
Install pre-commit in an isolated environment

A virtual environment keeps this project's development package separate from system-wide Python packages. The existing .gitignore file prevents .venv from entering Git history.

macOS

  • Create the .venv environment inside commit-quality-gate-clone by running this command:
python3 -m venv .venv

What Does This Command Do?

Python creates an isolated environment in the .venv directory. Packages installed after activation stay associated with this project.

  • Confirm .venv appears beneath commit-quality-gate-clone in the Visual Studio Code file sidebar.
  • Activate the environment by running this command:
source .venv/bin/activate

What Does Activation Change?

Activation makes the terminal use the Python tools inside .venv. Your prompt usually shows the environment name while it is active.

  • Confirm your Bash prompt shows the active .venv environment.

Windows

  • Create the .venv environment inside commit-quality-gate-clone by running this command in Git Bash:
py -m venv .venv

What Does This Command Do?

Python creates an isolated environment in the .venv directory. Its activation scripts live in the environment's Scripts directory.

  • Confirm .venv appears beneath commit-quality-gate-clone in the Visual Studio Code file sidebar.
  • Activate the environment by running this command in Git Bash:
source .venv/Scripts/activate

What Does Activation Change?

The Bash activation script makes Git Bash use the Python tools inside .venv. Your prompt usually shows the environment name while it is active.

  • Confirm your Git Bash prompt shows the active .venv environment.

Linux

  • Create the .venv environment inside commit-quality-gate-clone by running this command:
python3 -m venv .venv

What Does This Command Do?

Python creates an isolated environment in the .venv directory. Packages installed after activation stay associated with this project.

  • Confirm .venv appears beneath commit-quality-gate-clone in the Visual Studio Code file sidebar.
  • Activate the environment by running this command:
source .venv/bin/activate

What Does Activation Change?

Activation makes the terminal use the Python tools inside .venv. Your prompt usually shows the environment name while it is active.

  • Confirm your Bash prompt shows the active .venv environment.

Virtual Environment Not Activating?

On macOS or Linux, confirm the activation path is .venv/bin/activate. In Windows Git Bash, confirm the path is .venv/Scripts/activate.

If activation still fails, help me activate my project virtual environment.

  • Install the pinned dependency from requirements-dev.txt by running this command:
python -m pip install -r requirements-dev.txt

What Does This Command Do?

The active environment's package installer reads requirements-dev.txt. It installs pre-commit 4.7.0 inside .venv.

  • Confirm the installation finishes without an error.

Package Installation Failing?

Confirm your terminal prompt shows the active environment. Check that requirements-dev.txt contains the exact package pin.

If the installation still fails, help me diagnose my pre-commit installation.

Before you check the installation, which pre-commit version do you expect the active environment to report?

  • Check the installed version by running this command:
pre-commit --version

What Does This Command Check?

The command asks the active environment which pre-commit release it provides. This confirms whether the dependency pin was installed correctly.

You should see pre-commit 4.7.0 in the output.

✔️ I see pre-commit 4.7.0

That's the isolated setup complete. Your active .venv now provides the exact pre-commit release pinned by the project.

ⓧ I see a different version

The active environment resolved a different pre-commit installation. Reinstall the package from the project's pinned requirements file.

  • Reinstall the pinned dependency by running this command:
python -m pip install -r requirements-dev.txt

Why Reinstall From the File?

The requirements file specifies pre-commit 4.7.0. Reinstalling from that file brings the environment back to the project pin.

  • Check the installed version again by running this command:
pre-commit --version

What Should This Confirm?

The active environment should now report pre-commit 4.7.0.

ⓧ Command not found

The shell cannot find the project installation when .venv is inactive. Reactivate the environment for your operating system.

macOS

  • Reactivate the environment by running this command:
source .venv/bin/activate
What Does This Restore?

Activation places the executables from .venv on the current shell's command path.

Windows

  • Reactivate the environment in Git Bash by running this command:
source .venv/Scripts/activate
What Does This Restore?

Activation places the executables from .venv on the current Git Bash command path.

Linux

  • Reactivate the environment by running this command:
source .venv/bin/activate
What Does This Restore?

Activation places the executables from .venv on the current shell's command path.

  • Install the pinned dependency in the reactivated environment by running this command:
python -m pip install -r requirements-dev.txt

Where Is the Package Installed?

The installation now targets the reactivated .venv environment. It reads the package pin from requirements-dev.txt.

  • Verify the installation by running this command:
pre-commit --version

What Should This Confirm?

The active environment should now report pre-commit 4.7.0.

Install the hook and reveal the YAML failure

The package provides the command-line tool. The clone still needs a launcher in .git/hooks/pre-commit so Git can trigger the tracked checks before a commit.

  • Install the repository hook launcher by running this command:
pre-commit install

What Does This Command Do?

Pre-commit installs its launcher at the native hook location inside this clone. Git can now trigger the tracked configuration during the pre-commit event.

You should see pre-commit installed at .git/hooks/pre-commit in the terminal.

Hook Launcher Not Installed?

Confirm Bash is still inside commit-quality-gate-clone. Check that .venv remains active.

If installation still fails, help me install the pre-commit launcher in my clone.

The first full run can take longer while pre-commit downloads the hook environment. A short wait here means the checks are being prepared.

Before you run the checks, do you think the invalid config.yaml file will pass or fail?

  • Run every configured check against the repository files by running this command:
pre-commit run --all-files

What Does This Command Test?

  • The --all-files flag runs every configured hook against all repository files.
  • The three hook IDs in .pre-commit-config.yaml determine which checks run.
  • The check yaml check tries to parse each YAML file.

You'll see check yaml fail for config.yaml. The end-of-file check also runs.

The trailing-whitespace check runs as well. This planned failure proves the tracked gate detects the broken YAML that previously entered the clone.

Configured Checks Did Not Run?

Confirm .pre-commit-config.yaml is saved inside commit-quality-gate-clone. Check that its indentation matches the full-code comparison.

If the result still differs, help me debug my pre-commit hook run.

Your clone now carries a version-controlled quality gate plus the local launcher that runs it. Next, you will repair the invalid YAML before completing a guarded commit.

Fix the Failure and Commit Cleanly

Your clone exposed the sharing gap. Git accepted broken YAML before the shared pre-commit checks were installed.

A useful quality gate turns failure output into a clear repair. You will fix config.yaml before creating a commit that passes the same checks.

In this step, get ready to:
  • Replace the invalid YAML value with a valid Boolean.
  • Run all three checks until each result passes.
  • Create a guarded commit from the repaired files.
Repair the YAML and rerun the gate

The failing value starts a YAML list without completing it. A plain Boolean gives enabled one complete value that the YAML checker can parse.

  • Replace the contents of config.yaml with the code below:
project:
  name: commit-quality-gate
  enabled: true

What does this configuration do?

  • The project mapping groups the repository settings.
  • The name value identifies this commit quality gate.
  • The enabled: true entry stores a complete Boolean value that the YAML checker can parse.
  • Save config.yaml.

✔️ Awesome, I've got everything!

Your saved config.yaml now contains the repaired project settings.

ⓧ I'd like to double check the full code

  • Compare your saved config.yaml with this complete reference:
project:
  name: commit-quality-gate
  enabled: true

What should match?

The indentation places name and enabled inside project. The final value is the Boolean true.

Before you run the gate, do you expect the repaired file to clear all three checks?

  • Test every repository file by running this command:
pre-commit run --all-files

What does this command check?

  • The --all-files flag sends every tracked repository file through the configured hooks.
  • The check-yaml hook confirms that YAML files contain parseable syntax.
  • The end-of-file-fixer and trailing-whitespace hooks check text formatting.

✔️ All three checks passed

You will see all three checks report Passed. That is the repair confirmed: your shared gate now accepts the repository.

ⓧ A fixer changed a file

A formatting hook can repair a file during its run. The repaired content needs to be reviewed before another check.

  • Review the changed file in your editor.
  • Stage the reviewed correction by running this command:
git add .

What does this command stage?

The command updates Git's staging area with the reviewed repository changes. The next check now reads the repaired content.

  • Rerun every configured check by running this command:
pre-commit run --all-files

Why run the checks again?

The second run tests the content after the formatter's repair. You can continue when all three checks report Passed.

Checks still failing?

  • Confirm that config.yaml contains enabled: true with two spaces before enabled.
  • Confirm that your .venv environment remains active in Bash.
  • Save every changed file before rerunning the checks.

If the failure continues, help me diagnose the remaining pre-commit failure.

Commit through the installed hook

The direct check is green. The installed launcher now runs the same checks against staged content during the next commit.

A non-zero result stops the commit before Git creates it. Passing checks let the commit proceed.

  • Stage the repaired repository files by running this command:
git add .

What enters the guarded commit?

Git updates its staging area with the repaired YAML file and the shared quality-gate files. The installed hook checks this staged snapshot during the commit.

Before you commit, do you expect the installed gate to stop the commit or allow it to complete?

  • Create the guarded commit by running this command:
git commit -m "Add shareable quality gate"

What happens during this commit?

  • The installed pre-commit launcher runs before Git creates the commit.
  • Each configured hook checks the staged content.
  • Git creates the commit after every check passes.

You will see all three checks report Passed. Git then completes the commit with the message Add shareable quality gate.

Commit blocked?

  • Read the hook output to identify the file that failed.
  • Review any automatic formatting change before staging the file again.
  • Rerun the all-files check before attempting the commit again.

If you cannot identify the cause, help me debug the blocked guarded commit.

  • Confirm the new commit appears in the repository history by running this command:
git log --oneline

What does the history prove?

The compact history lists each commit on one line. The newest entry proves that the installed gate allowed the repaired staged content through.

You will see Add shareable quality gate at the top of the history. That closes the loop: your shared checks now produce a repeatable passing result before a commit is created.

Commit missing from the history?

  • Review the previous commit output for a failed hook result.
  • Confirm that every changed file was staged before the commit attempt.

If the commit still does not appear, help me trace why the commit was not created.

Secret mission

Block DO NOT COMMIT Markers

General format checks cannot catch every team convention. Add a repository-local pattern rule that rejects DO NOT COMMIT markers while avoiding a match against its own configuration.

Clean Up Your Resources

Clean Up Your Resources

Everything in this project runs locally, so keeping it creates no cloud resources or ongoing usage charges. Choose whether to keep the repositories ready, pause your active session, or remove the project entirely.

Resources you used:

  • The original commit-quality-gate Git repository with its native sample hook. Its rejected README.md draft remains staged.
  • The commit-quality-gate-clone repository. It contains the .venv virtual environment. The installed pre-commit launcher remains at .git/hooks/pre-commit. The tracked quality gate files remain inside the clone.
  • The local pre-commit cache containing the downloaded hook environments.

Keep everything running

No action needed. Choose this if you want to keep testing the quality gate or extend its checks.

  • Keep the commit-quality-gate folder to preserve the native-hook demonstration.
  • Keep the commit-quality-gate-clone folder to preserve the shareable quality gate.
  • Retain the .venv folder so the pinned development dependency stays ready.
  • Retain the pre-commit cache so future hook runs can reuse the downloaded environments.

Pause - I'll come back to this later

Pause the active project session while keeping both repositories ready for another day. Your local files continue to create no ongoing charges.

  • Deactivate the active project environment by running this command:
deactivate

What does this command do?

This ends the active virtual environment session. It leaves the environment files inside .venv unchanged.

Your session is paused safely. Every project file stays in place.

  • Close Visual Studio Code after deactivating the environment.
  • Leave the commit-quality-gate folder on disk.
  • Leave the commit-quality-gate-clone folder on disk.
  • Keep the pre-commit cache for your next hook run.

Delete - I don't want to use this again

Deleting the folders is permanent. Choose this only if you no longer need the local repositories.

  • Remove the cached hook environments by running this command while .venv is still active:
pre-commit clean

What does this command do?

This clears cached pre-commit files before you remove the repositories.

That's one cleanup layer handled: the cached hook environments are gone.

  • Deactivate the project environment by running this command:
deactivate

Why deactivate first?

This returns Bash to its normal environment before you remove the folder containing .venv.

  • Close Visual Studio Code.
  • On macOS, use Finder to delete the commit-quality-gate folder.
  • On macOS, use Finder to delete the commit-quality-gate-clone folder.
  • On Windows, use File Explorer to delete the commit-quality-gate folder.
  • On Windows, use File Explorer to delete the commit-quality-gate-clone folder.
  • Confirm that neither repository remains in their shared parent folder.

Cleanup is complete. Removing the clone also removes its nested .venv folder and installed hook launcher.

Nice Work!

Nice Work!

Brilliant work! You built a shareable commit quality gate using Git and pre-commit to check staged content before every guarded commit.

You've learned how to:

  • Trigger a native pre-commit hook that rejects staged trailing whitespace before Git creates a commit.
  • Expose the clone limitation by committing invalid YAML in a fresh clone that never received the original client-side hook.
  • Replace the local-only setup with a shareable quality gate that checks YAML, final newlines, and trailing whitespace. Repair a failing file until all three checks pass before committing.
  • Complete the Secret Mission by adding a repository-local marker check that rejects DO NOT COMMIT. Exclude .pre-commit-config.yaml so the check does not match its own rule.

Ready to quiz yourself?