diff mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CheckoutRepository.java @ 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 31a1aca3305c
children a6405f5aad54
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);
     }
   }