The myth says that if staging and production run the same git commit, they run the same software. In practice the commit fixes your source code only. Dependencies, the base image, and the runtime can all differ, so the same commit can produce different running systems.
What a commit does and does not pin
A commit pins every file in your repository. It does not pin anything that is fetched at build or start time. That includes:
- Packages resolved from a registry when no lockfile exists, or when a range is used and the install command updates the lock.
- A base image referenced by a mutable tag.
- Operating system packages installed with a package manager inside the Dockerfile.
- The language runtime and build tool versions on the build host.
| Fact | Pinned by the commit? |
|---|---|
| Application source | Yes |
| Lockfile contents | Yes, if committed |
| Version a range resolves to today | No |
| Content behind an image tag | No |
| OS packages added at build time | No |
A short example
Two builds of one commit, two weeks apart. The Dockerfile starts from a tag and runs an OS package install. Between builds, the publisher updated the image behind the tag and a library got a new patch release. Staging got the first build, production the second. Same commit, different libraries. A scan of staging does not describe production.
How to make the commit mean more
- Commit the lockfile and install from it with a command that fails on mismatch.
- Reference base images by digest, and update the digest through reviewed pull requests. Tag or digest explains the trade-off.
- Build one artifact per commit and promote it, rather than rebuilding per environment. See build once, promote the same artifact.
- Record the SBOM next to the artifact, so the build output is documented, not assumed.
- Pin runtime versions in the repository, not on the build host.
How to test whether the myth is hurting you
Take any service. Find the commit running in staging and production. If they match, export the installed packages from both and diff them. If the lists differ, you have just proved the myth wrong for that service, and you know which of the four gaps to close first.
Why it matters for review and audit
Release records often cite a commit hash as proof of what shipped. That is fair evidence of source, but weak evidence of composition. Adding an artifact identifier and an SBOM turns a claim about code into a claim about the whole build.
Try it yourself
Click through it at your own pace, or open it full screen.
Open the inventory and notice how much of it is code you did not write. None of that is fixed by the commit hash alone.
What Safeguard does here
Safeguard generates SBOMs and keeps monitoring them against new advisories, so the composition of a build is recorded next to the commit. Try a free scan at gold.safeguard.sh/scan.
Quick check
Does a committed lockfile make the myth true?
It makes it truer for application packages. Base images, OS packages, and runtimes still need their own pins.
What is the cheapest first fix?
Install from the lockfile with a command that fails when it is out of sync, in every environment's build.
Last reviewed: 19 October 2026.