This guide shows how to mirror Android 15 (AOSP android-15.0.0_r30
) to your own Gerrit server, preserving full commit history and tags, while keeping the original clone-depth
settings in the manifest — so that downstream users can sync with the same behavior as Google’s AOSP repo.
Prerequisites
Install essential tools:
sudo add-apt-repository ppa:git-core/ppa
sudo apt update
sudo apt install git
mkdir -p ~/bin
curl -o ~/bin/repo https://storage.googleapis.com/git-repo-downloads/repo
chmod +x ~/bin/repo
export PATH=~/bin:$PATH
Add to your shell profile (~/.bashrc
, ~/.zshrc
, etc.):
export PATH=~/bin:$PATH
Ensure your .gitconfig
includes the following:
[user]
email = your email
name = your name
[color]
ui = auto
[url "ssh://maksonlee@gerrit.maksonlee.com:29418/"]
insteadof = "git://gerrit.maksonlee.com/"
pushinsteadof = "git://gerrit.maksonlee.com/"
- Initialize the AOSP Manifest
mkdir ~/aosp-15 && cd ~/aosp-15
repo init -u https://android.googlesource.com/platform/manifest -b android-15.0.0_r30
This initializes the official manifest, which includes Google’s clone-depth
settings.
- Remove
clone-depth
from Manifest
sed -i 's/ clone-depth="[0-9]\+"//g' .repo/manifests/default.xml
This ensures repo sync
clones full Git history for all projects, even if the manifest tries to enforce shallow clones.
- Sync Repositories
repo sync -c -j8
This synchronizes the repositories with the specified manifest.
- Gerrit Server Configuration
- Permissions
In All-Projects → Access, add following permissions for administrator:
refs/tags/*
Forge Committer Identity
Forge Server Identity
Forge Author Identity
refs/heads/*
Push
Forge Committer Identity
- Prevent Timeout
In your Gerrit configuration file (gerrit.config
), set the receive timeout:
[receive]
timeout = 30 min
- Performance Tuning
Adjust the following settings to optimize performance:
[core]
packedGitWindowSize = 32m # default is only 8k
packedGitLimit = 512m # raise from default 10m
deltaBaseCacheLimit = 512m # raise from default 10m
streamFileThreshold = 20m # to avoid temp file usage for large blobs
packedGitUseStrongRefs = true # more stable memory behavior
packedGitOpenFiles = 256 # if you have many packfiles (raise ulimit if needed)
[receive]
checkReferencedObjectsAreReachable = false
- Create Projects in Gerrit
Save the following script as create-projects.sh
and run it:
#!/bin/bash -e
echo "=== Fetching list of existing projects from Gerrit ==="
ssh -p 29418 maksonlee@gerrit.maksonlee.com gerrit ls-projects > existing_projects.txt
REPO_ROOT_DIR=$(pwd)
echo "=== Checking and creating missing projects ==="
repo forall -p -v -e -c '
if grep -q "^$REPO_PROJECT$" "'"$REPO_ROOT_DIR"'/existing_projects.txt"; then
echo ">>> Project $REPO_PROJECT already exists."
else
echo ">>> Project $REPO_PROJECT does not exist. Creating it now..."
ssh -p 29418 maksonlee@gerrit.maksonlee.com gerrit create-project "$REPO_PROJECT" --empty-commit
echo ">>> Project $REPO_PROJECT creation command finished."
fi
'
echo "=== Project creation phase completed. ==="
Then run:
bash create-projects.sh
- Push All Projects to Your Gerrit Server
Push all repositories:
repo forall -p -v -e -c 'git push -o skip-validation --no-tags git://gerrit.maksonlee.com/$REPO_PROJECT HEAD:refs/heads/android-15.0.0_r30'
- Push Tags
repo forall -p -v -c 'git tag --merged android-15.0.0_r30 | awk '\''{print "refs/tags/"$0":refs/tags/"$0}'\'' | xargs -r -n100 git push --porcelain git://gerrit.maksonlee.com/$REPO_PROJECT'
- Push Manifests
cd .repo/manifests
git checkout default.xml
ssh -p 29418 maksonlee@gerrit.maksonlee.com gerrit create-project platform/manifest --empty-commit
git push -o skip-validation --no-tags git://gerrit.maksonlee.com/platform/manifest HEAD:refs/heads/android-15.0.0_r30
git tag --merged android-15.0.0_r30 | awk '{print "refs/tags/"$0":refs/tags/"$0}' | xargs -r -n100 git push --porcelain git://gerrit.maksonlee.com/platform/manifest
Why run git checkout default.xml
here?
Earlier we edited our working copy’s .repo/manifests/default.xml
with sed
to remove clone-depth
for a full-history local sync.
git checkout default.xml
(or git restore --source=HEAD default.xml
) restores the original upstream file (with clone-depth
) before we push the manifest to Gerrit. This ensures downstream users keep Google’s shallow-clone behavior.
- Run Gerrit Garbage Collection (gc)
After all repositories have been successfully pushed to the Gerrit server, it’s highly recommended to run a Gerrit garbage collection. This step helps optimize Git repository storage and significantly improves performance for downstream developers syncing the repo
.
Run the following command on the Gerrit server:
ssh -p 29418 admin@localhost gerrit gc --all
This will:
- Pack loose objects
- Repack repository history
- Reduce disk usage
- Speed up
repo sync
operations for clients
Done!
You now have:
- A complete mirror of Android 15 AOSP with all history and tags
- A self-hosted
repo
source via Gerrit - Support for shallow clones on downstream clients — just like Google