Git submodules let a repository refer to another repository at a recorded commit. They can support a deliberate source dependency boundary, but they require clear checkout and update practices. A path appearing in the parent project is not proof that the submodule is initialized, at the recorded state, or trusted.
This guide explains how to review the relationship for repositories you maintain. It does not recommend fetching unknown sources or running their build scripts without inspection. Treat both the dependency origin and the recorded revision as part of the project’s supply-chain contract.
Define the Git submodules purpose
Identify why the dependency is maintained as a submodule rather than another supported packaging approach. A source dependency with its own history can justify the model, but it adds operational requirements for contributors and CI.
Record the owner, source, update process, and expected build relationship. A dependency that nobody reviews can drift into an unexplained state even when Git tracks its pointer correctly.
Keep the parent project’s approval process explicit. Updating the recorded commit is a change to the product’s dependency, not merely housekeeping.
Review source configuration before fetching
Inspect the declared submodule configuration and any supported local overrides. URLs and paths deserve review, especially in an unfamiliar repository. Do not assume a source is safe because the directory name resembles a trusted project.
Confirm the approved remote and authentication method. Avoid storing credentials in a committed URL or broadly exposed configuration. Follow the repository’s supported access process.
The Git submodule guide explains the relationship and common operations. Match the procedure to the installed version and your project’s policy.
Distinguish recorded state from local state
The parent repository records a specific submodule commit. A developer’s local submodule checkout can differ, contain modifications, or be absent. Inspect both the parent pointer and the working state before building or committing.
A checkout can use a detached state under common workflows. Understand where new commits would be preserved before editing the dependency. Do not create work that is reachable only through an easily discarded local state.
Keep status inspection part of the build and review process. A successful local build may rely on changes that the parent repository does not record.
Initialize through the supported workflow
Use the project’s documented checkout process to obtain the intended submodule state. Review whether nested submodules are required and what sources they introduce. Recursion can broaden the dependency set beyond the first visible entry.
Do not run arbitrary initialization or update commands from an untrusted repository without examining the sources and downstream build behavior. The checkout process is part of the trust boundary.
Verify the resulting revisions and required files. A command completing successfully does not prove that the application has every dependency it expects.
Update dependencies deliberately
Select and review the desired upstream revision, test it, and record the parent change through the ordinary review process. Avoid treating a remote branch’s latest state as automatically suitable for a release.
Inspect the dependency’s changes and relevant compatibility notes. A small parent diff can represent a large change in the submodule’s code. Reviewers need the underlying context, not just the new commit identifier.
Keep rollback and ownership clear. A dependency update that breaks the product should have a known previous state and a supported correction path.
Preserve reproducible builds
Ensure CI checks out the intended recorded revisions under approved credentials and sources. A build script that silently updates to another revision can undermine the parent repository’s declared dependency state.
Record relevant build inputs and verify output through the project’s artifact process. Our artifact provenance guide explains why source selection and released-artifact evidence need a clear relationship.
Do not equate a commit identifier with complete trust. Verification, review, and supported source authentication still matter.
Handle local work and cleanup carefully
Inspect uncommitted changes in both the parent and dependency before switching state or removing a working directory. Preserve work through the project’s normal branch and commit process.
Review deinitialization or removal procedures rather than deleting files blindly. The parent configuration, tracked pointer, and local repository state have different roles. A cleanup should intentionally address the relevant pieces.
Keep contributor instructions clear enough to reproduce. Submodule confusion often comes from a workflow whose required state is hidden in one person’s local environment.
A practical dependency review
Consider a parent application with one approved source dependency. Perform a clean checkout through the documented process and compare the submodule revision with the parent pointer. Build and test without relying on an older working directory.
Then review a proposed pointer update. Inspect the dependency’s actual changes, run representative compatibility tests, and confirm the CI checkout produces the same intended source state. Include nested sources if the project uses them.
Record approved remotes, revisions, authentication, test outcomes, and the rollback target. This is stronger evidence than observing that a developer’s existing checkout builds successfully. The latter may contain unrecorded local edits or another revision. Keep that distinction visible in release review and onboarding material.
Review dependency state at handoff
Submodule workflows cross a contributor’s local checkout, the parent repository’s recorded pointer, and the build system’s actual inputs. A handoff should make those states explicit rather than expecting another engineer to infer them from a directory name.
- Record approved remotes and any relevant local overrides without including credentials. A dependency source should remain understandable when a new contributor or clean CI worker initializes the project.
- Compare the working revision with the parent pointer and inspect local modifications. A build that relies on unrecorded changes cannot be reproduced merely by checking out the parent commit.
- Include nested dependencies when the supported workflow initializes them. A single visible submodule can introduce another source relationship that deserves the same origin and revision review.
- Review the underlying changes when updating a pointer. One short parent diff can represent a significant upstream change with compatibility, licensing, or security consequences for the released product.
- Verify that CI does not silently move to a different revision during build. The released artifact should have an approved relationship to the dependency state the review actually evaluated.
Keep recovery and contributor instructions current. A predictable source contract is more useful than a checkout that works only because one developer remembers an undocumented sequence of update commands.
Frequently asked questions
Does the parent repository contain the dependency’s whole source?
The submodule relationship records a source repository and commit under its model. Checkout and initialization requirements remain distinct from ordinary parent files.
Is a pointer update always a small change?
Not in impact. One changed identifier can refer to substantial upstream modifications. Review the underlying diff and compatibility.
What should I verify before release?
Approved origins, recorded revisions, clean checkout behavior, local modifications, and the actual build inputs used by CI.