Run git ls-files with a quoted pathspec for each lockfile name, such as package-lock.json or poetry.lock. That lists every tracked lockfile at any depth. Then compare the list with your workspace config, because a package with no lockfile is a package a scanner can only guess about.
Why a lockfile inventory comes first
A scan is only as complete as the files it reads. In a monorepo, lockfiles sit at the root, inside packages, or in service folders that nobody has touched for a year. If you do not know where they are, you cannot say what a scan covered.
An inventory also answers a question auditors and customers ask: which parts of this repository are pinned, and which are not?
The command
The Git documentation describes git ls-files as listing the files in the index, which means tracked files. It accepts pathspec arguments, and the docs show a quoted pattern for package-lock.json. Quote the pattern so your shell does not expand it first.
git ls-files '*package-lock.json' '*pnpm-lock.yaml' '*yarn.lock' \
'*poetry.lock' '*uv.lock' '*Pipfile.lock' '*Cargo.lock' \
'*go.sum' '*Gemfile.lock' '*composer.lock' '*packages.lock.json'
Add one pattern per lockfile format you use. The docs state that untracked files need a separate option, so also run the next command to see lockfiles that exist locally but are not committed.
git ls-files --others --exclude-standard
The exclude-standard option applies your gitignore rules, so build output does not flood the list.
Compare the list to your workspaces
Now list the places that should have a lockfile and check each one.
| Question | How to answer it |
|---|---|
| Which folders are workspace members? | Read the workspace config at the repo root |
| Which folders hold a manifest? | List tracked package.json, pyproject.toml, pom.xml and similar |
| Which of those have a lockfile at or above them? | Walk up from each manifest to the nearest lockfile |
| Which have none? | These are your gaps |
Remember that many workspace tools use one lockfile for the whole workspace. pnpm, for example, documents a single pnpm-lock.yaml at the workspace root by default. A missing lockfile inside a member package is normal in that case. The gap is a missing lockfile at the root.
What to do with the gaps
For each package without a lockfile, pick one of three paths.
- Generate and commit one, if it is an application or a service you deploy.
- Document why not, if it is a library where consumers resolve their own versions.
- Mark it out of scope on purpose, if it is a sample, a fixture or dead code.
Write the decision down in the repo. The inventory is only useful if it is repeatable, so put the command in a script and run it in CI. A new service that arrives without a lockfile then shows up as a diff in the inventory rather than as a surprise in an audit.
Try it yourself
The demo shows how a dependency inventory is built from the manifests and lockfiles in a project. Click through to see which files feed the component list.
Click through it at your own pace, or open it full screen.
Safeguard generates SBOMs and scans dependencies per project, so a lockfile inventory tells you which folders to point it at. You can try a single project with the free scan at https://gold.safeguard.sh/scan.
Quick check
Does git ls-files show lockfiles listed in gitignore?
No. By default it lists tracked files. Untracked files need a separate option, and applying the standard exclusions hides ignored ones.
Should every package in a workspace have its own lockfile?
Not always. Some tools keep one lockfile at the workspace root. Check your tool's setting before treating a missing member lockfile as a gap.
Sources
Last reviewed: 19 October 2026.