Mercurial > hg > mercurial
view mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesNoRevsets.java @ 757:b7deb8f24278
replace bare File with MercurialLogTemplate
author | eugene.petrenko@jetbrains.com |
---|---|
date | Tue, 25 Feb 2014 11:36:50 +0100 |
parents | 31a1aca3305c |
children | 196f62e515db |
line wrap: on
line source
/* * Copyright 2000-2014 JetBrains s.r.o. * * 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command; import com.intellij.openapi.util.Pair; import jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialLogTemplate; import jetbrains.buildServer.buildTriggers.vcs.mercurial.ServerHgRepo; import jetbrains.buildServer.util.graph.DAG; import jetbrains.buildServer.util.graph.DAGIterator; import jetbrains.buildServer.util.graph.DAGs; import jetbrains.buildServer.vcs.VcsException; import org.jetbrains.annotations.NotNull; import java.util.*; /** * @author dmitry.neverov */ public class CollectChangesNoRevsets extends CollectChangesCommand { private final HgVcsRoot myRoot; private final ServerHgRepo myRepo; private final MercurialLogTemplate myLogNoFilesTemplate; public CollectChangesNoRevsets(@NotNull HgVcsRoot root, @NotNull ServerHgRepo repo, @NotNull MercurialLogTemplate logNoFilesTemplate) { myRoot = root; myRepo = repo; myLogNoFilesTemplate = logNoFilesTemplate; } @Override public List<ChangeSet> call() throws VcsException { return call(myFromRevisions.get(0), myToRevision); } @NotNull @Override public List<ChangeSet> call(@NotNull List<String> fromCommits, @NotNull String toCommit) throws VcsException { return call(fromCommits.get(0), toCommit); } @NotNull public List<ChangeSet> call(@NotNull final String fromCommit, @NotNull final String toCommit) throws VcsException { List<ChangeSet> revisionIntervalCsets = getRevisionsBetween(fromCommit, toCommit); List<Pair<String, String>> revisionIntervalEdges = getEdges(revisionIntervalCsets); Map<String, ChangeSet> revisionIntervalMap = getChangesetMap(revisionIntervalCsets); DAG<String> revisionIntervalDag = DAGs.createFromEdges(revisionIntervalEdges); DAGIterator<String> iter = revisionIntervalDag.iterator(toCommit); iter.markUninteresting(fromCommit); List<ChangeSet> revisionIntervalReachableChangesets = new ArrayList<ChangeSet>(); Set<String> missingParents = new HashSet<String>(); while (iter.hasNext()) { String csetId = iter.next(); ChangeSet cset = revisionIntervalMap.get(csetId); if (cset != null) { revisionIntervalReachableChangesets.add(cset); } else { missingParents.add(csetId); } } if (missingParents.isEmpty()) { Collections.reverse(revisionIntervalReachableChangesets); return revisionIntervalReachableChangesets; } Pair<List<ChangeSet>, Integer> commitsWithoutFiles = getCommitsWithoutFiles(fromCommit, toCommit); List<ChangeSet> csetsWithoutFiles = commitsWithoutFiles.first; Integer minRevNum = commitsWithoutFiles.second; if (csetsWithoutFiles.isEmpty()) return revisionIntervalCsets; List<ChangeSet> commitsWithFiles = getRevisionsBetween(minRevNum, fromCommit); Map<String, ChangeSet> csetMap = getChangesetMap(commitsWithFiles); csetMap.putAll(revisionIntervalMap); List<ChangeSet> result = new ArrayList<ChangeSet>(); for (ChangeSet cset : csetsWithoutFiles) { ChangeSet csetWithFiles = csetMap.get(cset.getId()); if (csetWithFiles != null) result.add(csetWithFiles); } return result; } @NotNull private Pair<List<ChangeSet>, Integer> getCommitsWithoutFiles(@NotNull String fromCommit, @NotNull String toCommit) throws VcsException { List<ChangeSet> csets = getAllHistoryUpTo(toCommit); Map<String, ChangeSet> csetsMap = getChangesetMap(csets); if (csetsMap.containsKey(fromCommit)) { DAG<String> dag = DAGs.createFromEdges(getEdges(csets)); DAGIterator<String> iter = dag.iterator(toCommit); iter.markUninteresting(fromCommit); List<ChangeSet> result = new ArrayList<ChangeSet>(); int minRevNum = Integer.MAX_VALUE; while (iter.hasNext()) { String commit = iter.next(); ChangeSet cset = csetsMap.get(commit); if (cset == null) continue;//commit is parent of some commit and wasn't included in the log int revNum = cset.getRevNumber(); if (revNum < minRevNum) minRevNum = revNum; result.add(cset); } Collections.reverse(result); return Pair.create(result, minRevNum); } else { return new Pair<List<ChangeSet>, Integer>(Collections.<ChangeSet>emptyList(), Integer.MAX_VALUE); } } //csetId -> cset private Map<String, ChangeSet> getChangesetMap(@NotNull final List<ChangeSet> csets) { Map<String, ChangeSet> result = new HashMap<String, ChangeSet>(csets.size()); for (ChangeSet cset : csets) { result.put(cset.getId(), cset); } return result; } private List<ChangeSet> getAllHistoryUpTo(@NotNull final String revision) throws VcsException { return myRepo.log(myRoot) .fromRevision(revision) .toRevision("0") .showCommitsFromAllBranches() .withTemplate(myLogNoFilesTemplate) .call(); } private List<ChangeSet> getRevisionsBetween(@NotNull String fromCommit, @NotNull String toCommit) throws VcsException { return myRepo.log(myRoot) .fromRevision(toCommit) .toRevision(fromCommit) .showCommitsFromAllBranches() .call(); } private List<ChangeSet> getRevisionsBetween(int fromRevNum, @NotNull String toCommit) throws VcsException { return myRepo.log(myRoot) .fromRevision(toCommit) .toRevision(String.valueOf(fromRevNum)) .showCommitsFromAllBranches() .call(); } private List<Pair<String, String>> getEdges(List<ChangeSet> csets) { List<Pair<String, String>> result = new ArrayList<Pair<String, String>>(); for (ChangeSet cset : csets) { for (ChangeSetRevision parent : cset.getParents()) { result.add(Pair.create(cset.getId(), parent.getId())); } } return result; } }