Last active
July 26, 2025 20:50
-
-
Save todbot/aa644de99d9dacf0307267ea03fdbc64 to your computer and use it in GitHub Desktop.
Git diff for Kicad PCB layouts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# kicad-diff-pcb -- Git diff for Kicad PCB layouts | |
# 22 Jul 2025 - @todbot / Tod Kurt | |
# | |
# Install steps: | |
# 1. Make sure `kicad-cli` is in your PATH | |
# 2. Save this file somewhere in your PATH, I prefer "~/bin" | |
# 3. Make this script executable: "chmod +x kicad-diff-pcb" | |
# 4. Add the following to your ~/.gitconfig | |
# | |
# [difftool "diff-kicad-pcb"] | |
# cmd = ~/bin/diff-kicad-pcb $LOCAL $REMOTE | |
# [alias] | |
# diff-kicad-pcb = "difftool -t diff-kicad-pcb" | |
# | |
# Usage: | |
# git diff-kicad-pcb <git-commit-hash> mypcb.kicad_pcb | |
# | |
# | |
# Takes ideas from: | |
# from: https://forum.kicad.info/t/pcb-diff-with-custom-tool-and-kicad-cli/46664 | |
# | |
set -euo pipefail | |
TEMPDIR=$(mktemp -d) | |
TEMPSVG1="$TEMPDIR/pcb1.svg" | |
TEMPSVG2="$TEMPDIR/pcb2.svg" | |
TEMPHTML="$TEMPDIR/diff-kicad-pcb-viewer.html" | |
# command used to a URL | |
OPENCMD="open" # MacOS to open an HTML file in a web browser | |
# try to autoconfigure what other OSes do | |
unameS="$(uname -s)" | |
if [[ "$unameS" == "Linux" ]]; then | |
OPENCMD="xdg-open" | |
elif [[ "$unameS" == "Windows" ]]; then | |
OPENCMD="explorer.exe" | |
fi | |
generate_svg() { | |
INPUT=$1 | |
OUTPUT=$2 | |
kicad-cli pcb export svg --mode-single --exclude-drawing-sheet --page-size-mode 0 \ | |
-l "B.Cu,F.Cu,B.Silkscreen,F.Silkscreen,Edge.Cuts,B.Mask,F.Mask" \ | |
-o $OUTPUT $INPUT | |
} | |
generate_html() { | |
cat <<EOF | |
<!doctype html> | |
<html> | |
<head> | |
<style> | |
body { | |
font-family: Arial; | |
} | |
.svg-container { | |
position: relative; | |
width: 1000px; | |
height: 1000px; | |
} | |
.svg-container div { | |
position: absolute; | |
inset: 0; | |
object-fit: cover; /* to maintain aspect ratio */ | |
} | |
#img1 { | |
z-index: 1; | |
} | |
#img2 { | |
z-index: 2; | |
background: white; | |
-webkit-mask-image: linear-gradient(to right,transparent 50%,#fff 0%); | |
-webkit-mask-size: 210%; | |
-webkit-mask-position: 0; | |
animation: slideIn 2s ease-in-out infinite alternate; | |
} | |
@keyframes slideIn { | |
to { | |
-webkit-mask-position: 100%;; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<h1>PCB diff</h1> | |
<div class="svg-container" id="container"> | |
<div id="img1"><b>old:</b><img id="svg1" src="$1" /></div> | |
<div id="img2"><b>new:</b><img id="svg2" src="$2" /></div> | |
</div> | |
</body> | |
</html> | |
EOF | |
} | |
generate_svg $1 $TEMPSVG1 | |
generate_svg $2 $TEMPSVG2 | |
html=$(generate_html $TEMPSVG1 $TEMPSVG2) | |
echo $html > $TEMPHTML | |
echo "opening viewer page '$TEMPHTML'" | |
$OPENCMD "$TEMPHTML" |
Note: updated to use CSS animations and not need mouse clicks. It now auto-animates.
Can also use this without editing .gitconfig with something like:
git difftool b5fe1a3c1f32584b7e0cd15fd699b884e30ec378 eight_by_qtpy.kicad_pcb --extcmd 'diff-kicad-pcb'
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Demo of the script above:
diff-kicad-pcb-demo-23Jul2025.mp4