Skip to content

Workflow Modes

The mode parameter controls how Copybara creates commits in the destination repository.

ModeCommitsDestinationReviewBest For
SQUASHAll → 1Direct pushNoSimple sync
ITERATIVE1 → 1Direct pushNoHistory preservation
CHANGE_REQUESTAll → 1 PRPR/CLYesExternal review
CHANGE_REQUEST_FROM_SOTAll → 1 PRPR/CLYesBidirectional

The default and most commonly used mode. All origin changes are combined into a single destination commit.

core.workflow(
name = "export",
mode = "SQUASH",
...
)
Diagram

SQUASH mode creates a commit message with metadata:

Sync from origin
- Change A description
- Change B description
- Change C description
GitOrigin-RevId: abc123def456
  • Most sync workflows
  • When origin history isn’t important
  • When you want clean destination history
  • When dealing with complex merge histories

Preserves individual commits from the origin. Each origin commit becomes a destination commit.

core.workflow(
name = "export",
mode = "ITERATIVE",
...
)
Diagram
  • When commit history must be preserved
  • When individual changes need to be traceable
  • For auditing or compliance requirements
  • Merge commits can cause issues
  • More complex to troubleshoot
  • Larger initial sync time

Creates a pull request (GitHub) or change list (Gerrit) instead of pushing directly.

core.workflow(
name = "export",
mode = "CHANGE_REQUEST",
destination = git.github_pr_destination(
url = "https://github.com/org/repo",
destination_ref = "main",
pr_branch = "copybara/sync-${CONTEXT_REFERENCE}",
title = "Sync from internal",
),
...
)
Diagram
  • When changes need review before merging
  • When you don’t have direct push access
  • For audited change processes
  • When human approval is required
git.github_pr_destination(
url = "https://github.com/org/repo",
destination_ref = "main",
pr_branch = "copybara/sync-${CONTEXT_REFERENCE}",
title = "Sync: ${CONTEXT_REFERENCE}",
body = "Automated sync from internal repository",
# Optional settings
update_description = True, # Update PR description on re-run
primary_branch_migration = True, # Use default branch if main doesn't exist
)

Similar to CHANGE_REQUEST, but designed for importing changes back to the source of truth.

core.workflow(
name = "import",
mode = "CHANGE_REQUEST_FROM_SOT",
origin = git.github_pr_origin(
url = "https://github.com/org/public-repo",
branch = "main",
),
destination = git.gerrit_destination(
url = "https://gerrit.internal/repo",
push_to_refs_for = "main",
),
...
)

Imports external PRs as internal CLs for review:

Diagram
  • Importing external contributions to internal systems
  • When external changes need internal review
  • Gerrit-based internal development

Use SQUASH:

mode = "SQUASH",
destination = git.destination(url = ..., push = "main"),

Best for: Regular sync where destination history doesn’t need to match origin.