Managing Monorepo Bloat with Mercurial Narrow
Learn how to use the Mercurial narrow extension to clone specific directories in large monorepos, reducing disk usage and clone times significantly.
28 Dec 2025, 22:06 UTC

When a repository grows to tens of gigabytes or millions of historical commits, the standard hg clone command becomes a bottleneck. In a traditional Mercurial setup, every developer downloads the entire directed acyclic graph (DAG), including every file version ever created. For a developer working on a single microservice within a monorepo, downloading the history of the entire project is a waste of disk space and bandwidth.
The solution is the narrow extension. Unlike a shallow clone which only limits history depth, narrow allows you to clone only a specific subset of the directory tree. This keeps your local environment lightweight while maintaining the integrity of the global version control structure.
Enabling the Narrow Extension
Because narrow is not part of the core Mercurial binary, you must enable it in your configuration. You can do this globally in your user hgrc or within the repo-specific hgrc.
[extensions] narrow =
To verify it is active, run the following in your terminal:
hg extensions
If narrow appears in the list, you are ready to perform partial clones.
Cloning a Subset
The power of this extension lies in the --include flag used during the clone process. This tells Mercurial to only fetch the manifest and file data related to the paths you specify.
Suppose you have a massive monorepo but only need to work on the services/api-gateway directory. You would execute:
hg clone --include "^services/api-gateway/" https://example.com/large-monorepo
After the command completes, your local directory will only contain the api-gateway folder. If you run hg status, you will see only that path. You can verify the narrow set by checking the hg manifest, which will show only those paths are currently tracked in your local repository segment.
Working with the Narrow Set
Once cloned, you can commit, branch, and tag as usual. However, if you realize you need files from another directory later, you don't need to re-clone. You can expand your narrow set using the include command:
hg include "services/auth-service/"
This fetches only the missing metadata and file data for the auth service. Conversely, you can shrink your working set using exclude:
hg exclude "^services/legacy-code/"
Trade-offs and Limitations
While narrow solves the storage issue, it introduces specific workflow complexities:
- Merge Complexity: If you attempt to merge a branch that contains files outside your narrowed set, Mercurial may require you to include those paths to resolve the merge correctly.
- Context Blindness: You cannot see the global state of the project. If your code depends on a change made in a directory you haven't included, you will encounter build errors that are difficult to debug without expanding your set.
- Push Restrictions: While you can push narrow changes back to a central server, the server must be configured to handle partial updates, though most modern hosting providers handle this natively.
Summary: narrow is an essential tool for engineers working in massive codebases. It transforms Mercurial from a "heavyweight clone" tool into a surgical instrument that fetches only the context required for the task.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.