---
title: Making QMK easier to use with Git submodules
description: Gone are the pains of keeping a fork up-to-date!
publishedDate: 2024-06-23
tags:
    - guide
    - keyboards
---
Typically, when people use QMK, the [popular custom mechanical keyboard firmware](https://qmk.fm), they maintain a fork of the QMK repo with all their keymaps added to it. QMK is a very fast-moving, frequently-updated project, so it's very easy to end up a long way behind QMK's `master` branch if you don't keep on top of your fork.

![A screenshot of a GitHub fork with the text "This branch is 40 commits ahead of, 9692 commits behind qmk/qmk_firmware:master."](manybehind.png)

Personally, I don't find myself reflashing my keyboards that often, so usually my fork goes unmaintained for a long period of time. When I came back to it recently after one of my keyboards' microcontrollers died and needed reflashing, I had to fix a load of merge conflicts without really knowing what I was doing, and landed myself with a fork that refused to build - I was told it was best start again on a fresh copy of QMK.

Frustrated by this, I decided to look into overlaying my changes onto QMK instead of ever comitting anything to the QMK source tree, and the simplest way I could think of this was to use Git submodules. This way, I can update QMK without having to make sure my changes mesh nicely with the upstream content, and it's a lot less painful to use as a result.

Copies of all my modified files live in one directory called `repo` that resembles QMK's structure...

```
repo
└── keyboards
    ├── codemicro
    │   └── macropad
    │       ├── config.h
    │       ├── info.json
    │       ├── keymaps
    │       │   ├── codemicro
    │       │   │   ├── keymap.c
    │       │   │   └── layout.c
    │       │   └── default
    │       │       └── keymap.c
    │       ├── readme.md
    │       └── rules.mk
    ├── keychron
    │   └── v4
    │       └── iso
    │           └── keymaps
    │               └── codemicro
    │                   └── keymap.json
    └── lets_split
        └── keymaps
            └── codemicro
                ├── abi_stock.json
                ├── bit-c_led.h
                ├── config.h
                ├── keymap.c
                └── layout.c
```

and there's a directory alongside that called `qmk` that contains the QMK submodule.

The workflow is like this:

1. Setup the QMK submodule using `git submodule add https://github.com/qmk/qmk_firmware/ qmk`
2. Commit the new `.gitmodules` file and the submodule
3. Copy my modifications from `repo` over the top of the QMK source using `cp -r repo/* qmk`
4. `cd` into `qmk` and run my build commands, eg. `make keychron/v4/iso:codemicro:flash`.

If I ever want to undo any changes I've made to QMK, I can use `git submodule foreach git clean -fd`, the `-fd` argument of which tells Git to delete any unstaged and untracked files and directories. It's also possible to pull in the latest version of QMK without any hassle using `git submodule update --remote --merge`.

That can all be thrown into a `Makefile`...

```Makefile
.PHONY: apply reset pull

apply: reset
	cp -r repo/* qmk

pull: reset
	git submodule update --remote --merge

reset:
	git submodule foreach git clean -fd

```

and you're all set! You can see my working version at [https://git.tdpain.net/codemicro/qmk_overlay](https://git.tdpain.net/codemicro/qmk_overlay).

If you do choose to do this, remember to update the `qmk` tool's `user.qmk_home` config key to point the submodule using `qmk config user.qmk_home=/path/to/your/qmk_overlay/qmk`!

# Addendum: Why not [external QMK userspaces](https://docs.qmk.fm/newbs_external_userspace)?

I'm not quite sure how QMK's external userspaces feature works, but I do know that it's new, comes with a functionality disclaimer and requires learning about how to use and configure it. When I was setting this up, I just wanted something that I understood and could get working super quickly, plus my custom QMK config contains a whole new keyboard, and the docs didn't say if adding entire keyboards instead of just keymaps was supported by userspaces.