Hello World
Hello World
Section titled “Hello World”Welcome to your first Copybara tutorial! By the end of this guide, you’ll understand how Copybara works by syncing files between two local folders.
No GitHub account or remote servers needed - everything runs on your computer.
What You’ll Build
Section titled “What You’ll Build”You’ll create a workflow that:
- Reads files from a “source” folder
- Replaces placeholder text (like
MYCOMPANY→Acme Corp) - Writes the transformed files to a “destination” folder
This is the same pattern used for real-world tasks like publishing internal code to GitHub.
Before You Start
Section titled “Before You Start”Make sure you have:
- Java 11 or newer - Check with
java -version - Git - Check with
git --version - Copybara JAR file - See Installation
Project Setup
Section titled “Project Setup”We’ll create this folder structure:
Directorycopybara-tutorial/
Directorysource/ The folder we’ll read from (origin)
- README.md
Directorysrc/
- app.py
Directorydestination/ The folder we’ll write to (empty for now)
- …
- copy.bara.sky Your Copybara configuration
Create the folders
Section titled “Create the folders”Open your terminal and run:
mkdir -p ~/copybara-tutorial/source/srcmkdir -p ~/copybara-tutorial/destinationcd ~/copybara-tutorialCreate the source files
Section titled “Create the source files”Create source/README.md with this content:
# Welcome to MYPROJECT
This project is built by MYCOMPANY.
For help, contact support@internal.mycompany.comCreate source/src/app.py with this content:
# MYPROJECT - Main Application# Copyright MYCOMPANY
def main(): print("Hello from MYPROJECT!")
if __name__ == "__main__": main()Initialize Git repositories
Section titled “Initialize Git repositories”Copybara works with Git repositories, so we need to initialize both folders:
# Initialize the source repositorycd ~/copybara-tutorial/sourcegit initgit add .git commit -m "Initial commit"# Initialize the destination repositorycd ~/copybara-tutorial/destinationgit initgit commit --allow-empty -m "Initial commit"Write the Configuration
Section titled “Write the Configuration”Now for the main part - the Copybara configuration file.
Create copy.bara.sky in the copybara-tutorial folder:
sourceUrl = "file://" + "/Users/YOURNAME/copybara-tutorial/source"destinationUrl = "file://" + "/Users/YOURNAME/copybara-tutorial/destination"
core.workflow( name = "default",
origin = git.origin( url = sourceUrl, ref = "main", ),
destination = git.destination( url = destinationUrl, fetch = "main", push = "main", ),
authoring = authoring.overwrite("Tutorial <tutorial@example.com>"),
transformations = [ core.replace( before = "MYCOMPANY", after = "Acme Corp", ), core.replace( before = "MYPROJECT", after = "My Awesome App", ), core.replace( before = "internal.mycompany.com", after = "example.com", ), ],)Understanding the configuration
Section titled “Understanding the configuration”Let’s break down what each part does:
| Part | What it does |
|---|---|
origin | Where to read files from (our source folder) |
destination | Where to write files to (our destination folder) |
ref = "main" | Which Git branch to use |
authoring | Who to credit as the commit author |
transformations | Changes to make to the files |
The core.replace() transformation finds text and replaces it - like find-and-replace in a text editor, but for your entire project.
Run Copybara
Section titled “Run Copybara”Now let’s run it! From the copybara-tutorial folder:
cd ~/copybara-tutorial
java -jar copybara.jar migrate copy.bara.sky default --forceDon’t have copybara.jar in this folder? Use the full path:
java -jar ~/Downloads/copybara_deploy.jar migrate copy.bara.sky default --forceYou should see output ending with:
Migration finished successfully.Check the Results
Section titled “Check the Results”Let’s see what Copybara created:
cd ~/copybara-tutorial/destinationls -laYou should see README.md and src/app.py.
Now check the content:
cat README.mdOutput:
# Welcome to My Awesome App
This project is built by Acme Corp.
For help, contact support@example.comThe placeholders were replaced:
| Before | After |
|---|---|
MYPROJECT | My Awesome App |
MYCOMPANY | Acme Corp |
internal.mycompany.com | example.com |
Check the Python file too:
cat src/app.py# My Awesome App - Main Application# Copyright Acme Corp
def main(): print("Hello from My Awesome App!")
if __name__ == "__main__": main()What Happened?
Section titled “What Happened?”Copybara:
- Read all committed files from the source Git repository
- Applied transformations - replaced the placeholder text
- Wrote the transformed files to the destination
- Committed the changes in the destination repository
Make a Change and Sync Again
Section titled “Make a Change and Sync Again”Let’s see incremental sync in action. Edit the source file:
cd ~/copybara-tutorial/sourceAdd a new file source/src/utils.py:
# MYPROJECT utilities# Author: MYCOMPANY Team
def helper(): return "I help MYPROJECT run smoothly!"Commit the change:
git add src/utils.pygit commit -m "Add utilities"Run Copybara again (no --force needed now):
cd ~/copybara-tutorialjava -jar copybara.jar migrate copy.bara.sky defaultCheck the destination:
cat ~/copybara-tutorial/destination/src/utils.pyThe new file appears with all replacements applied - only the new changes were synced.
Troubleshooting
Section titled “Troubleshooting””Cannot find reference ‘main’”
Section titled “”Cannot find reference ‘main’””Your Git might use master as the default branch. Either:
Option A: Change the config to use master:
ref = "master",fetch = "master",push = "master",Option B: Rename your branch to main:
cd ~/copybara-tutorial/sourcegit branch -m master maincd ~/copybara-tutorial/destinationgit branch -m master main“Nothing to migrate”
Section titled ““Nothing to migrate””This means source and destination are already in sync. Make a change in the source, commit it, then run Copybara again.
”Cannot find workflow ‘default’”
Section titled “”Cannot find workflow ‘default’””Make sure your workflow in copy.bara.sky has name = "default", or use the name you chose:
java -jar copybara.jar migrate copy.bara.sky YOUR_WORKFLOW_NAME --forceJava errors about paths
Section titled “Java errors about paths”Double-check that:
- The paths in your config use
file://prefix - The paths are absolute (start with
/) - You replaced
YOURNAMEwith your actual username - Both Git repos have at least one commit
What’s Next?
Section titled “What’s Next?”Now that you understand the basics:
- Open Source a Project - A real-world example with GitHub
- CLI Reference - All available commands and flags
- Transformations - All the ways to modify files
- Core Concepts - Deeper understanding of Copybara