State Management
Copybara tracks synchronization state to know which commits have been synced. Understanding this mechanism helps diagnose issues and recover from problems.
How State Tracking Works
Section titled “How State Tracking Works”GitOrigin-RevId Marker
Section titled “GitOrigin-RevId Marker”Copybara embeds a marker in each synced commit message:
Sync latest changes from upstream
GitOrigin-RevId: abc123def456789This marker identifies the source commit that was synced. On subsequent runs, Copybara:
- Reads the most recent commit in the destination
- Extracts the
GitOrigin-RevIdvalue - Syncs only commits newer than that revision
Finding Current State
Section titled “Finding Current State”Check what revision was last synced:
# In the destination repositorygit log --grep="GitOrigin-RevId" -1
# Extract just the revisiongit log --grep="GitOrigin-RevId" -1 --format="%B" | grep "GitOrigin-RevId" | cut -d: -f2 | tr -d ' 'State Mismatch Problems
Section titled “State Mismatch Problems”Symptoms
Section titled “Symptoms”- “No changes to migrate” when changes exist
- Duplicate commits in destination
- Missing commits
- Sync fails with revision errors
Common Causes
Section titled “Common Causes”- Manual commits in destination without marker
- Force pushes that rewrote history
- Multiple workflows syncing to same destination
- Destination branch reset or deleted
Recovery Procedures
Section titled “Recovery Procedures”Reset to Specific Revision
Section titled “Reset to Specific Revision”Force Copybara to start from a known-good commit:
# Start from a specific source commitcopybara migrate copy.bara.sky --last-rev abc123def
# Start from N commits backcopybara migrate copy.bara.sky --last-rev HEAD~10Force Full Re-sync
Section titled “Force Full Re-sync”When state is completely corrupted, re-sync everything:
# Delete destination branch and start freshgit push origin --delete target-branch
# Run sync from beginning (or specific point)copybara migrate copy.bara.sky --last-rev <first-commit-to-sync>Fix Missing Marker
Section titled “Fix Missing Marker”If commits were made without markers, add one manually:
# In destination repogit commit --allow-empty -m "State recovery
GitOrigin-RevId: <last-synced-source-sha>"Multi-Workflow Coordination
Section titled “Multi-Workflow Coordination”Problem: Conflicting Workflows
Section titled “Problem: Conflicting Workflows”Multiple workflows syncing to the same destination can corrupt state:
Workflow A syncs commit 123 → destinationWorkflow B syncs commit 124 → destinationWorkflow A looks for 123, finds 124, gets confusedSolution: Separate State Tracking
Section titled “Solution: Separate State Tracking”Use different branches or labels per workflow:
# Workflow A - uses custom labelcore.workflow( name = "sync-a", destination = git.destination( url = "...", push = "sync-a-branch", ), # ...)
# Workflow B - separate branchcore.workflow( name = "sync-b", destination = git.destination( url = "...", push = "sync-b-branch", ), # ...)Solution: Custom Label Name
Section titled “Solution: Custom Label Name”Use a unique label per workflow:
core.workflow( name = "my-workflow", transformations = [ metadata.add_header("MyWorkflow-RevId: ${COPYBARA_REVISION}"), ], # ...)Inspecting State
Section titled “Inspecting State”View Sync History
Section titled “View Sync History”# List all synced revisionsgit log --grep="GitOrigin-RevId" --format="%h %s" | head -20
# Show full marker for each syncgit log --grep="GitOrigin-RevId" --format="%B" | grep -A1 "GitOrigin-RevId"Verify Source-Destination Mapping
Section titled “Verify Source-Destination Mapping”# For each destination commit, find source commitfor sha in $(git log --grep="GitOrigin-RevId" --format="%h" | head -5); do source_rev=$(git log -1 --format="%B" $sha | grep "GitOrigin-RevId" | cut -d: -f2) echo "$sha <- $source_rev"doneCompare Repositories
Section titled “Compare Repositories”Check if repos are in sync:
# Get last synced revision from destinationLAST_SYNCED=$(git log --grep="GitOrigin-RevId" -1 --format="%B" | grep "GitOrigin-RevId" | cut -d: -f2 | tr -d ' ')
# Check commits since then in sourcecd /path/to/sourcegit log $LAST_SYNCED..HEAD --onelineBackup Strategies
Section titled “Backup Strategies”Before Major Changes
Section titled “Before Major Changes”# Tag current state before risky operationsgit tag backup-before-rebase-$(date +%Y%m%d)
# Push tag to remotegit push origin backup-before-rebase-$(date +%Y%m%d)Automated State Snapshots
Section titled “Automated State Snapshots”#!/bin/bash# Run before each syncDEST_BRANCH="main"BACKUP_TAG="copybara-state-$(date +%Y%m%d-%H%M)"
git fetch origin $DEST_BRANCHgit tag $BACKUP_TAG origin/$DEST_BRANCHgit push origin $BACKUP_TAGDry Run Validation
Section titled “Dry Run Validation”Test before actual sync:
# Preview what would be syncedcopybara migrate copy.bara.sky --dry-run
# Validate configuration onlycopybara validate copy.bara.skyTroubleshooting Checklist
Section titled “Troubleshooting Checklist”When state issues occur:
-
Check current state
Terminal window git log --grep="GitOrigin-RevId" -1 -
Verify source commit exists
Terminal window cd /source && git cat-file -t <revid> -
Check for manual commits
Terminal window git log --format="%h %s" | grep -v "GitOrigin-RevId" | head -5 -
Verify workflow name
Terminal window copybara validate copy.bara.sky -
Try with explicit revision
Terminal window copybara migrate copy.bara.sky --last-rev <known-good>
Next Steps
Section titled “Next Steps”- Common issues - Error resolution
- Debugging - Detailed diagnostics
- CLI reference - Command options