The One Version Rule

There may only be one version of a package in //third_party. This rule applies to both different versions of a single package, and forks or separate copies having different package names under //third_party. There are several reasons for this restriction.


The package owner responsibilities require owners to stay up to date with supported versions. At best, having multiple copies of the code means twice as many locations need to be kept up to date. At worst, a substantial fork needs frequent manual maintenance to integrate changes from new upstream versions into the fork.

Diamond Dependencies

The transitive dependencies of the google3 build system mean that if there are two versions present, eventually someone will try to build a project that depends on both versions. Untangling this after the fact can be very time consuming. Worse, it can stop a project dead that was not involved in submitting either version.

Example of how a project breaks (A→B means A “depends on” B):

Initial dependencies: Project A depends indirectly on third_party/FooV1 and
Project C

Now suppose that:

  1. FooV2 is added to third_party and made the “default” version, and
  2. Project C starts using FooV2 (and correctly selects the default V2)

New dependencies: Now Project C depends on third_party/FooV2

Project A just broke. It depends on two different versions of Foo and will select a random one at runtime.

Both Project A and Project C followed the rules, yet one of them now needs to stop and resolve the multiple version issue. Depending on the upgrade and possibly chaining version issues, this can take days or weeks. In C++ this shows up as a static link failure. In Java, this shows up as both versions of Foo being present on project A’s classpath and a random version being used at runtime.

In short, google3 depends on there being exactly one version of every dependency.

When we allowed versioned directories (.../v1_20/...) we found people would think it was okay to have multiple versions. This is why we have since changed the policy and don’t even allow versioned directories (except for Java and Haskell, which have special infrastructure in place for this kind of thing).

Temporary exceptions

Sometimes it is useful to temporarily have two versions in order to migrate all of google3 to a single new version. If migration will take less than a month, just get started and notify us on emailremoved@. Otherwise, please do the following.

  1. Create a doc describing your plan to migrate everyone to your version and remove the duplicate. Include a reasonable time and staffing estimate. This is usually one quarter for software projects and two quarters for hardware projects, but it can vary based on context.

  2. Get the doc signed off by your director. Send an email asking for the temporary exception to emailremoved@. Link to the document and cc your director.

  3. Wait for confirmation on that thread by a emailremoved@ owner before you proceed.

We typically do not grant permanent exceptions to the one version policy. It’s part of the maintainability tax for benefitting from google3.

Example of a short term exception plan

If you’re looking for guidance on how to execute a migration during a short-term exception, you can reach out to the third party team. Here is one example of how you could do it (but YMMV):

  1. Add the new version but with locked-down visibility so no targets are using it.

  2. Prepare a CL that updates forwarding targets to point to the new version. Run Presubmit global presubmit.

  3. If there are easy fixes to be made, make them in that CL.

  4. Assess. Contact callers and ask them to help. Come up with a plan.

  5. If the CL from step (3) is large, break it into two pieces: one that updates forwarding targets to point to the new version and makes broken callers point explicitly to the old version, and one that updates those callers to use the unversioned target again. Use go/rosie to shard out the second piece (see also go/lsc).

If something unforeseen happens and it’s necessary to roll back after having started the rosie change, then create separate rollback CLs (or get global approval).


Please document any one-version exceptions (whether temporary or permanent) in the METADATA file in the directory above the versioned packages. Add a multiple_versions field to the third_party section.

Except as otherwise noted, the content of this page is licensed under CC-BY-4.0 license. Third-party product names and logos may be the trademarks of their respective owners.