Understanding branching in Infrahub
Infrahub’s branching model allows teams to work on features, fixes, or experiments in isolated environments. Each branch represents a separate line of development, enabling parallel work streams without interference. Unlike traditional version control systems that branch files, Infrahub branches graph data representing your infrastructure, providing flexibility when working with complex, interconnected components.Why branching matters for infrastructure
Infrastructure changes are risky. Deploying untested configurations to production can cause outages. Making large-scale architecture changes requires coordination across teams. Testing new ideas in production isn’t feasible. Branching solves these challenges by providing isolated workspaces:- Risk isolation: Test changes without affecting production systems
- Parallel workflows: Multiple teams work simultaneously without conflicts
- Change validation: Review and test before merging to production
- Experimentation: Try new approaches in a safe environment
- Atomic changes: Group related modifications into coherent units
Core concepts
Branches as isolated realities
Each branch provides a complete, isolated environment where changes can be made without affecting other branches. When you create a branch, you establish a separate reality where your infrastructure exists in a specific state. Changes you make in that branch are invisible to other branches until explicitly merged. This isolation extends to all aspects of Infrahub:- Data changes (devices, interfaces, IP addresses)
- Schema modifications (adding attributes, changing relationships)
- Generated artifacts (configuration files, documentation)
- Validation results (checks, tests, constraints)
Branch hierarchy
Infrahub implements a hierarchical branch model:- Branches are created from a parent branch (currently always
main) - Changes flow back to the parent through controlled merge operations
- Each branch tracks its creation point (
branched_from) for accurate diffing
The default branch
The default branch (typically namedmain) serves as the authoritative source of truth for your infrastructure. It has unique characteristics that distinguish it from other branches:
Integrity guarantees: The default branch enforces comprehensive validation to ensure production data quality:
- Schema validation: All data must conform to current schema definitions
- Relationship integrity: All references between objects must be valid
- Uniqueness constraints: Duplicate values in unique fields are prevented
- Required fields: All mandatory attributes must have values
- Sequential writes: Certain operations serialize to prevent conflicts
- Validation overhead: Every change undergoes comprehensive validation
- Lock contention: Concurrent modifications may experience delays
Branch isolation modes
When creating a branch, you choose how it interacts with external Git repositories: Full branches (sync_with_git: true): Extend to Git repositories, allowing infrastructure-as-code changes. These branches are synchronized with corresponding Git branches, enabling coordinated changes across both Infrahub data and infrastructure code.
Data-only branches (sync_with_git: false): Isolate changes to Infrahub data without affecting Git repositories. These branches are ideal for data updates, corrections, or enhancements that don’t require changes to infrastructure code.
This flexibility allows different workflows—from quick data fixes to comprehensive infrastructure changes involving both data and code.
Branch-aware vs. branch-agnostic
Unlike Git where all content is branch-specific, Infrahub introduces a nuanced approach where some schema elements can bypass the branching system and be global to all branches: Branch-aware: Records that are local to branches and follow the standard branching workflow. Changes to branch-aware records in one branch do not affect other branches until explicitly merged. Most user-created infrastructure data falls into this category. Branch-agnostic: Records that exist globally regardless of branch. These typically include system data, global configurations, and reference information that should remain consistent across all branches. Changes to these records are immediately visible in all branches. Branch-local: Records that exist only within a specific branch and are not meant to be merged to other branches. These include temporary data, experimental configurations, or branch-specific metadata that supports the workflow but isn’t part of the final solution. You can define the branch behavior for each node or attribute in the schema:Architecture and implementation
Copy-on-write semantics
Branches don’t duplicate the entire database. Instead, they maintain:- A pointer to their base (
branched_fromtimestamp) - Only the delta of changes made within the branch
- References to unchanged data in the parent branch
- Looks for changes made in the branch after the
branched_fromtimestamp - Falls back to the parent branch for unchanged data
- Traverses this relationship recursively up the branch hierarchy
Branch operations
Infrahub provides a comprehensive set of operations to manage the branch lifecycle: Branch creation: Start a new branch from an existing one, typically themain branch. This creates a snapshot of the current state that can be modified independently:
Merge semantics
Infrahub implements a “latest-value wins” merge strategy. During a merge, only the most recent value for each changed attribute transfers to the destination branch. The complete change history within the branch doesn’t carry over—instead, the final state becomes a single change at the merge point. This approach provides several benefits:- Maintains immutability of the main branch by creating a clean, atomic change
- Simplifies conflict resolution by focusing only on the final state rather than intermediate changes
- Provides clear merge points in history that are straightforward to trace and understand
- Reduces storage overhead by not duplicating the entire change history of the branch
Rebase operations
Rebasing is a powerful operation that updates a branch with the latest changes from its parent branch:- The branch’s base point (
branched_from) updates to the current time - Changes in the branch are analyzed and replayed on top of the new base
- Conflicts that arise during this process require manual resolution
- The branch history resets, preserving only the final state
- Resolving conflicts before merge: Identify and address conflicts in the development branch before creating a Proposed Change
- Incorporating upstream changes: Ensure your branch includes the latest updates from the main branch
- Maintaining a clean merge history: Produce a cleaner, more linear history
Conflict detection and resolution
Conflicts occur when the same data changes in both a feature branch and the main branch. Infrahub’s conflict management system automatically detects several types of conflicts: Attribute conflicts: The same field of an object has been modified in both branches with different values. For example, the hostname of a device is changed to “router-1” in one branch and “router-primary” in another. Relationship conflicts: Conflicting changes to object relationships occur when the connections between objects are modified differently in separate branches. For instance, a device might be assigned to datacenter A in one branch and datacenter B in another. Schema conflicts: Incompatible schema modifications between branches can cause structural conflicts. This might happen when a field is removed in one branch but modified in another. Uniqueness conflicts: Changes that would violate uniqueness constraints upon merge are flagged to prevent data integrity issues. This occurs when both branches create different objects with the same unique identifier. The Proposed Change feature provides comprehensive tools for managing these conflicts with intuitive side-by-side diffs that clearly highlight differences between branches.Use cases and workflows
Large scale changes
Create a branch for a large feature or refactor, allowing for extensive changes without impacting the production pipeline. This is particularly valuable when:- Redesigning network architectures (moving from spine-leaf to fat-tree topology)
- Migrating to a new vendor (replacing all Cisco devices with Arista)
- Implementing new standards (transitioning from IPv4 to IPv6)
- Create branch
feature-ipv6-migration - Add IPv6 attributes to device and interface schemas
- Populate IPv6 addresses across all interfaces
- Update routing protocol configurations
- Generate updated device configurations in the branch
- Test in staging environment
- Create Proposed Change to review and merge
Collaborative review
Create a branch for a feature, allowing team members to review and discuss changes before merging:- Junior engineer creates
fix-vlan-assignmentsbranch - Makes necessary changes to VLAN configurations
- Creates Proposed Change for review
- Senior engineer reviews changes, leaves comments
- Junior engineer addresses feedback in the branch
- Changes are validated by automated checks
- Senior engineer approves and merges
Experimentation
Use branches to test new ideas or approaches without affecting the production environment: A/B testing: Create two branches with different BGP configurations, deploy to test routers, measure performance, and merge the winner. Schema evolution: Test a new schema structure in a branch to ensure it meets requirements before committing to it in production. Vendor evaluation: Model configurations for different vendors in separate branches to compare approaches.Transaction support
Group related changes into a single branch, ensuring atomic updates and easier rollbacks: Service deployment: When deploying a new service, create a branch that includes:- New device records
- Interface configurations
- IP address allocations
- Routing protocol changes
- Firewall rules
Best practices
Use descriptive branch names
Name branches in a way that clearly identifies their purpose:feature-network-redesign- Adding new capabilityfix-datacenter-connectivity- Fixing a problemexperiment-bgp-tuning- Testing an idearefactor-location-schema- Improving structure
Keep branches short-lived
Complete work and merge branches promptly to minimize drift from the main branch and reduce conflict potential. Long-lived branches accumulate changes that make merging more complex. Target: Feature branches live days to weeks, not months.Rebase before creating a Proposed Change
Update your branch with the latest changes from the default branch to identify and resolve conflicts early. This makes the review process smoother and reduces merge complexity.Use data-only branches for quick fixes
When changes don’t require infrastructure code updates, data-only branches provide a streamlined workflow:- Fixing incorrect IP addresses
- Updating device serial numbers
- Correcting location assignments
- Adding missing interfaces
Leverage branch permissions
Restrict who can create branches and merge to the default branch to maintain quality control in production environments. Use Infrahub’s permission system to:- Allow all engineers to create feature branches
- Require senior engineers to approve merges to main
- Restrict schema changes to architecture team
Document branch purpose
Add clear descriptions to branches to help team members understand their purpose and scope:Branch lifecycle
Understanding the branch lifecycle helps teams manage the flow of changes through Infrahub:- Branch creation: Establishes an isolated workspace at a specific point in time, capturing the state of the parent branch as a starting point
- Development: Changes accumulate in the branch without affecting the main branch, allowing for focused work and experimentation
- Validation: Proposed Changes run automated checks and tests to verify the integrity and functionality of modifications
- Conflict resolution: Any conflicts with the main branch are identified and resolved, ensuring smooth integration
- Merge: Approved changes integrate into the main branch through a controlled process that preserves production integrity
- Cleanup: The branch can be deleted after successful merge, maintaining a clean workspace
Design trade-offs
Single-level hierarchy
Infrahub currently supports only one level of branch hierarchy (branches from main). This limitation simplifies conflict resolution and ensures clear change lineage but prevents some workflows:- Can’t create a branch from a feature branch
- Can’t have long-lived development branches with sub-features
- Can’t isolate experimental work within a feature branch
Merge vs. rebase philosophy
Infrahub’s “latest-value wins” merge strategy differs from Git’s approach. Git preserves commit history during merge; Infrahub captures only the final state. This trade-off optimizes for:- Simpler conflict resolution (only final state matters)
- Cleaner main branch history (atomic merge commits)
- Reduced storage overhead (no duplicate history)
Performance characteristics
Feature branches optimize for development speed by relaxing some validation constraints. The default branch optimizes for data integrity by enforcing comprehensive validation. This creates different performance profiles:- Feature branches: Faster writes, some validation deferred
- Default branch: Slower writes, complete validation
Related topics
- Version Control - Immutable history and time travel queries
- Proposed Changes - Change review and validation workflow
- Schema System - How schemas branch and merge
- Graph Database - Implementation details of branch storage