All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gerrit.server.submit.MergeOpRepoManager Maven / Gradle / Ivy

There is a newer version: 3.10.0-rc4
Show newest version
// Copyright (C) 2016 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.server.submit;

import static com.google.common.base.Preconditions.checkState;

import com.google.common.collect.Maps;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MergeTip;
import com.google.gerrit.server.git.validators.OnSubmitValidators;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.inject.Inject;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevFlag;
import org.eclipse.jgit.revwalk.RevSort;

/**
 * This is a helper class for MergeOp and not intended for general use.
 *
 * 

Some database backends require to open a repository just once within a transaction of a * submission, this caches open repositories to satisfy that requirement. */ public class MergeOpRepoManager implements AutoCloseable { public class OpenRepo { final Repository repo; final CodeReviewRevWalk rw; final RevFlag canMergeFlag; final ObjectInserter ins; final ProjectState project; BatchUpdate update; private final ObjectReader reader; private final Map branches; private OpenRepo(Repository repo, ProjectState project) { this.repo = repo; this.project = project; ins = repo.newObjectInserter(); reader = ins.newReader(); rw = CodeReviewCommit.newRevWalk(reader); rw.sort(RevSort.TOPO); rw.sort(RevSort.COMMIT_TIME_DESC, true); rw.setRetainBody(false); canMergeFlag = rw.newFlag("CAN_MERGE"); rw.retainOnReset(canMergeFlag); branches = Maps.newHashMapWithExpectedSize(1); } OpenBranch getBranch(Branch.NameKey branch) throws IntegrationException { OpenBranch ob = branches.get(branch); if (ob == null) { ob = new OpenBranch(this, branch); branches.put(branch, ob); } return ob; } public Repository getRepo() { return repo; } Project.NameKey getProjectName() { return project.getNameKey(); } public CodeReviewRevWalk getCodeReviewRevWalk() { return rw; } public BatchUpdate getUpdate() { checkState(db != null, "call setContext before getUpdate"); if (update == null) { update = batchUpdateFactory .create(db, getProjectName(), caller, ts) .setRepository(repo, rw, ins) .setOnSubmitValidators(onSubmitValidatorsFactory.create()); } return update; } private void close() { if (update != null) { update.close(); } rw.close(); reader.close(); ins.close(); repo.close(); } } public static class OpenBranch { final RefUpdate update; final CodeReviewCommit oldTip; MergeTip mergeTip; OpenBranch(OpenRepo or, Branch.NameKey name) throws IntegrationException { try { update = or.repo.updateRef(name.get()); if (update.getOldObjectId() != null) { oldTip = or.rw.parseCommit(update.getOldObjectId()); } else if (Objects.equals(or.repo.getFullBranch(), name.get()) || Objects.equals(RefNames.REFS_CONFIG, name.get())) { oldTip = null; update.setExpectedOldObjectId(ObjectId.zeroId()); } else { throw new IntegrationException( "The destination branch " + name + " does not exist anymore."); } } catch (IOException e) { throw new IntegrationException("Cannot open branch " + name, e); } } } private final Map openRepos; private final BatchUpdate.Factory batchUpdateFactory; private final OnSubmitValidators.Factory onSubmitValidatorsFactory; private final GitRepositoryManager repoManager; private final ProjectCache projectCache; private ReviewDb db; private Timestamp ts; private IdentifiedUser caller; @Inject MergeOpRepoManager( GitRepositoryManager repoManager, ProjectCache projectCache, BatchUpdate.Factory batchUpdateFactory, OnSubmitValidators.Factory onSubmitValidatorsFactory) { this.repoManager = repoManager; this.projectCache = projectCache; this.batchUpdateFactory = batchUpdateFactory; this.onSubmitValidatorsFactory = onSubmitValidatorsFactory; openRepos = new HashMap<>(); } public void setContext(ReviewDb db, Timestamp ts, IdentifiedUser caller) { this.db = db; this.ts = ts; this.caller = caller; } public OpenRepo getRepo(Project.NameKey project) throws NoSuchProjectException, IOException { if (openRepos.containsKey(project)) { return openRepos.get(project); } ProjectState projectState = projectCache.get(project); if (projectState == null) { throw new NoSuchProjectException(project); } try { OpenRepo or = new OpenRepo(repoManager.openRepository(project), projectState); openRepos.put(project, or); return or; } catch (RepositoryNotFoundException e) { throw new NoSuchProjectException(project, e); } } public List batchUpdates(Collection projects) throws NoSuchProjectException, IOException { List updates = new ArrayList<>(projects.size()); for (Project.NameKey project : projects) { updates.add(getRepo(project).getUpdate().setRefLogMessage("merged")); } return updates; } @Override public void close() { for (OpenRepo repo : openRepos.values()) { repo.close(); } openRepos.clear(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy