Skip to main content

Master of android repo mirrors

Sometimes you want to mirror an entire android platform repo, locally, so that you can init & sync to a working directory without being connected to the internet. Handy if your internet connection sucks, or you travel a lot. I'm sure you can use your imagination. Updating means you just have to keep track of a list of mirrors and make sure they are synced in order (for reference chaining).

For AOSP, this task is pretty simple, and the first repository you'll probably mirror:

    mkdir aosp-mirror
    pushd $_
    repo init -u --mirror
    repo sync -j[dl-jobs]

NOTES: $_ in bash is the first argument to the previous command, also dl-jobs is the number of download jobs. popd is the directory we started in. If say, I were on my Mac10.8 and made a case-sensitive sparse disk, and: mkdir /Volumes/Android/mirrors && cd /Volumes/Android/mirrors/ then popd will just return the current directory, as current working directory is the only item on the stack. We pushd to aosp-mirror, init and sync.

Go outside and do something. This will probably take a while.

For CyanogenMod, it's a little bit more difficult. There is no mirror/manifest for CyanogenMod, so we have to do that part ourselves:

    mkdir cyanogenmod-mirror
    pushd $_
    git ls-remote -h git:// > CM-$(date +%Y%m%d%H%M%S).xml
    for branch in $(awk 'BEGIN { FS = "/" } ; { print $3 }' $(ls -t1 CM-*.xml | head -n1)); do \
        repo init -u git:// -b ${branch} --mirror --reference /Volumes/Android/aosp-mirror; \
        mv .repo .repo-${branch}; \
        ln -sf .repo-${branch} .repo; \
        repo sync -j4; \
        rm .repo; \

Notice a pattern? {pre,post}-{init,sync}? Yes! pre-init we get a list of branches, post-init we move .repo to be specific for the current branch, and post-sync we remove the symbolic link to the current branch's .repo. The rest is the same, except this repo mirror references the aosp-mirror.

That's pretty much it for now. You can now go up a directory from your aosp-mirror and cyanogenmod-mirror directories (probably in /Volumes/Android/ if you followed my directions) and sync a local working directory:

    cd /Volumes/Android/mirrors/cyanogenmod-mirror/
    ln -sf .repo-cm10.1 .repo
    mkdir -p /Volumes/Android/work/cm-10.1
    cd $_
    repo init -u file:///Volumes/Android/mirrors/cyanogenmod-mirror/ -b cm-10.1
    repo sync

This could be done for a number of other aosp-based android platform repository mirrors.

I'm starting with this post on a series of disconnected android platform development on Mac OS X. It should work on Linux, and Windows/Cygwin/mingw(not tested!)... whatever you use on windows.

I will be working on tutorials for setting up mirror management (soon a tool for doing this, repo-mm on my github account), setting up eclipse for development, and eventually some tips and tricks.

Stay tuned!


  1. This method works fine if all you want is the git repositories in the manifests. Chirayu Desai helped me figure out how to mirror all repositories reported by gerrit with the following gist:


Post a Comment

Popular posts from this blog

Using repo-mm's

Overview From my previous post on the topic of using a local mirror to do android platform development while not connected to the internet, I've started working on a small shell project called repo-mm . On the road to completing repo-mm's goal, i've created a small component called Eventually, this will be a part of repo-mm's script, but this is a WIP... In this post, we'll sync AOSP and CyanogenMod, and setup a cm-10.1 working directory. I'll also show some manual steps that will be later managed by repo-mm. The scope does not include building CyanogenMod. Their wiki does a great job with that . Install and Setup First step is to get the repo-mm repository and fetch the submodules. I use Mac OS X 10.8.4 and homebrew . But this should also work on Linux and Windows[Cygwin/MinGW]. On Mac OS X, don't forget to make a case-sensitive disk image ! I called mine Android. Go figure. I recommend making a large sparse image. This way

What the SHELL!?!?

Have you ever had that lingering question of: What else can I do with the SHELL environment variable in GNU/Make? Well, I did and tried a few different little tests and figured I'd share them with you. If you do much work with GNU/Make, you've probably seen some projects specifically use /bin/bash instead of /bin/sh. But outside of that, maybe you've never seen SHELL set to anything else. I have two new favorite features in GNU/Make 3.82: .SHELLFLAGS .ONESHELL:  .SHELLFLAGS The argument(s) passed to the shell are taken from the variable .SHELLFLAGS . The default value of .SHELLFLAGS is -c normally, or -ec in POSIX-conforming mode. .ONESHELL: Sometimes you would prefer that all the lines in the recipe be passed to a single invocation of the shell. Lets have some fun! Lets say instead of using a posix shell for our Makefile recipe, lets use Python instead! SHELL = /usr/bin/python .PHONY: all clea