| // 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.googlesource.gerrit.plugins.batch.util; |
| |
| import com.google.gerrit.common.Nullable; |
| import com.google.gerrit.extensions.restapi.BadRequestException; |
| import com.google.gerrit.reviewdb.client.BooleanProjectConfig; |
| 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.server.git.GitRepositoryManager; |
| import com.google.gerrit.server.project.NoSuchRefException; |
| import com.google.gerrit.server.project.ProjectCache; |
| import com.google.gerrit.server.project.ProjectState; |
| import com.google.gerrit.server.submit.IntegrationException; |
| import com.google.inject.Inject; |
| import com.google.inject.assistedinject.Assisted; |
| import com.googlesource.gerrit.plugins.batch.util.MergeBuilder.FastForwardMode; |
| import java.io.IOException; |
| import java.util.concurrent.Callable; |
| import org.eclipse.jgit.errors.RepositoryNotFoundException; |
| import org.eclipse.jgit.lib.ObjectId; |
| import org.eclipse.jgit.lib.Ref; |
| import org.eclipse.jgit.lib.Repository; |
| import org.eclipse.jgit.merge.MergeStrategy; |
| |
| public class MergeBranch implements Callable<ObjectId> { |
| public interface Factory { |
| MergeBranch create( |
| @Assisted Branch.NameKey destBranch, |
| @Assisted("destSha") @Nullable String destSha, |
| @Assisted("sourceRef") String srcName, |
| @Assisted MergeStrategy strategy, |
| @Assisted FastForwardMode fastForwardMode, |
| @Assisted("message") String message); |
| } |
| |
| protected final GitRepositoryManager repoManager; |
| protected final ProjectCache projectCache; |
| protected final MergeBuilder.Factory builderFactory; |
| protected final Project.NameKey projectName; |
| protected final String destName; |
| protected ObjectId destId; |
| protected final String srcName; |
| protected final String message; |
| protected MergeStrategy strategy; |
| protected FastForwardMode fastForwardMode = FastForwardMode.FF; |
| |
| @Inject |
| MergeBranch( |
| GitRepositoryManager repoManager, |
| ProjectCache projectCache, |
| MergeBuilder.Factory builderFactory, |
| @Assisted Branch.NameKey destBranch, |
| @Assisted("destSha") @Nullable String destSha, |
| @Assisted("sourceRef") String srcName, |
| @Assisted("message") @Nullable String message, |
| @Assisted @Nullable MergeStrategy strategy, |
| @Assisted @Nullable FastForwardMode fastForwardMode) { |
| this.projectCache = projectCache; |
| this.repoManager = repoManager; |
| this.builderFactory = builderFactory; |
| this.projectName = destBranch.getParentKey(); |
| destName = RefNames.fullName(destBranch.get()); |
| if (destSha != null) { |
| this.destId = ObjectId.fromString(destSha); |
| } |
| this.srcName = srcName; |
| this.message = message; |
| this.strategy = strategy; |
| if (fastForwardMode != null) { |
| this.fastForwardMode = fastForwardMode; |
| } |
| } |
| |
| @Override |
| public ObjectId call() |
| throws IOException, NoSuchRefException, RepositoryNotFoundException, IntegrationException, |
| BadRequestException { |
| try (Repository repo = repoManager.openRepository(projectName)) { |
| Ref destRef = repo.getRefDatabase().getRef(destName); |
| if (destRef == null) { |
| throw new NoSuchRefException(destName); |
| } |
| if (destId == null) { |
| destId = repo.resolve(destName); |
| if (destId == null) { |
| throw new BadRequestException("Invalid Revision"); |
| } |
| } |
| ObjectId srcId = repo.resolve(srcName); |
| if (srcId == null) { |
| throw new BadRequestException("Invalid Revision"); |
| } |
| strategy = defaultStrategy(strategy); |
| return builderFactory |
| .create(projectName, message, strategy, fastForwardMode, destId, srcId) |
| .call(); |
| } |
| } |
| |
| protected MergeStrategy defaultStrategy(MergeStrategy strategy) { |
| if (strategy == null) { |
| ProjectState project = projectFromName(projectName); |
| if (project != null && project.is(BooleanProjectConfig.USE_CONTENT_MERGE)) { |
| return MergeStrategy.RESOLVE; |
| } |
| return MergeStrategy.SIMPLE_TWO_WAY_IN_CORE; |
| } |
| return strategy; |
| } |
| |
| protected ProjectState projectFromName(Project.NameKey name) { |
| ProjectState ps = projectCache.get(name); |
| return ps != null ? ps : null; |
| } |
| } |