# Using Git Pre-Commit Hooks

DevFeed: [Using Git Pre-Commit Hooks](<https://devfeed.tech/articles/using-git-pre-commit-hooks-10917.md>)

Original publisher: [Read original article](<https://blog.scottlowe.org/2025/10/20/using-git-pre-commit-hooks/>)

Author: Scott Lowe

Published: 2025-10-20T15:00:00Z

Content type: tutorial

Language: en

Sources: [Scott's Weblog](<https://devfeed.tech/sources/scott-s-weblog.md>)

Topics: [Git](<https://devfeed.tech/topics/git.md>), [Markdown](<https://devfeed.tech/topics/markdown.md>), [Bash](<https://devfeed.tech/topics/bash.md>), [Script](<https://devfeed.tech/topics/script.md>)

Tags: [aws](<https://devfeed.tech/tags/aws.md>), [bash](<https://devfeed.tech/tags/bash.md>), [cilium](<https://devfeed.tech/tags/cilium.md>), [cli](<https://devfeed.tech/tags/cli.md>), [cloud](<https://devfeed.tech/tags/cloud.md>), [cni](<https://devfeed.tech/tags/cni.md>), [code](<https://devfeed.tech/tags/code.md>), [containers](<https://devfeed.tech/tags/containers.md>), [cri-o](<https://devfeed.tech/tags/cri-o.md>), [devops](<https://devfeed.tech/tags/devops.md>), [docker](<https://devfeed.tech/tags/docker.md>), [git](<https://devfeed.tech/tags/git.md>), [git-commit](<https://devfeed.tech/tags/git-commit.md>), [git-hook](<https://devfeed.tech/tags/git-hook.md>), [go](<https://devfeed.tech/tags/go.md>), [hooks](<https://devfeed.tech/tags/hooks.md>), [iac](<https://devfeed.tech/tags/iac.md>), [k8s](<https://devfeed.tech/tags/k8s.md>), [kubernetes](<https://devfeed.tech/tags/kubernetes.md>), [lint](<https://devfeed.tech/tags/lint.md>), [linux](<https://devfeed.tech/tags/linux.md>), [markdown](<https://devfeed.tech/tags/markdown.md>), [networking](<https://devfeed.tech/tags/networking.md>), [oci](<https://devfeed.tech/tags/oci.md>), [script](<https://devfeed.tech/tags/script.md>), [security](<https://devfeed.tech/tags/security.md>), [tests](<https://devfeed.tech/tags/tests.md>)

## AI overview

This tutorial explains Git pre-commit hooks and demonstrates using one to run Markdownlint on staged Markdown files before a commit. It notes that a non-zero hook exit status aborts the commit and presents a Bash implementation based on the author's site.

## Source excerpt

A while ago I wrote an article about linting Markdown files with markdownlint. In that article, I presented the use case of linting the Markdown source files for this site. While manually running linting checks is fine--there are times and situations when this is appropriate and necessary--this is the sort of task that is ideally suited for a Git pre-commit hook. In this post, I'll discuss Git pre-commit hooks in the context of using them to run linting checks. Before moving on, a disclaimer: I am not an expert on Git hooks. This post shares my limited experience and provides an example based on what I use for this site. I have no doubt that my current implementation will improve over time as my knowledge and experience grow. What is a Git Hook? As this page explains, a hook is a program "you can place in a hooks directory to trigger actions at certain points in git's execution." Generally, a hook is a script of some sort. Git supports different hooks that get invoked in response to specific actions in Git; in this particular instance, I'm focusing on the pre-commit hook. This hook gets invoked by git-commit (i.e., the user running a git commit command) and allows users to perform a series of checks or tests before actually making a commit. If the pre-commit script exits with a non-zero status, then Git aborts the commit. Using a Pre-Commit Hook to Lint Markdown For my use case, I wanted to run Markdownlint to lint the Markdown files (as described in the previous article on linting Markdown) before the commit. To do that, I came up with the following script: #!/usr/bin/env bash MDLINT="/usr/local/bin/markdownlint" for file in $(git diff --cached --name-only --diff-filter=ACM | grep "\.md"); do if ! $MDLINT "$file"; then echo "Lint check failed on file '$file'." echo "Run markdownlint to identify the errors and try again." exit 1 fi done To make this script active as a pre-commit hook, you must name it pre-commit, you must place it into Git's hook directory (which defa