Skip to content

Instantly share code, notes, and snippets.

@todbot
Last active July 26, 2025 20:50
Show Gist options
  • Save todbot/aa644de99d9dacf0307267ea03fdbc64 to your computer and use it in GitHub Desktop.
Save todbot/aa644de99d9dacf0307267ea03fdbc64 to your computer and use it in GitHub Desktop.
Git diff for Kicad PCB layouts
#!/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"
@todbot
Copy link
Author

todbot commented Jul 23, 2025

Demo of the script above:

diff-kicad-pcb-demo-23Jul2025.mp4

@todbot
Copy link
Author

todbot commented Jul 24, 2025

Note: updated to use CSS animations and not need mouse clicks. It now auto-animates.

@todbot
Copy link
Author

todbot commented Jul 25, 2025

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