Hoist BranchNameKey to top level

The rest of Branch was completely unused, so rather than leave it as a
completely empty container for NameKey, remove it entirely.

Change-Id: I8fc7389f47eb27ed10d052397224d4e3d4316f36
diff --git a/java/com/google/gerrit/acceptance/AbstractDaemonTest.java b/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
index 9203845..56db9a9 100644
--- a/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
+++ b/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
@@ -82,7 +82,7 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
@@ -692,14 +692,14 @@
     return push.to("refs/for/" + branch + "%topic=" + name(topic));
   }
 
-  protected BranchApi createBranch(Branch.NameKey branch) throws Exception {
+  protected BranchApi createBranch(BranchNameKey branch) throws Exception {
     return gApi.projects()
         .name(branch.project().get())
         .branch(branch.branch())
         .create(new BranchInput());
   }
 
-  protected BranchApi createBranchWithRevision(Branch.NameKey branch, String revision)
+  protected BranchApi createBranchWithRevision(BranchNameKey branch, String revision)
       throws Exception {
     BranchInput in = new BranchInput();
     in.revision = revision;
@@ -1143,7 +1143,7 @@
     assertThat(replyTo.getString()).contains(email);
   }
 
-  protected Map<Branch.NameKey, ObjectId> fetchFromSubmitPreview(String changeId) throws Exception {
+  protected Map<BranchNameKey, ObjectId> fetchFromSubmitPreview(String changeId) throws Exception {
     try (BinaryResult result = gApi.changes().id(changeId).current().submitPreview()) {
       return fetchFromBundles(result);
     }
@@ -1155,7 +1155,7 @@
    *
    * <p>Omits NoteDb meta refs.
    */
-  protected Map<Branch.NameKey, ObjectId> fetchFromBundles(BinaryResult bundles) throws Exception {
+  protected Map<BranchNameKey, ObjectId> fetchFromBundles(BinaryResult bundles) throws Exception {
     assertThat(bundles.getContentType()).isEqualTo("application/x-zip");
 
     FileSystem fs = Jimfs.newFileSystem();
@@ -1163,7 +1163,7 @@
     try (OutputStream out = Files.newOutputStream(previewPath)) {
       bundles.writeTo(out);
     }
-    Map<Branch.NameKey, ObjectId> ret = new HashMap<>();
+    Map<BranchNameKey, ObjectId> ret = new HashMap<>();
     try (FileSystem zipFs = FileSystems.newFileSystem(previewPath, null);
         DirectoryStream<Path> dirStream =
             Files.newDirectoryStream(Iterables.getOnlyElement(zipFs.getRootDirectories()))) {
@@ -1192,7 +1192,7 @@
               continue;
             }
             RevCommit c = localRepo.getRevWalk().parseCommit(r.getObjectId());
-            ret.put(Branch.nameKey(proj, refName), c.getTree().copy());
+            ret.put(BranchNameKey.create(proj, refName), c.getTree().copy());
           }
         }
       }
@@ -1202,13 +1202,13 @@
   }
 
   /** Assert that the given branches have the given tree ids. */
-  protected void assertTrees(Project.NameKey proj, Map<Branch.NameKey, ObjectId> trees)
+  protected void assertTrees(Project.NameKey proj, Map<BranchNameKey, ObjectId> trees)
       throws Exception {
     TestRepository<?> localRepo = cloneProject(proj);
     GitUtil.fetch(localRepo, "refs/*:refs/*");
-    Map<Branch.NameKey, RevTree> refValues = new HashMap<>();
+    Map<BranchNameKey, RevTree> refValues = new HashMap<>();
 
-    for (Branch.NameKey b : trees.keySet()) {
+    for (BranchNameKey b : trees.keySet()) {
       if (!b.project().equals(proj)) {
         continue;
       }
diff --git a/java/com/google/gerrit/common/data/SubscribeSection.java b/java/com/google/gerrit/common/data/SubscribeSection.java
index 7761111..60ac12a 100644
--- a/java/com/google/gerrit/common/data/SubscribeSection.java
+++ b/java/com/google/gerrit/common/data/SubscribeSection.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -60,7 +60,7 @@
    * @param branch the branch to check
    * @return if the branch could trigger a superproject update
    */
-  public boolean appliesTo(Branch.NameKey branch) {
+  public boolean appliesTo(BranchNameKey branch) {
     for (RefSpec r : matchingRefSpecs) {
       if (r.matchSource(branch.branch())) {
         return true;
diff --git a/java/com/google/gerrit/reviewdb/client/Branch.java b/java/com/google/gerrit/reviewdb/client/Branch.java
deleted file mode 100644
index 5c43fcf..0000000
--- a/java/com/google/gerrit/reviewdb/client/Branch.java
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (C) 2008 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.reviewdb.client;
-
-import com.google.auto.value.AutoValue;
-
-/** Line of development within a {@link Project}. */
-public final class Branch {
-  public static NameKey nameKey(Project.NameKey projectName, String branchName) {
-    return new AutoValue_Branch_NameKey(projectName, RefNames.fullName(branchName));
-  }
-
-  public static NameKey nameKey(String projectName, String branchName) {
-    return nameKey(Project.nameKey(projectName), branchName);
-  }
-
-  /** Branch name key */
-  @AutoValue
-  public abstract static class NameKey implements Comparable<NameKey> {
-    public abstract Project.NameKey project();
-
-    public abstract String branch();
-
-    public String shortName() {
-      return RefNames.shortName(branch());
-    }
-
-    @Override
-    public int compareTo(NameKey o) {
-      // TODO(dborowitz): Only compares branch name in order to match old StringKey behavior.
-      // Consider comparing project name first.
-      return branch().compareTo(o.branch());
-    }
-
-    @Override
-    public String toString() {
-      return project() + "," + KeyUtil.encode(branch());
-    }
-  }
-
-  protected NameKey name;
-  protected RevId revision;
-  protected boolean canDelete;
-
-  protected Branch() {}
-
-  public Branch(Branch.NameKey newName) {
-    name = newName;
-  }
-
-  public Branch.NameKey getNameKey() {
-    return name;
-  }
-
-  public String getName() {
-    return name.branch();
-  }
-
-  public String getShortName() {
-    return name.shortName();
-  }
-
-  public RevId getRevision() {
-    return revision;
-  }
-
-  public void setRevision(RevId id) {
-    revision = id;
-  }
-
-  public boolean getCanDelete() {
-    return canDelete;
-  }
-
-  public void setCanDelete(boolean canDelete) {
-    this.canDelete = canDelete;
-  }
-}
diff --git a/java/com/google/gerrit/reviewdb/client/BranchNameKey.java b/java/com/google/gerrit/reviewdb/client/BranchNameKey.java
new file mode 100644
index 0000000..bb5bfd9
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/client/BranchNameKey.java
@@ -0,0 +1,49 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.client;
+
+import com.google.auto.value.AutoValue;
+
+/** Branch name key */
+@AutoValue
+public abstract class BranchNameKey implements Comparable<BranchNameKey> {
+  public static BranchNameKey create(Project.NameKey projectName, String branchName) {
+    return new AutoValue_BranchNameKey(projectName, RefNames.fullName(branchName));
+  }
+
+  public static BranchNameKey create(String projectName, String branchName) {
+    return create(Project.nameKey(projectName), branchName);
+  }
+
+  public abstract Project.NameKey project();
+
+  public abstract String branch();
+
+  public String shortName() {
+    return RefNames.shortName(branch());
+  }
+
+  @Override
+  public int compareTo(BranchNameKey o) {
+    // TODO(dborowitz): Only compares branch name in order to match old StringKey behavior.
+    // Consider comparing project name first.
+    return branch().compareTo(o.branch());
+  }
+
+  @Override
+  public String toString() {
+    return project() + "," + KeyUtil.encode(branch());
+  }
+}
diff --git a/java/com/google/gerrit/reviewdb/client/Change.java b/java/com/google/gerrit/reviewdb/client/Change.java
index b58b7dc..b7fd134 100644
--- a/java/com/google/gerrit/reviewdb/client/Change.java
+++ b/java/com/google/gerrit/reviewdb/client/Change.java
@@ -25,7 +25,7 @@
 import java.util.Arrays;
 
 /**
- * A change proposed to be merged into a {@link Branch}.
+ * A change proposed to be merged into a branch.
  *
  * <p>The data graph rooted below a Change can be quite complex:
  *
@@ -440,7 +440,7 @@
   protected Account.Id owner;
 
   /** The branch (and project) this change merges into. */
-  protected Branch.NameKey dest;
+  protected BranchNameKey dest;
 
   // DELETED: id = 9 (open)
 
@@ -496,7 +496,7 @@
       Change.Key newKey,
       Change.Id newId,
       Account.Id ownedBy,
-      Branch.NameKey forBranch,
+      BranchNameKey forBranch,
       Timestamp ts) {
     changeKey = newKey;
     changeId = newId;
@@ -583,11 +583,11 @@
     this.owner = owner;
   }
 
-  public Branch.NameKey getDest() {
+  public BranchNameKey getDest() {
     return dest;
   }
 
-  public void setDest(Branch.NameKey dest) {
+  public void setDest(BranchNameKey dest) {
     this.dest = dest;
   }
 
diff --git a/java/com/google/gerrit/reviewdb/client/SubmoduleSubscription.java b/java/com/google/gerrit/reviewdb/client/SubmoduleSubscription.java
index 270761e..6a451bb 100644
--- a/java/com/google/gerrit/reviewdb/client/SubmoduleSubscription.java
+++ b/java/com/google/gerrit/reviewdb/client/SubmoduleSubscription.java
@@ -25,13 +25,13 @@
  * <p>A subscriber operates a submodule in defined path.
  */
 public final class SubmoduleSubscription {
-  protected Branch.NameKey superProject;
+  protected BranchNameKey superProject;
 
   protected String submodulePath;
 
-  protected Branch.NameKey submodule;
+  protected BranchNameKey submodule;
 
-  public SubmoduleSubscription(Branch.NameKey superProject, Branch.NameKey submodule, String path) {
+  public SubmoduleSubscription(BranchNameKey superProject, BranchNameKey submodule, String path) {
     this.superProject = superProject;
     this.submodule = submodule;
     this.submodulePath = path;
@@ -41,7 +41,7 @@
    * Indicates the super project, aka subscriber: the project owner of the gitlinks to the
    * submodules.
    */
-  public Branch.NameKey getSuperProject() {
+  public BranchNameKey getSuperProject() {
     return superProject;
   }
 
@@ -49,7 +49,7 @@
     return submodulePath;
   }
 
-  public Branch.NameKey getSubmodule() {
+  public BranchNameKey getSubmodule() {
     return submodule;
   }
 
diff --git a/java/com/google/gerrit/reviewdb/converter/BranchNameKeyProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/BranchNameKeyProtoConverter.java
index e04945c..f1018fc 100644
--- a/java/com/google/gerrit/reviewdb/converter/BranchNameKeyProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/BranchNameKeyProtoConverter.java
@@ -15,19 +15,19 @@
 package com.google.gerrit.reviewdb.converter;
 
 import com.google.gerrit.proto.Entities;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.protobuf.Parser;
 
 public enum BranchNameKeyProtoConverter
-    implements ProtoConverter<Entities.Branch_NameKey, Branch.NameKey> {
+    implements ProtoConverter<Entities.Branch_NameKey, BranchNameKey> {
   INSTANCE;
 
   private final ProtoConverter<Entities.Project_NameKey, Project.NameKey> projectNameConverter =
       ProjectNameKeyProtoConverter.INSTANCE;
 
   @Override
-  public Entities.Branch_NameKey toProto(Branch.NameKey nameKey) {
+  public Entities.Branch_NameKey toProto(BranchNameKey nameKey) {
     return Entities.Branch_NameKey.newBuilder()
         .setProject(projectNameConverter.toProto(nameKey.project()))
         .setBranch(nameKey.branch())
@@ -35,8 +35,9 @@
   }
 
   @Override
-  public Branch.NameKey fromProto(Entities.Branch_NameKey proto) {
-    return Branch.nameKey(projectNameConverter.fromProto(proto.getProject()), proto.getBranch());
+  public BranchNameKey fromProto(Entities.Branch_NameKey proto) {
+    return BranchNameKey.create(
+        projectNameConverter.fromProto(proto.getProject()), proto.getBranch());
   }
 
   @Override
diff --git a/java/com/google/gerrit/reviewdb/converter/ChangeProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/ChangeProtoConverter.java
index f6e5f0e..384dbca 100644
--- a/java/com/google/gerrit/reviewdb/converter/ChangeProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/ChangeProtoConverter.java
@@ -16,7 +16,7 @@
 
 import com.google.gerrit.proto.Entities;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.protobuf.Parser;
@@ -31,7 +31,7 @@
       ChangeKeyProtoConverter.INSTANCE;
   private final ProtoConverter<Entities.Account_Id, Account.Id> accountIdConverter =
       AccountIdProtoConverter.INSTANCE;
-  private final ProtoConverter<Entities.Branch_NameKey, Branch.NameKey> branchNameConverter =
+  private final ProtoConverter<Entities.Branch_NameKey, BranchNameKey> branchNameConverter =
       BranchNameKeyProtoConverter.INSTANCE;
 
   @Override
@@ -86,7 +86,7 @@
         proto.hasChangeKey() ? changeKeyConverter.fromProto(proto.getChangeKey()) : null;
     Account.Id owner =
         proto.hasOwnerAccountId() ? accountIdConverter.fromProto(proto.getOwnerAccountId()) : null;
-    Branch.NameKey destination =
+    BranchNameKey destination =
         proto.hasDest() ? branchNameConverter.fromProto(proto.getDest()) : null;
     Change change =
         new Change(key, changeId, owner, destination, new Timestamp(proto.getCreatedOn()));
diff --git a/java/com/google/gerrit/server/ProjectUtil.java b/java/com/google/gerrit/server/ProjectUtil.java
index e816b38..490c143 100644
--- a/java/com/google/gerrit/server/ProjectUtil.java
+++ b/java/com/google/gerrit/server/ProjectUtil.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.server;
 
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import java.io.IOException;
@@ -33,7 +33,7 @@
    * @throws RepositoryNotFoundException the repository of the branch's project does not exist.
    * @throws IOException error while retrieving the branch from the repository.
    */
-  public static boolean branchExists(final GitRepositoryManager repoManager, Branch.NameKey branch)
+  public static boolean branchExists(final GitRepositoryManager repoManager, BranchNameKey branch)
       throws RepositoryNotFoundException, IOException {
     try (Repository repo = repoManager.openRepository(branch.project())) {
       boolean exists = repo.getRefDatabase().exactRef(branch.branch()) != null;
diff --git a/java/com/google/gerrit/server/account/DestinationList.java b/java/com/google/gerrit/server/account/DestinationList.java
index 1b32362..8f4e72e 100644
--- a/java/com/google/gerrit/server/account/DestinationList.java
+++ b/java/com/google/gerrit/server/account/DestinationList.java
@@ -18,7 +18,7 @@
 import com.google.common.collect.MultimapBuilder;
 import com.google.common.collect.SetMultimap;
 import com.google.common.collect.Sets;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.git.ValidationError;
 import com.google.gerrit.server.git.meta.TabFile;
@@ -28,10 +28,10 @@
 
 public class DestinationList extends TabFile {
   public static final String DIR_NAME = "destinations";
-  private SetMultimap<String, Branch.NameKey> destinations =
+  private SetMultimap<String, BranchNameKey> destinations =
       MultimapBuilder.hashKeys().hashSetValues().build();
 
-  public Set<Branch.NameKey> getDestinations(String label) {
+  public Set<BranchNameKey> getDestinations(String label) {
     return destinations.get(label);
   }
 
@@ -40,21 +40,21 @@
   }
 
   String asText(String label) {
-    Set<Branch.NameKey> dests = destinations.get(label);
+    Set<BranchNameKey> dests = destinations.get(label);
     if (dests == null) {
       return null;
     }
     List<Row> rows = Lists.newArrayListWithCapacity(dests.size());
-    for (Branch.NameKey dest : sort(dests)) {
+    for (BranchNameKey dest : sort(dests)) {
       rows.add(new Row(dest.branch(), dest.project().get()));
     }
     return asText("Ref", "Project", rows);
   }
 
-  private static Set<Branch.NameKey> toSet(List<Row> destRows) {
-    Set<Branch.NameKey> dests = Sets.newHashSetWithExpectedSize(destRows.size());
+  private static Set<BranchNameKey> toSet(List<Row> destRows) {
+    Set<BranchNameKey> dests = Sets.newHashSetWithExpectedSize(destRows.size());
     for (Row row : destRows) {
-      dests.add(Branch.nameKey(Project.nameKey(row.right), row.left));
+      dests.add(BranchNameKey.create(Project.nameKey(row.right), row.left));
     }
     return dests;
   }
diff --git a/java/com/google/gerrit/server/args4j/ChangeIdHandler.java b/java/com/google/gerrit/server/args4j/ChangeIdHandler.java
index 5410f25..a91883d 100644
--- a/java/com/google/gerrit/server/args4j/ChangeIdHandler.java
+++ b/java/com/google/gerrit/server/args4j/ChangeIdHandler.java
@@ -18,7 +18,7 @@
 
 import com.google.common.base.Splitter;
 import com.google.gerrit.exceptions.StorageException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.query.change.ChangeData;
@@ -60,7 +60,7 @@
     try {
       final Change.Key key = Change.Key.parse(tokens.get(2));
       final Project.NameKey project = Project.nameKey(tokens.get(0));
-      final Branch.NameKey branch = Branch.nameKey(project, tokens.get(1));
+      final BranchNameKey branch = BranchNameKey.create(project, tokens.get(1));
       for (ChangeData cd : queryProvider.get().byBranchKey(branch, key)) {
         setter.addValue(cd.getId());
         return 1;
diff --git a/java/com/google/gerrit/server/change/ChangeInserter.java b/java/com/google/gerrit/server/change/ChangeInserter.java
index ca61d377..34bad7b 100644
--- a/java/com/google/gerrit/server/change/ChangeInserter.java
+++ b/java/com/google/gerrit/server/change/ChangeInserter.java
@@ -36,7 +36,7 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.ChangeMessage;
 import com.google.gerrit.reviewdb.client.PatchSet;
@@ -185,7 +185,7 @@
             getChangeKey(ctx.getRevWalk(), commitId),
             changeId,
             ctx.getAccountId(),
-            Branch.nameKey(ctx.getProject(), refName),
+            BranchNameKey.create(ctx.getProject(), refName),
             ctx.getWhen());
     change.setStatus(MoreObjects.firstNonNull(status, Change.Status.NEW));
     change.setTopic(topic);
@@ -525,7 +525,7 @@
         commitValidatorsFactory
             .forGerritCommits(
                 permissionBackend.user(ctx.getUser()).project(ctx.getProject()),
-                Branch.nameKey(ctx.getProject(), refName),
+                BranchNameKey.create(ctx.getProject(), refName),
                 ctx.getIdentifiedUser(),
                 new NoSshInfo(),
                 ctx.getRevWalk(),
diff --git a/java/com/google/gerrit/server/change/ChangeTriplet.java b/java/com/google/gerrit/server/change/ChangeTriplet.java
index c038f72..f8b11b1 100644
--- a/java/com/google/gerrit/server/change/ChangeTriplet.java
+++ b/java/com/google/gerrit/server/change/ChangeTriplet.java
@@ -16,7 +16,7 @@
 
 import com.google.auto.value.AutoValue;
 import com.google.gerrit.extensions.restapi.Url;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
 import java.util.Optional;
@@ -27,7 +27,7 @@
     return format(change.getDest(), change.getKey());
   }
 
-  private static String format(Branch.NameKey branch, Change.Key change) {
+  private static String format(BranchNameKey branch, Change.Key change) {
     return branch.project().get() + "~" + branch.shortName() + "~" + change.get();
   }
 
@@ -53,14 +53,14 @@
     String changeId = Url.decode(triplet.substring(z + 1));
     return Optional.of(
         new AutoValue_ChangeTriplet(
-            Branch.nameKey(Project.nameKey(project), branch), Change.key(changeId)));
+            BranchNameKey.create(Project.nameKey(project), branch), Change.key(changeId)));
   }
 
   public final Project.NameKey project() {
     return branch().project();
   }
 
-  public abstract Branch.NameKey branch();
+  public abstract BranchNameKey branch();
 
   public abstract Change.Key id();
 
diff --git a/java/com/google/gerrit/server/change/MergeabilityCache.java b/java/com/google/gerrit/server/change/MergeabilityCache.java
index 3a7f3ab..944ac89 100644
--- a/java/com/google/gerrit/server/change/MergeabilityCache.java
+++ b/java/com/google/gerrit/server/change/MergeabilityCache.java
@@ -15,7 +15,7 @@
 package com.google.gerrit.server.change;
 
 import com.google.gerrit.extensions.client.SubmitType;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
@@ -29,7 +29,7 @@
         Ref intoRef,
         SubmitType submitType,
         String mergeStrategy,
-        Branch.NameKey dest,
+        BranchNameKey dest,
         Repository repo) {
       throw new UnsupportedOperationException("Mergeability checking disabled");
     }
@@ -46,7 +46,7 @@
       Ref intoRef,
       SubmitType submitType,
       String mergeStrategy,
-      Branch.NameKey dest,
+      BranchNameKey dest,
       Repository repo);
 
   Boolean getIfPresent(ObjectId commit, Ref intoRef, SubmitType submitType, String mergeStrategy);
diff --git a/java/com/google/gerrit/server/change/MergeabilityCacheImpl.java b/java/com/google/gerrit/server/change/MergeabilityCacheImpl.java
index d408519..0903fc9 100644
--- a/java/com/google/gerrit/server/change/MergeabilityCacheImpl.java
+++ b/java/com/google/gerrit/server/change/MergeabilityCacheImpl.java
@@ -26,7 +26,7 @@
 import com.google.common.util.concurrent.UncheckedExecutionException;
 import com.google.gerrit.extensions.client.SubmitType;
 import com.google.gerrit.proto.Protos;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.server.cache.CacheModule;
 import com.google.gerrit.server.cache.proto.Cache.MergeabilityKeyProto;
 import com.google.gerrit.server.cache.serialize.BooleanCacheSerializer;
@@ -191,7 +191,7 @@
       Ref intoRef,
       SubmitType submitType,
       String mergeStrategy,
-      Branch.NameKey dest,
+      BranchNameKey dest,
       Repository repo) {
     ObjectId into = intoRef != null ? intoRef.getObjectId() : ObjectId.zeroId();
     EntryKey key = new EntryKey(commit, into, submitType, mergeStrategy);
diff --git a/java/com/google/gerrit/server/change/RebaseUtil.java b/java/com/google/gerrit/server/change/RebaseUtil.java
index 2531bcb..3865802 100644
--- a/java/com/google/gerrit/server/change/RebaseUtil.java
+++ b/java/com/google/gerrit/server/change/RebaseUtil.java
@@ -21,7 +21,7 @@
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.RevId;
@@ -56,7 +56,7 @@
     this.psUtil = psUtil;
   }
 
-  public boolean canRebase(PatchSet patchSet, Branch.NameKey dest, Repository git, RevWalk rw) {
+  public boolean canRebase(PatchSet patchSet, BranchNameKey dest, Repository git, RevWalk rw) {
     try {
       findBaseRevision(patchSet, dest, git, rw);
       return true;
@@ -141,7 +141,7 @@
    * @throws IOException if accessing the repository fails.
    */
   public ObjectId findBaseRevision(
-      PatchSet patchSet, Branch.NameKey destBranch, Repository git, RevWalk rw)
+      PatchSet patchSet, BranchNameKey destBranch, Repository git, RevWalk rw)
       throws RestApiException, IOException {
     String baseRev = null;
     RevCommit commit = rw.parseCommit(ObjectId.fromString(patchSet.getRevision().get()));
diff --git a/java/com/google/gerrit/server/change/ReviewerAdder.java b/java/com/google/gerrit/server/change/ReviewerAdder.java
index a6ad559..6802c89 100644
--- a/java/com/google/gerrit/server/change/ReviewerAdder.java
+++ b/java/com/google/gerrit/server/change/ReviewerAdder.java
@@ -44,7 +44,7 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.PatchSetApproval;
@@ -369,7 +369,7 @@
     return new ReviewerAddition(input, notes, user, null, ImmutableList.of(adr), true);
   }
 
-  private boolean isValidReviewer(Branch.NameKey branch, Account member)
+  private boolean isValidReviewer(BranchNameKey branch, Account member)
       throws PermissionBackendException {
     try {
       // Check ref permission instead of change permission, since change permissions take into
diff --git a/java/com/google/gerrit/server/events/EventBroker.java b/java/com/google/gerrit/server/events/EventBroker.java
index d8efc8d..8d0bde0 100644
--- a/java/com/google/gerrit/server/events/EventBroker.java
+++ b/java/com/google/gerrit/server/events/EventBroker.java
@@ -18,7 +18,7 @@
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.lifecycle.LifecycleModule;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.PatchSet.Id;
@@ -82,7 +82,7 @@
   }
 
   @Override
-  public void postEvent(Branch.NameKey branchName, RefEvent event)
+  public void postEvent(BranchNameKey branchName, RefEvent event)
       throws PermissionBackendException {
     fireEvent(branchName, event);
   }
@@ -121,7 +121,7 @@
     fireEventForUnrestrictedListeners(event);
   }
 
-  protected void fireEvent(Branch.NameKey branchName, RefEvent event)
+  protected void fireEvent(BranchNameKey branchName, RefEvent event)
       throws PermissionBackendException {
     for (PluginSetEntryContext<UserScopedEventListener> c : listeners) {
       CurrentUser user = c.call(UserScopedEventListener::getUser);
@@ -175,7 +175,7 @@
     }
   }
 
-  protected boolean isVisibleTo(Branch.NameKey branchName, CurrentUser user)
+  protected boolean isVisibleTo(BranchNameKey branchName, CurrentUser user)
       throws PermissionBackendException {
     ProjectState pe = projectCache.get(branchName.project());
     if (pe == null || !pe.statePermitsRead()) {
diff --git a/java/com/google/gerrit/server/events/EventDispatcher.java b/java/com/google/gerrit/server/events/EventDispatcher.java
index e6735f2..ab84acc 100644
--- a/java/com/google/gerrit/server/events/EventDispatcher.java
+++ b/java/com/google/gerrit/server/events/EventDispatcher.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.server.events;
 
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.permissions.PermissionBackendException;
@@ -37,7 +37,7 @@
    * @param event The event to post
    * @throws PermissionBackendException on failure of permission checks
    */
-  void postEvent(Branch.NameKey branchName, RefEvent event) throws PermissionBackendException;
+  void postEvent(BranchNameKey branchName, RefEvent event) throws PermissionBackendException;
 
   /**
    * Post a stream event that is related to a project.
diff --git a/java/com/google/gerrit/server/events/EventFactory.java b/java/com/google/gerrit/server/events/EventFactory.java
index e46493c..c29a129 100644
--- a/java/com/google/gerrit/server/events/EventFactory.java
+++ b/java/com/google/gerrit/server/events/EventFactory.java
@@ -28,7 +28,7 @@
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.gerrit.index.IndexConfig;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.ChangeMessage;
 import com.google.gerrit.reviewdb.client.Comment;
@@ -174,7 +174,7 @@
    * @return object suitable for serialization to JSON
    */
   public RefUpdateAttribute asRefUpdateAttribute(
-      ObjectId oldId, ObjectId newId, Branch.NameKey refName) {
+      ObjectId oldId, ObjectId newId, BranchNameKey refName) {
     RefUpdateAttribute ru = new RefUpdateAttribute();
     ru.newRev = newId != null ? newId.getName() : ObjectId.zeroId().getName();
     ru.oldRev = oldId != null ? oldId.getName() : ObjectId.zeroId().getName();
diff --git a/java/com/google/gerrit/server/events/RefEvent.java b/java/com/google/gerrit/server/events/RefEvent.java
index 3b7c306..3a8d246 100644
--- a/java/com/google/gerrit/server/events/RefEvent.java
+++ b/java/com/google/gerrit/server/events/RefEvent.java
@@ -14,15 +14,15 @@
 
 package com.google.gerrit.server.events;
 
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 
 public abstract class RefEvent extends ProjectEvent {
   protected RefEvent(String type) {
     super(type);
   }
 
-  public Branch.NameKey getBranchNameKey() {
-    return Branch.nameKey(getProjectNameKey(), getRefName());
+  public BranchNameKey getBranchNameKey() {
+    return BranchNameKey.create(getProjectNameKey(), getRefName());
   }
 
   public abstract String getRefName();
diff --git a/java/com/google/gerrit/server/events/StreamEventsApiListener.java b/java/com/google/gerrit/server/events/StreamEventsApiListener.java
index d28c920..85ef149 100644
--- a/java/com/google/gerrit/server/events/StreamEventsApiListener.java
+++ b/java/com/google/gerrit/server/events/StreamEventsApiListener.java
@@ -43,7 +43,7 @@
 import com.google.gerrit.extensions.events.WorkInProgressStateChangedListener;
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.server.PatchSetUtil;
@@ -360,7 +360,7 @@
     if (ev.getUpdater() != null) {
       event.submitter = accountAttributeSupplier(ev.getUpdater());
     }
-    final Branch.NameKey refName = Branch.nameKey(ev.getProjectName(), ev.getRefName());
+    final BranchNameKey refName = BranchNameKey.create(ev.getProjectName(), ev.getRefName());
     event.refUpdate =
         Suppliers.memoize(
             () ->
diff --git a/java/com/google/gerrit/server/git/ChangeMessageModifier.java b/java/com/google/gerrit/server/git/ChangeMessageModifier.java
index 7d4edcf..85c700a 100644
--- a/java/com/google/gerrit/server/git/ChangeMessageModifier.java
+++ b/java/com/google/gerrit/server/git/ChangeMessageModifier.java
@@ -15,7 +15,7 @@
 package com.google.gerrit.server.git;
 
 import com.google.gerrit.extensions.annotations.ExtensionPoint;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import org.eclipse.jgit.revwalk.RevCommit;
 
 /**
@@ -47,5 +47,5 @@
    * @return a new not null commit message.
    */
   String onSubmit(
-      String newCommitMessage, RevCommit original, RevCommit mergeTip, Branch.NameKey destination);
+      String newCommitMessage, RevCommit original, RevCommit mergeTip, BranchNameKey destination);
 }
diff --git a/java/com/google/gerrit/server/git/MergeUtil.java b/java/com/google/gerrit/server/git/MergeUtil.java
index 68b6c53..5322daa 100644
--- a/java/com/google/gerrit/server/git/MergeUtil.java
+++ b/java/com/google/gerrit/server/git/MergeUtil.java
@@ -40,7 +40,7 @@
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.LabelId;
 import com.google.gerrit.reviewdb.client.PatchSet;
@@ -126,7 +126,7 @@
     }
 
     public String generate(
-        RevCommit original, RevCommit mergeTip, Branch.NameKey dest, String originalMessage) {
+        RevCommit original, RevCommit mergeTip, BranchNameKey dest, String originalMessage) {
       requireNonNull(original.getRawBuffer());
       if (mergeTip != null) {
         requireNonNull(mergeTip.getRawBuffer());
@@ -733,7 +733,7 @@
       CodeReviewRevWalk rw,
       ObjectInserter inserter,
       Config repoConfig,
-      Branch.NameKey destBranch,
+      BranchNameKey destBranch,
       CodeReviewCommit mergeTip,
       CodeReviewCommit n)
       throws IntegrationException {
@@ -788,7 +788,7 @@
       PersonIdent committer,
       CodeReviewRevWalk rw,
       ObjectInserter inserter,
-      Branch.NameKey destBranch,
+      BranchNameKey destBranch,
       CodeReviewCommit mergeTip,
       ObjectId treeId,
       CodeReviewCommit n)
diff --git a/java/com/google/gerrit/server/git/receive/BranchCommitValidator.java b/java/com/google/gerrit/server/git/receive/BranchCommitValidator.java
index ed13e24..2d1d1a9 100644
--- a/java/com/google/gerrit/server/git/receive/BranchCommitValidator.java
+++ b/java/com/google/gerrit/server/git/receive/BranchCommitValidator.java
@@ -18,7 +18,7 @@
 
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.common.Nullable;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RevId;
@@ -48,12 +48,12 @@
   private final IdentifiedUser user;
   private final PermissionBackend.ForProject permissions;
   private final Project project;
-  private final Branch.NameKey branch;
+  private final BranchNameKey branch;
   private final SshInfo sshInfo;
 
   interface Factory {
     BranchCommitValidator create(
-        ProjectState projectState, Branch.NameKey branch, IdentifiedUser user);
+        ProjectState projectState, BranchNameKey branch, IdentifiedUser user);
   }
 
   @Inject
@@ -62,7 +62,7 @@
       PermissionBackend permissionBackend,
       SshInfo sshInfo,
       @Assisted ProjectState projectState,
-      @Assisted Branch.NameKey branch,
+      @Assisted BranchNameKey branch,
       @Assisted IdentifiedUser user) {
     this.sshInfo = sshInfo;
     this.user = user;
diff --git a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
index a7e8a35..d060a1e 100644
--- a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
+++ b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
@@ -81,7 +81,7 @@
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.PatchSetInfo;
@@ -660,7 +660,7 @@
       logger.atFine().withCause(e).log("update failed:");
     }
 
-    Set<Branch.NameKey> branches = new HashSet<>();
+    Set<BranchNameKey> branches = new HashSet<>();
     for (ReceiveCommand c : cmds) {
       // Most post-update steps should happen in UpdateOneRefOp#postUpdate. The only steps that
       // should happen in this loop are things that can't happen within one BatchUpdate because
@@ -676,7 +676,7 @@
             Task closeProgress = progress.beginSubTask("closed", UNKNOWN);
             autoCloseChanges(c, closeProgress);
             closeProgress.end();
-            branches.add(Branch.nameKey(project.getNameKey(), c.getRefName()));
+            branches.add(BranchNameKey.create(project.getNameKey(), c.getRefName()));
             break;
 
           case DELETE:
@@ -1226,7 +1226,7 @@
       return;
     }
 
-    Branch.NameKey branch = Branch.nameKey(project.getName(), cmd.getRefName());
+    BranchNameKey branch = BranchNameKey.create(project.getName(), cmd.getRefName());
     try {
       // Must pass explicit user instead of injecting a provider into CreateRefControl, since
       // Provider<CurrentUser> within ReceiveCommits will always return anonymous.
@@ -1240,7 +1240,7 @@
     }
 
     if (validRefOperation(cmd)) {
-      validateRegularPushCommits(Branch.nameKey(project.getNameKey(), cmd.getRefName()), cmd);
+      validateRegularPushCommits(BranchNameKey.create(project.getNameKey(), cmd.getRefName()), cmd);
     }
   }
 
@@ -1253,7 +1253,8 @@
         return;
       }
       if (validRefOperation(cmd)) {
-        validateRegularPushCommits(Branch.nameKey(project.getNameKey(), cmd.getRefName()), cmd);
+        validateRegularPushCommits(
+            BranchNameKey.create(project.getNameKey(), cmd.getRefName()), cmd);
       }
     } else {
       rejectProhibited(cmd, err.get());
@@ -1312,7 +1313,7 @@
     logger.atFine().log("Rewinding %s", cmd);
 
     if (newObject != null) {
-      validateRegularPushCommits(Branch.nameKey(project.getNameKey(), cmd.getRefName()), cmd);
+      validateRegularPushCommits(BranchNameKey.create(project.getNameKey(), cmd.getRefName()), cmd);
       if (cmd.getResult() != NOT_ATTEMPTED) {
         return;
       }
@@ -1367,7 +1368,7 @@
     final ReceiveCommand cmd;
     final LabelTypes labelTypes;
     private final boolean defaultPublishComments;
-    Branch.NameKey dest;
+    BranchNameKey dest;
     PermissionBackend.ForRef perm;
     Set<String> reviewer = Sets.newLinkedHashSet();
     Set<String> cc = Sets.newLinkedHashSet();
@@ -1705,7 +1706,7 @@
       return;
     }
 
-    magicBranch.dest = Branch.nameKey(project.getNameKey(), ref);
+    magicBranch.dest = BranchNameKey.create(project.getNameKey(), ref);
     magicBranch.perm = permissions.ref(ref);
 
     Optional<AuthException> err = checkRefPermission(magicBranch.perm, RefPermission.CREATE_CHANGE);
@@ -1856,7 +1857,7 @@
   // branch.  If they aren't, we want to abort. We do this check by
   // looking to see if we can compute a merge base between the new
   // commits and the target branch head.
-  private boolean validateConnected(ReceiveCommand cmd, Branch.NameKey dest, RevCommit tip) {
+  private boolean validateConnected(ReceiveCommand cmd, BranchNameKey dest, RevCommit tip) {
     RevWalk walk = receivePack.getRevWalk();
     try {
       Ref targetRef = receivePack.getAdvertisedRefs().get(dest.branch());
@@ -1905,7 +1906,7 @@
     }
   }
 
-  private RevCommit readBranchTip(Branch.NameKey branch) throws IOException {
+  private RevCommit readBranchTip(BranchNameKey branch) throws IOException {
     Ref r = allRefs().get(branch.branch());
     if (r == null) {
       return null;
@@ -3061,7 +3062,7 @@
    *
    * <p>On validation failure, the command is rejected.
    */
-  private void validateRegularPushCommits(Branch.NameKey branch, ReceiveCommand cmd)
+  private void validateRegularPushCommits(BranchNameKey branch, ReceiveCommand cmd)
       throws PermissionBackendException {
     if (!RefNames.REFS_CONFIG.equals(cmd.getRefName())
         && !(MagicBranch.isMagicBranch(cmd.getRefName())
@@ -3143,7 +3144,7 @@
               // TODO(dborowitz): Teach BatchUpdate to ignore missing changes.
 
               RevCommit newTip = rw.parseCommit(cmd.getNewId());
-              Branch.NameKey branch = Branch.nameKey(project.getNameKey(), refName);
+              BranchNameKey branch = BranchNameKey.create(project.getNameKey(), refName);
 
               rw.reset();
               rw.markStart(newTip);
@@ -3255,7 +3256,7 @@
     }
   }
 
-  private Map<Change.Key, ChangeNotes> openChangesByKeyByBranch(Branch.NameKey branch) {
+  private Map<Change.Key, ChangeNotes> openChangesByKeyByBranch(BranchNameKey branch) {
     Map<Change.Key, ChangeNotes> r = new HashMap<>();
     for (ChangeData cd : queryProvider.get().byBranchOpen(branch)) {
       try {
diff --git a/java/com/google/gerrit/server/git/receive/ReplaceOp.java b/java/com/google/gerrit/server/git/receive/ReplaceOp.java
index b6eb199..396a350 100644
--- a/java/com/google/gerrit/server/git/receive/ReplaceOp.java
+++ b/java/com/google/gerrit/server/git/receive/ReplaceOp.java
@@ -35,7 +35,7 @@
 import com.google.gerrit.extensions.client.ReviewerState;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.ChangeMessage;
 import com.google.gerrit.reviewdb.client.Comment;
@@ -99,7 +99,7 @@
   public interface Factory {
     ReplaceOp create(
         ProjectState projectState,
-        Branch.NameKey dest,
+        BranchNameKey dest,
         boolean checkMergedInto,
         @Assisted("priorPatchSetId") PatchSet.Id priorPatchSetId,
         @Assisted("priorCommitId") ObjectId priorCommit,
@@ -131,7 +131,7 @@
   private final ReviewerAdder reviewerAdder;
 
   private final ProjectState projectState;
-  private final Branch.NameKey dest;
+  private final BranchNameKey dest;
   private final boolean checkMergedInto;
   private final PatchSet.Id priorPatchSetId;
   private final ObjectId priorCommitId;
@@ -175,7 +175,7 @@
       @SendEmailExecutor ExecutorService sendEmailExecutor,
       ReviewerAdder reviewerAdder,
       @Assisted ProjectState projectState,
-      @Assisted Branch.NameKey dest,
+      @Assisted BranchNameKey dest,
       @Assisted boolean checkMergedInto,
       @Assisted("priorPatchSetId") PatchSet.Id priorPatchSetId,
       @Assisted("priorCommitId") ObjectId priorCommitId,
diff --git a/java/com/google/gerrit/server/git/validators/CommitValidators.java b/java/com/google/gerrit/server/git/validators/CommitValidators.java
index a685cb7..42e3b82 100644
--- a/java/com/google/gerrit/server/git/validators/CommitValidators.java
+++ b/java/com/google/gerrit/server/git/validators/CommitValidators.java
@@ -30,7 +30,7 @@
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.GerritPersonIdent;
@@ -127,7 +127,7 @@
 
     public CommitValidators forReceiveCommits(
         PermissionBackend.ForProject forProject,
-        Branch.NameKey branch,
+        BranchNameKey branch,
         IdentifiedUser user,
         SshInfo sshInfo,
         NoteMap rejectCommits,
@@ -161,7 +161,7 @@
 
     public CommitValidators forGerritCommits(
         PermissionBackend.ForProject forProject,
-        Branch.NameKey branch,
+        BranchNameKey branch,
         IdentifiedUser user,
         SshInfo sshInfo,
         RevWalk rw,
@@ -191,7 +191,7 @@
     }
 
     public CommitValidators forMergedCommits(
-        PermissionBackend.ForProject forProject, Branch.NameKey branch, IdentifiedUser user)
+        PermissionBackend.ForProject forProject, BranchNameKey branch, IdentifiedUser user)
         throws IOException {
       // Generally only include validators that are based on permissions of the
       // user creating a change for a merged commit; generally exclude
@@ -389,7 +389,7 @@
   /** If this is the special project configuration branch, validate the config. */
   public static class ConfigValidator implements CommitValidationListener {
     private final ProjectConfig.Factory projectConfigFactory;
-    private final Branch.NameKey branch;
+    private final BranchNameKey branch;
     private final IdentifiedUser user;
     private final RevWalk rw;
     private final AllUsersName allUsers;
@@ -397,7 +397,7 @@
 
     public ConfigValidator(
         ProjectConfig.Factory projectConfigFactory,
-        Branch.NameKey branch,
+        BranchNameKey branch,
         IdentifiedUser user,
         RevWalk rw,
         AllUsersName allUsers,
diff --git a/java/com/google/gerrit/server/git/validators/MergeValidationListener.java b/java/com/google/gerrit/server/git/validators/MergeValidationListener.java
index 6edd04e..ccb67d4 100644
--- a/java/com/google/gerrit/server/git/validators/MergeValidationListener.java
+++ b/java/com/google/gerrit/server/git/validators/MergeValidationListener.java
@@ -15,7 +15,7 @@
 package com.google.gerrit.server.git.validators;
 
 import com.google.gerrit.extensions.annotations.ExtensionPoint;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.git.CodeReviewCommit;
@@ -44,7 +44,7 @@
       Repository repo,
       CodeReviewCommit commit,
       ProjectState destProject,
-      Branch.NameKey destBranch,
+      BranchNameKey destBranch,
       PatchSet.Id patchSetId,
       IdentifiedUser caller)
       throws MergeValidationException;
diff --git a/java/com/google/gerrit/server/git/validators/MergeValidators.java b/java/com/google/gerrit/server/git/validators/MergeValidators.java
index 8cd4751..08950b7 100644
--- a/java/com/google/gerrit/server/git/validators/MergeValidators.java
+++ b/java/com/google/gerrit/server/git/validators/MergeValidators.java
@@ -23,7 +23,7 @@
 import com.google.gerrit.extensions.registration.Extension;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
@@ -80,7 +80,7 @@
       Repository repo,
       CodeReviewCommit commit,
       ProjectState destProject,
-      Branch.NameKey destBranch,
+      BranchNameKey destBranch,
       PatchSet.Id patchSetId,
       IdentifiedUser caller)
       throws MergeValidationException {
@@ -156,7 +156,7 @@
         final Repository repo,
         final CodeReviewCommit commit,
         final ProjectState destProject,
-        final Branch.NameKey destBranch,
+        final BranchNameKey destBranch,
         final PatchSet.Id patchSetId,
         IdentifiedUser caller)
         throws MergeValidationException {
@@ -251,7 +251,7 @@
         Repository repo,
         CodeReviewCommit commit,
         ProjectState destProject,
-        Branch.NameKey destBranch,
+        BranchNameKey destBranch,
         PatchSet.Id patchSetId,
         IdentifiedUser caller)
         throws MergeValidationException {
@@ -285,7 +285,7 @@
         Repository repo,
         CodeReviewCommit commit,
         ProjectState destProject,
-        Branch.NameKey destBranch,
+        BranchNameKey destBranch,
         PatchSet.Id patchSetId,
         IdentifiedUser caller)
         throws MergeValidationException {
@@ -335,7 +335,7 @@
         Repository repo,
         CodeReviewCommit commit,
         ProjectState destProject,
-        Branch.NameKey destBranch,
+        BranchNameKey destBranch,
         PatchSet.Id patchSetId,
         IdentifiedUser caller)
         throws MergeValidationException {
diff --git a/java/com/google/gerrit/server/index/change/ReindexAfterRefUpdate.java b/java/com/google/gerrit/server/index/change/ReindexAfterRefUpdate.java
index 955c3a0..32d63fc 100644
--- a/java/com/google/gerrit/server/index/change/ReindexAfterRefUpdate.java
+++ b/java/com/google/gerrit/server/index/change/ReindexAfterRefUpdate.java
@@ -23,7 +23,7 @@
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
@@ -153,7 +153,7 @@
       if (ref.equals(RefNames.REFS_CONFIG)) {
         return asChanges(queryProvider.get().byProjectOpen(project));
       }
-      return asChanges(queryProvider.get().byBranchNew(Branch.nameKey(project, ref)));
+      return asChanges(queryProvider.get().byBranchNew(BranchNameKey.create(project, ref)));
     }
 
     @Override
diff --git a/java/com/google/gerrit/server/mail/send/NotificationEmail.java b/java/com/google/gerrit/server/mail/send/NotificationEmail.java
index 6ac9b82..10d6ba5 100644
--- a/java/com/google/gerrit/server/mail/send/NotificationEmail.java
+++ b/java/com/google/gerrit/server/mail/send/NotificationEmail.java
@@ -23,7 +23,7 @@
 import com.google.gerrit.mail.Address;
 import com.google.gerrit.mail.MailHeader;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.server.account.ProjectWatches.NotifyType;
 import com.google.gerrit.server.mail.send.ProjectWatch.Watchers;
 import java.util.HashMap;
@@ -33,9 +33,9 @@
 public abstract class NotificationEmail extends OutgoingEmail {
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 
-  protected Branch.NameKey branch;
+  protected BranchNameKey branch;
 
-  protected NotificationEmail(EmailArguments ea, String mc, Branch.NameKey branch) {
+  protected NotificationEmail(EmailArguments ea, String mc, BranchNameKey branch) {
     super(ea, mc);
     this.branch = branch;
   }
diff --git a/java/com/google/gerrit/server/notedb/ChangeNotes.java b/java/com/google/gerrit/server/notedb/ChangeNotes.java
index 6bf7583..3e7d9bd 100644
--- a/java/com/google/gerrit/server/notedb/ChangeNotes.java
+++ b/java/com/google/gerrit/server/notedb/ChangeNotes.java
@@ -38,7 +38,7 @@
 import com.google.gerrit.common.data.SubmitRecord;
 import com.google.gerrit.exceptions.StorageException;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.ChangeMessage;
 import com.google.gerrit.reviewdb.client.Comment;
@@ -127,7 +127,7 @@
 
     public static Change newChange(Project.NameKey project, Change.Id changeId) {
       return new Change(
-          null, changeId, null, Branch.nameKey(project, "INVALID_NOTE_DB_ONLY"), null);
+          null, changeId, null, BranchNameKey.create(project, "INVALID_NOTE_DB_ONLY"), null);
     }
 
     public ChangeNotes create(Project.NameKey project, Change.Id changeId) {
diff --git a/java/com/google/gerrit/server/notedb/ChangeNotesState.java b/java/com/google/gerrit/server/notedb/ChangeNotesState.java
index daebd32..e818153 100644
--- a/java/com/google/gerrit/server/notedb/ChangeNotesState.java
+++ b/java/com/google/gerrit/server/notedb/ChangeNotesState.java
@@ -39,7 +39,7 @@
 import com.google.gerrit.mail.Address;
 import com.google.gerrit.proto.Protos;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.ChangeMessage;
 import com.google.gerrit.reviewdb.client.Comment;
@@ -308,7 +308,7 @@
             c.changeKey(),
             changeId(),
             c.owner(),
-            Branch.nameKey(project, c.branch()),
+            BranchNameKey.create(project, c.branch()),
             c.createdOn());
     copyNonConstructorColumnsTo(change);
     return change;
@@ -322,7 +322,7 @@
         this);
     change.setKey(c.changeKey());
     change.setOwner(c.owner());
-    change.setDest(Branch.nameKey(change.getProject(), c.branch()));
+    change.setDest(BranchNameKey.create(change.getProject(), c.branch()));
     change.setCreatedOn(c.createdOn());
     copyNonConstructorColumnsTo(change);
   }
diff --git a/java/com/google/gerrit/server/permissions/DefaultRefFilter.java b/java/com/google/gerrit/server/permissions/DefaultRefFilter.java
index 5948048..2a8619f 100644
--- a/java/com/google/gerrit/server/permissions/DefaultRefFilter.java
+++ b/java/com/google/gerrit/server/permissions/DefaultRefFilter.java
@@ -38,7 +38,7 @@
 import com.google.gerrit.metrics.MetricMaker;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
@@ -89,7 +89,7 @@
   private final Counter0 skipFilterCount;
   private final boolean skipFullRefEvaluationIfAllRefsAreVisible;
 
-  private Map<Change.Id, Branch.NameKey> visibleChanges;
+  private Map<Change.Id, BranchNameKey> visibleChanges;
 
   @Inject
   DefaultRefFilter(
@@ -375,11 +375,10 @@
     return false;
   }
 
-  private Map<Change.Id, Branch.NameKey> visibleChangesBySearch()
-      throws PermissionBackendException {
+  private Map<Change.Id, BranchNameKey> visibleChangesBySearch() throws PermissionBackendException {
     Project.NameKey project = projectState.getNameKey();
     try {
-      Map<Change.Id, Branch.NameKey> visibleChanges = new HashMap<>();
+      Map<Change.Id, BranchNameKey> visibleChanges = new HashMap<>();
       for (ChangeData cd : changeCache.getChangeData(project)) {
         ChangeNotes notes = changeNotesFactory.createFromIndexedChange(cd.change());
         if (!projectState.statePermitsRead()) {
@@ -400,7 +399,7 @@
     }
   }
 
-  private Map<Change.Id, Branch.NameKey> visibleChangesByScan(Repository repo)
+  private Map<Change.Id, BranchNameKey> visibleChangesByScan(Repository repo)
       throws PermissionBackendException {
     Project.NameKey p = projectState.getNameKey();
     ImmutableList<ChangeNotesResult> changes;
@@ -412,7 +411,7 @@
       return Collections.emptyMap();
     }
 
-    Map<Change.Id, Branch.NameKey> result = Maps.newHashMapWithExpectedSize(changes.size());
+    Map<Change.Id, BranchNameKey> result = Maps.newHashMapWithExpectedSize(changes.size());
     for (ChangeNotesResult notesResult : changes) {
       ChangeNotes notes = toNotes(notesResult);
       if (notes != null) {
diff --git a/java/com/google/gerrit/server/permissions/PermissionBackend.java b/java/com/google/gerrit/server/permissions/PermissionBackend.java
index d246688..119d414 100644
--- a/java/com/google/gerrit/server/permissions/PermissionBackend.java
+++ b/java/com/google/gerrit/server/permissions/PermissionBackend.java
@@ -30,7 +30,7 @@
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.notedb.ChangeNotes;
@@ -157,7 +157,7 @@
     public abstract ForProject project(Project.NameKey project);
 
     /** Returns an instance scoped for the {@code ref}, and its parent project. */
-    public ForRef ref(Branch.NameKey ref) {
+    public ForRef ref(BranchNameKey ref) {
       return project(ref.project()).ref(ref.branch());
     }
 
diff --git a/java/com/google/gerrit/server/permissions/ProjectControl.java b/java/com/google/gerrit/server/permissions/ProjectControl.java
index 369028b..bc00b88 100644
--- a/java/com/google/gerrit/server/permissions/ProjectControl.java
+++ b/java/com/google/gerrit/server/permissions/ProjectControl.java
@@ -27,7 +27,7 @@
 import com.google.gerrit.extensions.conditions.BooleanCondition;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
@@ -108,7 +108,7 @@
     return changeControlFactory.create(controlForRef(notes.getChange().getDest()), notes);
   }
 
-  RefControl controlForRef(Branch.NameKey ref) {
+  RefControl controlForRef(BranchNameKey ref) {
     return controlForRef(ref.branch());
   }
 
diff --git a/java/com/google/gerrit/server/project/BranchResource.java b/java/com/google/gerrit/server/project/BranchResource.java
index 882dab7..40403b4 100644
--- a/java/com/google/gerrit/server/project/BranchResource.java
+++ b/java/com/google/gerrit/server/project/BranchResource.java
@@ -15,7 +15,7 @@
 package com.google.gerrit.server.project;
 
 import com.google.gerrit.extensions.restapi.RestView;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.server.CurrentUser;
 import com.google.inject.TypeLiteral;
 import org.eclipse.jgit.lib.Ref;
@@ -33,8 +33,8 @@
     this.revision = ref.getObjectId() != null ? ref.getObjectId().name() : null;
   }
 
-  public Branch.NameKey getBranchKey() {
-    return Branch.nameKey(getNameKey(), refName);
+  public BranchNameKey getBranchKey() {
+    return BranchNameKey.create(getNameKey(), refName);
   }
 
   @Override
diff --git a/java/com/google/gerrit/server/project/CreateRefControl.java b/java/com/google/gerrit/server/project/CreateRefControl.java
index 63cb294..21be8e3 100644
--- a/java/com/google/gerrit/server/project/CreateRefControl.java
+++ b/java/com/google/gerrit/server/project/CreateRefControl.java
@@ -17,7 +17,7 @@
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.permissions.PermissionBackend;
@@ -64,10 +64,7 @@
    * @throws ResourceConflictException if the project state does not permit the operation
    */
   public void checkCreateRef(
-      Provider<? extends CurrentUser> user,
-      Repository repo,
-      Branch.NameKey branch,
-      RevObject object)
+      Provider<? extends CurrentUser> user, Repository repo, BranchNameKey branch, RevObject object)
       throws AuthException, PermissionBackendException, NoSuchProjectException, IOException,
           ResourceConflictException {
     ProjectState ps = projectCache.checkedGet(branch.project());
diff --git a/java/com/google/gerrit/server/project/ProjectConfig.java b/java/com/google/gerrit/server/project/ProjectConfig.java
index 5ef9651..e29a48a 100644
--- a/java/com/google/gerrit/server/project/ProjectConfig.java
+++ b/java/com/google/gerrit/server/project/ProjectConfig.java
@@ -48,7 +48,7 @@
 import com.google.gerrit.mail.Address;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.account.GroupBackend;
@@ -341,7 +341,7 @@
     return subscribeSections;
   }
 
-  public Collection<SubscribeSection> getSubscribeSections(Branch.NameKey branch) {
+  public Collection<SubscribeSection> getSubscribeSections(BranchNameKey branch) {
     Collection<SubscribeSection> ret = new ArrayList<>();
     for (SubscribeSection s : subscribeSections.values()) {
       if (s.appliesTo(branch)) {
diff --git a/java/com/google/gerrit/server/project/ProjectState.java b/java/com/google/gerrit/server/project/ProjectState.java
index dbe5580..acfbf40 100644
--- a/java/com/google/gerrit/server/project/ProjectState.java
+++ b/java/com/google/gerrit/server/project/ProjectState.java
@@ -39,7 +39,7 @@
 import com.google.gerrit.metrics.Timer1;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.account.CapabilityCollection;
@@ -463,7 +463,7 @@
   }
 
   /** All available label types for this branch. */
-  public LabelTypes getLabelTypes(Branch.NameKey destination) {
+  public LabelTypes getLabelTypes(BranchNameKey destination) {
     List<LabelType> all = getLabelTypes().getLabelTypes();
 
     List<LabelType> r = Lists.newArrayListWithCapacity(all.size());
@@ -524,7 +524,7 @@
     return null;
   }
 
-  public Collection<SubscribeSection> getSubscribeSections(Branch.NameKey branch) {
+  public Collection<SubscribeSection> getSubscribeSections(BranchNameKey branch) {
     Collection<SubscribeSection> ret = new ArrayList<>();
     for (ProjectState s : tree()) {
       ret.addAll(s.getConfig().getSubscribeSections(branch));
@@ -591,7 +591,7 @@
     return new LabelTypes(Collections.unmodifiableList(all));
   }
 
-  private boolean match(Branch.NameKey destination, String refPattern) {
+  private boolean match(BranchNameKey destination, String refPattern) {
     return RefPatternMatcher.getMatcher(refPattern).match(destination.branch(), null);
   }
 }
diff --git a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index e9c2ddb..c2e09b0 100644
--- a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -45,7 +45,7 @@
 import com.google.gerrit.mail.Address;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.AnonymousUser;
@@ -1179,7 +1179,7 @@
     try (Repository git = args.repoManager.openRepository(args.allUsersName)) {
       VersionedAccountDestinations d = VersionedAccountDestinations.forUser(self());
       d.load(args.allUsersName, git);
-      Set<Branch.NameKey> destinations = d.getDestinationList().getDestinations(name);
+      Set<BranchNameKey> destinations = d.getDestinationList().getDestinations(name);
       if (destinations != null && !destinations.isEmpty()) {
         return new DestinationPredicate(destinations, name);
       }
diff --git a/java/com/google/gerrit/server/query/change/ConflictsPredicate.java b/java/com/google/gerrit/server/query/change/ConflictsPredicate.java
index fad6b68..fe0a9c9 100644
--- a/java/com/google/gerrit/server/query/change/ConflictsPredicate.java
+++ b/java/com/google/gerrit/server/query/change/ConflictsPredicate.java
@@ -25,7 +25,7 @@
 import com.google.gerrit.index.query.Predicate;
 import com.google.gerrit.index.query.QueryParseException;
 import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.git.CodeReviewCommit;
@@ -97,7 +97,7 @@
 
   private static final class CheckConflict extends PostFilterPredicate<ChangeData> {
     private final Arguments args;
-    private final Branch.NameKey dest;
+    private final BranchNameKey dest;
     private final ChangeDataCache changeDataCache;
 
     CheckConflict(String value, Arguments args, Change c, ChangeDataCache changeDataCache) {
diff --git a/java/com/google/gerrit/server/query/change/DestinationPredicate.java b/java/com/google/gerrit/server/query/change/DestinationPredicate.java
index 702745e..bd07914 100644
--- a/java/com/google/gerrit/server/query/change/DestinationPredicate.java
+++ b/java/com/google/gerrit/server/query/change/DestinationPredicate.java
@@ -15,14 +15,14 @@
 package com.google.gerrit.server.query.change;
 
 import com.google.gerrit.index.query.PostFilterPredicate;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import java.util.Set;
 
 public class DestinationPredicate extends PostFilterPredicate<ChangeData> {
-  protected Set<Branch.NameKey> destinations;
+  protected Set<BranchNameKey> destinations;
 
-  public DestinationPredicate(Set<Branch.NameKey> destinations, String value) {
+  public DestinationPredicate(Set<BranchNameKey> destinations, String value) {
     super(ChangeQueryBuilder.FIELD_DESTINATION, value);
     this.destinations = destinations;
   }
diff --git a/java/com/google/gerrit/server/query/change/InternalChangeQuery.java b/java/com/google/gerrit/server/query/change/InternalChangeQuery.java
index 147ec84..b364e98 100644
--- a/java/com/google/gerrit/server/query/change/InternalChangeQuery.java
+++ b/java/com/google/gerrit/server/query/change/InternalChangeQuery.java
@@ -28,7 +28,7 @@
 import com.google.gerrit.index.IndexConfig;
 import com.google.gerrit.index.query.InternalQuery;
 import com.google.gerrit.index.query.Predicate;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
@@ -55,7 +55,7 @@
  * holding on to a single instance.
  */
 public class InternalChangeQuery extends InternalQuery<ChangeData, InternalChangeQuery> {
-  private static Predicate<ChangeData> ref(Branch.NameKey branch) {
+  private static Predicate<ChangeData> ref(BranchNameKey branch) {
     return new RefPredicate(branch.branch());
   }
 
@@ -110,20 +110,20 @@
     return query(or(preds));
   }
 
-  public List<ChangeData> byBranchKey(Branch.NameKey branch, Change.Key key) {
+  public List<ChangeData> byBranchKey(BranchNameKey branch, Change.Key key) {
     return query(byBranchKeyPred(branch, key));
   }
 
   public List<ChangeData> byBranchKeyOpen(Project.NameKey project, String branch, Change.Key key) {
-    return query(and(byBranchKeyPred(Branch.nameKey(project, branch), key), open()));
+    return query(and(byBranchKeyPred(BranchNameKey.create(project, branch), key), open()));
   }
 
   public static Predicate<ChangeData> byBranchKeyOpenPred(
       Project.NameKey project, String branch, Change.Key key) {
-    return and(byBranchKeyPred(Branch.nameKey(project, branch), key), open());
+    return and(byBranchKeyPred(BranchNameKey.create(project, branch), key), open());
   }
 
-  private static Predicate<ChangeData> byBranchKeyPred(Branch.NameKey branch, Change.Key key) {
+  private static Predicate<ChangeData> byBranchKeyPred(BranchNameKey branch, Change.Key key) {
     return and(ref(branch), project(branch.project()), change(key));
   }
 
@@ -131,16 +131,16 @@
     return query(project(project));
   }
 
-  public List<ChangeData> byBranchOpen(Branch.NameKey branch) {
+  public List<ChangeData> byBranchOpen(BranchNameKey branch) {
     return query(and(ref(branch), project(branch.project()), open()));
   }
 
-  public List<ChangeData> byBranchNew(Branch.NameKey branch) {
+  public List<ChangeData> byBranchNew(BranchNameKey branch) {
     return query(and(ref(branch), project(branch.project()), status(Change.Status.NEW)));
   }
 
   public Iterable<ChangeData> byCommitsOnBranchNotMerged(
-      Repository repo, Branch.NameKey branch, Collection<String> hashes) throws IOException {
+      Repository repo, BranchNameKey branch, Collection<String> hashes) throws IOException {
     return byCommitsOnBranchNotMerged(
         repo,
         branch,
@@ -151,7 +151,7 @@
 
   @VisibleForTesting
   Iterable<ChangeData> byCommitsOnBranchNotMerged(
-      Repository repo, Branch.NameKey branch, Collection<String> hashes, int indexLimit)
+      Repository repo, BranchNameKey branch, Collection<String> hashes, int indexLimit)
       throws IOException {
     if (hashes.size() > indexLimit) {
       return byCommitsOnBranchNotMergedFromDatabase(repo, branch, hashes);
@@ -160,7 +160,7 @@
   }
 
   private Iterable<ChangeData> byCommitsOnBranchNotMergedFromDatabase(
-      Repository repo, Branch.NameKey branch, Collection<String> hashes) throws IOException {
+      Repository repo, BranchNameKey branch, Collection<String> hashes) throws IOException {
     Set<Change.Id> changeIds = Sets.newHashSetWithExpectedSize(hashes.size());
     String lastPrefix = null;
     for (Ref ref : repo.getRefDatabase().getRefsByPrefix(RefNames.REFS_CHANGES)) {
@@ -190,7 +190,7 @@
   }
 
   private Iterable<ChangeData> byCommitsOnBranchNotMergedFromIndex(
-      Branch.NameKey branch, Collection<String> hashes) {
+      BranchNameKey branch, Collection<String> hashes) {
     return query(
         and(
             ref(branch),
@@ -241,7 +241,7 @@
     return query(byBranchCommitPred(project, branch, hash));
   }
 
-  public List<ChangeData> byBranchCommit(Branch.NameKey branch, String hash) {
+  public List<ChangeData> byBranchCommit(BranchNameKey branch, String hash) {
     return byBranchCommit(branch.project().get(), branch.branch(), hash);
   }
 
diff --git a/java/com/google/gerrit/server/restapi/change/CherryPick.java b/java/com/google/gerrit/server/restapi/change/CherryPick.java
index 548aeb7..3fd80df 100644
--- a/java/com/google/gerrit/server/restapi/change/CherryPick.java
+++ b/java/com/google/gerrit/server/restapi/change/CherryPick.java
@@ -23,7 +23,7 @@
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.webui.UiAction;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.change.ChangeJson;
 import com.google.gerrit.server.change.RevisionResource;
@@ -103,7 +103,7 @@
               rsrc.getChange(),
               rsrc.getPatchSet(),
               input,
-              Branch.nameKey(rsrc.getProject(), refName));
+              BranchNameKey.create(rsrc.getProject(), refName));
       CherryPickChangeInfo changeInfo =
           json.noOptions()
               .format(rsrc.getProject(), cherryPickResult.changeId(), CherryPickChangeInfo::new);
diff --git a/java/com/google/gerrit/server/restapi/change/CherryPickChange.java b/java/com/google/gerrit/server/restapi/change/CherryPickChange.java
index 2293a24..780499c 100644
--- a/java/com/google/gerrit/server/restapi/change/CherryPickChange.java
+++ b/java/com/google/gerrit/server/restapi/change/CherryPickChange.java
@@ -29,7 +29,7 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
@@ -139,7 +139,7 @@
       Change change,
       PatchSet patch,
       CherryPickInput input,
-      Branch.NameKey dest)
+      BranchNameKey dest)
       throws IOException, InvalidChangeOperationException, IntegrationException, UpdateException,
           RestApiException, ConfigInvalidException, NoSuchProjectException {
     return cherryPick(
@@ -157,7 +157,7 @@
       Project.NameKey project,
       ObjectId sourceCommit,
       CherryPickInput input,
-      Branch.NameKey dest)
+      BranchNameKey dest)
       throws IOException, InvalidChangeOperationException, IntegrationException, UpdateException,
           RestApiException, ConfigInvalidException, NoSuchProjectException {
 
@@ -235,7 +235,7 @@
           changeKey = Change.key("I" + computedChangeId.name());
         }
 
-        Branch.NameKey newDest = Branch.nameKey(project, destRef.getName());
+        BranchNameKey newDest = BranchNameKey.create(project, destRef.getName());
         List<ChangeData> destChanges =
             queryProvider.get().setLimit(2).byBranchKey(newDest, changeKey);
         if (destChanges.size() > 1) {
@@ -344,7 +344,7 @@
       throws IOException {
     Change.Id changeId = Change.id(seq.nextChangeId());
     ChangeInserter ins = changeInserterFactory.create(changeId, cherryPickCommit, refName);
-    Branch.NameKey sourceBranch = sourceChange == null ? null : sourceChange.getDest();
+    BranchNameKey sourceBranch = sourceChange == null ? null : sourceChange.getDest();
     ins.setMessage(
             messageForDestinationChange(
                 ins.getPatchSetId(), sourceBranch, sourceCommit, cherryPickCommit))
@@ -375,7 +375,7 @@
 
   private String messageForDestinationChange(
       PatchSet.Id patchSetId,
-      Branch.NameKey sourceBranch,
+      BranchNameKey sourceBranch,
       ObjectId sourceCommit,
       CodeReviewCommit cherryPickCommit) {
     StringBuilder stringBuilder = new StringBuilder("Patch Set ").append(patchSetId.get());
diff --git a/java/com/google/gerrit/server/restapi/change/CherryPickCommit.java b/java/com/google/gerrit/server/restapi/change/CherryPickCommit.java
index f498a96..ff5c377 100644
--- a/java/com/google/gerrit/server/restapi/change/CherryPickCommit.java
+++ b/java/com/google/gerrit/server/restapi/change/CherryPickCommit.java
@@ -20,7 +20,7 @@
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.CurrentUser;
@@ -102,7 +102,7 @@
               projectName,
               commit,
               input,
-              Branch.nameKey(rsrc.getProjectState().getNameKey(), refName));
+              BranchNameKey.create(rsrc.getProjectState().getNameKey(), refName));
       CherryPickChangeInfo changeInfo =
           json.noOptions()
               .format(projectName, cherryPickResult.changeId(), CherryPickChangeInfo::new);
diff --git a/java/com/google/gerrit/server/restapi/change/CreateMergePatchSet.java b/java/com/google/gerrit/server/restapi/change/CreateMergePatchSet.java
index fb64b85..0cee74a 100644
--- a/java/com/google/gerrit/server/restapi/change/CreateMergePatchSet.java
+++ b/java/com/google/gerrit/server/restapi/change/CreateMergePatchSet.java
@@ -28,7 +28,7 @@
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
@@ -138,7 +138,7 @@
     PatchSet ps = psUtil.current(rsrc.getNotes());
     Change change = rsrc.getChange();
     Project.NameKey project = change.getProject();
-    Branch.NameKey dest = change.getDest();
+    BranchNameKey dest = change.getDest();
     try (Repository git = gitManager.openRepository(project);
         ObjectInserter oi = git.newObjectInserter();
         ObjectReader reader = oi.newReader();
@@ -215,7 +215,7 @@
   private RevCommit createMergeCommit(
       MergePatchSetInput in,
       ProjectState projectState,
-      Branch.NameKey dest,
+      BranchNameKey dest,
       Repository git,
       ObjectInserter oi,
       RevWalk rw,
diff --git a/java/com/google/gerrit/server/restapi/change/Move.java b/java/com/google/gerrit/server/restapi/change/Move.java
index 0cfcd27..31f760e 100644
--- a/java/com/google/gerrit/server/restapi/change/Move.java
+++ b/java/com/google/gerrit/server/restapi/change/Move.java
@@ -32,7 +32,7 @@
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.webui.UiAction;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.ChangeMessage;
 import com.google.gerrit.reviewdb.client.LabelId;
@@ -135,7 +135,7 @@
       throw new ResourceConflictException("Change is " + ChangeUtil.status(change));
     }
 
-    Branch.NameKey newDest = Branch.nameKey(project, input.destinationBranch);
+    BranchNameKey newDest = BranchNameKey.create(project, input.destinationBranch);
     if (change.getDest().equals(newDest)) {
       throw new ResourceConflictException("Change is already destined for the specified branch");
     }
@@ -164,7 +164,7 @@
     private final MoveInput input;
 
     private Change change;
-    private Branch.NameKey newDestKey;
+    private BranchNameKey newDestKey;
 
     Op(MoveInput input) {
       this.input = input;
@@ -183,8 +183,8 @@
       }
 
       Project.NameKey projectKey = change.getProject();
-      newDestKey = Branch.nameKey(projectKey, input.destinationBranch);
-      Branch.NameKey changePrevDest = change.getDest();
+      newDestKey = BranchNameKey.create(projectKey, input.destinationBranch);
+      BranchNameKey changePrevDest = change.getDest();
       if (changePrevDest.equals(newDestKey)) {
         throw new ResourceConflictException("Change is already destined for the specified branch");
       }
diff --git a/java/com/google/gerrit/server/restapi/change/Rebase.java b/java/com/google/gerrit/server/restapi/change/Rebase.java
index b5fe1d0..a92a382 100644
--- a/java/com/google/gerrit/server/restapi/change/Rebase.java
+++ b/java/com/google/gerrit/server/restapi/change/Rebase.java
@@ -26,7 +26,7 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.webui.UiAction;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.server.ChangeUtil;
@@ -137,7 +137,7 @@
       Repository repo, RevWalk rw, RevisionResource rsrc, RebaseInput input)
       throws RestApiException, IOException, NoSuchChangeException, AuthException,
           PermissionBackendException {
-    Branch.NameKey destRefKey = rsrc.getChange().getDest();
+    BranchNameKey destRefKey = rsrc.getChange().getDest();
     if (input == null || input.base == null) {
       return rebaseUtil.findBaseRevision(rsrc.getPatchSet(), destRefKey, repo, rw);
     }
diff --git a/java/com/google/gerrit/server/restapi/change/Submit.java b/java/com/google/gerrit/server/restapi/change/Submit.java
index f0a00c6..73df1e7 100644
--- a/java/com/google/gerrit/server/restapi/change/Submit.java
+++ b/java/com/google/gerrit/server/restapi/change/Submit.java
@@ -32,7 +32,7 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.extensions.webui.UiAction;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
@@ -385,8 +385,8 @@
       mergeabilityMap.add(change);
     }
 
-    ListMultimap<Branch.NameKey, ChangeData> cbb = cs.changesByBranch();
-    for (Branch.NameKey branch : cbb.keySet()) {
+    ListMultimap<BranchNameKey, ChangeData> cbb = cs.changesByBranch();
+    for (BranchNameKey branch : cbb.keySet()) {
       Collection<ChangeData> targetBranch = cbb.get(branch);
       HashMap<Change.Id, RevCommit> commits = findCommits(targetBranch, branch.project());
 
diff --git a/java/com/google/gerrit/server/restapi/project/CheckAccess.java b/java/com/google/gerrit/server/restapi/project/CheckAccess.java
index 9eb9be4..41bcbb8 100644
--- a/java/com/google/gerrit/server/restapi/project/CheckAccess.java
+++ b/java/com/google/gerrit/server/restapi/project/CheckAccess.java
@@ -24,7 +24,7 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.server.account.AccountResolver;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.permissions.DefaultPermissionMappings;
@@ -106,7 +106,7 @@
       try {
         permissionBackend
             .absentUser(match)
-            .ref(Branch.nameKey(rsrc.getNameKey(), input.ref))
+            .ref(BranchNameKey.create(rsrc.getNameKey(), input.ref))
             .check(refPerm);
       } catch (AuthException e) {
         info.status = HttpServletResponse.SC_FORBIDDEN;
diff --git a/java/com/google/gerrit/server/restapi/project/CreateBranch.java b/java/com/google/gerrit/server/restapi/project/CreateBranch.java
index 9ea2f2c..e86230c 100644
--- a/java/com/google/gerrit/server/restapi/project/CreateBranch.java
+++ b/java/com/google/gerrit/server/restapi/project/CreateBranch.java
@@ -24,7 +24,7 @@
 import com.google.gerrit.extensions.restapi.IdString;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.RestCollectionCreateView;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
@@ -108,7 +108,7 @@
               + "\"");
     }
 
-    final Branch.NameKey name = Branch.nameKey(rsrc.getNameKey(), ref);
+    final BranchNameKey name = BranchNameKey.create(rsrc.getNameKey(), ref);
     try (Repository repo = repoManager.openRepository(rsrc.getNameKey())) {
       ObjectId revid = RefUtil.parseBaseRevision(repo, rsrc.getNameKey(), input.revision);
       RevWalk rw = RefUtil.verifyConnected(repo, revid);
diff --git a/java/com/google/gerrit/server/restapi/project/DeleteRef.java b/java/com/google/gerrit/server/restapi/project/DeleteRef.java
index 4e5154e..6b7987c 100644
--- a/java/com/google/gerrit/server/restapi/project/DeleteRef.java
+++ b/java/com/google/gerrit/server/restapi/project/DeleteRef.java
@@ -27,7 +27,7 @@
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
@@ -260,7 +260,7 @@
     }
 
     if (!refName.startsWith(R_TAGS)) {
-      Branch.NameKey branchKey = Branch.nameKey(projectState.getNameKey(), ref.getName());
+      BranchNameKey branchKey = BranchNameKey.create(projectState.getNameKey(), ref.getName());
       if (!queryProvider.get().setLimit(1).byBranchOpen(branchKey).isEmpty()) {
         command.setResult(Result.REJECTED_OTHER_REASON, "it has open changes");
       }
diff --git a/java/com/google/gerrit/server/submit/ChangeSet.java b/java/com/google/gerrit/server/submit/ChangeSet.java
index e721be41ab..b6dbbb6 100644
--- a/java/com/google/gerrit/server/submit/ChangeSet.java
+++ b/java/com/google/gerrit/server/submit/ChangeSet.java
@@ -20,7 +20,7 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ListMultimap;
 import com.google.common.collect.MultimapBuilder;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.query.change.ChangeData;
@@ -76,8 +76,8 @@
     return changeData;
   }
 
-  public ListMultimap<Branch.NameKey, ChangeData> changesByBranch() {
-    ListMultimap<Branch.NameKey, ChangeData> ret =
+  public ListMultimap<BranchNameKey, ChangeData> changesByBranch() {
+    ListMultimap<BranchNameKey, ChangeData> ret =
         MultimapBuilder.hashKeys().arrayListValues().build();
     for (ChangeData cd : changeData.values()) {
       ret.put(cd.change().getDest(), cd);
diff --git a/java/com/google/gerrit/server/submit/GitModules.java b/java/com/google/gerrit/server/submit/GitModules.java
index 59641a4..1770c4a 100644
--- a/java/com/google/gerrit/server/submit/GitModules.java
+++ b/java/com/google/gerrit/server/submit/GitModules.java
@@ -16,7 +16,7 @@
 
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.common.Nullable;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.SubmoduleSubscription;
 import com.google.gerrit.server.config.CanonicalWebUrl;
@@ -45,7 +45,7 @@
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 
   public interface Factory {
-    GitModules create(Branch.NameKey project, MergeOpRepoManager m);
+    GitModules create(BranchNameKey project, MergeOpRepoManager m);
   }
 
   private static final String GIT_MODULES = ".gitmodules";
@@ -55,7 +55,7 @@
   @Inject
   GitModules(
       @CanonicalWebUrl @Nullable String canonicalWebUrl,
-      @Assisted Branch.NameKey branch,
+      @Assisted BranchNameKey branch,
       @Assisted MergeOpRepoManager orm)
       throws IOException {
     Project.NameKey project = branch.project();
@@ -89,7 +89,7 @@
     }
   }
 
-  Collection<SubmoduleSubscription> subscribedTo(Branch.NameKey src) {
+  Collection<SubmoduleSubscription> subscribedTo(BranchNameKey src) {
     Collection<SubmoduleSubscription> ret = new ArrayList<>();
     for (SubmoduleSubscription s : subscriptions) {
       if (s.getSubmodule().equals(src)) {
diff --git a/java/com/google/gerrit/server/submit/LocalMergeSuperSetComputation.java b/java/com/google/gerrit/server/submit/LocalMergeSuperSetComputation.java
index ab92270..d076a51 100644
--- a/java/com/google/gerrit/server/submit/LocalMergeSuperSetComputation.java
+++ b/java/com/google/gerrit/server/submit/LocalMergeSuperSetComputation.java
@@ -27,7 +27,7 @@
 import com.google.gerrit.extensions.client.SubmitType;
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.gerrit.extensions.restapi.AuthException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.permissions.ChangePermission;
@@ -75,12 +75,12 @@
 
   @AutoValue
   abstract static class QueryKey {
-    private static QueryKey create(Branch.NameKey branch, Iterable<String> hashes) {
+    private static QueryKey create(BranchNameKey branch, Iterable<String> hashes) {
       return new AutoValue_LocalMergeSuperSetComputation_QueryKey(
           branch, ImmutableSet.copyOf(hashes));
     }
 
-    abstract Branch.NameKey branch();
+    abstract BranchNameKey branch();
 
     abstract ImmutableSet<String> hashes();
   }
@@ -88,7 +88,7 @@
   private final PermissionBackend permissionBackend;
   private final Provider<InternalChangeQuery> queryProvider;
   private final Map<QueryKey, ImmutableList<ChangeData>> queryCache;
-  private final Map<Branch.NameKey, Optional<RevCommit>> heads;
+  private final Map<BranchNameKey, Optional<RevCommit>> heads;
   private final ProjectCache projectCache;
   private final ChangeIsVisibleToPredicate changeIsVisibleToPredicate;
 
@@ -115,9 +115,9 @@
 
     // For each target branch we run a separate rev walk to find open changes
     // reachable from changes already in the merge super set.
-    ImmutableListMultimap<Branch.NameKey, ChangeData> bc =
+    ImmutableListMultimap<BranchNameKey, ChangeData> bc =
         byBranch(Iterables.concat(changeSet.changes(), changeSet.nonVisibleChanges()));
-    for (Branch.NameKey b : bc.keySet()) {
+    for (BranchNameKey b : bc.keySet()) {
       OpenRepo or = getRepo(orm, b.project());
       List<RevCommit> visibleCommits = new ArrayList<>();
       List<RevCommit> nonVisibleCommits = new ArrayList<>();
@@ -160,9 +160,9 @@
     return new ChangeSet(visibleChanges, nonVisibleChanges);
   }
 
-  private static ImmutableListMultimap<Branch.NameKey, ChangeData> byBranch(
+  private static ImmutableListMultimap<BranchNameKey, ChangeData> byBranch(
       Iterable<ChangeData> changes) {
-    ImmutableListMultimap.Builder<Branch.NameKey, ChangeData> builder =
+    ImmutableListMultimap.Builder<BranchNameKey, ChangeData> builder =
         ImmutableListMultimap.builder();
     for (ChangeData cd : changes) {
       builder.put(cd.change().getDest(), cd);
@@ -211,7 +211,7 @@
   }
 
   private ChangeSet byCommitsOnBranchNotMerged(
-      OpenRepo or, Branch.NameKey branch, Set<String> visibleHashes, Set<String> nonVisibleHashes)
+      OpenRepo or, BranchNameKey branch, Set<String> visibleHashes, Set<String> nonVisibleHashes)
       throws IOException {
     List<ChangeData> potentiallyVisibleChanges =
         byCommitsOnBranchNotMerged(or, branch, visibleHashes);
@@ -229,7 +229,7 @@
   }
 
   private ImmutableList<ChangeData> byCommitsOnBranchNotMerged(
-      OpenRepo or, Branch.NameKey branch, Set<String> hashes) throws IOException {
+      OpenRepo or, BranchNameKey branch, Set<String> hashes) throws IOException {
     if (hashes.isEmpty()) {
       return ImmutableList.of();
     }
@@ -245,7 +245,7 @@
   }
 
   private Set<String> walkChangesByHashes(
-      Collection<RevCommit> sourceCommits, Set<String> ignoreHashes, OpenRepo or, Branch.NameKey b)
+      Collection<RevCommit> sourceCommits, Set<String> ignoreHashes, OpenRepo or, BranchNameKey b)
       throws IOException {
     Set<String> destHashes = new HashSet<>();
     or.rw.reset();
@@ -269,7 +269,7 @@
     return destHashes;
   }
 
-  private void markHeadUninteresting(OpenRepo or, Branch.NameKey b) throws IOException {
+  private void markHeadUninteresting(OpenRepo or, BranchNameKey b) throws IOException {
     Optional<RevCommit> head = heads.get(b);
     if (head == null) {
       Ref ref = or.repo.getRefDatabase().exactRef(b.branch());
diff --git a/java/com/google/gerrit/server/submit/MergeOp.java b/java/com/google/gerrit/server/submit/MergeOp.java
index 2da4f71..b133e59 100644
--- a/java/com/google/gerrit/server/submit/MergeOp.java
+++ b/java/com/google/gerrit/server/submit/MergeOp.java
@@ -48,7 +48,7 @@
 import com.google.gerrit.metrics.Counter0;
 import com.google.gerrit.metrics.Description;
 import com.google.gerrit.metrics.MetricMaker;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.ChangeMessage;
 import com.google.gerrit.reviewdb.client.PatchSet;
@@ -119,7 +119,7 @@
 
   public static class CommitStatus {
     private final ImmutableMap<Change.Id, ChangeData> changes;
-    private final ImmutableSetMultimap<Branch.NameKey, Change.Id> byBranch;
+    private final ImmutableSetMultimap<BranchNameKey, Change.Id> byBranch;
     private final Map<Change.Id, CodeReviewCommit> commits;
     private final ListMultimap<Change.Id, String> problems;
     private final boolean allowClosed;
@@ -128,7 +128,7 @@
       checkArgument(
           !cs.furtherHiddenChanges(), "CommitStatus must not be called with hidden changes");
       changes = cs.changesById();
-      ImmutableSetMultimap.Builder<Branch.NameKey, Change.Id> bb = ImmutableSetMultimap.builder();
+      ImmutableSetMultimap.Builder<BranchNameKey, Change.Id> bb = ImmutableSetMultimap.builder();
       for (ChangeData cd : cs.changes()) {
         bb.put(cd.change().getDest(), cd.getId());
       }
@@ -142,7 +142,7 @@
       return changes.keySet();
     }
 
-    public ImmutableSet<Change.Id> getChangeIds(Branch.NameKey branch) {
+    public ImmutableSet<Change.Id> getChangeIds(BranchNameKey branch) {
       return byBranch.get(branch);
     }
 
@@ -573,17 +573,17 @@
       throws IntegrationException, RestApiException, UpdateException {
     checkArgument(!cs.furtherHiddenChanges(), "cannot integrate hidden changes into history");
     logger.atFine().log("Beginning merge attempt on %s", cs);
-    Map<Branch.NameKey, BranchBatch> toSubmit = new HashMap<>();
+    Map<BranchNameKey, BranchBatch> toSubmit = new HashMap<>();
 
-    ListMultimap<Branch.NameKey, ChangeData> cbb;
+    ListMultimap<BranchNameKey, ChangeData> cbb;
     try {
       cbb = cs.changesByBranch();
     } catch (StorageException e) {
       throw new IntegrationException("Error reading changes to submit", e);
     }
-    Set<Branch.NameKey> branches = cbb.keySet();
+    Set<BranchNameKey> branches = cbb.keySet();
 
-    for (Branch.NameKey branch : branches) {
+    for (BranchNameKey branch : branches) {
       OpenRepo or = openRepo(branch.project());
       if (or != null) {
         toSubmit.put(branch, validateChangeList(or, cbb.get(branch)));
@@ -641,13 +641,13 @@
   }
 
   private List<SubmitStrategy> getSubmitStrategies(
-      Map<Branch.NameKey, BranchBatch> toSubmit, SubmoduleOp submoduleOp, boolean dryrun)
+      Map<BranchNameKey, BranchBatch> toSubmit, SubmoduleOp submoduleOp, boolean dryrun)
       throws IntegrationException, NoSuchProjectException, IOException {
     List<SubmitStrategy> strategies = new ArrayList<>();
-    Set<Branch.NameKey> allBranches = submoduleOp.getBranchesInOrder();
+    Set<BranchNameKey> allBranches = submoduleOp.getBranchesInOrder();
     Set<CodeReviewCommit> allCommits =
         toSubmit.values().stream().map(BranchBatch::commits).flatMap(Set::stream).collect(toSet());
-    for (Branch.NameKey branch : allBranches) {
+    for (BranchNameKey branch : allBranches) {
       OpenRepo or = orm.getRepo(branch.project());
       if (toSubmit.containsKey(branch)) {
         BranchBatch submitting = toSubmit.get(branch);
@@ -769,7 +769,7 @@
       }
 
       PatchSet ps;
-      Branch.NameKey destBranch = chg.getDest();
+      BranchNameKey destBranch = chg.getDest();
       try {
         ps = cd.currentPatchSet();
       } catch (StorageException e) {
diff --git a/java/com/google/gerrit/server/submit/MergeOpRepoManager.java b/java/com/google/gerrit/server/submit/MergeOpRepoManager.java
index c3d3b54..d985b7f 100644
--- a/java/com/google/gerrit/server/submit/MergeOpRepoManager.java
+++ b/java/com/google/gerrit/server/submit/MergeOpRepoManager.java
@@ -18,7 +18,7 @@
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.collect.Maps;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.IdentifiedUser;
@@ -67,7 +67,7 @@
     BatchUpdate update;
 
     private final ObjectReader reader;
-    private final Map<Branch.NameKey, OpenBranch> branches;
+    private final Map<BranchNameKey, OpenBranch> branches;
 
     private OpenRepo(Repository repo, ProjectState project) {
       this.repo = repo;
@@ -84,7 +84,7 @@
       branches = Maps.newHashMapWithExpectedSize(1);
     }
 
-    OpenBranch getBranch(Branch.NameKey branch) throws IntegrationException {
+    OpenBranch getBranch(BranchNameKey branch) throws IntegrationException {
       OpenBranch ob = branches.get(branch);
       if (ob == null) {
         ob = new OpenBranch(this, branch);
@@ -134,7 +134,7 @@
     final CodeReviewCommit oldTip;
     MergeTip mergeTip;
 
-    OpenBranch(OpenRepo or, Branch.NameKey name) throws IntegrationException {
+    OpenBranch(OpenRepo or, BranchNameKey name) throws IntegrationException {
       try {
         update = or.repo.updateRef(name.branch());
         if (update.getOldObjectId() != null) {
diff --git a/java/com/google/gerrit/server/submit/RebaseSorter.java b/java/com/google/gerrit/server/submit/RebaseSorter.java
index 829ee9c..21ab6b7 100644
--- a/java/com/google/gerrit/server/submit/RebaseSorter.java
+++ b/java/com/google/gerrit/server/submit/RebaseSorter.java
@@ -16,7 +16,7 @@
 
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.exceptions.StorageException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.git.CodeReviewCommit;
 import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
@@ -108,7 +108,7 @@
     return sorted;
   }
 
-  private boolean isAlreadyMerged(CodeReviewCommit commit, Branch.NameKey dest) throws IOException {
+  private boolean isAlreadyMerged(CodeReviewCommit commit, BranchNameKey dest) throws IOException {
     try (CodeReviewRevWalk mirw = CodeReviewCommit.newRevWalk(rw.getObjectReader())) {
       mirw.reset();
       mirw.markStart(commit);
diff --git a/java/com/google/gerrit/server/submit/SubmitDryRun.java b/java/com/google/gerrit/server/submit/SubmitDryRun.java
index fbfa468..3a59a45 100644
--- a/java/com/google/gerrit/server/submit/SubmitDryRun.java
+++ b/java/com/google/gerrit/server/submit/SubmitDryRun.java
@@ -21,7 +21,7 @@
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.extensions.client.SubmitType;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.git.CodeReviewCommit;
 import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
@@ -112,7 +112,7 @@
       SubmitType submitType,
       Repository repo,
       CodeReviewRevWalk rw,
-      Branch.NameKey destBranch,
+      BranchNameKey destBranch,
       ObjectId tip,
       ObjectId toMerge,
       Set<RevCommit> alreadyAccepted)
@@ -155,7 +155,7 @@
     }
   }
 
-  private ProjectState getProject(Branch.NameKey branch) throws NoSuchProjectException {
+  private ProjectState getProject(BranchNameKey branch) throws NoSuchProjectException {
     ProjectState p = projectCache.get(branch.project());
     if (p == null) {
       throw new NoSuchProjectException(branch.project());
diff --git a/java/com/google/gerrit/server/submit/SubmitStrategy.java b/java/com/google/gerrit/server/submit/SubmitStrategy.java
index 4acfd33..73cbc8f 100644
--- a/java/com/google/gerrit/server/submit/SubmitStrategy.java
+++ b/java/com/google/gerrit/server/submit/SubmitStrategy.java
@@ -20,7 +20,7 @@
 import com.google.gerrit.extensions.api.changes.SubmitInput;
 import com.google.gerrit.extensions.client.SubmitType;
 import com.google.gerrit.extensions.config.FactoryModule;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.server.ApprovalsUtil;
 import com.google.gerrit.server.ChangeMessagesUtil;
@@ -82,7 +82,7 @@
     interface Factory {
       Arguments create(
           SubmitType submitType,
-          Branch.NameKey destBranch,
+          BranchNameKey destBranch,
           CommitStatus commitStatus,
           CodeReviewRevWalk rw,
           IdentifiedUser caller,
@@ -114,7 +114,7 @@
     final ProjectConfig.Factory projectConfigFactory;
     final SetPrivateOp.Factory setPrivateOpFactory;
 
-    final Branch.NameKey destBranch;
+    final BranchNameKey destBranch;
     final CodeReviewRevWalk rw;
     final CommitStatus commitStatus;
     final IdentifiedUser caller;
@@ -152,7 +152,7 @@
         Provider<InternalChangeQuery> queryProvider,
         ProjectConfig.Factory projectConfigFactory,
         SetPrivateOp.Factory setPrivateOpFactory,
-        @Assisted Branch.NameKey destBranch,
+        @Assisted BranchNameKey destBranch,
         @Assisted CommitStatus commitStatus,
         @Assisted CodeReviewRevWalk rw,
         @Assisted IdentifiedUser caller,
diff --git a/java/com/google/gerrit/server/submit/SubmitStrategyFactory.java b/java/com/google/gerrit/server/submit/SubmitStrategyFactory.java
index 30326f7..e2e4991 100644
--- a/java/com/google/gerrit/server/submit/SubmitStrategyFactory.java
+++ b/java/com/google/gerrit/server/submit/SubmitStrategyFactory.java
@@ -17,7 +17,7 @@
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.extensions.api.changes.SubmitInput;
 import com.google.gerrit.extensions.client.SubmitType;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.git.CodeReviewCommit;
 import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
@@ -48,7 +48,7 @@
       RevFlag canMergeFlag,
       Set<RevCommit> alreadyAccepted,
       Set<CodeReviewCommit> incoming,
-      Branch.NameKey destBranch,
+      BranchNameKey destBranch,
       IdentifiedUser caller,
       MergeTip mergeTip,
       CommitStatus commitStatus,
diff --git a/java/com/google/gerrit/server/submit/SubmitStrategyOp.java b/java/com/google/gerrit/server/submit/SubmitStrategyOp.java
index b363735..02dfd09 100644
--- a/java/com/google/gerrit/server/submit/SubmitStrategyOp.java
+++ b/java/com/google/gerrit/server/submit/SubmitStrategyOp.java
@@ -25,7 +25,7 @@
 import com.google.gerrit.common.data.SubmitRecord;
 import com.google.gerrit.exceptions.StorageException;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.ChangeMessage;
 import com.google.gerrit.reviewdb.client.LabelId;
@@ -89,7 +89,7 @@
     return toMerge;
   }
 
-  protected final Branch.NameKey getDest() {
+  protected final BranchNameKey getDest() {
     return toMerge.change().getDest();
   }
 
diff --git a/java/com/google/gerrit/server/submit/SubmoduleOp.java b/java/com/google/gerrit/server/submit/SubmoduleOp.java
index 75a3d00..7fc47dc 100644
--- a/java/com/google/gerrit/server/submit/SubmoduleOp.java
+++ b/java/com/google/gerrit/server/submit/SubmoduleOp.java
@@ -24,7 +24,7 @@
 import com.google.gerrit.common.UsedAt;
 import com.google.gerrit.common.data.SubscribeSection;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.reviewdb.client.SubmoduleSubscription;
@@ -79,9 +79,9 @@
 
   /** Only used for branches without code review changes */
   public class GitlinkOp implements RepoOnlyOp {
-    private final Branch.NameKey branch;
+    private final BranchNameKey branch;
 
-    GitlinkOp(Branch.NameKey branch) {
+    GitlinkOp(BranchNameKey branch) {
       this.branch = branch;
     }
 
@@ -114,7 +114,7 @@
       this.projectCache = projectCache;
     }
 
-    public SubmoduleOp create(Set<Branch.NameKey> updatedBranches, MergeOpRepoManager orm)
+    public SubmoduleOp create(Set<BranchNameKey> updatedBranches, MergeOpRepoManager orm)
         throws SubmoduleException {
       return new SubmoduleOp(
           gitmodulesFactory, serverIdent.get(), cfg, projectCache, updatedBranches, orm);
@@ -129,41 +129,41 @@
   private final long maxCombinedCommitMessageSize;
   private final long maxCommitMessages;
   private final MergeOpRepoManager orm;
-  private final Map<Branch.NameKey, GitModules> branchGitModules;
+  private final Map<BranchNameKey, GitModules> branchGitModules;
 
   /** Branches updated as part of the enclosing submit or push batch. */
-  private final ImmutableSet<Branch.NameKey> updatedBranches;
+  private final ImmutableSet<BranchNameKey> updatedBranches;
 
   /**
    * Current branch tips, taking into account commits created during the submit process as well as
    * submodule updates produced by this class.
    */
-  private final Map<Branch.NameKey, CodeReviewCommit> branchTips;
+  private final Map<BranchNameKey, CodeReviewCommit> branchTips;
 
   /**
    * Branches in a superproject that contain submodule subscriptions, plus branches in submodules
    * which are subscribed to by some superproject.
    */
-  private final Set<Branch.NameKey> affectedBranches;
+  private final Set<BranchNameKey> affectedBranches;
 
   /** Copy of {@link #affectedBranches}, sorted by submodule traversal order. */
-  private final ImmutableSet<Branch.NameKey> sortedBranches;
+  private final ImmutableSet<BranchNameKey> sortedBranches;
 
   /** Multimap of superproject branch to submodule subscriptions contained in that branch. */
-  private final SetMultimap<Branch.NameKey, SubmoduleSubscription> targets;
+  private final SetMultimap<BranchNameKey, SubmoduleSubscription> targets;
 
   /**
    * Multimap of superproject name to all branch names within that superproject which have submodule
    * subscriptions.
    */
-  private final SetMultimap<Project.NameKey, Branch.NameKey> branchesByProject;
+  private final SetMultimap<Project.NameKey, BranchNameKey> branchesByProject;
 
   private SubmoduleOp(
       GitModules.Factory gitmodulesFactory,
       PersonIdent myIdent,
       Config cfg,
       ProjectCache projectCache,
-      Set<Branch.NameKey> updatedBranches,
+      Set<BranchNameKey> updatedBranches,
       MergeOpRepoManager orm)
       throws SubmoduleException {
     this.gitmodulesFactory = gitmodulesFactory;
@@ -214,15 +214,15 @@
   //
   // In addition to improving readability, this approach has the advantage of making (1) and (2)
   // testable using small tests.
-  private ImmutableSet<Branch.NameKey> calculateSubscriptionMaps() throws SubmoduleException {
+  private ImmutableSet<BranchNameKey> calculateSubscriptionMaps() throws SubmoduleException {
     if (!enableSuperProjectSubscriptions) {
       logger.atFine().log("Updating superprojects disabled");
       return null;
     }
 
     logger.atFine().log("Calculating superprojects - submodules map");
-    LinkedHashSet<Branch.NameKey> allVisited = new LinkedHashSet<>();
-    for (Branch.NameKey updatedBranch : updatedBranches) {
+    LinkedHashSet<BranchNameKey> allVisited = new LinkedHashSet<>();
+    for (BranchNameKey updatedBranch : updatedBranches) {
       if (allVisited.contains(updatedBranch)) {
         continue;
       }
@@ -240,9 +240,9 @@
   }
 
   private void searchForSuperprojects(
-      Branch.NameKey current,
-      LinkedHashSet<Branch.NameKey> currentVisited,
-      LinkedHashSet<Branch.NameKey> allVisited)
+      BranchNameKey current,
+      LinkedHashSet<BranchNameKey> currentVisited,
+      LinkedHashSet<BranchNameKey> allVisited)
       throws SubmoduleException {
     logger.atFine().log("Now processing %s", current);
 
@@ -261,7 +261,7 @@
       Collection<SubmoduleSubscription> subscriptions =
           superProjectSubscriptionsForSubmoduleBranch(current);
       for (SubmoduleSubscription sub : subscriptions) {
-        Branch.NameKey superBranch = sub.getSuperProject();
+        BranchNameKey superBranch = sub.getSuperProject();
         searchForSuperprojects(superBranch, currentVisited, allVisited);
         targets.put(superBranch, sub);
         branchesByProject.put(superBranch.project(), superBranch);
@@ -303,9 +303,9 @@
     return sb.toString();
   }
 
-  private Collection<Branch.NameKey> getDestinationBranches(Branch.NameKey src, SubscribeSection s)
+  private Collection<BranchNameKey> getDestinationBranches(BranchNameKey src, SubscribeSection s)
       throws IOException {
-    Collection<Branch.NameKey> ret = new HashSet<>();
+    Collection<BranchNameKey> ret = new HashSet<>();
     logger.atFine().log("Inspecting SubscribeSection %s", s);
     for (RefSpec r : s.getMatchingRefSpecs()) {
       logger.atFine().log("Inspecting [matching] ref %s", r);
@@ -314,14 +314,16 @@
       }
       if (r.isWildcard()) {
         // refs/heads/*[:refs/somewhere/*]
-        ret.add(Branch.nameKey(s.getProject(), r.expandFromSource(src.branch()).getDestination()));
+        ret.add(
+            BranchNameKey.create(
+                s.getProject(), r.expandFromSource(src.branch()).getDestination()));
       } else {
         // e.g. refs/heads/master[:refs/heads/stable]
         String dest = r.getDestination();
         if (dest == null) {
           dest = r.getSource();
         }
-        ret.add(Branch.nameKey(s.getProject(), dest));
+        ret.add(BranchNameKey.create(s.getProject(), dest));
       }
     }
 
@@ -344,7 +346,7 @@
         if (r.getDestination() != null && !r.matchDestination(ref.getName())) {
           continue;
         }
-        Branch.NameKey b = Branch.nameKey(s.getProject(), ref.getName());
+        BranchNameKey b = BranchNameKey.create(s.getProject(), ref.getName());
         if (!ret.contains(b)) {
           ret.add(b);
         }
@@ -356,14 +358,14 @@
 
   @UsedAt(UsedAt.Project.PLUGIN_DELETE_PROJECT)
   public Collection<SubmoduleSubscription> superProjectSubscriptionsForSubmoduleBranch(
-      Branch.NameKey srcBranch) throws IOException {
+      BranchNameKey srcBranch) throws IOException {
     logger.atFine().log("Calculating possible superprojects for %s", srcBranch);
     Collection<SubmoduleSubscription> ret = new ArrayList<>();
     Project.NameKey srcProject = srcBranch.project();
     for (SubscribeSection s : projectCache.get(srcProject).getSubscribeSections(srcBranch)) {
       logger.atFine().log("Checking subscribe section %s", s);
-      Collection<Branch.NameKey> branches = getDestinationBranches(srcBranch, s);
-      for (Branch.NameKey targetBranch : branches) {
+      Collection<BranchNameKey> branches = getDestinationBranches(srcBranch, s);
+      for (BranchNameKey targetBranch : branches) {
         Project.NameKey targetProject = targetBranch.project();
         try {
           OpenRepo or = orm.getRepo(targetProject);
@@ -403,7 +405,7 @@
           superProjects.add(project);
           // get a new BatchUpdate for the super project
           OpenRepo or = orm.getRepo(project);
-          for (Branch.NameKey branch : branchesByProject.get(project)) {
+          for (BranchNameKey branch : branchesByProject.get(project)) {
             addOp(or.getUpdate(), branch);
           }
         }
@@ -415,7 +417,7 @@
   }
 
   /** Create a separate gitlink commit */
-  private CodeReviewCommit composeGitlinksCommit(Branch.NameKey subscriber)
+  private CodeReviewCommit composeGitlinksCommit(BranchNameKey subscriber)
       throws IOException, SubmoduleException {
     OpenRepo or;
     try {
@@ -485,7 +487,7 @@
   }
 
   /** Amend an existing commit with gitlink updates */
-  CodeReviewCommit composeGitlinksCommit(Branch.NameKey subscriber, CodeReviewCommit currentCommit)
+  CodeReviewCommit composeGitlinksCommit(BranchNameKey subscriber, CodeReviewCommit currentCommit)
       throws IOException, SubmoduleException {
     OpenRepo or;
     try {
@@ -675,7 +677,7 @@
       addAllSubmoduleProjects(project, new LinkedHashSet<>(), projects);
     }
 
-    for (Branch.NameKey branch : updatedBranches) {
+    for (BranchNameKey branch : updatedBranches) {
       projects.add(branch.project());
     }
     return ImmutableSet.copyOf(projects);
@@ -697,7 +699,7 @@
 
     current.add(project);
     Set<Project.NameKey> subprojects = new HashSet<>();
-    for (Branch.NameKey branch : branchesByProject.get(project)) {
+    for (BranchNameKey branch : branchesByProject.get(project)) {
       Collection<SubmoduleSubscription> subscriptions = targets.get(branch);
       for (SubmoduleSubscription s : subscriptions) {
         subprojects.add(s.getSubmodule().project());
@@ -712,8 +714,8 @@
     projects.add(project);
   }
 
-  ImmutableSet<Branch.NameKey> getBranchesInOrder() {
-    LinkedHashSet<Branch.NameKey> branches = new LinkedHashSet<>();
+  ImmutableSet<BranchNameKey> getBranchesInOrder() {
+    LinkedHashSet<BranchNameKey> branches = new LinkedHashSet<>();
     if (sortedBranches != null) {
       branches.addAll(sortedBranches);
     }
@@ -721,15 +723,15 @@
     return ImmutableSet.copyOf(branches);
   }
 
-  boolean hasSubscription(Branch.NameKey branch) {
+  boolean hasSubscription(BranchNameKey branch) {
     return targets.containsKey(branch);
   }
 
-  void addBranchTip(Branch.NameKey branch, CodeReviewCommit tip) {
+  void addBranchTip(BranchNameKey branch, CodeReviewCommit tip) {
     branchTips.put(branch, tip);
   }
 
-  void addOp(BatchUpdate bu, Branch.NameKey branch) {
+  void addOp(BatchUpdate bu, BranchNameKey branch) {
     bu.addRepoOnlyOp(new GitlinkOp(branch));
   }
 }
diff --git a/java/com/google/gerrit/server/util/git/SubmoduleSectionParser.java b/java/com/google/gerrit/server/util/git/SubmoduleSectionParser.java
index 85fd42a..433a5f1 100644
--- a/java/com/google/gerrit/server/util/git/SubmoduleSectionParser.java
+++ b/java/com/google/gerrit/server/util/git/SubmoduleSectionParser.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.server.util.git;
 
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.SubmoduleSubscription;
 import java.net.URI;
@@ -45,10 +45,10 @@
 
   private final Config config;
   private final String canonicalWebUrl;
-  private final Branch.NameKey superProjectBranch;
+  private final BranchNameKey superProjectBranch;
 
   public SubmoduleSectionParser(
-      Config config, String canonicalWebUrl, Branch.NameKey superProjectBranch) {
+      Config config, String canonicalWebUrl, BranchNameKey superProjectBranch) {
     this.config = config;
     this.canonicalWebUrl = canonicalWebUrl;
     this.superProjectBranch = superProjectBranch;
@@ -135,7 +135,7 @@
         }
         Project.NameKey projectKey = Project.nameKey(project);
         return new SubmoduleSubscription(
-            superProjectBranch, Branch.nameKey(projectKey, branch), path);
+            superProjectBranch, BranchNameKey.create(projectKey, branch), path);
       }
     } catch (URISyntaxException e) {
       // Error in url syntax (in fact it is uri syntax)
diff --git a/java/com/google/gerrit/testing/TestChanges.java b/java/com/google/gerrit/testing/TestChanges.java
index 20948d6..da967b5 100644
--- a/java/com/google/gerrit/testing/TestChanges.java
+++ b/java/com/google/gerrit/testing/TestChanges.java
@@ -19,7 +19,7 @@
 import com.google.common.collect.Ordering;
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.PatchSetInfo;
@@ -58,7 +58,7 @@
             Change.key("Iabcd1234abcd1234abcd1234abcd1234abcd1234"),
             changeId,
             userId,
-            Branch.nameKey(project, "master"),
+            BranchNameKey.create(project, "master"),
             TimeUtil.nowTs());
     incrementPatchSet(c);
     return c;
diff --git a/java/gerrit/PRED_change_branch_1.java b/java/gerrit/PRED_change_branch_1.java
index d0a1e47..aef00f2 100644
--- a/java/gerrit/PRED_change_branch_1.java
+++ b/java/gerrit/PRED_change_branch_1.java
@@ -14,7 +14,7 @@
 
 package gerrit;
 
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.server.rules.StoredValues;
 import com.googlecode.prolog_cafe.exceptions.PrologException;
 import com.googlecode.prolog_cafe.lang.Operation;
@@ -34,7 +34,7 @@
     engine.setB0();
     Term a1 = arg1.dereference();
 
-    Branch.NameKey name = StoredValues.getChange(engine).getDest();
+    BranchNameKey name = StoredValues.getChange(engine).getDest();
 
     if (!a1.unify(SymbolTerm.create(name.branch()), engine.trail)) {
       return engine.fail();
diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
index 76befff..a375c31 100644
--- a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
@@ -104,7 +104,7 @@
 import com.google.gerrit.mail.Address;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
@@ -2692,7 +2692,7 @@
   @Test
   public void deleteDraftCommentsSkipsInvisibleChanges() throws Exception {
     try {
-      createBranch(Branch.nameKey(project, "secret"));
+      createBranch(BranchNameKey.create(project, "secret"));
       PushOneCommit.Result r1 = createChange();
       PushOneCommit.Result r2 = createChange("refs/for/secret");
 
diff --git a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
index 52bfa6f..4b06349 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -136,7 +136,7 @@
 import com.google.gerrit.mail.Address;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
@@ -4244,7 +4244,7 @@
   }
 
   private BranchApi createBranch(String branch) throws Exception {
-    return createBranch(Branch.nameKey(project, branch));
+    return createBranch(BranchNameKey.create(project, branch));
   }
 
   private ThrowableSubject assertThatQueryException(String query) throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/api/project/CommitIncludedInIT.java b/javatests/com/google/gerrit/acceptance/api/project/CommitIncludedInIT.java
index 7009411..54aa192 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/CommitIncludedInIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/CommitIncludedInIT.java
@@ -24,7 +24,7 @@
 import com.google.gerrit.extensions.api.changes.IncludedInInfo;
 import com.google.gerrit.extensions.api.changes.ReviewInput;
 import com.google.gerrit.extensions.api.projects.TagInput;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import org.eclipse.jgit.lib.ObjectId;
 import org.junit.Test;
 
@@ -54,7 +54,7 @@
 
     assertThat(getIncludedIn(result.getCommit().getId()).tags).containsExactly("test-tag");
 
-    createBranch(Branch.nameKey(project, "test-branch"));
+    createBranch(BranchNameKey.create(project, "test-branch"));
 
     assertThat(getIncludedIn(result.getCommit().getId()).branches)
         .containsExactly("master", "test-branch");
diff --git a/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java b/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java
index 9e91245..f58294b 100644
--- a/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java
@@ -83,7 +83,7 @@
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.extensions.webui.PatchSetWebLink;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSetApproval;
 import com.google.gerrit.server.change.RevisionResource;
@@ -627,7 +627,7 @@
         createCherryPickableMerge(parent1FileName, parent2FileName);
 
     String cherryPickBranchName = "branch_for_cherry_pick";
-    createBranch(Branch.nameKey(project, cherryPickBranchName));
+    createBranch(BranchNameKey.create(project, cherryPickBranchName));
 
     CherryPickInput cherryPickInput = new CherryPickInput();
     cherryPickInput.destination = cherryPickBranchName;
@@ -654,7 +654,7 @@
         createCherryPickableMerge(parent1FileName, parent2FileName);
 
     String cherryPickBranchName = "branch_for_cherry_pick";
-    createBranch(Branch.nameKey(project, cherryPickBranchName));
+    createBranch(BranchNameKey.create(project, cherryPickBranchName));
 
     CherryPickInput cherryPickInput = new CherryPickInput();
     cherryPickInput.destination = cherryPickBranchName;
@@ -682,7 +682,7 @@
         createCherryPickableMerge(parent1FileName, parent2FileName);
 
     String cherryPickBranchName = "branch_for_cherry_pick";
-    createBranch(Branch.nameKey(project, cherryPickBranchName));
+    createBranch(BranchNameKey.create(project, cherryPickBranchName));
 
     CherryPickInput cherryPickInput = new CherryPickInput();
     cherryPickInput.destination = cherryPickBranchName;
@@ -703,7 +703,7 @@
         createCherryPickableMerge(parent1FileName, parent2FileName);
 
     String cherryPickBranchName = "branch_for_cherry_pick";
-    createBranch(Branch.nameKey(project, cherryPickBranchName));
+    createBranch(BranchNameKey.create(project, cherryPickBranchName));
 
     CherryPickInput cherryPickInput = new CherryPickInput();
     cherryPickInput.destination = cherryPickBranchName;
@@ -718,9 +718,9 @@
 
   @Test
   public void cherryPickNotify() throws Exception {
-    createBranch(Branch.nameKey(project, "branch-1"));
-    createBranch(Branch.nameKey(project, "branch-2"));
-    createBranch(Branch.nameKey(project, "branch-3"));
+    createBranch(BranchNameKey.create(project, "branch-1"));
+    createBranch(BranchNameKey.create(project, "branch-2"));
+    createBranch(BranchNameKey.create(project, "branch-3"));
 
     // Creates a change for 'admin'.
     PushOneCommit.Result result = createChange();
@@ -759,7 +759,7 @@
 
   @Test
   public void cherryPickKeepReviewers() throws Exception {
-    createBranch(Branch.nameKey(project, "stable"));
+    createBranch(BranchNameKey.create(project, "stable"));
 
     // Change is created by 'admin'.
     PushOneCommit.Result r = createChange();
@@ -793,7 +793,7 @@
 
   @Test
   public void cherryPickToMergedChangeRevision() throws Exception {
-    createBranch(Branch.nameKey(project, "foo"));
+    createBranch(BranchNameKey.create(project, "foo"));
 
     PushOneCommit.Result dstChange = createChange(testRepo, "foo", SUBJECT, "b.txt", "b", "t");
     dstChange.assertOkStatus();
@@ -817,7 +817,7 @@
 
   @Test
   public void cherryPickToOpenChangeRevision() throws Exception {
-    createBranch(Branch.nameKey(project, "foo"));
+    createBranch(BranchNameKey.create(project, "foo"));
 
     PushOneCommit.Result dstChange = createChange(testRepo, "foo", SUBJECT, "b.txt", "b", "t");
     dstChange.assertOkStatus();
@@ -835,7 +835,7 @@
 
   @Test
   public void cherryPickToNonVisibleChangeFails() throws Exception {
-    createBranch(Branch.nameKey(project, "foo"));
+    createBranch(BranchNameKey.create(project, "foo"));
 
     PushOneCommit.Result dstChange = createChange(testRepo, "foo", SUBJECT, "b.txt", "b", "t");
     dstChange.assertOkStatus();
@@ -1525,9 +1525,9 @@
     RevCommit initialCommit = getHead(repo(), "HEAD");
 
     String branchAName = "branchA";
-    createBranch(Branch.nameKey(project, branchAName));
+    createBranch(BranchNameKey.create(project, branchAName));
     String branchBName = "branchB";
-    createBranch(Branch.nameKey(project, branchBName));
+    createBranch(BranchNameKey.create(project, branchBName));
 
     PushOneCommit.Result changeAResult =
         pushFactory
diff --git a/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java b/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
index 8a86380..2cdce4d 100644
--- a/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
@@ -24,7 +24,7 @@
 import com.google.gerrit.extensions.api.changes.ReviewInput;
 import com.google.gerrit.extensions.client.ChangeStatus;
 import com.google.gerrit.extensions.client.SubmitType;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.change.TestSubmitInput;
 import com.google.gerrit.testing.ConfigSuite;
@@ -136,7 +136,7 @@
     gApi.changes().id(id2).current().review(ReviewInput.approve());
     gApi.changes().id(id3).current().review(ReviewInput.approve());
 
-    Map<Branch.NameKey, ObjectId> preview = fetchFromSubmitPreview(id1);
+    Map<BranchNameKey, ObjectId> preview = fetchFromSubmitPreview(id1);
     gApi.changes().id(id1).current().submit();
     ObjectId subRepoId =
         subRepo
@@ -152,8 +152,8 @@
     // As the submodules have changed commits, the superproject tree will be
     // different, so we cannot directly compare the trees here, so make
     // assumptions only about the changed branches:
-    assertThat(preview).containsKey(Branch.nameKey(superKey, "refs/heads/master"));
-    assertThat(preview).containsKey(Branch.nameKey(subKey, "refs/heads/master"));
+    assertThat(preview).containsKey(BranchNameKey.create(superKey, "refs/heads/master"));
+    assertThat(preview).containsKey(BranchNameKey.create(subKey, "refs/heads/master"));
 
     if ((getSubmitType() == SubmitType.CHERRY_PICK)
         || (getSubmitType() == SubmitType.REBASE_ALWAYS)) {
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
index 474d75f..ba09299 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
@@ -62,7 +62,7 @@
 import com.google.gerrit.extensions.webui.UiAction;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.PatchSetApproval;
@@ -153,7 +153,7 @@
     assertThat(projectOperations.project(project).hasHead("master")).isFalse();
     PushOneCommit.Result change = createChange();
     assertThat(change.getCommit().getParents()).isEmpty();
-    Map<Branch.NameKey, ObjectId> actual = fetchFromSubmitPreview(change.getChangeId());
+    Map<BranchNameKey, ObjectId> actual = fetchFromSubmitPreview(change.getChangeId());
     assertThat(projectOperations.project(project).hasHead("master")).isFalse();
     assertThat(actual).hasSize(1);
 
@@ -166,7 +166,7 @@
   public void submitSingleChange() throws Exception {
     RevCommit initialHead = getRemoteHead();
     PushOneCommit.Result change = createChange();
-    Map<Branch.NameKey, ObjectId> actual = fetchFromSubmitPreview(change.getChangeId());
+    Map<BranchNameKey, ObjectId> actual = fetchFromSubmitPreview(change.getChangeId());
     RevCommit headAfterSubmit = getRemoteHead();
     assertThat(headAfterSubmit).isEqualTo(initialHead);
     assertRefUpdatedEvents();
@@ -276,12 +276,12 @@
     PushOneCommit.Result change4 = createChange("Change 4", "e", "e");
     // change 2 is not approved, but we ignore labels
     approve(change3.getChangeId());
-    Map<Branch.NameKey, ObjectId> actual = fetchFromSubmitPreview(change4.getChangeId());
+    Map<BranchNameKey, ObjectId> actual = fetchFromSubmitPreview(change4.getChangeId());
     Map<String, Map<String, Integer>> expected = new HashMap<>();
     expected.put(project.get(), new HashMap<>());
     expected.get(project.get()).put("refs/heads/master", 3);
 
-    assertThat(actual).containsKey(Branch.nameKey(project, "refs/heads/master"));
+    assertThat(actual).containsKey(BranchNameKey.create(project, "refs/heads/master"));
     if (getSubmitType() == SubmitType.CHERRY_PICK) {
       // CherryPick ignores dependencies, thus only change and destination
       // branch refs are modified.
@@ -546,7 +546,7 @@
     PushOneCommit.Result visible = createChange("refs/for/master/" + name("topic"));
     Change.Id num = visible.getChange().getId();
 
-    createBranch(Branch.nameKey(project, "hidden"));
+    createBranch(BranchNameKey.create(project, "hidden"));
     PushOneCommit.Result hidden = createChange("refs/for/hidden/" + name("topic"));
     approve(hidden.getChangeId());
     blockRead("refs/heads/hidden");
@@ -1065,7 +1065,7 @@
     assertThat(projectOperations.project(project).hasHead("master")).isFalse();
     PushOneCommit.Result change = createChange();
     assertThat(change.getCommit().getParents()).isEmpty();
-    Map<Branch.NameKey, ObjectId> actual = fetchFromSubmitPreview(change.getChangeId());
+    Map<BranchNameKey, ObjectId> actual = fetchFromSubmitPreview(change.getChangeId());
     assertThat(projectOperations.project(project).hasHead("master")).isFalse();
     assertThat(actual).hasSize(1);
 
@@ -1087,7 +1087,7 @@
     assertThat(change.getCommit().getTree())
         .isEqualTo(ObjectId.fromString("4b825dc642cb6eb9a060e54bf8d69288fbee4904"));
 
-    Map<Branch.NameKey, ObjectId> actual = fetchFromSubmitPreview(change.getChangeId());
+    Map<BranchNameKey, ObjectId> actual = fetchFromSubmitPreview(change.getChangeId());
     assertThat(projectOperations.project(project).hasHead("master")).isFalse();
     assertThat(actual).hasSize(1);
 
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByRebase.java b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByRebase.java
index 7ee4e56..c577e09 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByRebase.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByRebase.java
@@ -29,7 +29,7 @@
 import com.google.gerrit.extensions.client.InheritableBoolean;
 import com.google.gerrit.extensions.client.SubmitType;
 import com.google.gerrit.extensions.common.ChangeInfo;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.project.testing.Util;
 import com.google.inject.Inject;
@@ -287,7 +287,7 @@
     PushOneCommit.Result change2 = createChange();
     approve(change2.getChangeId());
     Project.NameKey project = change2.getChange().change().getProject();
-    Branch.NameKey branch = Branch.nameKey(project, "branch");
+    BranchNameKey branch = BranchNameKey.create(project, "branch");
     createBranchWithRevision(branch, change2.getCommit().getName());
     gApi.changes().id(change2.getChangeId()).current().submit();
     assertMerged(change2.getChangeId());
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/ChangeIncludedInIT.java b/javatests/com/google/gerrit/acceptance/rest/change/ChangeIncludedInIT.java
index d7d359e..f05d4dc 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/ChangeIncludedInIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/ChangeIncludedInIT.java
@@ -23,7 +23,7 @@
 import com.google.gerrit.common.data.Permission;
 import com.google.gerrit.extensions.api.changes.ReviewInput;
 import com.google.gerrit.extensions.api.projects.TagInput;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import org.junit.Test;
 
 @NoHttpd
@@ -55,7 +55,7 @@
     assertThat(gApi.changes().id(result.getChangeId()).includedIn().tags)
         .containsExactly("test-tag");
 
-    createBranch(Branch.nameKey(project, "test-branch"));
+    createBranch(BranchNameKey.create(project, "test-branch"));
 
     assertThat(gApi.changes().id(result.getChangeId()).includedIn().branches)
         .containsExactly("master", "test-branch");
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/CreateChangeIT.java b/javatests/com/google/gerrit/acceptance/rest/change/CreateChangeIT.java
index 72eca40..d94b02f 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/CreateChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/CreateChangeIT.java
@@ -46,7 +46,7 @@
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.submit.ChangeAlreadyMergedException;
@@ -449,7 +449,7 @@
 
   @Test
   public void createChangeOnExistingBranchNotPermitted() throws Exception {
-    createBranch(Branch.nameKey(project, "foo"));
+    createBranch(BranchNameKey.create(project, "foo"));
     blockRead("refs/heads/*");
     requestScopeOperations.setApiUser(user.id());
     ChangeInput input = newChangeInput(ChangeStatus.NEW);
@@ -568,8 +568,8 @@
     initialCommit.assertOkStatus();
 
     // create two new branches
-    createBranch(Branch.nameKey(project, branchA));
-    createBranch(Branch.nameKey(project, branchB));
+    createBranch(BranchNameKey.create(project, branchA));
+    createBranch(BranchNameKey.create(project, branchB));
 
     // create a commit in branchA
     Result changeA =
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/MoveChangeIT.java b/javatests/com/google/gerrit/acceptance/rest/change/MoveChangeIT.java
index 2dc2658..f2a3952 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/MoveChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/MoveChangeIT.java
@@ -36,7 +36,7 @@
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.server.group.SystemGroupBackend;
 import com.google.gerrit.server.project.testing.Util;
 import com.google.inject.Inject;
@@ -54,7 +54,7 @@
   public void moveChangeWithShortRef() throws Exception {
     // Move change to a different branch using short ref name
     PushOneCommit.Result r = createChange();
-    Branch.NameKey newBranch = Branch.nameKey(r.getChange().change().getProject(), "moveTest");
+    BranchNameKey newBranch = BranchNameKey.create(r.getChange().change().getProject(), "moveTest");
     createBranch(newBranch);
     move(r.getChangeId(), newBranch.shortName());
     assertThat(r.getChange().change().getDest()).isEqualTo(newBranch);
@@ -64,7 +64,7 @@
   public void moveChangeWithFullRef() throws Exception {
     // Move change to a different branch using full ref name
     PushOneCommit.Result r = createChange();
-    Branch.NameKey newBranch = Branch.nameKey(r.getChange().change().getProject(), "moveTest");
+    BranchNameKey newBranch = BranchNameKey.create(r.getChange().change().getProject(), "moveTest");
     createBranch(newBranch);
     move(r.getChangeId(), newBranch.branch());
     assertThat(r.getChange().change().getDest()).isEqualTo(newBranch);
@@ -74,7 +74,7 @@
   public void moveChangeWithMessage() throws Exception {
     // Provide a message using --message flag
     PushOneCommit.Result r = createChange();
-    Branch.NameKey newBranch = Branch.nameKey(r.getChange().change().getProject(), "moveTest");
+    BranchNameKey newBranch = BranchNameKey.create(r.getChange().change().getProject(), "moveTest");
     createBranch(newBranch);
     String moveMessage = "Moving for the move test";
     move(r.getChangeId(), newBranch.branch(), moveMessage);
@@ -99,7 +99,7 @@
   public void moveChangeToSameChangeId() throws Exception {
     // Move change to a branch with existing change with same change ID
     PushOneCommit.Result r = createChange();
-    Branch.NameKey newBranch = Branch.nameKey(r.getChange().change().getProject(), "moveTest");
+    BranchNameKey newBranch = BranchNameKey.create(r.getChange().change().getProject(), "moveTest");
     createBranch(newBranch);
     int changeNum = r.getChange().change().getChangeId();
     createChange(newBranch.branch(), r.getChangeId());
@@ -116,8 +116,8 @@
   public void moveChangeToNonExistentRef() throws Exception {
     // Move change to a non-existing branch
     PushOneCommit.Result r = createChange();
-    Branch.NameKey newBranch =
-        Branch.nameKey(r.getChange().change().getProject(), "does_not_exist");
+    BranchNameKey newBranch =
+        BranchNameKey.create(r.getChange().change().getProject(), "does_not_exist");
     exception.expect(ResourceConflictException.class);
     exception.expectMessage("Destination " + newBranch.branch() + " not found in the project");
     move(r.getChangeId(), newBranch.branch());
@@ -127,7 +127,7 @@
   public void moveClosedChange() throws Exception {
     // Move a change which is not open
     PushOneCommit.Result r = createChange();
-    Branch.NameKey newBranch = Branch.nameKey(r.getChange().change().getProject(), "moveTest");
+    BranchNameKey newBranch = BranchNameKey.create(r.getChange().change().getProject(), "moveTest");
     createBranch(newBranch);
     merge(r);
     exception.expect(ResourceConflictException.class);
@@ -153,7 +153,8 @@
     pushHead(testRepo, "refs/for/master", false, false);
 
     // Try to move the merge commit to another branch
-    Branch.NameKey newBranch = Branch.nameKey(r1.getChange().change().getProject(), "moveTest");
+    BranchNameKey newBranch =
+        BranchNameKey.create(r1.getChange().change().getProject(), "moveTest");
     createBranch(newBranch);
     exception.expect(ResourceConflictException.class);
     exception.expectMessage("Merge commit cannot be moved");
@@ -164,8 +165,8 @@
   public void moveChangeToBranchWithoutUploadPerms() throws Exception {
     // Move change to a destination where user doesn't have upload permissions
     PushOneCommit.Result r = createChange();
-    Branch.NameKey newBranch =
-        Branch.nameKey(r.getChange().change().getProject(), "blocked_branch");
+    BranchNameKey newBranch =
+        BranchNameKey.create(r.getChange().change().getProject(), "blocked_branch");
     createBranch(newBranch);
     block(
         "refs/for/" + newBranch.branch(),
@@ -180,7 +181,7 @@
   public void moveChangeFromBranchWithoutAbandonPerms() throws Exception {
     // Move change for which user does not have abandon permissions
     PushOneCommit.Result r = createChange();
-    Branch.NameKey newBranch = Branch.nameKey(r.getChange().change().getProject(), "moveTest");
+    BranchNameKey newBranch = BranchNameKey.create(r.getChange().change().getProject(), "moveTest");
     createBranch(newBranch);
     block(
         r.getChange().change().getDest().branch(),
@@ -202,7 +203,7 @@
     int changeNum = r.getChange().change().getChangeId();
 
     // Create a branch with that same commit
-    Branch.NameKey newBranch = Branch.nameKey(r.getChange().change().getProject(), "moveTest");
+    BranchNameKey newBranch = BranchNameKey.create(r.getChange().change().getProject(), "moveTest");
     BranchInput bi = new BranchInput();
     bi.revision = r.getCommit().name();
     gApi.projects().name(newBranch.project().get()).branch(newBranch.branch()).create(bi);
@@ -218,7 +219,7 @@
   public void moveChangeWithCurrentPatchSetLocked() throws Exception {
     // Move change that is locked
     PushOneCommit.Result r = createChange();
-    Branch.NameKey newBranch = Branch.nameKey(r.getChange().change().getProject(), "moveTest");
+    BranchNameKey newBranch = BranchNameKey.create(r.getChange().change().getProject(), "moveTest");
     createBranch(newBranch);
 
     try (ProjectConfigUpdate u = updateProject(project)) {
@@ -247,7 +248,7 @@
   public void moveChangeOnlyKeepVetoVotes() throws Exception {
     // A vote for a label will be kept after moving if the label's function is *WithBlock and the
     // vote holds the minimum value.
-    createBranch(Branch.nameKey(project, "foo"));
+    createBranch(BranchNameKey.create(project, "foo"));
 
     String codeReviewLabel = "Code-Review"; // 'Code-Review' uses 'MaxWithBlock' function.
     String testLabelA = "Label-A";
@@ -302,7 +303,7 @@
 
   @Test
   public void moveToBranchWithoutLabel() throws Exception {
-    createBranch(Branch.nameKey(project, "foo"));
+    createBranch(BranchNameKey.create(project, "foo"));
     String testLabelA = "Label-A";
     configLabel(testLabelA, LabelFunction.MAX_WITH_BLOCK, Arrays.asList("refs/heads/master"));
 
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
index 8ee632f..f43b73b 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
@@ -33,7 +33,7 @@
 import com.google.gerrit.extensions.restapi.BinaryResult;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.inject.Inject;
@@ -180,7 +180,7 @@
     approve(change3.getChangeId());
 
     // get a preview before submitting:
-    Map<Branch.NameKey, ObjectId> preview = fetchFromSubmitPreview(change1b.getChangeId());
+    Map<BranchNameKey, ObjectId> preview = fetchFromSubmitPreview(change1b.getChangeId());
     submit(change1b.getChangeId());
 
     RevCommit tip1 = getRemoteLog(p1, "master").get(0);
@@ -196,19 +196,19 @@
       // check that the preview matched what happened:
       assertThat(preview).hasSize(3);
 
-      assertThat(preview).containsKey(Branch.nameKey(p1, "refs/heads/master"));
+      assertThat(preview).containsKey(BranchNameKey.create(p1, "refs/heads/master"));
       assertTrees(p1, preview);
 
-      assertThat(preview).containsKey(Branch.nameKey(p2, "refs/heads/master"));
+      assertThat(preview).containsKey(BranchNameKey.create(p2, "refs/heads/master"));
       assertTrees(p2, preview);
 
-      assertThat(preview).containsKey(Branch.nameKey(p3, "refs/heads/master"));
+      assertThat(preview).containsKey(BranchNameKey.create(p3, "refs/heads/master"));
       assertTrees(p3, preview);
     } else {
       assertThat(tip2.getShortMessage()).isEqualTo(initialHead2.getShortMessage());
       assertThat(tip3.getShortMessage()).isEqualTo(initialHead3.getShortMessage());
       assertThat(preview).hasSize(1);
-      assertThat(preview.get(Branch.nameKey(p1, "refs/heads/master"))).isNotNull();
+      assertThat(preview.get(BranchNameKey.create(p1, "refs/heads/master"))).isNotNull();
     }
   }
 
@@ -624,7 +624,7 @@
 
     // Move the first change to a destination branch that is non-visible to user so that user cannot
     // this change anymore.
-    Branch.NameKey secretBranch = Branch.nameKey(project, "secretBranch");
+    BranchNameKey secretBranch = BranchNameKey.create(project, "secretBranch");
     gApi.projects()
         .name(secretBranch.project().get())
         .branch(secretBranch.branch())
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/CheckMergeabilityIT.java b/javatests/com/google/gerrit/acceptance/rest/project/CheckMergeabilityIT.java
index e2244f7..10e3e99 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/CheckMergeabilityIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/CheckMergeabilityIT.java
@@ -25,7 +25,7 @@
 import com.google.gerrit.extensions.api.changes.ReviewInput;
 import com.google.gerrit.extensions.api.projects.BranchInput;
 import com.google.gerrit.extensions.common.MergeableInfo;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.transport.RefSpec;
@@ -34,11 +34,11 @@
 
 public class CheckMergeabilityIT extends AbstractDaemonTest {
 
-  private Branch.NameKey branch;
+  private BranchNameKey branch;
 
   @Before
   public void setUp() throws Exception {
-    branch = Branch.nameKey(project, "test");
+    branch = BranchNameKey.create(project, "test");
     gApi.projects().name(branch.project().get()).branch(branch.branch()).create(new BranchInput());
   }
 
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java b/javatests/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java
index 9214ce2..7ebf96b 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java
@@ -32,7 +32,7 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.inject.Inject;
 import org.junit.Before;
@@ -41,11 +41,11 @@
 public class CreateBranchIT extends AbstractDaemonTest {
   @Inject private RequestScopeOperations requestScopeOperations;
 
-  private Branch.NameKey testBranch;
+  private BranchNameKey testBranch;
 
   @Before
   public void setUp() throws Exception {
-    testBranch = Branch.nameKey(project, "test");
+    testBranch = BranchNameKey.create(project, "test");
   }
 
   @Test
@@ -104,7 +104,7 @@
     String metaRef = RefNames.REFS_META + "foo";
     allow(metaRef, Permission.CREATE, REGISTERED_USERS);
     allow(metaRef, Permission.PUSH, REGISTERED_USERS);
-    assertCreateSucceeds(Branch.nameKey(project, metaRef));
+    assertCreateSucceeds(BranchNameKey.create(project, metaRef));
   }
 
   @Test
@@ -112,7 +112,7 @@
     allow(allUsers, RefNames.REFS_USERS + "*", Permission.CREATE, REGISTERED_USERS);
     allow(allUsers, RefNames.REFS_USERS + "*", Permission.PUSH, REGISTERED_USERS);
     assertCreateFails(
-        Branch.nameKey(allUsers, RefNames.refsUsers(Account.id(1))),
+        BranchNameKey.create(allUsers, RefNames.refsUsers(Account.id(1))),
         RefNames.refsUsers(admin.id()),
         ResourceConflictException.class,
         "Not allowed to create user branch.");
@@ -123,7 +123,7 @@
     allow(allUsers, RefNames.REFS_GROUPS + "*", Permission.CREATE, REGISTERED_USERS);
     allow(allUsers, RefNames.REFS_GROUPS + "*", Permission.PUSH, REGISTERED_USERS);
     assertCreateFails(
-        Branch.nameKey(allUsers, RefNames.refsGroups(AccountGroup.uuid("foo"))),
+        BranchNameKey.create(allUsers, RefNames.refsGroups(AccountGroup.uuid("foo"))),
         RefNames.refsGroups(adminGroupUuid()),
         ResourceConflictException.class,
         "Not allowed to create group branch.");
@@ -137,23 +137,23 @@
     allow("refs/*", Permission.OWNER, REGISTERED_USERS);
   }
 
-  private BranchApi branch(Branch.NameKey branch) throws Exception {
+  private BranchApi branch(BranchNameKey branch) throws Exception {
     return gApi.projects().name(branch.project().get()).branch(branch.branch());
   }
 
-  private void assertCreateSucceeds(Branch.NameKey branch) throws Exception {
+  private void assertCreateSucceeds(BranchNameKey branch) throws Exception {
     BranchInfo created = branch(branch).create(new BranchInput()).get();
     assertThat(created.ref).isEqualTo(branch.branch());
   }
 
   private void assertCreateFails(
-      Branch.NameKey branch, Class<? extends RestApiException> errType, String errMsg)
+      BranchNameKey branch, Class<? extends RestApiException> errType, String errMsg)
       throws Exception {
     assertCreateFails(branch, null, errType, errMsg);
   }
 
   private void assertCreateFails(
-      Branch.NameKey branch,
+      BranchNameKey branch,
       String revision,
       Class<? extends RestApiException> errType,
       String errMsg)
@@ -167,7 +167,7 @@
     branch(branch).create(in);
   }
 
-  private void assertCreateFails(Branch.NameKey branch, Class<? extends RestApiException> errType)
+  private void assertCreateFails(BranchNameKey branch, Class<? extends RestApiException> errType)
       throws Exception {
     assertCreateFails(branch, errType, null);
   }
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java b/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java
index a5fd830..557ffe7 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java
@@ -30,7 +30,7 @@
 import com.google.gerrit.extensions.restapi.IdString;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.inject.Inject;
 import org.junit.Before;
@@ -40,12 +40,12 @@
   @Inject private ProjectOperations projectOperations;
   @Inject private RequestScopeOperations requestScopeOperations;
 
-  private Branch.NameKey testBranch;
+  private BranchNameKey testBranch;
 
   @Before
   public void setUp() throws Exception {
     project = projectOperations.newProject().create();
-    testBranch = Branch.nameKey(project, "test");
+    testBranch = BranchNameKey.create(project, "test");
     branch(testBranch).create(new BranchInput());
   }
 
@@ -124,7 +124,7 @@
     allow(metaRef, Permission.CREATE, REGISTERED_USERS);
     allow(metaRef, Permission.PUSH, REGISTERED_USERS);
 
-    Branch.NameKey metaBranch = Branch.nameKey(project, metaRef);
+    BranchNameKey metaBranch = BranchNameKey.create(project, metaRef);
     branch(metaBranch).create(new BranchInput());
 
     grantDelete();
@@ -138,7 +138,7 @@
 
     exception.expect(ResourceConflictException.class);
     exception.expectMessage("Not allowed to delete user branch.");
-    branch(Branch.nameKey(allUsers, RefNames.refsUsers(admin.id()))).delete();
+    branch(BranchNameKey.create(allUsers, RefNames.refsUsers(admin.id()))).delete();
   }
 
   @Test
@@ -148,7 +148,7 @@
 
     exception.expect(ResourceConflictException.class);
     exception.expectMessage("Not allowed to delete group branch.");
-    branch(Branch.nameKey(allUsers, RefNames.refsGroups(adminGroupUuid()))).delete();
+    branch(BranchNameKey.create(allUsers, RefNames.refsGroups(adminGroupUuid()))).delete();
   }
 
   private void blockForcePush() throws Exception {
@@ -167,11 +167,11 @@
     allow("refs/*", Permission.OWNER, REGISTERED_USERS);
   }
 
-  private BranchApi branch(Branch.NameKey branch) throws Exception {
+  private BranchApi branch(BranchNameKey branch) throws Exception {
     return gApi.projects().name(branch.project().get()).branch(branch.branch());
   }
 
-  private void assertDeleteByRestSucceeds(Branch.NameKey branch, String ref) throws Exception {
+  private void assertDeleteByRestSucceeds(BranchNameKey branch, String ref) throws Exception {
     RestResponse r =
         userRestSession.delete(
             "/projects/"
@@ -183,7 +183,7 @@
     branch(branch).get();
   }
 
-  private void assertDeleteSucceeds(Branch.NameKey branch) throws Exception {
+  private void assertDeleteSucceeds(BranchNameKey branch) throws Exception {
     assertThat(branch(branch).get().canDelete).isTrue();
     String branchRev = branch(branch).get().revision;
     branch(branch).delete();
@@ -193,7 +193,7 @@
     branch(branch).get();
   }
 
-  private void assertDeleteForbidden(Branch.NameKey branch) throws Exception {
+  private void assertDeleteForbidden(BranchNameKey branch) throws Exception {
     assertThat(branch(branch).get().canDelete).isNull();
     exception.expect(AuthException.class);
     exception.expectMessage("not permitted: delete");
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/FileBranchIT.java b/javatests/com/google/gerrit/acceptance/rest/project/FileBranchIT.java
index 637b310..ad8cf03 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/FileBranchIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/FileBranchIT.java
@@ -22,18 +22,18 @@
 import com.google.gerrit.extensions.api.projects.BranchApi;
 import com.google.gerrit.extensions.restapi.BinaryResult;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import org.junit.Before;
 import org.junit.Test;
 
 @NoHttpd
 public class FileBranchIT extends AbstractDaemonTest {
 
-  private Branch.NameKey branch;
+  private BranchNameKey branch;
 
   @Before
   public void setUp() throws Exception {
-    branch = Branch.nameKey(project, "master");
+    branch = BranchNameKey.create(project, "master");
     PushOneCommit.Result change = createChange();
     approve(change.getChangeId());
     revision(change).submit();
diff --git a/javatests/com/google/gerrit/acceptance/server/permissions/PermissionBackendConditionIT.java b/javatests/com/google/gerrit/acceptance/server/permissions/PermissionBackendConditionIT.java
index 6a00675..bea3633 100644
--- a/javatests/com/google/gerrit/acceptance/server/permissions/PermissionBackendConditionIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/permissions/PermissionBackendConditionIT.java
@@ -20,7 +20,7 @@
 import com.google.gerrit.acceptance.AbstractDaemonTest;
 import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
 import com.google.gerrit.extensions.conditions.BooleanCondition;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.permissions.ChangePermission;
@@ -122,7 +122,7 @@
 
   @Test
   public void refPermissions_sameResourceAndUserEquals() throws Exception {
-    Branch.NameKey branch = Branch.nameKey(project, "branch");
+    BranchNameKey branch = BranchNameKey.create(project, "branch");
     BooleanCondition cond1 = pb.user(user()).ref(branch).testCond(RefPermission.READ);
     BooleanCondition cond2 = pb.user(user()).ref(branch).testCond(RefPermission.READ);
 
@@ -132,7 +132,7 @@
 
   @Test
   public void refPermissions_sameResourceAndDifferentUserDoesNotEqual() throws Exception {
-    Branch.NameKey branch = Branch.nameKey(project, "branch");
+    BranchNameKey branch = BranchNameKey.create(project, "branch");
     BooleanCondition cond1 = pb.user(user()).ref(branch).testCond(RefPermission.READ);
     BooleanCondition cond2 = pb.user(admin()).ref(branch).testCond(RefPermission.READ);
 
@@ -142,8 +142,8 @@
 
   @Test
   public void refPermissions_differentResourceAndSameUserDoesNotEqual() throws Exception {
-    Branch.NameKey branch1 = Branch.nameKey(project, "branch");
-    Branch.NameKey branch2 = Branch.nameKey(project, "branch2");
+    BranchNameKey branch1 = BranchNameKey.create(project, "branch");
+    BranchNameKey branch2 = BranchNameKey.create(project, "branch2");
     BooleanCondition cond1 = pb.user(user()).ref(branch1).testCond(RefPermission.READ);
     BooleanCondition cond2 = pb.user(user()).ref(branch2).testCond(RefPermission.READ);
 
@@ -153,8 +153,8 @@
 
   @Test
   public void refPermissions_differentResourceAndSameUserDoesNotEqual2() throws Exception {
-    Branch.NameKey branch1 = Branch.nameKey(project, "branch");
-    Branch.NameKey branch2 = Branch.nameKey(projectOperations.newProject().create(), "branch");
+    BranchNameKey branch1 = BranchNameKey.create(project, "branch");
+    BranchNameKey branch2 = BranchNameKey.create(projectOperations.newProject().create(), "branch");
     BooleanCondition cond1 = pb.user(user()).ref(branch1).testCond(RefPermission.READ);
     BooleanCondition cond2 = pb.user(user()).ref(branch2).testCond(RefPermission.READ);
 
diff --git a/javatests/com/google/gerrit/reviewdb/client/BranchTest.java b/javatests/com/google/gerrit/reviewdb/client/BranchTest.java
index 334e7ac..ac99a1a 100644
--- a/javatests/com/google/gerrit/reviewdb/client/BranchTest.java
+++ b/javatests/com/google/gerrit/reviewdb/client/BranchTest.java
@@ -21,19 +21,19 @@
 public class BranchTest {
   @Test
   public void canonicalizeNameDuringConstruction() {
-    assertThat(Branch.nameKey(new Project.NameKey("foo"), "bar").branch())
+    assertThat(BranchNameKey.create(new Project.NameKey("foo"), "bar").branch())
         .isEqualTo("refs/heads/bar");
-    assertThat(Branch.nameKey(new Project.NameKey("foo"), "refs/heads/bar").branch())
+    assertThat(BranchNameKey.create(new Project.NameKey("foo"), "refs/heads/bar").branch())
         .isEqualTo("refs/heads/bar");
   }
 
   @Test
   public void idToString() {
-    assertThat(Branch.nameKey(new Project.NameKey("foo"), "bar").toString())
+    assertThat(BranchNameKey.create(new Project.NameKey("foo"), "bar").toString())
         .isEqualTo("foo,refs/heads/bar");
-    assertThat(Branch.nameKey(new Project.NameKey("foo bar"), "bar baz").toString())
+    assertThat(BranchNameKey.create(new Project.NameKey("foo bar"), "bar baz").toString())
         .isEqualTo("foo+bar,refs/heads/bar+baz");
-    assertThat(Branch.nameKey(new Project.NameKey("foo^bar"), "bar^baz").toString())
+    assertThat(BranchNameKey.create(new Project.NameKey("foo^bar"), "bar^baz").toString())
         .isEqualTo("foo%5Ebar,refs/heads/bar%5Ebaz");
   }
 }
diff --git a/javatests/com/google/gerrit/reviewdb/converter/BranchNameKeyProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/BranchNameKeyProtoConverterTest.java
index 0e62a6b..2f6bb61 100644
--- a/javatests/com/google/gerrit/reviewdb/converter/BranchNameKeyProtoConverterTest.java
+++ b/javatests/com/google/gerrit/reviewdb/converter/BranchNameKeyProtoConverterTest.java
@@ -21,7 +21,7 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.gerrit.proto.Entities;
 import com.google.gerrit.proto.testing.SerializedClassSubject;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.protobuf.Parser;
 import java.lang.reflect.Type;
@@ -33,7 +33,7 @@
 
   @Test
   public void allValuesConvertedToProto() {
-    Branch.NameKey nameKey = Branch.nameKey(Project.nameKey("project-13"), "branch-72");
+    BranchNameKey nameKey = BranchNameKey.create(Project.nameKey("project-13"), "branch-72");
 
     Entities.Branch_NameKey proto = branchNameKeyProtoConverter.toProto(nameKey);
 
@@ -47,9 +47,9 @@
 
   @Test
   public void allValuesConvertedToProtoAndBackAgain() {
-    Branch.NameKey nameKey = Branch.nameKey(Project.nameKey("project-52"), "branch 14");
+    BranchNameKey nameKey = BranchNameKey.create(Project.nameKey("project-52"), "branch 14");
 
-    Branch.NameKey convertedNameKey =
+    BranchNameKey convertedNameKey =
         branchNameKeyProtoConverter.fromProto(branchNameKeyProtoConverter.toProto(nameKey));
 
     assertThat(convertedNameKey).isEqualTo(nameKey);
@@ -73,7 +73,7 @@
   /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
   @Test
   public void methodsExistAsExpected() {
-    assertThatSerializedClass(Branch.NameKey.class)
+    assertThatSerializedClass(BranchNameKey.class)
         .hasAutoValueMethods(
             ImmutableMap.<String, Type>builder()
                 .put("project", Project.NameKey.class)
diff --git a/javatests/com/google/gerrit/reviewdb/converter/ChangeProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/ChangeProtoConverterTest.java
index 58ed0af..0393c15 100644
--- a/javatests/com/google/gerrit/reviewdb/converter/ChangeProtoConverterTest.java
+++ b/javatests/com/google/gerrit/reviewdb/converter/ChangeProtoConverterTest.java
@@ -22,7 +22,7 @@
 import com.google.gerrit.proto.Entities;
 import com.google.gerrit.proto.testing.SerializedClassSubject;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
@@ -41,7 +41,7 @@
             Change.key("change 1"),
             Change.id(14),
             Account.id(35),
-            Branch.nameKey(Project.nameKey("project 67"), "branch 74"),
+            BranchNameKey.create(Project.nameKey("project 67"), "branch 74"),
             new Timestamp(987654L));
     change.setLastUpdatedOn(new Timestamp(1234567L));
     change.setStatus(Change.Status.MERGED);
@@ -91,7 +91,7 @@
             Change.key("change 1"),
             Change.id(14),
             Account.id(35),
-            Branch.nameKey(Project.nameKey("project 67"), "branch-74"),
+            BranchNameKey.create(Project.nameKey("project 67"), "branch-74"),
             new Timestamp(987654L));
 
     Entities.Change proto = changeProtoConverter.toProto(change);
@@ -127,7 +127,7 @@
             Change.key("change 1"),
             Change.id(14),
             Account.id(35),
-            Branch.nameKey(Project.nameKey("project 67"), "branch-74"),
+            BranchNameKey.create(Project.nameKey("project 67"), "branch-74"),
             new Timestamp(987654L));
     // O as ID actually means that no current patch set is present.
     change.setCurrentPatchSet(PatchSet.id(Change.id(14), 0), null, null);
@@ -165,7 +165,7 @@
             Change.key("change 1"),
             Change.id(14),
             Account.id(35),
-            Branch.nameKey(Project.nameKey("project 67"), "branch-74"),
+            BranchNameKey.create(Project.nameKey("project 67"), "branch-74"),
             new Timestamp(987654L));
     change.setCurrentPatchSet(PatchSet.id(Change.id(14), 23), "subject ABC", null);
 
@@ -202,7 +202,7 @@
             Change.key("change 1"),
             Change.id(14),
             Account.id(35),
-            Branch.nameKey(Project.nameKey("project 67"), "branch-74"),
+            BranchNameKey.create(Project.nameKey("project 67"), "branch-74"),
             new Timestamp(987654L));
     change.setLastUpdatedOn(new Timestamp(1234567L));
     change.setStatus(Change.Status.MERGED);
@@ -227,7 +227,7 @@
             Change.key("change 1"),
             Change.id(14),
             Account.id(35),
-            Branch.nameKey(Project.nameKey("project 67"), "branch-74"),
+            BranchNameKey.create(Project.nameKey("project 67"), "branch-74"),
             new Timestamp(987654L));
 
     Change convertedChange = changeProtoConverter.fromProto(changeProtoConverter.toProto(change));
@@ -323,7 +323,7 @@
                 .put("createdOn", Timestamp.class)
                 .put("lastUpdatedOn", Timestamp.class)
                 .put("owner", Account.Id.class)
-                .put("dest", Branch.NameKey.class)
+                .put("dest", BranchNameKey.class)
                 .put("status", char.class)
                 .put("currentPatchSetId", int.class)
                 .put("subject", String.class)
diff --git a/javatests/com/google/gerrit/server/account/DestinationListTest.java b/javatests/com/google/gerrit/server/account/DestinationListTest.java
index a216162..71dc5ef 100644
--- a/javatests/com/google/gerrit/server/account/DestinationListTest.java
+++ b/javatests/com/google/gerrit/server/account/DestinationListTest.java
@@ -16,7 +16,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.git.ValidationError;
 import com.google.gerrit.testing.GerritBaseTests;
@@ -55,11 +55,11 @@
   public static final String LABEL = "label";
   public static final String LABEL2 = "another";
 
-  public static final Branch.NameKey B_FOO = dest(P_MY, R_FOO);
-  public static final Branch.NameKey B_BAR = dest(P_SLASH, R_BAR);
-  public static final Branch.NameKey B_COMPLEX = dest(P_COMPLEX, R_FOO);
+  public static final BranchNameKey B_FOO = dest(P_MY, R_FOO);
+  public static final BranchNameKey B_BAR = dest(P_SLASH, R_BAR);
+  public static final BranchNameKey B_COMPLEX = dest(P_COMPLEX, R_FOO);
 
-  public static final Set<Branch.NameKey> D_SIMPLE = new HashSet<>();
+  public static final Set<BranchNameKey> D_SIMPLE = new HashSet<>();
 
   static {
     D_SIMPLE.clear();
@@ -67,15 +67,15 @@
     D_SIMPLE.add(B_BAR);
   }
 
-  private static Branch.NameKey dest(String project, String ref) {
-    return Branch.nameKey(Project.nameKey(project), ref);
+  private static BranchNameKey dest(String project, String ref) {
+    return BranchNameKey.create(Project.nameKey(project), ref);
   }
 
   @Test
   public void testParseSimple() throws Exception {
     DestinationList dl = new DestinationList();
     dl.parseLabel(LABEL, F_SIMPLE, null);
-    Set<Branch.NameKey> branches = dl.getDestinations(LABEL);
+    Set<BranchNameKey> branches = dl.getDestinations(LABEL);
     assertThat(branches).containsExactlyElementsIn(D_SIMPLE);
   }
 
@@ -83,7 +83,7 @@
   public void testParseWHeader() throws Exception {
     DestinationList dl = new DestinationList();
     dl.parseLabel(LABEL, HEADER + F_SIMPLE, null);
-    Set<Branch.NameKey> branches = dl.getDestinations(LABEL);
+    Set<BranchNameKey> branches = dl.getDestinations(LABEL);
     assertThat(branches).containsExactlyElementsIn(D_SIMPLE);
   }
 
@@ -91,7 +91,7 @@
   public void testParseWComments() throws Exception {
     DestinationList dl = new DestinationList();
     dl.parseLabel(LABEL, C1 + F_SIMPLE + C2, null);
-    Set<Branch.NameKey> branches = dl.getDestinations(LABEL);
+    Set<BranchNameKey> branches = dl.getDestinations(LABEL);
     assertThat(branches).containsExactlyElementsIn(D_SIMPLE);
   }
 
@@ -99,7 +99,7 @@
   public void testParseFooComment() throws Exception {
     DestinationList dl = new DestinationList();
     dl.parseLabel(LABEL, "#" + L_FOO + L_BAR, null);
-    Set<Branch.NameKey> branches = dl.getDestinations(LABEL);
+    Set<BranchNameKey> branches = dl.getDestinations(LABEL);
     assertThat(branches).doesNotContain(B_FOO);
     assertThat(branches).contains(B_BAR);
   }
@@ -108,7 +108,7 @@
   public void testParsePaddedFronts() throws Exception {
     DestinationList dl = new DestinationList();
     dl.parseLabel(LABEL, F_PAD_F, null);
-    Set<Branch.NameKey> branches = dl.getDestinations(LABEL);
+    Set<BranchNameKey> branches = dl.getDestinations(LABEL);
     assertThat(branches).containsExactlyElementsIn(D_SIMPLE);
   }
 
@@ -116,7 +116,7 @@
   public void testParsePaddedEnds() throws Exception {
     DestinationList dl = new DestinationList();
     dl.parseLabel(LABEL, F_PAD_E, null);
-    Set<Branch.NameKey> branches = dl.getDestinations(LABEL);
+    Set<BranchNameKey> branches = dl.getDestinations(LABEL);
     assertThat(branches).containsExactlyElementsIn(D_SIMPLE);
   }
 
@@ -124,7 +124,7 @@
   public void testParseComplex() throws Exception {
     DestinationList dl = new DestinationList();
     dl.parseLabel(LABEL, L_COMPLEX, null);
-    Set<Branch.NameKey> branches = dl.getDestinations(LABEL);
+    Set<BranchNameKey> branches = dl.getDestinations(LABEL);
     assertThat(branches).contains(B_COMPLEX);
   }
 
@@ -140,7 +140,7 @@
   public void testParse2Labels() throws Exception {
     DestinationList dl = new DestinationList();
     dl.parseLabel(LABEL, F_SIMPLE, null);
-    Set<Branch.NameKey> branches = dl.getDestinations(LABEL);
+    Set<BranchNameKey> branches = dl.getDestinations(LABEL);
     assertThat(branches).containsExactlyElementsIn(D_SIMPLE);
 
     dl.parseLabel(LABEL2, L_COMPLEX, null);
diff --git a/javatests/com/google/gerrit/server/notedb/ChangeNotesTest.java b/javatests/com/google/gerrit/server/notedb/ChangeNotesTest.java
index 9103d35..f8f4b05 100644
--- a/javatests/com/google/gerrit/server/notedb/ChangeNotesTest.java
+++ b/javatests/com/google/gerrit/server/notedb/ChangeNotesTest.java
@@ -39,7 +39,7 @@
 import com.google.gerrit.exceptions.StorageException;
 import com.google.gerrit.mail.Address;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.ChangeMessage;
 import com.google.gerrit.reviewdb.client.Comment;
@@ -835,7 +835,7 @@
     Change c = newChange();
 
     ChangeNotes notes = newNotes(c);
-    Branch.NameKey expectedBranch = Branch.nameKey(project, "refs/heads/master");
+    BranchNameKey expectedBranch = BranchNameKey.create(project, "refs/heads/master");
     assertThat(notes.getChange().getDest()).isEqualTo(expectedBranch);
 
     // An update doesn't affect the branch
@@ -849,7 +849,8 @@
     update = newUpdate(c, changeOwner);
     update.setBranch(otherBranch);
     update.commit();
-    assertThat(newNotes(c).getChange().getDest()).isEqualTo(Branch.nameKey(project, otherBranch));
+    assertThat(newNotes(c).getChange().getDest())
+        .isEqualTo(BranchNameKey.create(project, otherBranch));
   }
 
   @Test
diff --git a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
index 35acb5b..0106ba4 100644
--- a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
+++ b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
@@ -74,7 +74,7 @@
 import com.google.gerrit.index.query.Predicate;
 import com.google.gerrit.lifecycle.LifecycleManager;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Patch;
 import com.google.gerrit.reviewdb.client.PatchSet;
@@ -2451,7 +2451,7 @@
     List<String> shas = new ArrayList<>(n + extra.size());
     extra.forEach(i -> shas.add(i.name()));
     List<Integer> expectedIds = new ArrayList<>(n);
-    Branch.NameKey dest = null;
+    BranchNameKey dest = null;
     for (int i = 0; i < n; i++) {
       ChangeInserter ins = newChange(repo);
       insert(repo, ins);
@@ -3371,7 +3371,7 @@
           .append(c.changeId)
           .append("), ")
           .append("dest=")
-          .append(Branch.nameKey(Project.nameKey(c.project), c.branch))
+          .append(BranchNameKey.create(Project.nameKey(c.project), c.branch))
           .append(", ")
           .append("status=")
           .append(c.status)
diff --git a/javatests/com/google/gerrit/server/util/git/SubmoduleSectionParserTest.java b/javatests/com/google/gerrit/server/util/git/SubmoduleSectionParserTest.java
index bd66f26..6c682a2 100644
--- a/javatests/com/google/gerrit/server/util/git/SubmoduleSectionParserTest.java
+++ b/javatests/com/google/gerrit/server/util/git/SubmoduleSectionParserTest.java
@@ -17,7 +17,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import com.google.common.collect.Sets;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.BranchNameKey;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.SubmoduleSubscription;
 import com.google.gerrit.testing.GerritBaseTests;
@@ -40,14 +40,15 @@
             + p.get()
             + "\n"
             + "branch = master\n");
-    Branch.NameKey targetBranch = Branch.nameKey(Project.nameKey("project"), "master");
+    BranchNameKey targetBranch = BranchNameKey.create(Project.nameKey("project"), "master");
 
     Set<SubmoduleSubscription> res =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
 
     Set<SubmoduleSubscription> expected =
         Sets.newHashSet(
-            new SubmoduleSubscription(targetBranch, Branch.nameKey(p, "master"), "localpath-to-a"));
+            new SubmoduleSubscription(
+                targetBranch, BranchNameKey.create(p, "master"), "localpath-to-a"));
 
     assertThat(res).containsExactlyElementsIn(expected);
   }
@@ -65,24 +66,25 @@
             + "\n"
             + "branch = .\n");
 
-    Branch.NameKey targetBranch1 = Branch.nameKey(Project.nameKey("project"), "master");
+    BranchNameKey targetBranch1 = BranchNameKey.create(Project.nameKey("project"), "master");
 
     Set<SubmoduleSubscription> res1 =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch1).parseAllSections();
 
     Set<SubmoduleSubscription> expected1 =
-        Sets.newHashSet(new SubmoduleSubscription(targetBranch1, Branch.nameKey(p, "master"), "a"));
+        Sets.newHashSet(
+            new SubmoduleSubscription(targetBranch1, BranchNameKey.create(p, "master"), "a"));
 
     assertThat(res1).containsExactlyElementsIn(expected1);
 
-    Branch.NameKey targetBranch2 = Branch.nameKey(Project.nameKey("project"), "somebranch");
+    BranchNameKey targetBranch2 = BranchNameKey.create(Project.nameKey("project"), "somebranch");
 
     Set<SubmoduleSubscription> res2 =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch2).parseAllSections();
 
     Set<SubmoduleSubscription> expected2 =
         Sets.newHashSet(
-            new SubmoduleSubscription(targetBranch2, Branch.nameKey(p, "somebranch"), "a"));
+            new SubmoduleSubscription(targetBranch2, BranchNameKey.create(p, "somebranch"), "a"));
 
     assertThat(res2).containsExactlyElementsIn(expected2);
   }
@@ -100,14 +102,14 @@
             + "\n"
             + "branch = anotherbranch\n");
 
-    Branch.NameKey targetBranch = Branch.nameKey(Project.nameKey("project"), "master");
+    BranchNameKey targetBranch = BranchNameKey.create(Project.nameKey("project"), "master");
 
     Set<SubmoduleSubscription> res =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
 
     Set<SubmoduleSubscription> expected =
         Sets.newHashSet(
-            new SubmoduleSubscription(targetBranch, Branch.nameKey(p, "anotherbranch"), "a"));
+            new SubmoduleSubscription(targetBranch, BranchNameKey.create(p, "anotherbranch"), "a"));
 
     assertThat(res).containsExactlyElementsIn(expected);
   }
@@ -125,13 +127,14 @@
             + "\n"
             + "branch = master\n");
 
-    Branch.NameKey targetBranch = Branch.nameKey(Project.nameKey("project"), "master");
+    BranchNameKey targetBranch = BranchNameKey.create(Project.nameKey("project"), "master");
 
     Set<SubmoduleSubscription> res =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
 
     Set<SubmoduleSubscription> expected =
-        Sets.newHashSet(new SubmoduleSubscription(targetBranch, Branch.nameKey(p, "master"), "a"));
+        Sets.newHashSet(
+            new SubmoduleSubscription(targetBranch, BranchNameKey.create(p, "master"), "a"));
 
     assertThat(res).containsExactlyElementsIn(expected);
   }
@@ -149,13 +152,14 @@
             + "\n"
             + "branch = master\n");
 
-    Branch.NameKey targetBranch = Branch.nameKey(Project.nameKey("project"), "master");
+    BranchNameKey targetBranch = BranchNameKey.create(Project.nameKey("project"), "master");
 
     Set<SubmoduleSubscription> res =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
 
     Set<SubmoduleSubscription> expected =
-        Sets.newHashSet(new SubmoduleSubscription(targetBranch, Branch.nameKey(p, "master"), "a"));
+        Sets.newHashSet(
+            new SubmoduleSubscription(targetBranch, BranchNameKey.create(p, "master"), "a"));
 
     assertThat(res).containsExactlyElementsIn(expected);
   }
@@ -173,14 +177,15 @@
             + "\n"
             + "branch = master\n");
 
-    Branch.NameKey targetBranch = Branch.nameKey(Project.nameKey("project"), "master");
+    BranchNameKey targetBranch = BranchNameKey.create(Project.nameKey("project"), "master");
 
     Set<SubmoduleSubscription> res =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
 
     Set<SubmoduleSubscription> expected =
         Sets.newHashSet(
-            new SubmoduleSubscription(targetBranch, Branch.nameKey(p, "master"), "a/b/c/d/e"));
+            new SubmoduleSubscription(
+                targetBranch, BranchNameKey.create(p, "master"), "a/b/c/d/e"));
 
     assertThat(res).containsExactlyElementsIn(expected);
   }
@@ -205,15 +210,15 @@
             + "\n"
             + "		branch = master\n");
 
-    Branch.NameKey targetBranch = Branch.nameKey(Project.nameKey("project"), "master");
+    BranchNameKey targetBranch = BranchNameKey.create(Project.nameKey("project"), "master");
 
     Set<SubmoduleSubscription> res =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
 
     Set<SubmoduleSubscription> expected =
         Sets.newHashSet(
-            new SubmoduleSubscription(targetBranch, Branch.nameKey(p1, "master"), "a"),
-            new SubmoduleSubscription(targetBranch, Branch.nameKey(p2, "master"), "b"));
+            new SubmoduleSubscription(targetBranch, BranchNameKey.create(p1, "master"), "a"),
+            new SubmoduleSubscription(targetBranch, BranchNameKey.create(p2, "master"), "b"));
 
     assertThat(res).containsExactlyElementsIn(expected);
   }
@@ -238,15 +243,15 @@
             + "\n"
             + "branch = .\n");
 
-    Branch.NameKey targetBranch = Branch.nameKey(Project.nameKey("project"), "master");
+    BranchNameKey targetBranch = BranchNameKey.create(Project.nameKey("project"), "master");
 
     Set<SubmoduleSubscription> res =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
 
     Set<SubmoduleSubscription> expected =
         Sets.newHashSet(
-            new SubmoduleSubscription(targetBranch, Branch.nameKey(p2, "master"), "b"),
-            new SubmoduleSubscription(targetBranch, Branch.nameKey(p1, "master"), "a/b"));
+            new SubmoduleSubscription(targetBranch, BranchNameKey.create(p2, "master"), "b"),
+            new SubmoduleSubscription(targetBranch, BranchNameKey.create(p1, "master"), "a/b"));
 
     assertThat(res).containsExactlyElementsIn(expected);
   }
@@ -289,15 +294,15 @@
             + "\n"
             + "    branch = refs/heads/master\n");
 
-    Branch.NameKey targetBranch = Branch.nameKey(Project.nameKey("project"), "master");
+    BranchNameKey targetBranch = BranchNameKey.create(Project.nameKey("project"), "master");
 
     Set<SubmoduleSubscription> res =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
 
     Set<SubmoduleSubscription> expected =
         Sets.newHashSet(
-            new SubmoduleSubscription(targetBranch, Branch.nameKey(p1, "master"), "a"),
-            new SubmoduleSubscription(targetBranch, Branch.nameKey(p4, "master"), "e"));
+            new SubmoduleSubscription(targetBranch, BranchNameKey.create(p1, "master"), "a"),
+            new SubmoduleSubscription(targetBranch, BranchNameKey.create(p4, "master"), "e"));
 
     assertThat(res).containsExactlyElementsIn(expected);
   }
@@ -313,7 +318,7 @@
             // Project "a" doesn't exist
             + "branch = .\\n");
 
-    Branch.NameKey targetBranch = Branch.nameKey(Project.nameKey("project"), "master");
+    BranchNameKey targetBranch = BranchNameKey.create(Project.nameKey("project"), "master");
 
     Set<SubmoduleSubscription> res =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
@@ -334,7 +339,7 @@
             + "\n"
             + "branch = .");
 
-    Branch.NameKey targetBranch = Branch.nameKey(Project.nameKey("project"), "master");
+    BranchNameKey targetBranch = BranchNameKey.create(Project.nameKey("project"), "master");
 
     Set<SubmoduleSubscription> res =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
@@ -355,13 +360,14 @@
             + "\n"
             + "branch = master\n");
 
-    Branch.NameKey targetBranch = Branch.nameKey(Project.nameKey("project"), "master");
+    BranchNameKey targetBranch = BranchNameKey.create(Project.nameKey("project"), "master");
 
     Set<SubmoduleSubscription> res =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
 
     Set<SubmoduleSubscription> expected =
-        Sets.newHashSet(new SubmoduleSubscription(targetBranch, Branch.nameKey(p1, "master"), "a"));
+        Sets.newHashSet(
+            new SubmoduleSubscription(targetBranch, BranchNameKey.create(p1, "master"), "a"));
 
     assertThat(res).containsExactlyElementsIn(expected);
   }
@@ -379,13 +385,14 @@
             + "\n"
             + "branch = master\n");
 
-    Branch.NameKey targetBranch = Branch.nameKey(Project.nameKey("nested/project"), "master");
+    BranchNameKey targetBranch = BranchNameKey.create(Project.nameKey("nested/project"), "master");
 
     Set<SubmoduleSubscription> res =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
 
     Set<SubmoduleSubscription> expected =
-        Sets.newHashSet(new SubmoduleSubscription(targetBranch, Branch.nameKey(p1, "master"), "a"));
+        Sets.newHashSet(
+            new SubmoduleSubscription(targetBranch, BranchNameKey.create(p1, "master"), "a"));
 
     assertThat(res).containsExactlyElementsIn(expected);
   }
@@ -403,13 +410,14 @@
             + "\n"
             + "branch = master\n");
 
-    Branch.NameKey targetBranch = Branch.nameKey(Project.nameKey("nested/project"), "master");
+    BranchNameKey targetBranch = BranchNameKey.create(Project.nameKey("nested/project"), "master");
 
     Set<SubmoduleSubscription> res =
         new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
 
     Set<SubmoduleSubscription> expected =
-        Sets.newHashSet(new SubmoduleSubscription(targetBranch, Branch.nameKey(p1, "master"), "a"));
+        Sets.newHashSet(
+            new SubmoduleSubscription(targetBranch, BranchNameKey.create(p1, "master"), "a"));
 
     assertThat(res).containsExactlyElementsIn(expected);
   }
diff --git a/plugins/delete-project b/plugins/delete-project
index 86baa26..2cc987a 160000
--- a/plugins/delete-project
+++ b/plugins/delete-project
@@ -1 +1 @@
-Subproject commit 86baa2628036cfea5d067d752825af1ebbe9af6d
+Subproject commit 2cc987aef12d5c357b7e8463caee593e66343158
diff --git a/plugins/hooks b/plugins/hooks
index 9401a4e..60fb334 160000
--- a/plugins/hooks
+++ b/plugins/hooks
@@ -1 +1 @@
-Subproject commit 9401a4ec2656f05fa636def116ce566bf7318bc7
+Subproject commit 60fb334f44329caca37d8aa0d43feba651c959b2
diff --git a/plugins/replication b/plugins/replication
index 7743523..486e6f0 160000
--- a/plugins/replication
+++ b/plugins/replication
@@ -1 +1 @@
-Subproject commit 774352392db33950f85ec8da5a75c29085e3bf56
+Subproject commit 486e6f0dec5cf7981e750d79cda940314e67ff99
diff --git a/plugins/webhooks b/plugins/webhooks
index 0402faa..67d2588 160000
--- a/plugins/webhooks
+++ b/plugins/webhooks
@@ -1 +1 @@
-Subproject commit 0402faa6e0b00689f034d64d858b5c08febc6422
+Subproject commit 67d258822cd33ee7d7ea10679e60cca2c1f1fd29