Practical Repo Workflow for Android: Installation, Manifests, and Daily Operations
Android source is maintained with Git, reviewed with Gerrit, and orchestrated with Repo—a Python-based wrapper that coordinates hundreds of Git repositories through a central manifest.
Install the Repo CLI
mkdir -p ~/bin
PATH=~/bin:$PATH
curl -o ~/bin/repo https://storage.googleapis.com/git-repo-downloads/repo
chmod a+x ~/bin/repo
Manifest fundamentals
A manifest repository (manifests.git) tracks which Git projects to sync, where to put them, and which revisions to use. Manifests are XML; a repo init points at a manifest repo and an optional branch/tag:
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-11.0.0_r27
Example manifest:
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote name="aosp"
fetch=".."
review="https://android-review.googlesource.com/" />
<default remote="aosp"
revision="refs/tags/android-11.0.0_r27"
sync-j="4" />
<project name="platform/build" path="build/make" groups="pdk">
<copyfile src="core/root.mk" dest="Makefile" />
<linkfile src="CleanSpec.mk" dest="build/CleanSpec.mk" />
<linkfile src="buildspec.mk.default" dest="build/buildspec.mk.default" />
<linkfile src="core" dest="build/core" />
<linkfile src="envsetup.sh" dest="build/envsetup.sh" />
<linkfile src="target" dest="build/target" />
<linkfile src="tools" dest="build/tools" />
</project>
<project name="platform/build/blueprint" path="build/blueprint" groups="pdk,tradefed" />
<!-- ... -->
</manifest>
- remote defines a logical remote (aosp) with a fetch base and a Gerrit review URL.
- default provides fallbacks for projects: which remote to use, the revision/branch/tag, and parallelism for sync.
- project declares a Git project to be checked out at path with upstream name.
- copyfile/linkfile perform post-checkout file operations inside a project.
Frequently used repo commands
repo init — bootstrap and select a manifest
repo init -u URL [OPTIONS]
Common flags:
- -u: manifest repo URL
- -m: which XML file inside the manifest repo (defaults to default.xml)
- -b: branch/tag in the manifest repo
What init does:
- Ensures the repo launcher is present in .repo/
- Clones the manifest repo into .repo/manifests
- Writes .repo/manifest.xml (now a real file that may include other XMLs)
Examples:
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-11.0.0_r27
repo init -u git://172.16.1.31/manifest.git -m android.xml # use a specific manifest XML
repo sync — fetch and update projects
repo sync [<project>...]
- For new projects: behaves like git clone
- For existing porjects: roughly equivalent to:
git remote update
git rebase origin/<tracked-branch>
Examples:
repo sync # sync everything
repo sync platform/build # sync a subset
repo start — create topic branches from manifest revision
repo start <topic> [--all | <project>...]
Creates a new local branch based on the manifest’s revision, not the current HEAD (unlike git checkout -b).
repo start stable --all
repo start stable platform/build platform/bionic
repo checkout — switch branches
repo checkout <branch> [<project>...]
Wrapper for git checkout (no -b support):
repo checkout crane-dev
repo checkout crane-dev platform/build platform/bionic
repo branches — list local branches
repo branches [<project>...]
repo branches
repo branches platform/build platform/bionic
repo diff — show uncommitted changes
repo diff [<project>...]
Displays git diff for one or more projects:
repo diff
repo diff platform/build platform/bionic
repo stage — interactively add changes
Interactive wrapper around git add --interactive:
repo stage -i [<project>...]
repo prune — delete merged topic branches
Equivalent to scanning and running git branch -d for merged branches:
repo prune [<project>...]
repo abandon — drop a topic branch
Force-delete a local branch across projects:
repo abandon <branch> [<project>...]
repo status — porcelain-style status by project
repo status [<project>...]
Shows per-project status. Each line prints two status columns followed by a path, similar to git’s porcelain format:
- First column (index): -, A, M, D, R, C, T, U
- Second column (work tree): -, m, d
Meaning highlights:
- A: added to index
- M/m: modified (index/work tree)
- D/d: deleted (index/work tree)
- R/C: rename/copy detected in index
- T: type/permission change in index
- U: unresolved merge
repo status platform/bionic
repo remote — manage extra remotes for projects
repo remote add <name> <url> [<project>...]
repo remote rm <name> [<project>...]
repo remote add org ssh://172.16.1.31/git_repo
repo remote rm org
repo push — push branches to a remote
repo push <remote> [--all | <project>...]
Queries projects with outgoing changes and pushes them:
repo push org
repo forall — run a shell command across projects
repo forall [<project>...] -c <command>
Useful flags:
- -c: shell command to run
- -p: prefix output with project path
- -v: show command errors
Injected environment variables:
- REPO_PROJECT: project name
- REPO_PATH: checkout path realtive to workspace root
- REPO_REMOTE: default remote name
- REPO_LREV: last known SHA1 in the remote
- REPO_RREV: manifest-specified revision
Quote the command with single quotes if referencing these variables.
Examples:
repo forall -c 'echo $REPO_PROJECT'
repo forall -c 'echo $REPO_PATH'
Merge a topic into master across all projects:
repo forall -p -c 'git checkout master && git merge --no-ff topic'
Tag all projects:
repo forall -c 'git tag crane-stable-1.6'
Add/remove a remote using REPO_PROJECT:
repo forall -c 'git remote add korg ssh://xiong@172.16.31/$REPO_PROJECT.git'
repo forall -c 'git remote remove korg'
Create and switch to a topic branch across projects:
repo forall -c 'git branch crane-dev'
repo forall -c 'git checkout -b crane-dev'
repo grep — search across files
Wrapper around git grep for projects under Repo control.
repo manifest — export the current manifest
repo manifest -o android.xml
repo version — print repo version
Displays the repo tool version in use.
repo upload — send changes to Gerrit for review
Similar to pushing, but targets Gerrit’s refs for code review over SSH. Each push becomes a change set in Gerrit; once reviewed and approved, Gerrit merges to the authoritative repo.
repo upload [--re --cc] {[<project>]... | --replace <project>}
Common flags:
- -h, --help: help output
- -t: include local branch name in the review
- --replace: upload as a new patch set for an existing change
- --re=REVIEWERS: request reviewers
- --cc=CC: notify additional addresses
repo download — fetch a change under review
Used by reviewers to pull a change from Gerrit:
repo download {project change [patchset]}...
repo selfupdate — update the repo launcher
Refreshes the repo tool to the latest available version.