Mercurial > hg > mercurial
changeset 783:d60aa99940ba Gaya-8.1.x
TW-36113 retrieve bookmarks with repository lock held
author | Dmitry Neverov <dmitry.neverov@gmail.com> |
---|---|
date | Thu, 17 Apr 2014 19:56:05 +0200 |
parents | 3cd449e58f70 |
children | f0327df85b9d 83e1fb5aa843 |
files | mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CheckoutRepository.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCollectChangesPolicy.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCommitsInfoBuilderSupport.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/VcsCallable.java |
diffstat | 5 files changed, 90 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CheckoutRepository.java Wed Apr 16 18:12:04 2014 +0200 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CheckoutRepository.java Thu Apr 17 19:56:05 2014 +0200 @@ -54,6 +54,7 @@ myPullTimeout = pullTimeout; myRoot = root; myWorkingDir = workingDir; + myGlobalTagsAsBranches = globalTagsAsBranches; } public CheckoutRepository setRevision(String revision) { @@ -73,13 +74,7 @@ private void checkout(@NotNull HgVcsRoot root, @NotNull File workingDir, @Nullable String revision) throws VcsException { - updateRepository(root, workingDir, revision); - if (revision == null && myBranch != null) { - HgRepo repo = myHgRepoFactory.createRepo(root, workingDir); - boolean includeTags = myGlobalTagsAsBranches && root.useTagsAsBranches(); - Map<String, String> revisions = repo.getBranchRevisions(true, includeTags); - revision = revisions.get(myBranch); - } + revision = updateRepository(root, workingDir, revision); if (revision == null) return; updateSubrepos(root, workingDir, revision); @@ -87,14 +82,15 @@ } - private void updateRepository(@NotNull HgVcsRoot root, - @NotNull File workingDir, - @Nullable String revision) throws VcsException { + @Nullable + private String updateRepository(@NotNull HgVcsRoot root, + @NotNull File workingDir, + @Nullable String revision) throws VcsException { HgRepo repo = myHgRepoFactory.createRepo(root, workingDir); if (revision != null && repo.containsRevision(revision)) - return; + return revision; - updateMirror(root, revision); + String rev = updateMirror(root, revision); String mirrorUrl = getMirrorUrl(root); if (repo.isValidRepository()) { @@ -108,6 +104,7 @@ repo.setDefaultPath(root.getRepository()); } + return rev; } @@ -163,24 +160,42 @@ } - private void updateMirror(@NotNull HgVcsRoot root, @Nullable String revision) throws VcsException { + /** + * @return the given revision if it was not null, or revision of the myBranch if myBranch != null, + * otherwise returns null. Need to resolve a branch revision with mirror lock because bookmarks + * can be deleted by another thread. + */ + @Nullable + private String updateMirror(@NotNull HgVcsRoot root, @Nullable String revision) throws VcsException { String url = root.getRepository(); File mirrorDir = myMirrorManager.getMirrorDir(url); - HgRepo repo = myHgRepoFactory.createRepo(root, mirrorDir); - if (revision != null && repo.containsRevision(revision)) { - return; - } + myMirrorManager.lockDir(mirrorDir); + try { + HgRepo repo = myHgRepoFactory.createRepo(root, mirrorDir); + if (revision != null && repo.containsRevision(revision)) { + return revision; + } - if (repo.isValidRepository()) { - repo.pull().fromRepository(root.getRepository()) - .withTimeout(myPullTimeout) - .call(); - } else { - repo.doClone().fromRepository(root.getRepository()) - .setUpdateWorkingDir(false) - .useUncompressedTransfer(root.isUncompressedTransfer()) - .call(); - repo.setDefaultPath(root.getRepository()); + if (repo.isValidRepository()) { + repo.pull().fromRepository(root.getRepository()) + .withTimeout(myPullTimeout) + .call(); + } else { + repo.doClone().fromRepository(root.getRepository()) + .setUpdateWorkingDir(false) + .useUncompressedTransfer(root.isUncompressedTransfer()) + .call(); + repo.setDefaultPath(root.getRepository()); + } + + if (revision != null) + return revision; + if (myBranch == null) + return null; + boolean includeTags = myGlobalTagsAsBranches && root.useTagsAsBranches(); + return repo.getBranchRevisions(true, includeTags).get(myBranch); + } finally { + myMirrorManager.unlockDir(mirrorDir); } }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCollectChangesPolicy.java Wed Apr 16 18:12:04 2014 +0200 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCollectChangesPolicy.java Thu Apr 17 19:56:05 2014 +0200 @@ -60,9 +60,12 @@ @NotNull public RepositoryStateData getCurrentState(@NotNull VcsRoot root) throws VcsException { - HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); - myVcs.syncRepository(hgRoot); - final Map<String, String> revisions = getHeads(hgRoot); + final HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); + Map<String, String> revisions = myVcs.syncRepository(hgRoot, new VcsCallable<Map<String, String>>() { + public Map<String, String> call() throws VcsException { + return getHeads(hgRoot); + } + }); String defaultBranchName = hgRoot.getBranchName(); if (revisions.get(defaultBranchName) == null) { throw new VcsException("Cannot find revision of the default branch '" +
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCommitsInfoBuilderSupport.java Wed Apr 16 18:12:04 2014 +0200 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCommitsInfoBuilderSupport.java Thu Apr 17 19:56:05 2014 +0200 @@ -59,9 +59,11 @@ final HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); final ServerHgRepo repo = mySupport.createRepo(hgRoot); - mySupport.syncRepository(hgRoot); - - final MultiMapToList<String, String> heads = commitToBranchs(mySupport.getCollectChangesPolicy().getHeads(hgRoot)); + final MultiMapToList<String, String> heads = mySupport.syncRepository(hgRoot, new VcsCallable<MultiMapToList<String, String>>() { + public MultiMapToList<String, String> call() throws VcsException { + return commitToBranchs(mySupport.getCollectChangesPolicy().getHeads(hgRoot)); + } + }); repo.logSubstates().call(new CommitsAndMountPointsCommand.Callback() { private final MercurialCommitsInfoBuilderStates subs = new MercurialCommitsInfoBuilderStates();
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Wed Apr 16 18:12:04 2014 +0200 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Thu Apr 17 19:56:05 2014 +0200 @@ -494,6 +494,10 @@ } public void syncRepository(@NotNull final HgVcsRoot root) throws VcsException { + syncRepository(root, VcsCallable.NO_OP); + } + + public <T> T syncRepository(@NotNull HgVcsRoot root, @NotNull VcsCallable<T> cmd) throws VcsException { File workingDir = getWorkingDir(root); lockWorkDir(workingDir); HgRepo repo = createRepo(root); @@ -520,6 +524,7 @@ .call(); repo.setDefaultPath(root.getRepository()); } + return cmd.call(); } finally { unlockWorkDir(workingDir); } @@ -638,7 +643,7 @@ return label.replace(':', '_').replace('\r', '_').replace('\n', '_'); } - public File getWorkingDir(HgVcsRoot root) { + public File getWorkingDir(@NotNull HgVcsRoot root) { File customDir = root.getCustomWorkingDir(); return customDir != null ? customDir : myMirrorManager.getMirrorDir(root.getRepository()); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/VcsCallable.java Thu Apr 17 19:56:05 2014 +0200 @@ -0,0 +1,31 @@ +/* + * 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; + +import jetbrains.buildServer.vcs.VcsException; + +import java.util.concurrent.Callable; + +public interface VcsCallable<T> extends Callable<T> { + VcsCallable<Void> NO_OP = new VcsCallable<Void>() { + public Void call() throws VcsException { + return null; + } + }; + + public T call() throws VcsException; +}