What are monorepo strategies in Git, and how do CODEOWNERS, path-based CI triggers, and virtual filesystem tools like VFS for Git address governance and scale?
Quick Answer
Monorepo strategies centralize multiple projects in one Git repository, requiring CODEOWNERS for team-based review governance, path-based CI triggers to avoid testing everything on every push, and virtual filesystem tools (VFS for Git, Sapling) for repos that exceed Git's native file system limits. The tradeoffs involve balancing atomic cross-project changes against build and ownership complexity.
Detailed Answer
Think of a monorepo like a city with all businesses in one building. The benefit is shared infrastructure: one address, one parking garage, one security system. Businesses can easily collaborate on shared projects (atomic cross-team changes). But as the building grows to house 500 businesses, you need floor-specific security (CODEOWNERS), elevators that only stop at your floor (sparse checkout), a directory that only shows your floor's map (virtual filesystem), and fire alarms that only alert the affected floor (path-based CI triggers). Without these, the shared building becomes a liability instead of an asset.
Monorepo governance starts with the CODEOWNERS file, which maps file patterns to responsible teams or individuals. GitHub requires approval from the designated owner before merging changes to matched paths. A typical CODEOWNERS file contains entries like: '/services/payments-api/ @acme-corp/payments-team', '/services/order-service/ @acme-corp/orders-team', '/shared/proto-definitions/ @acme-corp/platform-team @acme-corp/payments-team @acme-corp/orders-team'. This prevents one team from accidentally modifying another team's code without review. Combined with branch protection requiring CODEOWNER approval, it creates a decentralized governance model where each team controls their domain within the shared repository.
Path-based CI triggers solve the build fan-out problem. Without them, every push triggers every project's test suite, creating a CI queue that takes hours and wastes compute resources. GitHub Actions supports path-based triggers in workflow definitions: 'on: push: paths: [services/payments-api/, shared/proto-definitions/]'. GitLab CI uses rules with changes conditions. Bazel and similar build systems take this further with dependency-aware build graphs: they compute exactly which targets are affected by the changed files and build/test only those. The challenge is transitive dependencies: a change to shared/proto-definitions/ might need to trigger builds for every service that depends on it. Build systems solve this with a dependency graph, while CI path triggers require manual enumeration.
At extreme scale, standard Git becomes the bottleneck. Microsoft's Windows repository (300GB, 3.5 million files, 4,000 developers) exceeded Git's native capabilities, leading to VFS for Git (Virtual File System for Git, formerly GVFS). VFS for Git virtualizes the file system: it projects the repository contents as a virtual directory tree without actually downloading or materializing files on disk. When a process reads a file, VFS intercepts the read and fetches the content from the server on demand. This means git clone is nearly instant, git status only examines files that have been accessed or modified, and disk usage is proportional to the files actually used rather than the total repository size. Meta built Sapling (formerly Eden), a source control client with Git compatibility that takes a similar approach with a virtual filesystem and on-demand content fetching. For most organizations, the combination of partial clone, sparse checkout, commit-graph, and fsmonitor handles repositories up to several hundred thousand files without needing VFS-level tooling.
A critical gotcha: CODEOWNERS is only enforced when branch protection rules require CODEOWNER reviews. Without the branch protection setting, the CODEOWNERS file is informational only. Another trap: path-based CI triggers can miss critical test failures when a change in a shared library does not trigger downstream service tests. Either enumerate all downstream paths in the trigger configuration or use a build system that understands the dependency graph. Also, monorepos create social challenges beyond technical ones: teams may resist code changes that require approval from another team's CODEOWNERS, slowing velocity. Establish clear policies for shared code modifications and consider a 'platform team' that owns shared directories. Finally, VFS for Git requires a specialized Git server (GVFS protocol) and client-side drivers, making it a significant infrastructure investment that is only justified for the largest repositories.