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-vanillaacross all AOSP projects
- Point platform/manifest’sdefault.xmlto:- 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-vanillabranch cloned fromandroid-15.0.0_r30
- Your manifestrepo 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
