Mercurial > hg > mercurial
changeset 552:ba4f9148d39e
Optimize changes collecting
author | Dmitry Neverov <dmitry.neverov@jetbrains.com> |
---|---|
date | Mon, 25 Feb 2013 17:53:40 +0400 |
parents | 4a18bdd61aa6 |
children | ccc305e56189 |
files | mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java |
diffstat | 2 files changed, 62 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Mon Feb 25 16:49:13 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Mon Feb 25 17:53:40 2013 +0400 @@ -477,6 +477,8 @@ @NotNull CheckoutRules rules) throws VcsException { Set<String> reportedCsetIds = new HashSet<String>(); List<ModificationData> changes = new ArrayList<ModificationData>(); + OperationContext ctx = new OperationContext(this, myRepoFactory); + Set<String> prevStateRevisions = new HashSet<String>(fromState.getBranchRevisions().values()); for (Map.Entry<String, String> entry : toState.getBranchRevisions().entrySet()) { String branch = entry.getKey(); String toRevision = entry.getValue(); @@ -485,7 +487,9 @@ fromRevision = fromState.getBranchRevisions().get(fromState.getDefaultBranchName()); if (toRevision.equals(fromRevision)) continue; - List<ModificationData> branchChanges = collectChanges(root, fromRevision, toRevision, rules); + + List<String> fromRevisions = getFromRevisionsForBranch(ctx, root, prevStateRevisions, fromRevision, toRevision); + List<ModificationData> branchChanges = collectChanges(ctx, root, fromRevisions, toRevision, rules); for (ModificationData change : branchChanges) { if (reportedCsetIds.add(change.getVersion())) changes.add(change); @@ -494,6 +498,53 @@ return changes; } + + /** + * Collecting changes is per branch. We usually take branch revision in fromState, + * revision in toState and collect changes between them. This can lead to redundant + * changes being reported. Consider the following graph: + * + * default + * | topic + * | | + * V V + *101 + * |\ + * | 100 + * | | + *99 | + *..... + * | | + * |/ + * 1 + * + * When changes are collected between states {default:99, topic:100} and {default: 101, topic:100}, + * plugin reports changes from 1 to 101, even though it probably has reported changes reachable + * from 100 earlier. + * + * This method detects such a case and returns [99, 100] as fromRevisions for 101. + */ + @NotNull + private List<String> getFromRevisionsForBranch(@NotNull OperationContext ctx, + @NotNull VcsRoot root, + @NotNull Set<String> prevStateRevisions, + @NotNull String fromRevision, + @NotNull String toRevision) throws VcsException { + List<String> fromRevisions = new ArrayList<String>(); + fromRevisions.add(fromRevision); + + HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); + ctx.syncRepository(hgRoot); + ServerHgRepo repo = createRepo(ctx, hgRoot); + List<String> parentRevisions = repo.parents().ofRevision(toRevision).call(); + for (String parent : parentRevisions) { + if (!fromRevision.equals(parent) && prevStateRevisions.contains(parent)) + fromRevisions.add(parent); + } + + return fromRevisions; + } + @NotNull public List<ModificationData> collectChanges(@NotNull VcsRoot fromRoot, @NotNull String fromRootRevision, @NotNull VcsRoot toRoot, @Nullable String toRootRevision,
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java Mon Feb 25 16:49:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java Mon Feb 25 17:53:40 2013 +0400 @@ -20,8 +20,6 @@ import jetbrains.buildServer.vcs.*; import jetbrains.buildServer.vcs.impl.VcsRootImpl; import junit.framework.Assert; -import org.hamcrest.Description; -import org.hamcrest.TypeSafeMatcher; import org.jetbrains.annotations.NotNull; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -593,6 +591,16 @@ } + public void should_not_report_redundant_changes_after_merge() throws Exception { + VcsRootImpl root = createVcsRoot(myRep2Path); + List<ModificationData> changes = myVcs.collectChanges(root, + RepositoryStateData.createVersionState("default", map("default", "505c5b9d01e6", "personal-branch", "9ec402c74298")), + RepositoryStateData.createVersionState("default", map("default", "df04faa7575a", "personal-branch", "9ec402c74298")), + CheckoutRules.DEFAULT); + assertEquals(changes.size(), 1); + } + + private void assertFiles(final List<String> expectedFiles, final ModificationData modificationData) { Set<String> actualFiles = new HashSet<String>(); for (VcsChange vc: modificationData.getChanges()) {