Safeguard
Developer Tools•

How do you record which library commit shipped in a firmware release?

A git submodule stores a commit pointer, not files, so the superproject commit records the exact library version. How to use it for firmware releases.

Safeguard Security Team
3 min read

A git submodule records a dependency as a commit pointer inside your repository, so the superproject commit you tag for a firmware release also names the exact commit of each vendored library. Clone with recursion, update deliberately, and write the pointers into your SBOM.

How the pointer works

Pro Git explains that the superproject tree holds an entry for the submodule path with mode 160000, a commit recorded as a directory entry, plus the commit's SHA-1. The .gitmodules file maps each path to a URL. The submodule's files are not tracked by the superproject at all, only the commit it points at.

Two things follow. A release tag on your repository fixes every library commit at once. And moving a library forward is an ordinary change to the superproject, which you can review.

Getting a clean checkout

A plain clone creates the submodule folder but leaves it empty. Build scripts that assume the folder is populated will either fail or, worse, use a stale local copy.

git clone --recurse-submodules <repo-url>
git submodule update --init --recursive

Use the second line after switching branches or pulling. A pull fetches submodule objects but does not update the working tree unless you ask for recursion.

Updating on purpose

To move to the latest upstream commit, run git submodule update --remote, then git add the path and commit. That changes the recorded pointer, and the pull request shows the old and new commit. Review the upstream changelog for the range, and rebuild before merging.

Publish the library commits before the superproject: git push with the recurse-submodules on-demand option does this, so teammates are not left with a pointer to a commit they cannot fetch.

Turn pointers into inventory

At release time, list each submodule path, URL and pinned commit, and add them to your SBOM along with the upstream version the commit corresponds to. A commit hash alone is hard for a scanner to match to an advisory, so state the release it sits on or the nearest tag.

Release stepWhat to capture
Tag the firmwareSuperproject commit
List submodulesPath, URL, pinned commit
Map to versionsNearest upstream release
StoreSBOM and tag together

Where Safeguard fits

Safeguard provides SBOM and dependency scanning, reachability analysis, and policy gates for the source repositories and manifests it supports, and you can run a free scan at gold.safeguard.sh/scan. Check coverage for your build system before relying on it.

Try it yourself

Find a component and see which fields would let you match it to an advisory. A bare commit hash would need a version added.

Click through it at your own pace, or open it full screen.

Quick check

Does a submodule pointer prove the library is unmodified?

It proves which commit you pinned. If someone edits files inside the submodule folder, the working tree can differ from the pointer, so build from clean checkouts.

Can I just copy the library into my repository instead?

You can, but then the version is no longer recorded for you. If you copy, note the source URL, version and checksum next to the code.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.