Skip to content

Commit a430c93

Browse files
committed
New post
1 parent 2a4f0f7 commit a430c93

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
---
2+
layout: post
3+
title: "Git hooks to keep my blog clean"
4+
author: "Marcus Hammarberg"
5+
date: 2025-05-12 04:00:00
6+
tags:
7+
- Marcus private
8+
- Programming
9+
---
10+
11+
As I wrote in the [last post](https://www.marcusoft.net/2025/04/spell-checker-in-folders.html) I've created a little script that spell checks all my blog posts. That was about 3000+ spelling mistakes.
12+
13+
And I then created a similar script to lint the markdown on all blog posts. Another 1250 warnings and errors.
14+
15+
Now that I've cleaned that up - I never want to do that again.
16+
17+
No - rather I would like to check for problems every time I make a change. Preferably just before I check stuff into Git.
18+
19+
Turns out - there's a built-in Git-tool for that.
20+
21+
Let me show you how I did that.
22+
23+
<!-- excerpt-end -->
24+
25+
## Markdown linting
26+
27+
The markdown linting is another script that I put in the `scripts` folder of [this repository](https://github.com/marcusoftnet/marcusoftnet.github.io). It looks like this, not the way that I return the error code of the linting through `STATUS=$?` and `exit $STATUS`. This will become important later on.
28+
29+
```bash
30+
#!/bin/bash
31+
32+
# Usage: bash lint-all.sh _posts
33+
34+
if [ -z "$1" ]; then
35+
echo "Usage: $0 <directory>"
36+
exit 1
37+
fi
38+
39+
TARGET_DIR="$1"
40+
FIX_FLAG="$2"
41+
42+
# echo "Linting Markdown files in directory: $TARGET_DIR"
43+
44+
npx --yes markdownlint-cli --config ./.markdownlint.json $TARGET_DIR $FIX_FLAG
45+
46+
STATUS=$?
47+
48+
if [ $STATUS -ne 0 ]; then
49+
echo "❌ Markdown linting failed."
50+
else
51+
echo "✅ No markdown linting issues found."
52+
fi
53+
54+
exit $STATUS
55+
```
56+
57+
## Git hooks
58+
59+
Each local git installation resides in the `.git` folder. Inside that folder there's a `hooks` directory which are bash scripts that will be run at certain points in the life cycle of changes to git. For example `.git/hooks/pre-commit` runs just before each commit. This is the one we want.
60+
61+
Notice that there's a `.git/hooks/pre-commit.sample` to take inspiration from.
62+
63+
## Pre-commit script
64+
65+
I want my script to first check spelling (of all 1240+ blog posts) and then do markdown linting. If both of those are good I want to allow the commit.
66+
67+
This can be accomplished with the following script:
68+
69+
```bash
70+
#!/usr/bin/env bash
71+
72+
# Run spelling check
73+
bash ./scripts/check-spelling.sh _posts
74+
SPELL_STATUS=$?
75+
76+
# Run markdown lint
77+
bash ./scripts/markdown-lint.sh _posts --fix
78+
LINT_STATUS=$?
79+
80+
# Check results
81+
if [ $SPELL_STATUS -ne 0 ] || [ $LINT_STATUS -ne 0 ]; then
82+
echo "Pre-commit checks failed."
83+
[ $SPELL_STATUS -ne 0 ] && echo "❌ Spelling check failed"
84+
[ $LINT_STATUS -ne 0 ] && echo "❌ Markdown linting failed"
85+
exit 1
86+
fi
87+
88+
echo "✅ All pre-commit checks passed."
89+
exit 0
90+
91+
```
92+
93+
Here you can see how the exit code from the sub-scripts become important and I store them in `$SPELL_STATUS` and `$LINT_STATUS` respectively.
94+
95+
## Link to script in repo
96+
97+
Having a script in `.git/hooks/pre-commit` means that the script is local to only you. This can be useful but sharing the goodness is better.
98+
99+
Let's create the `pre-commit`-script inside the repository at `/scripts/git-hooks/pre-commit` for example and then make a link to the `.git/hooks/pre-commit`:
100+
101+
```bash
102+
ln -s ../../scripts/git-hooks/pre-commit .git/hooks/pre-commit
103+
```
104+
105+
Notice that the `../../` are need to get back to the root from the `.git/hooks`-directory.
106+
107+
Now you need to make the script executable in the `.git/hooks/` directory.
108+
109+
```bash
110+
chmod +x scripts/git-hooks/pre-commit
111+
```
112+
113+
And then try to do a commit, to see the linting and spell-checker run. If it fails the commit is not added, and once the checks pass without errors your commit is made.
114+
115+
Beautiful.

0 commit comments

Comments
 (0)