# HG changeset patch # User Dmitry Neverov # Date 1362064432 -14400 # Node ID 4f1c0ecc337186439495070d9c85f9fc8f1729c1 # Parent 110de749f460af877d081227d85c3980c52ef6b7 Do not report duplicate changes diff -r 110de749f460 -r 4f1c0ecc3371 mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java --- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Wed Feb 27 17:00:42 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Thu Feb 28 19:13:52 2013 +0400 @@ -40,6 +40,7 @@ import java.util.*; import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static jetbrains.buildServer.buildTriggers.vcs.mercurial.HgFileUtil.deleteDir; @@ -475,7 +476,6 @@ @NotNull RepositoryStateData fromState, @NotNull RepositoryStateData toState, @NotNull CheckoutRules rules) throws VcsException { - Set reportedCsetIds = new HashSet(); List changes = new ArrayList(); OperationContext ctx = new OperationContext(this, myRepoFactory); Set prevStateRevisions = new HashSet(fromState.getBranchRevisions().values()); @@ -491,10 +491,13 @@ List fromRevisions = getFromRevisionsForBranch(ctx, root, prevStateRevisions, fromRevision, toRevision); List branchChanges = collectChanges(ctx, root, fromRevisions, toRevision, rules); for (ModificationData change : branchChanges) { - if (reportedCsetIds.add(change.getVersion())) + if (!ctx.isReportedModification(change)) { changes.add(change); + ctx.markAsReported(change); + } } } + changes.addAll(getSubrepoChanges(ctx, root, changes)); return changes; } @@ -592,7 +595,9 @@ public List collectChanges(@NotNull VcsRoot root, @NotNull String fromVersion, @Nullable String currentVersion, @NotNull CheckoutRules checkoutRules) throws VcsException { OperationContext ctx = new OperationContext(this, myRepoFactory); - return collectChanges(ctx, root, asList(fromVersion), currentVersion, checkoutRules); + List changes = collectChanges(ctx, root, asList(fromVersion), currentVersion, checkoutRules); + changes.addAll(getSubrepoChanges(ctx, root, changes)); + return changes; } private List collectChanges(@NotNull OperationContext ctx, @@ -606,15 +611,66 @@ for (ChangeSet cset : getChangesets(ctx, hgRoot, fromVersion, currentVersion)) { result.add(createModificationData(ctx, cset, root, checkoutRules)); } + return result; + } - if (myConfig.detectSubrepoChanges() && hgRoot.detectSubrepoChanges()) { - List subrepoChanges = new ArrayList(); - for (ModificationData m : result) { - subrepoChanges.addAll(getSubrepoChanges(ctx, m)); + + @NotNull + private List getSubrepoChanges(@NotNull OperationContext ctx, @NotNull VcsRoot root, @NotNull List changes) throws VcsException { + if (changes.isEmpty()) + return emptyList(); + + HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); + if (!detectSubrepoChanges(hgRoot)) + return emptyList(); + + List subrepoConfigChanges = getSubrepoConfigChanges(changes); + List subrepoChanges = new ArrayList(); + + for (SubrepoConfigChange configChange : subrepoConfigChanges) { + VcsRootImpl subrepo = new VcsRootImpl(root.getId(), configChange.getSubrepoRootParams()); + if (ctx.isProcessedSubrepoChanges(subrepo, configChange.getPreviousSubrepoRevisions(), configChange.getCurrentSubrepoRevision())) + continue; + List subChanges = collectChanges(ctx, subrepo, configChange.getPreviousSubrepoRevisions(), configChange.getCurrentSubrepoRevision(), CheckoutRules.DEFAULT); + for (ModificationData m : subChanges) { + if (!ctx.isReportedModification(m)) { + subrepoChanges.add(m); + ctx.markAsReported(m); + } } - result.addAll(subrepoChanges); + ctx.markProcessedSubrepoChanges(subrepo, configChange.getPreviousSubrepoRevisions(), configChange.getCurrentSubrepoRevision()); } - return result; + + List subSubrepoChanges = getSubrepoChanges(ctx, root, subrepoChanges); + subrepoChanges.addAll(subSubrepoChanges); + return subrepoChanges; + } + + + private boolean detectSubrepoChanges(@NotNull HgVcsRoot root) { + return myConfig.detectSubrepoChanges() && root.detectSubrepoChanges(); + } + + + private List getSubrepoConfigChanges(@NotNull List mainRootChanges) { + List subrepoConfigChanges = new ArrayList(); + for (ModificationData m : mainRootChanges) { + subrepoConfigChanges.addAll(getSubrepoConfigChanges(m)); + } + return subrepoConfigChanges; + } + + + private List getSubrepoConfigChanges(@NotNull ModificationData m) { + List configChanges = new ArrayList(); + for (SubrepoConfigChange configChange : SubrepoConfigChangesAttributes.readSubrepoConfigChanges(m.getAttributes())) { + if (configChange.getSubrepoRootParams().isEmpty()) + continue; + if (configChange.getPreviousSubrepoRevisions().isEmpty()) + continue; + configChanges.add(configChange); + } + return configChanges; } @@ -669,7 +725,7 @@ private Map getAttributes(@NotNull OperationContext ctx, @NotNull VcsRoot mainRoot, @NotNull ChangeSet cset) throws VcsException { Map attributes = new HashMap(); HgVcsRoot root = myHgVcsRootFactory.createHgRoot(mainRoot); - if (myConfig.detectSubrepoChanges() && root.detectSubrepoChanges()) { + if (detectSubrepoChanges(root)) { try { ServerHgRepo repo = createRepo(ctx, root); SubrepoConfigChangesAttributes builder = new SubrepoConfigChangesAttributes(); @@ -706,23 +762,6 @@ } @NotNull - private List getSubrepoChanges(@NotNull OperationContext ctx, @NotNull ModificationData m) throws VcsException { - List subrepoChanges = new ArrayList(); - for (SubrepoConfigChange configChange : SubrepoConfigChangesAttributes.readSubrepoConfigChanges(m.getAttributes())) { - if (configChange.getSubrepoRootParams().isEmpty()) - continue; - if (configChange.getPreviousSubrepoRevisions().isEmpty()) - continue; - VcsRootImpl subrepo = new VcsRootImpl(m.getVcsRootObject().getId(), configChange.getSubrepoRootParams()); - if (ctx.isProcessedSubrepoChanges(subrepo, configChange.getPreviousSubrepoRevisions(), configChange.getCurrentSubrepoRevision())) - continue; - subrepoChanges.addAll(collectChanges(ctx, subrepo, configChange.getPreviousSubrepoRevisions(), configChange.getCurrentSubrepoRevision(), CheckoutRules.DEFAULT)); - ctx.markProcessedSubrepoChanges(subrepo, configChange.getPreviousSubrepoRevisions(), configChange.getCurrentSubrepoRevision()); - } - return subrepoChanges; - } - - @NotNull public BuildPatchPolicy getBuildPatchPolicy() { return this; } diff -r 110de749f460 -r 4f1c0ecc3371 mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/OperationContext.java --- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/OperationContext.java Wed Feb 27 17:00:42 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/OperationContext.java Thu Feb 28 19:13:52 2013 +0400 @@ -3,9 +3,11 @@ import com.intellij.openapi.util.Pair; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.AuthSettings; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; +import jetbrains.buildServer.vcs.ModificationData; import jetbrains.buildServer.vcs.VcsException; import jetbrains.buildServer.vcs.VcsRoot; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.*; @@ -16,7 +18,8 @@ private final RepoFactory myRepoFactory; private Set mySyncedDirs = new HashSet(); private Map myHgVersions = new HashMap(); - private Map> myProcessedSubrepoChanges = new HashMap>(); + private Map> myProcessedSubrepoChanges = new HashMap>();//subrepo url -> processed changes intervals + private Map> myRevisionsPerRoot = new HashMap>(); private Map myRepos = new HashMap(); public OperationContext(@NotNull MercurialVcsSupport vcs, @@ -74,9 +77,40 @@ return repo; } + public boolean isReportedModification(@NotNull ModificationData m) { + Set revisions = getReportedRootRevisions(m); + return revisions.contains(m.getVersion()); + } + + public void markAsReported(@NotNull ModificationData m) { + Set revisions = getReportedRootRevisions(m); + revisions.add(m.getVersion()); + } + + @NotNull + private Set getReportedRootRevisions(@NotNull ModificationData m) { + VcsRootKey key = VcsRootKey.create(m.getVcsRoot()); + Set revisions = myRevisionsPerRoot.get(key); + if (revisions == null) { + revisions = new HashSet(); + myRevisionsPerRoot.put(key, revisions); + } + return revisions; + } + private final static class SubrepoChangesInterval extends Pair, String> { private SubrepoChangesInterval(@NotNull List prevRevisions, @NotNull String currentRevision) { super(prevRevisions, currentRevision); } } + + private final static class VcsRootKey extends Pair { + private VcsRootKey(@NotNull String repositoryUrl, @Nullable String subrepoPath) { + super(repositoryUrl, subrepoPath); + } + + private static VcsRootKey create(@NotNull VcsRoot root) { + return new VcsRootKey(root.getProperty(Constants.REPOSITORY_PROP), root.getProperty("teamcity.internal.subrepo.path")); + } + } } diff -r 110de749f460 -r 4f1c0ecc3371 mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java --- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java Wed Feb 27 17:00:42 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java Thu Feb 28 19:13:52 2013 +0400 @@ -603,6 +603,16 @@ } + public void should_not_report_duplicate_changes() throws Exception { + VcsRootImpl root = createVcsRoot(myRep2Path); + List changes = myVcs.collectChanges(root, + RepositoryStateData.createVersionState("default", map("default", "505c5b9d01e6", "personal-branch", "96b78d73081d")), + RepositoryStateData.createVersionState("default", map("default", "df04faa7575a", "personal-branch", "9ec402c74298")), + CheckoutRules.DEFAULT); + assertEquals(changes.size(), 4); + } + + private void assertFiles(final List expectedFiles, final ModificationData modificationData) { Set actualFiles = new HashSet(); for (VcsChange vc: modificationData.getChanges()) {