the Chromium logo

The Chromium Projects

Local & Remote Source Tree Layouts

Here we discuss the layout of files in the local source checkout as well as the remote Git server. The goal is both to document the current state of things and to provide guidance when adding new repos.

Some repos might exist in places that don't follow these guidelines, but the goal is to align rather than keep adding exceptions.

Local Checkout

This is the layout as seen when you get a full CrOS checkout. We cover the source repos separately from the generated paths to make the provenance of the paths clearer.

Source directories

Some of these are marked as (non-standard) to indicate that, someday maybe, the repo would be moved to a more appropriate path.

Generated directories

These paths are all created on the fly and do not have any relationship to git repos on the servers. You should not normally need to manage these directly or clean them up. In fact, you should avoid trying to do so to avoid breaking the build system. If you're running out of space, use the cros clean command to help trim the various caches and build directories safely.

Git Server Layout

This is the layout as organized on the Git server. This isn't comprehensive, but should provide enough guidance here.

Note that the layout (and even specific names) of repos on the server do not need to exactly match the layout of the local source checkout. The manifest used by repo allows for the paths and names to be completely independent. Often times they are pretty similar since we try to keep the naming policies coherent as it's less confusing that way.

Public Chromium GoB

This is the public site.

The majority of repos should live under either platform/ or third_party/. It's very uncommon to create projects outside of those paths. If you want to create a new project somewhere else, please check with the build/infra team first using

Internal Chrome GoB

This is the internal site.

The majority of repos should live under overlays/, platform/, or third_party/. It's very uncommon to create projects outside of those paths. If you want to create a new project somewhere else, please check with the build/infra team first using

Branch naming

*** note Note: If forking an upstream repository, please see the Forking upstream projects section for additional rules on top of what's described here.

We have a few conventions when it comes to branch names in our repos. Not all repos follow all these rules, but moving forward new repos should.

When cloning/syncing git repos, only heads/ and tags/ normally get synced. Any other refs stay on the server and are accessed directly.

Note: All the paths here assume a refs/ prefix on them. So when using git push, make sure to use refs/heads/xxx and not just xxx to refer to the remote ref.

Automatic m/ repo refs

Locally, repo provides some pseudo refs to help developers. It uses the m/xxx style where xxx is the branch name used when running repo init. It often matches the actual git branch name used in the git repo, but there is no such requirement.

For example, when getting a repo checkout of the main branch (i.e. after running repo init -b main), every git repo will have a pseudo m/main that points to the branch associated with that project in the manifest. In chromite, m/main will point to heads/main, but in bluez, m/main will point to heads/chromeos.

In another example, when getting a repo checkout of the R70 release branch (i.e. after running repo init -b release-R70-11021.B), every git repo will have a pseudo m/release-R70-11021.B that points to the branch associated with that project in the manifest. In chromite, m/release-R70-11021.B will point to heads/release-R70-11021.B, but in kernel/v4.14, m/release-R70-11021.B-chromeos-4.14.

Other refs

There are a few additional paths that you might come across, although they aren't commonly used, or at least directly.

Local heads/ namespaces

You might see that, depending on the repo, the remote branches look like remotes/cros/xxx or remotes/cros-internal/xxx or remotes/aosp/xxx. The cros and such names come from the remote name used in the manifest for each project element.

For example, the manifest has:

  <remote  name="cros"
           review="" />

  <default revision="refs/heads/main"
           remote="cros" sync-j="8" />

  <project path="chromite" name="chromiumos/chromite" ?>
  <project path="src/aosp/external/minijail"
           remote="aosp" />

The default element sets remote to cros, so that's why it shows up in the chromite (whose project omits remote) repo as remotes/cros/xxx.

The minijail project has an explicit remote=aosp, so that's why it shows up as remotes/aosp/xxx in the local checkout.

Forking upstream projects

Sometimes we want to fork upstream projects to do significant development. We have some guidelines to keep things consistent.

Local checkout paths

You generally want to put projects under src/third_party/$PROJECT/. See the Local Checkout section for more details.

Server paths

Forked repositories live under /chromiumos/third_party/ on the Public Chromium GoB and under /chromeos/third_party/ on the Internal Chrome GoB.

Normally the project is placed directly in that namespace, but for groups of upstream projects, using similar name grouping is acceptable. For example, coreboot uses /chromiumos/third_party/coreboot.git, and it has additional repos under /chromiumos/third_party/coreboot/. If cloning a number of repos from a GitHub project, that layout may be replicated here: turns into /chromiumos/third_party/xxx/yyy. We don't require people to mangle names just to keep a flat namespace under /chromiumos/third_party/.

Do not create forks in the /external/ namespace. Our GoB hosts are shared between many projects & teams, and this namespace is also shared. Think of them like global variables: one team (ab)using it as a fork can surprise or upset another team who was expecting it to be a read-only upstream copy.

Ref (branches & tags) management

These rules exist on top of the common Branch naming rules, not in place of. We often need to fork these repositories as part of our release process.

Note: All the paths here assume a refs/ prefix on them.

Automatic syncing

By following the conventions outlined above, we can easily support automatic syncing with the respective upstream projects. That way you do not need to manually fetch & push tags, or fetch & rename & push refs from upstream's refs/heads/ to our forked refs/heads/upstream/.

Switching major releases

Some projects track major release series and switch between them periodically. If you use the chromeos-xxx ref naming convention, this makes things easier:

Testing upstream directly

*** note This process is undergoing evaluation by teams.

It is possible to have an ebuild track the upstream branch directly as an informational or local developer testing. The requirement is that it not be part of the normal release or build series.

For working examples, see these ebuilds:


How do I create a new repository on the server?

File a bug for the Infra>Git>Admin rotation. All these bugs are marked RVG by default so providing non-public info is OK. ~24hr response time can be expected.

Please do not ask specific people to create repositories for you, even if you happen to know they might have credentials to do so. The bug queue above goes into an oncall rotation queue to help distribute load.

If you are not a committer, make sure to mention someone by their or address who can help vouch/verify the request.

Be sure to fill out the template, and to provide these details:

Feel free to provide any other information you think would help with processing the request. We don't usually need full details (e.g. PRD/design docs), but usually "too much information" is not the problem we have :).

How do I mirror an upstream repository onto the git server?

See the How do I create a new repository on the server? FAQ above.

How do I add a repo to the manifest?

*** note The repository must already exist on the server. See How do I create a new repository on the server? first.

If the repo is public (i.e. exists on the Chromium GoB), then update the full.xml file in the internal manifest-internal repo. Do not modify the full.xml file in the public manifest repo. The public manifest repo will automatically sync with the internal manifest-internal repo.

If the repo is private (i.e. exists on the Chrome GoB), then update the internal_full.xml file in the internal manifest-internal repo.

You can follow the examples in the files already.

How do I change branches for an existing repo?

Set the revision attribute in the relevant <project .../> element in the manifest files.

See the previous question about adding a repo for details on which repos you will need to update.

How do I add a new repo from a new host to the manifest?

Our source code is hosted exclusively on the Chromium GoB & Chrome GoB (with a few exceptions on AOSP GoB, but we don't need to get into that). We do not want to add any more GoB hosts to our manifests.

This is problematic for many infra, release, and developer reasons:

These are not hypotheticals, they are failure modes the project has run into in the past and caused widespread outages.

If you want to use a project that's hosted on another GoB instance, see [How do I mirror an upstream repository onto the git server?].

Do not attempt to add any new remotes to CrOS manifests without first starting a discussion on chops-cros-help@ and getting approval from CrOS infra.

How do I test a manifest change?

The manifest and manifest-internal repos in the checkout are purely for developer convenience in making & uploading changes. They are not used for anything else.

When you run repo sync in your checkout, that only looks at the manifest under the .repo/manifests/ directory. That is an independent checkout of the manifest that was specified originally when running repo init.

So the flow is usually:

At this point, your checkout is in a modified state. That means any CLs other people are landing to the manifest will be pulled in when you run repo sync. If those changes cause conflicts, your checkout won't sync properly. Thus your final step should be to remove your changes.

If your manifest CL hasn't landed yet, then when you run repo sync, the changes you made will be lost. So if you were adding a repo, it will be deleted again from the checkout. If you were removing a repo, it will be added again to the checkout.

How do I initialize a new repository?

Once the repository is in the manifest (see the previous FAQs), you can repo sync to get it locally, and then add/commit/upload files like normal.

The manifest CLs do not need to be merged first -- if you want to generate content ahead of time, you can use the testing steps above to add it to your local manifest, and then start uploading CLs right away.

How do I create a new branch/tag in a repository on the git server?

You don't :). File a bug for the Infra>Git>Admin rotation with your exact request and you should hear back within ~24hrs.

Where do I put ebuilds only for Googlers and internal ChromeOS builds?

The chromeos-overlay holds all packages & settings for this. It is not made public or shared with any partners, so this is for restricted packages and features only.

Where do I put ebuilds to share with partners?

The chromeos-partner-overlay holds all packages & settings for this. It is not made public, but it is shared among all partners.

If you want to share a package with specific partners for a specific board, then put it in the respective src/private-overlays/xxx-private/ overlay.

Can I put ebuilds for private changes into public overlays?

No. All ebuilds in public overlays must be usable by the public. Even if the ebuild itself contains no secret details (e.g. it just installs a binary from a tarball), if the tarball is not publicly available, then we do not put the ebuild in the public overlays.

Use one of the respective private overlays instead. See the previous questions in this FAQ for more details.