changeset 958:6a16b17fcada

Merge branch Indore-10.0.x
author Dmitry Neverov <dmitry.neverov@gmail.com>
date Fri, 22 Jul 2016 12:41:21 +0200
parents ef995b1ed5ec (current diff) a0bb066bda0e (diff)
children 9e67a769bcc1
files
diffstat 22 files changed, 156 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CollectChangesContext.java	Wed Jun 22 21:33:59 2016 +0200
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CollectChangesContext.java	Fri Jul 22 12:41:21 2016 +0200
@@ -37,6 +37,7 @@
 
 public class CollectChangesContext extends OperationContext {
 
+  private final ServerPluginConfig myConfig;
   private final Set<String> myUninterestingRevisions;
   private final Map<VcsRootKey, DAG<String>> myDags = new HashMap<VcsRootKey, DAG<String>>();
   private Set<File> mySyncedDirs = new HashSet<File>();
@@ -46,25 +47,29 @@
   private boolean myIncludeFromRevisions = false;//by default don't include them, they should be included only for subrepos
   private TLongObjectHashMap<String> myStringPool = new TLongObjectHashMap<String>();
 
-  public CollectChangesContext(@NotNull MercurialVcsSupport vcs,
+  public CollectChangesContext(@NotNull ServerPluginConfig config,
+                               @NotNull MercurialVcsSupport vcs,
                                @NotNull RepoFactory repoFactory,
                                @NotNull MercurialProgress progress,
                                @NotNull RepositoryStateData fromState) {
-    this(vcs, repoFactory, progress, new HashSet<String>(fromState.getBranchRevisions().values()));
+    this(config, vcs, repoFactory, progress, new HashSet<String>(fromState.getBranchRevisions().values()));
   }
 
-  public CollectChangesContext(@NotNull MercurialVcsSupport vcs,
+  public CollectChangesContext(@NotNull ServerPluginConfig config,
+                               @NotNull MercurialVcsSupport vcs,
                                @NotNull RepoFactory repoFactory,
                                @NotNull MercurialProgress progress,
                                @NotNull String fromVersion) {
-    this(vcs, repoFactory, progress, setOf(fromVersion));
+    this(config, vcs, repoFactory, progress, setOf(fromVersion));
   }
 
-  public CollectChangesContext(@NotNull MercurialVcsSupport vcs,
+  public CollectChangesContext(@NotNull ServerPluginConfig config,
+                               @NotNull MercurialVcsSupport vcs,
                                @NotNull RepoFactory repoFactory,
                                @NotNull MercurialProgress progress,
                                @NotNull Collection<String> fromVersions) {
     super(vcs, repoFactory, progress);
+    myConfig = config;
     myUninterestingRevisions = new HashSet<String>(fromVersions);
   }
 
@@ -198,7 +203,7 @@
     syncRepository(root);
     ServerHgRepo repo = createRepo(root, myVcs.getWorkingDir(root));
 
-    if (!repo.supportRevsets())
+    if (!repo.supportRevsets() || !myConfig.computeFromRevisions())
       return singleton(fromRevision);
 
     Set<String> fromRevisions = new HashSet<String>();
@@ -251,8 +256,10 @@
   private final static class FindIntervalVisitor extends BFSVisitorAdapter<String> {
 
     private final DAG<String> myDag;
-    private final Collection<String> myUninterestingRevisions;
-    private final Set<String> myVisitedUninterestingRevisions = new HashSet<String>();
+    private final Collection<String> myUninterestingRevisions;//from state revisions
+    private final Set<String> myAllUninteresting = new HashSet<String>();//myUninterestingRevisions + all revisions reachable from them
+    private boolean myUninterestingInitialized = false;//become true when myAllUninteresting is computed
+    private final Set<String> myCoveredUninteresting = new HashSet<String>();//all revisions reachable from computed endpoints
     private final Set<String> myEndpoints = new HashSet<String>();
 
     private FindIntervalVisitor(@NotNull DAG<String> dag, @NotNull Collection<String> uninteresting) {
@@ -264,23 +271,27 @@
     public boolean discover(@NotNull String revision) {
       markUninteresting();
       if (!isInteresting(revision)) {
-        addEndpoint(revision);
+        if (!myCoveredUninteresting.contains(revision)) {
+          addEndpoint(revision);
+          myDag.breadthFirstSearch(revision, new MarkUninterestingRevisions(myCoveredUninteresting));
+        }
         return false;
       }
       return true;
     }
 
     private void markUninteresting() {
-      if (!myVisitedUninterestingRevisions.isEmpty())
+      if (myUninterestingInitialized)
         return;
       for (String rev : myUninterestingRevisions) {
         if (myDag.containsNode(rev))
-          myDag.breadthFirstSearch(rev, new MarkUninterestingRevisions());
+          myDag.breadthFirstSearch(rev, new MarkUninterestingRevisions(myAllUninteresting));
       }
+      myUninterestingInitialized = true;
     }
 
     private boolean isInteresting(@NotNull String revision) {
-      return !myVisitedUninterestingRevisions.contains(revision);
+      return !myAllUninteresting.contains(revision);
     }
 
     private void addEndpoint(@NotNull String revision) {
@@ -293,11 +304,17 @@
     }
 
     private class MarkUninterestingRevisions extends BFSVisitorAdapter<String> {
+      private final Set<String> myAccumulator;
+
+      public MarkUninterestingRevisions(@NotNull Set<String> accumulator) {
+        myAccumulator = accumulator;
+      }
+
       @Override
       public boolean discover(@NotNull String node) {
-        if (myVisitedUninterestingRevisions.contains(node))
+        if (myAccumulator.contains(node))
           return false;
-        myVisitedUninterestingRevisions.add(node);
+        myAccumulator.add(node);
         return true;
       }
     }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCollectChangesPolicy.java	Wed Jun 22 21:33:59 2016 +0200
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCollectChangesPolicy.java	Fri Jul 22 12:41:21 2016 +0200
@@ -105,7 +105,7 @@
                                                @NotNull CheckoutRules rules) throws VcsException {
     List<ModificationData> changes = new ArrayList<ModificationData>();
     HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root);
-    CollectChangesContext ctx = new CollectChangesContext(myVcs, myRepoFactory, createMercurialProgess(), fromState);
+    CollectChangesContext ctx = new CollectChangesContext(myConfig, myVcs, myRepoFactory, createMercurialProgess(), fromState);
     for (Map.Entry<String, String> entry : toState.getBranchRevisions().entrySet()) {
       String branch = entry.getKey();
       String toRevision = entry.getValue();
@@ -136,7 +136,7 @@
                                                @Nullable String toRootRevision,
                                                @NotNull CheckoutRules checkoutRules) throws VcsException {
     HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(toRoot);
-    CollectChangesContext context = new CollectChangesContext(myVcs, myRepoFactory, createMercurialProgess(), fromRootRevision);
+    CollectChangesContext context = new CollectChangesContext(myConfig, myVcs, myRepoFactory, createMercurialProgess(), fromRootRevision);
     context.syncRepository(hgRoot);
     String toRevision = toRootRevision;
     if (toRevision == null) {
@@ -156,7 +156,7 @@
                                                @NotNull CheckoutRules checkoutRules) throws VcsException {
     if (currentVersion == null)
       return emptyList();
-    CollectChangesContext ctx = new CollectChangesContext(myVcs, myRepoFactory, createMercurialProgess(), fromVersion);
+    CollectChangesContext ctx = new CollectChangesContext(myConfig, myVcs, myRepoFactory, createMercurialProgess(), fromVersion);
     return collectChanges(ctx, root, fromVersion, currentVersion, checkoutRules);
   }
 
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfig.java	Wed Jun 22 21:33:59 2016 +0200
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfig.java	Fri Jul 22 12:41:21 2016 +0200
@@ -59,4 +59,6 @@
   public String getMergeTool();
 
   public boolean runWithProfile(@NotNull HgVcsRoot root);
+
+  boolean computeFromRevisions();
 }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigImpl.java	Wed Jun 22 21:33:59 2016 +0200
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigImpl.java	Fri Jul 22 12:41:21 2016 +0200
@@ -129,4 +129,8 @@
     String urls = TeamCityProperties.getProperty("teamcity.hg.runCommandsWithProfile");
     return urls.contains(root.getRepository());
   }
+
+  public boolean computeFromRevisions() {
+    return TeamCityProperties.getBooleanOrTrue("teamcity.hg.computeFromRevisions");
+  }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CollectChangesContextTest.java	Fri Jul 22 12:41:21 2016 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2000-2016 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;
+
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot;
+import jetbrains.buildServer.util.TestFor;
+import jetbrains.buildServer.vcs.RepositoryStateData;
+import jetbrains.buildServer.vcs.impl.VcsRootImpl;
+import org.jetbrains.annotations.NotNull;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.util.Collection;
+
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialSupportBuilder.mercurialSupport;
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.ServerPluginConfigBuilder.serverPluginConfig;
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot;
+import static jetbrains.buildServer.util.Util.map;
+import static junit.framework.Assert.assertTrue;
+
+
+@RequiredHgVersion(min = "1.7.0")
+@Test(dataProviderClass = HgVersionConstraint.class, dataProvider = "installedHgVersion")
+public class CollectChangesContextTest extends BaseMercurialTestCase {
+
+  private ServerPluginConfig myConfig;
+  private MercurialVcsSupport myVcs;
+  private MercurialSupportBuilder myVcsBuilder;
+
+  @BeforeMethod
+  public void setUp() throws Exception {
+    super.setUp();
+    myConfig = serverPluginConfig()
+            .cachesDir(myTempFiles.createTempDir())
+            .hgPath(Util.getHgPath())
+            .build();
+    myVcsBuilder = mercurialSupport().withConfig(myConfig);
+    myVcs = myVcsBuilder.build();
+  }
+
+
+  @TestFor(issues = "TW-46340")
+  public void test_many_from_revisions(@NotNull HgVersion _) throws Exception {
+    //default
+    // | branch1
+    // V  |
+    //    V
+    //   100
+    //  /|
+    //99 |
+    // | |
+    //..... total 100 merges from default into branch1 like this
+    // | 5
+    // |/|
+    // 4 |
+    // | 3
+    // |/|
+    // 2 |
+    // |/
+    // 1
+    // |
+    // 0
+    //
+    // we collect changes from {default:99} to {default:99, branch1: 100}
+    // when we compute from revisions for branch1 99 is enough (it will filter out all commits in the default branch)
+    File remoteRepository = myTempFiles.createTempDir();
+    Util.copyRepository(new File("mercurial-tests/testData/manyFromRevisions"), remoteRepository);
+    VcsRootImpl root = vcsRoot().withUrl(remoteRepository.getAbsolutePath()).build();
+    HgVcsRoot hgRoot = myVcsBuilder.getHgRootFactory().createHgRoot(root);
+
+    RepositoryStateData fromState = RepositoryStateData.createVersionState("default", map("default", "d847416dd2eb"));
+    RepositoryStateData toState = RepositoryStateData.createVersionState("default", map("default", "d847416dd2eb", "branch1", "8c990164b769"));
+    CollectChangesContext context = new CollectChangesContext(myConfig, myVcs, myVcsBuilder.getHgRepoFactory(), MercurialProgress.NO_OP, fromState);
+    Collection<String> fromRevisions = context.getFromRevisionsForBranch(hgRoot, "d847416dd2eb", "8c990164b769", toState);
+    assertTrue(fromRevisions.size() == 1);
+    assertTrue(fromRevisions.contains("d847416dd2eb"));
+  }
+
+}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigBuilder.java	Wed Jun 22 21:33:59 2016 +0200
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigBuilder.java	Fri Jul 22 12:41:21 2016 +0200
@@ -111,6 +111,10 @@
       public boolean runWithProfile(@NotNull HgVcsRoot root) {
         return false;
       }
+
+      public boolean computeFromRevisions() {
+        return true;
+      }
     };
   }
 
--- a/mercurial-tests/src/testng.xml	Wed Jun 22 21:33:59 2016 +0200
+++ b/mercurial-tests/src/testng.xml	Fri Jul 22 12:41:21 2016 +0200
@@ -56,6 +56,7 @@
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CommitsAndMountPointsCommandParserTest"/>
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.PurgeTest"/>
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialCommitSupportTest"/>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.CollectChangesContextTest"/>
     </classes>
   </test>
 </suite>
Binary file mercurial-tests/testData/manyFromRevisions/hg/00changelog.i has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/branch	Fri Jul 22 12:41:21 2016 +0200
@@ -0,0 +1,1 @@
+default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/branchheads.cache	Fri Jul 22 12:41:21 2016 +0200
@@ -0,0 +1,3 @@
+8c990164b769e02a7b0536b7c6a3b0073620cd8f 200
+d847416dd2eb6f5cdce1f7c85075c07f4595f589 default
+8c990164b769e02a7b0536b7c6a3b0073620cd8f branch1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/cache/branch2-base	Fri Jul 22 12:41:21 2016 +0200
@@ -0,0 +1,3 @@
+8c990164b769e02a7b0536b7c6a3b0073620cd8f 200
+8c990164b769e02a7b0536b7c6a3b0073620cd8f o branch1
+d847416dd2eb6f5cdce1f7c85075c07f4595f589 o default
Binary file mercurial-tests/testData/manyFromRevisions/hg/cache/rbc-names-v1 has changed
Binary file mercurial-tests/testData/manyFromRevisions/hg/cache/rbc-revs-v1 has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/cache/tags2-visible	Fri Jul 22 12:41:21 2016 +0200
@@ -0,0 +1,1 @@
+200 8c990164b769e02a7b0536b7c6a3b0073620cd8f
Binary file mercurial-tests/testData/manyFromRevisions/hg/dirstate has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/hgrc	Fri Jul 22 12:41:21 2016 +0200
@@ -0,0 +1,2 @@
+[paths]
+default = /Users/nd/p/test/fromRevisionsTest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/requires	Fri Jul 22 12:41:21 2016 +0200
@@ -0,0 +1,4 @@
+dotencode
+fncache
+revlogv1
+store
Binary file mercurial-tests/testData/manyFromRevisions/hg/store/00changelog.i has changed
Binary file mercurial-tests/testData/manyFromRevisions/hg/store/00manifest.i has changed
Binary file mercurial-tests/testData/manyFromRevisions/hg/store/data/a.i has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/store/fncache	Fri Jul 22 12:41:21 2016 +0200
@@ -0,0 +1,1 @@
+data/a.i
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/manyFromRevisions/hg/tags.cache	Fri Jul 22 12:41:21 2016 +0200
@@ -0,0 +1,2 @@
+200 8c990164b769e02a7b0536b7c6a3b0073620cd8f
+