Summary
The challenge involves relative imports in repo manifests for hierarchical project structures. When using the Google repo tool, including one manifest file into another with a relative path (e.g., ../l2-1/manifest.xml) fails due to toolchain limitations, forcing developers to use absolute paths or submodules, which complicates change propagation across project layers.
Root Cause
- Repo tool’s manifest parser only resolves
nameattributes in<include>tags as absolute URLs or paths, not relative references. - Manifest resolution is context-agnostic; it doesn’t inherit the including file’s directory path.
- No built-in relative path support exists for cross-manifest imports, unlike standard filesystem operations.
Why This Happens in Real Systems
- Hierarchical project structures (e.g., superprojects containing subprojects) require modular manifest management.
- Avoiding submodule overhead (slow updates, complex propagation) is critical for large codebases.
- Toolchain constraints in
repomanifest handling prevent standard relative path resolution, forcing workarounds like:- Hardcoded absolute paths
- Duplicate manifest content
- Complex wrapper scripts
Real-World Impact
- Maintenance overhead: Manual path updates when restructuring projects
- Broken CI/CD pipelines: Failing repo syncs due to invalid manifest references
- Reduced portability: Manifests lose reusability across different repository layouts
- Compromised modularity: Forced duplication of manifest definitions
- Increased configuration drift: Inconsistencies when manifests are manually edited
Example or Code
Consider this failing structure:
manifest-repo/
├── l1/
│ ├── l1-manifest.xml
│ └── l2-1/
│ └── l2-1-manifest.xml
└── l2-2/
└── l2-2-manifest.xml
Invalid relative import in l1/l1-manifest.xml:
Workaround using absolute path:
How Senior Engineers Fix It
- Manifest repository pattern:
- Create a dedicated manifest repository with flat structure
- Use absolute URLs for all includes:
- Path injection via environment variables:
- Pass the base manifest URL during
repo init - Dynamically generate manifests with scripts
- Pass the base manifest URL during
- Custom manifest processing:
- Pre-process includes with sed/Python to resolve relative paths
- Generate manifests using Jinja templates with context-aware paths
- Layered manifest strategy:
Why Juniors Miss It
- Toolchain assumption: Misinterpreting repo manifests as regular XML files without understanding resolver limitations
- Context unawareness: Not realizing manifests operate in a URL-based namespace, not filesystem namespace
- Workaround reliance: Defaulting to submodules or absolute paths without seeking structural solutions
- Testing gaps: Failing to test manifest resolution across different repository layouts
- Documentation oversight: Ignoring repo tool’s include path constraints in official documentation