In my previous post, I explained how to mirror AOSP Android 15 into gerrit.maksonlee.com with complete commit history and tags. Once all projects are imported, the next step in Android platform bring-up is to create a product-specific branch, for example, prj-0001-15-vanilla,
across every repository.
Creating branches manually for hundreds of modules is tedious. In this post, I’ll show how to do it programmatically using the Gerrit REST API and Python, then update default.xml
in platform/manifest
to point to your Gerrit server and branch.
Authentication: OAuth for UI, HTTP Password for API
My Gerrit is configured with auth.type = OAUTH
, so I log in via Keycloak.
However, OAuth login credentials do not work for the REST API.
Instead, you must generate an HTTP password from Gerrit:
Go to Settings → HTTP Credentials, generate a password, and use it along with your username in API calls.
Goal
- Create a new branch
prj-0001-15-vanilla
across all AOSP projects - Point
platform/manifest
’sdefault.xml
to:refs/heads/prj-0001-15-vanilla
https://gerrit.maksonlee.com/
as the review server
Python Script: Create Branches in Bulk
import requests
import json
# --- Configuration ---
GERRIT_URL = "https://gerrit.maksonlee.com"
USERNAME = "maksonlee"
PASSWORD = "your_http_password" # From Settings → HTTP Credentials
SOURCE_BRANCH = "android-15.0.0_r30"
NEW_BRANCH = "prj-0001-15-vanilla"
auth = (USERNAME, PASSWORD)
# --- Get all projects (handle Gerrit's anti-CSRF prefix) ---
resp = requests.get(f"{GERRIT_URL}/a/projects/?d", auth=auth)
if not resp.ok:
raise RuntimeError(f"Failed to list projects: {resp.status_code} {resp.text}")
clean_text = resp.text.lstrip(")]}'\n")
projects = json.loads(clean_text).keys()
for project in projects:
print(f" Processing {project}")
project_encoded = project.replace("/", "%2F")
# --- Check if source branch exists ---
check_url = f"{GERRIT_URL}/a/projects/{project_encoded}/branches/{SOURCE_BRANCH}"
check_resp = requests.get(check_url, auth=auth)
if check_resp.status_code != 200:
print(f" Source branch {SOURCE_BRANCH} not found, skipping.")
continue
# --- Create new branch ---
new_branch_url = f"{GERRIT_URL}/a/projects/{project_encoded}/branches/{NEW_BRANCH}"
payload = {"revision": f"refs/heads/{SOURCE_BRANCH}"}
resp = requests.put(new_branch_url, auth=auth, json=payload)
if resp.status_code == 201:
print(f" Created {NEW_BRANCH}")
elif resp.status_code == 409:
print(f" Branch already exists")
else:
print(f" Failed (HTTP {resp.status_code}): {resp.text}")
Update platform/manifest
with the New Branch
After creating the branches, update your platform/manifest
repository’s default.xml
:
From:
<remote name="aosp"
fetch=".."
review="https://android-review.googlesource.com/" />
<default revision="refs/tags/android-15.0.0_r30"
remote="aosp"
sync-j="4" />
To:
<remote name="aosp"
fetch=".."
review="https://gerrit.maksonlee.com/" />
<default revision="refs/heads/prj-0001-15-vanilla"
remote="aosp"
sync-j="4" />
Final Result
- All projects now have a
prj-0001-15-vanilla
branch cloned fromandroid-15.0.0_r30
- Your
manifest
repo points to the new branch and your local Gerrit - Developers can now sync using:
repo init -u https://gerrit.maksonlee.com/platform/manifest -b prj-0001-15-vanilla
repo sync