How to Resolve Relative Import Failures in Google Repo Manifests

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 name attributes 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 repo manifest 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

  1. Manifest repository pattern:
    • Create a dedicated manifest repository with flat structure
    • Use absolute URLs for all includes:
  2. Path injection via environment variables:
    • Pass the base manifest URL during repo init
    • Dynamically generate manifests with scripts
  3. Custom manifest processing:
    • Pre-process includes with sed/Python to resolve relative paths
    • Generate manifests using Jinja templates with context-aware paths
  4. 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

Leave a Comment