Merge branch 'svn_18_3'
authorKonstantin Kolosovsky <konstantin.kolosovsky@jetbrains.com>
Tue, 18 Feb 2014 16:59:05 +0000 (20:59 +0400)
committerKonstantin Kolosovsky <konstantin.kolosovsky@jetbrains.com>
Tue, 18 Feb 2014 16:59:05 +0000 (20:59 +0400)
17 files changed:
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsNumbersCache.java
plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java
plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java
plugins/svn4idea/src/org/jetbrains/idea/svn/browse/CmdBrowseClient.java
plugins/svn4idea/src/org/jetbrains/idea/svn/browse/SvnKitBrowseClient.java
plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java
plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java
plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java
plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java
plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/QuickMerge.java
plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java
plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java
plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryLocation.java
plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java
plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesTask.java
plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java

index 30d8f5ef88c0fc57cb3f009498ce94fd53cfe899..03788f19619278371dd06a90433171dd82850411 100644 (file)
@@ -57,9 +57,8 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
       return "NOT_LOADED";
     }
 
-    public int compareTo(VcsRevisionNumber o) {
-      if (o == this) return 0;
-      return -1;
+    public int compareTo(@NotNull VcsRevisionNumber o) {
+      return o == this ? 0 : -1;
     }
   };
   public static final VcsRevisionNumber UNKNOWN = new VcsRevisionNumber() {
@@ -67,9 +66,8 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
       return "UNKNOWN";
     }
 
-    public int compareTo(VcsRevisionNumber o) {
-      if (o == this) return 0;
-      return -1;
+    public int compareTo(@NotNull VcsRevisionNumber o) {
+      return o == this ? 0 : -1;
     }
   };
   private final VcsConfiguration myVcsConfiguration;
@@ -156,7 +154,7 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
     synchronized (myLock) {
       final LazyRefreshingSelfQueue<String> oldQueue = getQueue(oldVcsRoot);
       final LazyRefreshingSelfQueue<String> newQueue = getQueue(newVcsRoot);
-      myData.put(key, new Pair<VcsRoot, VcsRevisionNumber>(newVcsRoot, NOT_LOADED));
+      myData.put(key, Pair.create(newVcsRoot, NOT_LOADED));
       oldQueue.forceRemove(key);
       newQueue.addRequest(key);
     }
@@ -178,7 +176,7 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
       final Pair<VcsRoot, VcsRevisionNumber> value = myData.get(key);
       if (value == null) {
         final LazyRefreshingSelfQueue<String> queue = getQueue(vcsRoot);
-        myData.put(key, new Pair<VcsRoot, VcsRevisionNumber>(vcsRoot, NOT_LOADED));
+        myData.put(key, Pair.create(vcsRoot, NOT_LOADED));
         queue.addRequest(key);
       } else if (! value.getFirst().equals(vcsRoot)) {
         switchVcs(value.getFirst(), vcsRoot, key);
@@ -196,7 +194,7 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
           final LazyRefreshingSelfQueue<String> queue = getQueue(vcsRoot);
           queue.forceRemove(path);
           queue.addRequest(path);
-          myData.put(path, new Pair<VcsRoot, VcsRevisionNumber>(vcsRoot, NOT_LOADED));
+          myData.put(path, Pair.create(vcsRoot, NOT_LOADED));
         }
       }
     }
@@ -268,7 +266,7 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
         myData.put(s, new Pair<VcsRoot, VcsRevisionNumber>(myVcsRoot, newNumber));
       }
 
-      if ((oldPair == null) || (oldPair != null) && (oldPair.getSecond().compareTo(newNumber) != 0)) {
+      if (oldPair == null || oldPair.getSecond().compareTo(newNumber) != 0) {
         LOG.debug("refresh triggered by " + s);
         mySomethingChanged = true;
       }
@@ -320,9 +318,6 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
 
   /**
    * Returns {@code true} if passed revision is up to date, comparing to latest repository revision.
-   *
-   * @param revision
-   * @return
    */
   private boolean getRevisionState(final ContentRevision revision) {
     if (revision != null) {
@@ -330,10 +325,8 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker {
       final VcsRevisionNumber local = revision.getRevisionNumber();
       final String path = revision.getFile().getIOFile().getAbsolutePath();
       final VcsRevisionNumber remote = getNumber(path);
-      if ((NOT_LOADED == remote) || (UNKNOWN == remote)) {
-        return true;
-      }
-      return local.compareTo(remote) >= 0;
+
+      return NOT_LOADED == remote || UNKNOWN == remote || local.compareTo(remote) >= 0;
     }
     return true;
   }
index 1b0792a51c227631ad26372d56cf18b439156ed7..39835e6488ad34803dc62d0109820b8e88ebda3b 100644 (file)
@@ -25,4 +25,5 @@ public interface SvnPropertyKeys {
   String SVN_IGNORE = "svn:ignore";
   String SVN_EXTERNALS = "svn:externals";
   String LOG = "svn:log";
+  String MERGE_INFO = "svn:mergeinfo";
 }
index 1e3fd7b1fb18e93e72dfdf9f39e0fb795291ffa6..3b8bb4ac57cf3abe9ace62b4ed804f028bf0bd08 100644 (file)
@@ -39,13 +39,14 @@ import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.VirtualFileManager;
 import com.intellij.openapi.wm.impl.status.StatusBarUtil;
 import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.Convertor;
 import com.intellij.util.containers.MultiMap;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
-import org.jetbrains.idea.svn.api.ClientFactory;
 import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
+import org.jetbrains.idea.svn.commandLine.SvnBindException;
 import org.jetbrains.idea.svn.dialogs.LockDialog;
 import org.tmatesoft.sqljet.core.SqlJetException;
 import org.tmatesoft.sqljet.core.table.SqlJetDb;
@@ -105,6 +106,16 @@ public class SvnUtil {
     return info != null;
   }
 
+  public static List<File> toFiles(Iterable<String> paths) {
+    List<File> result = ContainerUtil.newArrayList();
+
+    for (String path : paths) {
+      result.add(new File(path));
+    }
+
+    return result;
+  }
+
   public static Collection<VirtualFile> crawlWCRoots(final Project project, File path, SvnWCRootCrawler callback, ProgressIndicator progress) {
     final LocalFileSystem lfs = LocalFileSystem.getInstance();
     VirtualFile vf = lfs.findFileByIoFile(path);
@@ -763,16 +774,21 @@ public class SvnUtil {
   }
 
   @NotNull
-  public static SVNURL createUrl(@NotNull String url) throws SVNException {
-    SVNURL result = SVNURL.parseURIEncoded(url);
+  public static SVNURL createUrl(@NotNull String url) throws SvnBindException {
+    try {
+      SVNURL result = SVNURL.parseURIEncoded(url);
 
-    // explicitly check if port corresponds to default port and recreate url specifying default port indicator
-    if (result.hasPort() && hasDefaultPort(result)) {
-      result = SVNURL
-        .create(result.getProtocol(), result.getUserInfo(), result.getHost(), DEFAULT_PORT_INDICATOR, result.getURIEncodedPath(), true);
-    }
+      // explicitly check if port corresponds to default port and recreate url specifying default port indicator
+      if (result.hasPort() && hasDefaultPort(result)) {
+        result = SVNURL
+          .create(result.getProtocol(), result.getUserInfo(), result.getHost(), DEFAULT_PORT_INDICATOR, result.getURIEncodedPath(), true);
+      }
 
-    return result;
+      return result;
+    }
+    catch (SVNException e) {
+      throw new SvnBindException(e);
+    }
   }
 
   public static SVNURL parseUrl(@NotNull String url) {
index 2cbbc1c9024b25cf4cc763efce7bcb19e12281a5..5e1bba8ddccb2c726cedd1e0cdc13593e81a94bc 100644 (file)
@@ -15,7 +15,6 @@
  */
 package org.jetbrains.idea.svn.branchConfig;
 
-import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vcs.VcsException;
 import org.jetbrains.annotations.NotNull;
@@ -63,6 +62,7 @@ public class BranchesLoader {
   private static ISVNDirEntryHandler createHandler(@NotNull final SVNURL branchesUrl, @NotNull final List<SvnBranchItem> result) {
     return new ISVNDirEntryHandler() {
       public void handleDirEntry(final SVNDirEntry dirEntry) throws SVNException {
+        // TODO: Remove equality check with branchesUrl when SVNLogClient will not be used directly, but rather through BrowseClient.
         if (!branchesUrl.equals(dirEntry.getURL()) && dirEntry.getDate() != null) {
           result.add(new SvnBranchItem(dirEntry.getURL().toDecodedString(), dirEntry.getDate(), dirEntry.getRevision()));
         }
index b8fba0c6e6bf8106a707f75d20eedc8fc8586673..782d521dc5c00a3e13fba41d3181f5fd40ad65f2 100644 (file)
@@ -16,6 +16,7 @@
 package org.jetbrains.idea.svn.browse;
 
 import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.PathUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.api.BaseSvnClient;
@@ -129,12 +130,12 @@ public class CmdBrowseClient extends BaseSvnClient implements BrowseClient {
     }
 
     public SVNDirEntry toDirEntry(@NotNull SVNURL url) throws SVNException {
-      // TODO: repository root and relative path are not used for now
+      // TODO: repository is not used for now
       SVNDirEntry entry =
-        new SVNDirEntry(url.appendPath(name, false), null, name, SVNNodeKind.parseKind(kind), size, false, revision(), date(),
-                        author());
+        new SVNDirEntry(url.appendPath(name, false), null, PathUtil.getFileName(name), SVNNodeKind.parseKind(kind), size, false, revision(),
+                        date(), author());
 
-      entry.setRelativePath(null);
+      entry.setRelativePath(name);
       entry.setLock(lock != null ? lock.toLock(entry.getRelativePath()) : null);
 
       return entry;
index 29531ab7c8fa2146fd5875a5b8963368c5f16b05..95388a12a8ecacd7efaa7f4230db70a25c15de9a 100644 (file)
  */
 package org.jetbrains.idea.svn.browse;
 
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.VcsException;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.api.BaseSvnClient;
 import org.jetbrains.idea.svn.commandLine.SvnBindException;
-import org.tmatesoft.svn.core.ISVNDirEntryHandler;
-import org.tmatesoft.svn.core.SVNDepth;
-import org.tmatesoft.svn.core.SVNDirEntry;
-import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.*;
 import org.tmatesoft.svn.core.wc.SVNLogClient;
 import org.tmatesoft.svn.core.wc.SVNRevision;
 import org.tmatesoft.svn.core.wc2.SvnTarget;
@@ -40,17 +38,43 @@ public class SvnKitBrowseClient extends BaseSvnClient implements BrowseClient {
     assertUrl(target);
 
     SVNLogClient client = myVcs.createLogClient();
+    ISVNDirEntryHandler wrappedHandler = wrapHandler(handler);
 
     try {
       if (target.isFile()) {
-        client.doList(target.getFile(), target.getPegRevision(), revision, true, depth, SVNDirEntry.DIRENT_ALL, handler);
+        client.doList(target.getFile(), target.getPegRevision(), revision, true, depth, SVNDirEntry.DIRENT_ALL, wrappedHandler);
       }
       else {
-        client.doList(target.getURL(), target.getPegRevision(), revision, true, depth, SVNDirEntry.DIRENT_ALL, handler);
+        client.doList(target.getURL(), target.getPegRevision(), revision, true, depth, SVNDirEntry.DIRENT_ALL, wrappedHandler);
       }
     }
     catch (SVNException e) {
       throw new SvnBindException(e);
     }
   }
-}
+
+  @Nullable
+  private static ISVNDirEntryHandler wrapHandler(@Nullable ISVNDirEntryHandler handler) {
+    return handler == null ? null : new SkipEmptyNameDirectoriesHandler(handler);
+  }
+
+  public static class SkipEmptyNameDirectoriesHandler implements ISVNDirEntryHandler {
+
+    @NotNull private final ISVNDirEntryHandler handler;
+
+    public SkipEmptyNameDirectoriesHandler(@NotNull ISVNDirEntryHandler handler) {
+      this.handler = handler;
+    }
+
+    @Override
+    public void handleDirEntry(SVNDirEntry dirEntry) throws SVNException {
+      if (!isEmptyNameDirectory(dirEntry)) {
+        handler.handleDirEntry(dirEntry);
+      }
+    }
+
+    private static boolean isEmptyNameDirectory(SVNDirEntry dirEntry) {
+      return SVNNodeKind.DIR.equals(dirEntry.getKind()) && StringUtil.isEmpty(dirEntry.getName());
+    }
+  }
+}
\ No newline at end of file
index 8a4b2031c8ced40c5c20151e5ad853d7905f8ba8..96c96161c898f78c23a99a74a77f3ed83cecb4f8 100644 (file)
  */
 package org.jetbrains.idea.svn.checkin;
 
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.SvnBundle;
 import org.jetbrains.idea.svn.SvnUtil;
 import org.jetbrains.idea.svn.commandLine.CommitEventHandler;
 import org.jetbrains.idea.svn.commandLine.CommitEventType;
-import org.jetbrains.idea.svn.SvnBundle;
+import org.tmatesoft.svn.core.SVNCancelException;
 import org.tmatesoft.svn.core.wc.ISVNEventHandler;
 import org.tmatesoft.svn.core.wc.SVNEvent;
 import org.tmatesoft.svn.core.wc.SVNEventAction;
 
 import java.io.File;
+import java.util.List;
 
 /**
  * Created with IntelliJ IDEA.
@@ -34,10 +44,23 @@ import java.io.File;
  * Time: 11:13 AM
  */
 public class IdeaCommitHandler implements CommitEventHandler, ISVNEventHandler {
-  private final ProgressIndicator myProgress;
 
-  public IdeaCommitHandler(ProgressIndicator progress) {
+  @Nullable private final ProgressIndicator myProgress;
+  @NotNull private final List<VirtualFile> myDeletedFiles = ContainerUtil.newArrayList();
+  private final boolean myCheckCancel;
+
+  public IdeaCommitHandler(@Nullable ProgressIndicator progress) {
+    this(progress, false);
+  }
+
+  public IdeaCommitHandler(@Nullable ProgressIndicator progress, boolean checkCancel) {
     myProgress = progress;
+    myCheckCancel = checkCancel;
+  }
+
+  @NotNull
+  public List<VirtualFile> getDeletedFiles() {
+    return myDeletedFiles;
   }
 
   @Override
@@ -57,17 +80,30 @@ public class IdeaCommitHandler implements CommitEventHandler, ISVNEventHandler {
 
   public void handleEvent(SVNEvent event, double p) {
     final String path = SvnUtil.getPathForProgress(event);
-    if (path == null) {
-      return;
-    }
+    if (path != null) {
+      CommitEventType eventType = convert(event.getAction());
 
-    updateProgress(convert(event.getAction()), path);
+      if (CommitEventType.deleting.equals(eventType)) {
+        trackDeletedFile(event);
+      }
+      updateProgress(eventType, path);
+    }
   }
 
-  public void checkCancelled() {
+  public void checkCancelled() throws SVNCancelException {
+    if (myCheckCancel && myProgress != null) {
+      try {
+        myProgress.checkCanceled();
+      }
+      catch (ProcessCanceledException ex) {
+        throw new SVNCancelException();
+      }
+    }
   }
 
   private void updateProgress(@NotNull CommitEventType type, @NotNull String target) {
+    if (myProgress == null) return;
+
     if (CommitEventType.adding.equals(type)) {
       myProgress.setText2(SvnBundle.message("progress.text2.adding", target));
     } else if (CommitEventType.deleting.equals(type)) {
@@ -81,6 +117,21 @@ public class IdeaCommitHandler implements CommitEventHandler, ISVNEventHandler {
     }
   }
 
+  private void trackDeletedFile(@NotNull SVNEvent event) {
+    @NonNls final String filePath = "file://" + event.getFile().getAbsolutePath().replace(File.separatorChar, '/');
+    VirtualFile virtualFile = ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile>() {
+      @Nullable
+      public VirtualFile compute() {
+        return VirtualFileManager.getInstance().findFileByUrl(filePath);
+      }
+    });
+
+    if (virtualFile != null) {
+      myDeletedFiles.add(virtualFile);
+    }
+  }
+
+  @NotNull
   private static CommitEventType convert(@NotNull SVNEventAction action) {
     CommitEventType result = null;
 
index c296cb25b8b7aa8b21fda02c2a180eba0bdec5f6..8c9756ba8a1d8194815cdc47b2c06c5ee9de161d 100644 (file)
@@ -18,39 +18,42 @@ package org.jetbrains.idea.svn.checkin;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.diff.impl.patch.formove.FilePathComparator;
-import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.MessageType;
-import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vcs.*;
+import com.intellij.openapi.vcs.AbstractFilterChildren;
+import com.intellij.openapi.vcs.CheckinProjectPanel;
+import com.intellij.openapi.vcs.FilePath;
+import com.intellij.openapi.vcs.VcsException;
 import com.intellij.openapi.vcs.changes.Change;
 import com.intellij.openapi.vcs.changes.ChangeList;
 import com.intellij.openapi.vcs.changes.ChangesUtil;
 import com.intellij.openapi.vcs.changes.ContentRevision;
 import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
-import com.intellij.openapi.vcs.ui.Refreshable;
 import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
 import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
+import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.VirtualFileManager;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.FunctionUtil;
 import com.intellij.util.NullableFunction;
 import com.intellij.util.PairConsumer;
+import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.Convertor;
 import com.intellij.util.containers.MultiMap;
-import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.*;
 import org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient;
 import org.jetbrains.idea.svn.commandLine.SvnCommitRunner;
-import org.tmatesoft.svn.core.*;
+import org.tmatesoft.svn.core.SVNCommitInfo;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
 import org.tmatesoft.svn.core.wc.*;
 
 import javax.swing.*;
@@ -60,16 +63,17 @@ import java.util.*;
 import java.util.List;
 
 public class SvnCheckinEnvironment implements CheckinEnvironment {
-  private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.checkin.SvnCheckinEnvironment");
-  private final SvnVcs mySvnVcs;
 
-  public SvnCheckinEnvironment(SvnVcs svnVcs) {
+  private static final Logger LOG = Logger.getInstance(SvnCheckinEnvironment.class);
+  @NotNull private final SvnVcs mySvnVcs;
+
+  public SvnCheckinEnvironment(@NotNull SvnVcs svnVcs) {
     mySvnVcs = svnVcs;
   }
 
   public RefreshableOnComponent createAdditionalOptionsPanel(CheckinProjectPanel panel,
                                                              PairConsumer<Object, Object> additionalDataConsumer) {
-    return new KeepLocksComponent(panel);
+    return new KeepLocksComponent();
   }
 
   @Nullable
@@ -83,58 +87,16 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
   }
 
 
-  private List<VcsException> commitInt(List<File> paths, final String comment, final boolean force, final boolean recursive,
-                                       final Set<String> feedback) {
+  private List<VcsException> commitInt(List<File> paths, final String comment, final boolean force, final Set<String> feedback) {
     final List<VcsException> exception = new ArrayList<VcsException>();
     final List<File> committables = getCommitables(paths);
 
     final SVNCommitClient committer = mySvnVcs.createCommitClient();
 
     final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
-    final Collection<VirtualFile> deletedFiles = new ArrayList<VirtualFile>();
+    IdeaCommitHandler handler = new IdeaCommitHandler(progress, true);
     if (progress != null) {
-      committer.setEventHandler(new ISVNEventHandler() {
-        public void handleEvent(final SVNEvent event, double p) {
-          final String path = SvnUtil.getPathForProgress(event);
-          if (path == null) {
-            return;
-          }
-          if (event.getAction() == SVNEventAction.COMMIT_ADDED) {
-            progress.setText2(SvnBundle.message("progress.text2.adding", path));
-          }
-          else if (event.getAction() == SVNEventAction.COMMIT_DELETED) {
-            @NonNls final String filePath = "file://" + event.getFile().getAbsolutePath().replace(File.separatorChar, '/');
-            VirtualFile vf = ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile>() {
-              @Nullable public VirtualFile compute() {
-                return VirtualFileManager.getInstance().findFileByUrl(filePath);
-              }
-            });
-            if (vf != null) {
-              deletedFiles.add(vf);
-            }
-            progress.setText2(SvnBundle.message("progress.text2.deleting", path));
-          }
-          else if (event.getAction() == SVNEventAction.COMMIT_MODIFIED) {
-            progress.setText2(SvnBundle.message("progress.text2.sending", path));
-          }
-          else if (event.getAction() == SVNEventAction.COMMIT_REPLACED) {
-            progress.setText2(SvnBundle.message("progress.text2.replacing", path));
-          }
-          else if (event.getAction() == SVNEventAction.COMMIT_DELTA_SENT) {
-            progress.setText2(SvnBundle.message("progress.text2.transmitting.delta", path));
-          }
-          // do not need COMMIT_COMPLETED: same info is get another way
-        }
-
-        public void checkCancelled() throws SVNCancelException {
-          try {
-            progress.checkCanceled();
-          }
-          catch(ProcessCanceledException ex) {
-            throw new SVNCancelException();
-          }
-        }
-      });
+      committer.setEventHandler(handler);
     }
 
     if (progress != null) {
@@ -143,7 +105,6 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
     else if (ApplicationManager.getApplication().isDispatchThread()) {
       ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
         public void run() {
-          ProgressIndicator p = ProgressManager.getInstance().getProgressIndicator();
           doCommit(committables, committer, comment, force, exception, feedback);
         }
       }, SvnBundle.message("progress.title.commit"), false, mySvnVcs.getProject());
@@ -152,7 +113,9 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
       doCommit(committables, committer, comment, force, exception, feedback);
     }
 
-    for(VirtualFile f : deletedFiles) {
+    // TODO: Check if such processing of deleted files also necessary for command line. And if yes - use one handler instance for both
+    // TODO: SVNKit and command line code flows.
+    for(VirtualFile f : handler.getDeletedFiles()) {
       f.putUserData(VirtualFile.REQUESTOR_MARKER, this);
     }
     return exception;
@@ -163,9 +126,10 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
                         String comment,
                         boolean force,
                         List<VcsException> exception, final Set<String> feedback) {
+    //noinspection unchecked
     final MultiMap<Pair<SVNURL,WorkingCopyFormat>,File> map = SvnUtil.splitIntoRepositoriesMap(mySvnVcs, committables, Convertor.SELF);
     for (Map.Entry<Pair<SVNURL, WorkingCopyFormat>, Collection<File>> entry : map.entrySet()) {
-      doCommitOneRepo(entry.getValue(), committer, comment, force, exception, feedback, entry.getKey().getSecond(), entry.getKey().getFirst());
+      doCommitOneRepo(entry.getValue(), committer, comment, force, exception, feedback, entry.getKey().getSecond());
     }
   }
 
@@ -173,18 +137,18 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
                                SVNCommitClient committer,
                                String comment,
                                boolean force,
-                               List<VcsException> exception, final Set<String> feedback, final WorkingCopyFormat format, SVNURL url) {
+                               List<VcsException> exception, final Set<String> feedback, final WorkingCopyFormat format) {
     if (committables.isEmpty()) {
       return;
     }
-    if (WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) || WorkingCopyFormat.ONE_DOT_SEVEN.equals(format) &&
-        SvnConfiguration.getInstance(mySvnVcs.getProject()).isCommandLine() &&
-        (SvnAuthenticationManager.HTTP.equals(url.getProtocol()) || SvnAuthenticationManager.HTTPS.equals(url.getProtocol()))) {
+    // TODO: Create CommitClient and refactor to use common ClientFactory model.
+    if (WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) ||
+        !WorkingCopyFormat.ONE_DOT_SIX.equals(format) && mySvnVcs.getSvnConfiguration().isCommandLine()) {
       doWithCommandLine(committables, comment, exception, feedback);
-      return;
     }
-
-    doWithSvnkit(committables, committer, comment, force, exception, feedback);
+    else {
+      doWithSvnkit(committables, committer, comment, force, exception, feedback);
+    }
   }
 
   private void doWithSvnkit(Collection<File> committables,
@@ -209,18 +173,17 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
     }
     finally {
       if (commitPackets != null) {
-        for (int i = 0; i < commitPackets.length; i++) {
-          SVNCommitPacket commitPacket = commitPackets[i];
+        for (SVNCommitPacket commitPacket : commitPackets) {
           try {
             commitPacket.dispose();
           }
           catch (SVNException e) {
-            //
+            LOG.info(e);
           }
         }
       }
     }
-    final StringBuffer committedRevisions = new StringBuffer();
+    final StringBuilder committedRevisions = new StringBuilder();
     for (SVNCommitInfo result : results) {
       if (result.getErrorMessage() != null) {
         exception.add(new VcsException(result.getErrorMessage().getFullMessage()));
@@ -366,48 +329,36 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
     }
   }
 
-  private SVNStatus getStatus(File file) {
+  @Nullable
+  private SVNStatus getStatus(@NotNull File file) {
     SVNStatus result = null;
-    WorkingCopyFormat format = mySvnVcs.getWorkingCopyFormat(file);
 
     try {
-      result = WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) ? getStatusCommandLine(file) : getStatusSvnKit(file);
+      result = mySvnVcs.getFactory(file).createStatusClient().doStatus(file, false);
     }
     catch (SVNException e) {
-      // do nothing
+      LOG.info(e);
     }
 
     return result;
   }
 
-  private SVNStatus getStatusSvnKit(File file) throws SVNException {
-    return mySvnVcs.createStatusClient().doStatus(file, false);
-  }
-
-  private SVNStatus getStatusCommandLine(File file) throws SVNException {
-    return new SvnCommandLineStatusClient(mySvnVcs).doStatus(file, false);
-  }
-
-  private static List<File> collectPaths(final List<Change> changes) {
+  private static List<File> collectPaths(@NotNull List<Change> changes) {
     // case sensitive..
-    ArrayList<File> result = new ArrayList<File>();
+    Set<String> paths = ContainerUtil.newHashSet();
 
-    final Set<String> pathesSet = new HashSet<String>();
     for (Change change : changes) {
-      final ContentRevision beforeRevision = change.getBeforeRevision();
-      final ContentRevision afterRevision = change.getAfterRevision();
-      if (beforeRevision != null) {
-        pathesSet.add(beforeRevision.getFile().getIOFile().getAbsolutePath());
-      }
-      if (afterRevision != null) {
-        pathesSet.add(afterRevision.getFile().getIOFile().getAbsolutePath());
-      }
+      addPath(paths, change.getBeforeRevision());
+      addPath(paths, change.getAfterRevision());
     }
 
-    for (String s : pathesSet) {
-      result.add(new File(s));
+    return SvnUtil.toFiles(paths);
+  }
+
+  private static void addPath(@NotNull Collection<String> paths, @Nullable ContentRevision revision) {
+    if (revision != null) {
+      paths.add(revision.getFile().getIOFile().getAbsolutePath());
     }
-    return result;
   }
 
   public String getCheckinOperationName() {
@@ -418,11 +369,11 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
                                    String preparedComment,
                                    @NotNull NullableFunction<Object, Object> parametersHolder,
                                    Set<String> feedback) {
-    return commitInt(collectPaths(changes), preparedComment, true, false, feedback);
+    return commitInt(collectPaths(changes), preparedComment, true, feedback);
   }
 
   public List<VcsException> commit(List<Change> changes, String preparedComment) {
-    return commit(changes, preparedComment, FunctionUtil.<Object, Object>nullConstant(), null);
+    return commit(changes, preparedComment, FunctionUtil.nullConstant(), null);
   }
 
   public List<VcsException> scheduleMissingFileForDeletion(List<FilePath> filePaths) {
@@ -452,34 +403,25 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
   public static List<VcsException> scheduleUnversionedFilesForAddition(@NotNull SvnVcs vcs, List<VirtualFile> files, final boolean recursive) {
     Collections.sort(files, FilePathComparator.getInstance());
 
-    ISVNEventHandler eventHandler = new ISVNEventHandler() {
+    ISVNEventHandler eventHandler = new SvnProgressCanceller() {
       @Override
       public void handleEvent(SVNEvent event, double progress) throws SVNException {
-        final ProgressManager pm = ProgressManager.getInstance();
-        final ProgressIndicator pi = pm.getProgressIndicator();
-        // TODO: pi is null here when invoking "Add" action
-        if (pi != null && event.getFile() != null) {
-          File file = event.getFile();
-          pi.setText(SvnBundle.message("progress.text2.adding", file.getName() + " (" + file.getParent() + ")"));
-        }
-      }
+        // TODO: indicator is null here when invoking "Add" action
+        ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
+        File file = event.getFile();
 
-      @Override
-      public void checkCancelled() throws SVNCancelException {
-        final ProgressManager pm = ProgressManager.getInstance();
-        final ProgressIndicator pi = pm.getProgressIndicator();
-        if (pi != null) {
-          if (pi.isCanceled()) throw new SVNCancelException();
+        if (indicator != null && file != null) {
+          indicator.setText(SvnBundle.message("progress.text2.adding", file.getName() + " (" + file.getParent() + ")"));
         }
       }
     };
 
     List<VcsException> exceptions = new ArrayList<VcsException>();
+    SVNDepth depth = recursive ? SVNDepth.INFINITY : SVNDepth.EMPTY;
 
     for (VirtualFile file : files) {
       try {
-        File convertedFile = new File(FileUtil.toSystemDependentName(file.getPath()));
-        SVNDepth depth = recursive ? SVNDepth.INFINITY : SVNDepth.EMPTY;
+        File convertedFile = VfsUtilCore.virtualToIoFile(file);
 
         vcs.getFactory(convertedFile).createAddClient().add(convertedFile, depth, true, false, true, eventHandler);
       }
@@ -501,12 +443,13 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
   }
 
   private class KeepLocksComponent implements RefreshableOnComponent {
-    private final JCheckBox myKeepLocksBox;
+
+    @NotNull private final JCheckBox myKeepLocksBox;
     private boolean myIsKeepLocks;
-    private final JPanel myPanel;
-    private final JCheckBox myAutoUpdate;
+    @NotNull private final JPanel myPanel;
+    @NotNull private final JCheckBox myAutoUpdate;
 
-    public KeepLocksComponent(final Refreshable panel) {
+    public KeepLocksComponent() {
 
       myPanel = new JPanel(new BorderLayout());
       myKeepLocksBox = new JCheckBox(SvnBundle.message("checkbox.chckin.keep.files.locked"));
@@ -522,11 +465,11 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
     }
 
     public boolean isKeepLocks() {
-      return myKeepLocksBox != null && myKeepLocksBox.isSelected();
+      return myKeepLocksBox.isSelected();
     }
 
     public boolean isAutoUpdate() {
-      return myAutoUpdate != null && myAutoUpdate.isSelected();
+      return myAutoUpdate.isSelected();
     }
 
     public void refresh() {
@@ -544,5 +487,4 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
       myAutoUpdate.setSelected(configuration.isAutoUpdateAfterCommit());
     }
   }
-
 }
index ef4822607e3774e93932e69c8cd2948fabca89f1..8bbb58242e05c051fddc1f6ac4e05844a4346fe4 100644 (file)
@@ -195,7 +195,7 @@ public class SvnCommandLineInfoClient extends SvnkitSvnWcClient {
     }
   }
 
-  private void fillParameters(String path, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, List<String> parameters) {
+  private static void fillParameters(String path, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, List<String> parameters) {
     CommandUtil.put(parameters, depth);
     CommandUtil.put(parameters, revision);
     CommandUtil.put(parameters, path, pegRevision);
@@ -261,7 +261,7 @@ public class SvnCommandLineInfoClient extends SvnkitSvnWcClient {
       for (File file : paths) {
         CommandUtil.put(parameters, file);
       }
-      CommandUtil.put(parameters, true, "--xml");
+      parameters.add("--xml");
 
       // Currently do not handle exceptions here like in SvnVcs.handleInfoException - just continue with parsing in case of warnings for
       // some of the requested items
index 32b1dae809edea2038b5b1a47f3e890edc3963b6..6bd08c1089cb010b4a750f3fd88ff53a80fdc3ac 100644 (file)
@@ -34,8 +34,8 @@ import org.jetbrains.idea.svn.branchConfig.InfoReliability;
 import org.jetbrains.idea.svn.branchConfig.InfoStorage;
 import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigManager;
 import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
+import org.jetbrains.idea.svn.commandLine.SvnBindException;
 import org.jetbrains.idea.svn.integrate.SvnBranchItem;
-import org.tmatesoft.svn.core.SVNException;
 import org.tmatesoft.svn.core.SVNURL;
 import org.tmatesoft.svn.core.internal.util.SVNURLUtil;
 
@@ -164,7 +164,7 @@ public class BranchConfigurationDialog extends DialogWrapper {
       try {
         result = SvnUtil.createUrl(url);
       }
-      catch (SVNException e) {
+      catch (SvnBindException e) {
         myErrorPrompt.setText(e.getMessage());
       }
 
index 20077fc42e34c43bc5acc1c9c456c39cd032d1e9..2bf09e0b6dbaee260aefbd05f012254ed321080e 100644 (file)
@@ -46,6 +46,7 @@ import org.jetbrains.idea.svn.SvnBranchConfigurationManager;
 import org.jetbrains.idea.svn.SvnUtil;
 import org.jetbrains.idea.svn.SvnVcs;
 import org.jetbrains.idea.svn.actions.ChangeListsMergerFactory;
+import org.jetbrains.idea.svn.commandLine.SvnBindException;
 import org.jetbrains.idea.svn.history.SvnChangeList;
 import org.jetbrains.idea.svn.history.SvnCommittedChangesProvider;
 import org.jetbrains.idea.svn.history.SvnRepositoryLocation;
@@ -138,7 +139,7 @@ public class QuickMerge {
       try {
         url = SvnUtil.createUrl(mySourceUrl);
       }
-      catch (SVNException e) {
+      catch (SvnBindException e) {
         finishWithError(continuationContext, e.getMessage(), true);
       }
 
index 2af8f3c6d626cb410101a2bea444b71f6b7d1279..f894bb3f423e14ae59162a674c1ece664a0893ee 100644 (file)
@@ -24,22 +24,28 @@ package org.jetbrains.idea.svn.history;
 
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.AbstractVcs;
 import com.intellij.openapi.vcs.FilePath;
 import com.intellij.openapi.vcs.FilePathImpl;
+import com.intellij.openapi.vcs.VcsException;
 import com.intellij.openapi.vcs.changes.*;
 import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.ConstantFunction;
 import com.intellij.util.NotNullFunction;
+import com.intellij.util.UriUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.vcsUtil.VcsUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.*;
+import org.jetbrains.idea.svn.commandLine.SvnBindException;
 import org.tmatesoft.svn.core.*;
 import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
-import org.tmatesoft.svn.core.io.SVNRepository;
-import org.tmatesoft.svn.core.wc.SVNLogClient;
+import org.tmatesoft.svn.core.wc.SVNInfo;
 import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
 
 import java.io.DataInput;
 import java.io.DataOutput;
@@ -100,19 +106,15 @@ public class SvnChangeList implements CommittedChangeList {
     myVcs = vcs;
     myLocation = location;
     myRevision = logEntry.getRevision();
-    final String author = logEntry.getAuthor();
-    myAuthor = author == null ? "" : author;
+    myAuthor = StringUtil.notNullize(logEntry.getAuthor());
     myDate = logEntry.getDate();
-    final String message = logEntry.getMessage();
-    myMessage = message == null ? "" : message;
-
-    myRepositoryRoot = repositoryRoot.endsWith("/") ? repositoryRoot.substring(0, repositoryRoot.length() - 1) : repositoryRoot;
+    myMessage = StringUtil.notNullize(logEntry.getMessage());
+    myRepositoryRoot = UriUtil.trimTrailingSlashes(repositoryRoot);
 
     myCommonPathSearcher = new CommonPathSearcher();
 
     myKnownAsDirectories = new HashSet<String>(0);
-    for(Object o: logEntry.getChangedPaths().values()) {
-      final SVNLogEntryPath entry = (SVNLogEntryPath) o;
+    for(SVNLogEntryPath entry : logEntry.getChangedPaths().values()) {
       final String path = entry.getPath();
 
       if (SVNNodeKind.DIR.equals(entry.getKind())) {
@@ -146,15 +148,9 @@ public class SvnChangeList implements CommittedChangeList {
     myKnownAsDirectories = new HashSet<String>();
     readFromStream(stream, supportsCopyFromInfo, supportsReplaced);
     myCommonPathSearcher = new CommonPathSearcher();
-    for (String path : myAddedPaths) {
-      myCommonPathSearcher.next(path);
-    }
-    for (String path : myDeletedPaths) {
-      myCommonPathSearcher.next(path);
-    }
-    for (String path : myChangedPaths) {
-      myCommonPathSearcher.next(path);
-    }
+    myCommonPathSearcher.next(myAddedPaths);
+    myCommonPathSearcher.next(myDeletedPaths);
+    myCommonPathSearcher.next(myChangedPaths);
   }
 
   public Change getByPath(final String path) {
@@ -244,11 +240,7 @@ public class SvnChangeList implements CommittedChangeList {
           renamedChange.setIsReplaced(replaced);
 
           final ExternallyRenamedChange addedChange = copiedAddedChanges.get(myCopiedAddedPaths.get(addedPath));
-          if ((addedChange != null) && (addedChange.isCopied())) {
-            renamedChange.setCopied(true);
-          } else {
-            renamedChange.setCopied(false);
-          }
+          renamedChange.setCopied(addedChange != null && addedChange.isCopied());
 
           myListsHolder.add(path, renamedChange);
           break;
@@ -292,8 +284,7 @@ public class SvnChangeList implements CommittedChangeList {
 
   @Nullable
   private FilePath getLocalPath(final String path, final NotNullFunction<File, Boolean> detector) {
-    final String fullPath = myRepositoryRoot + path;
-    return myLocation.getLocalPath(fullPath, detector, myVcs);
+    return SvnRepositoryLocation.getLocalPath(myRepositoryRoot + path, detector, myVcs);
   }
 
   private long getRevision(final boolean isBeforeRevision) {
@@ -312,7 +303,6 @@ public class SvnChangeList implements CommittedChangeList {
     private final Map<String, Change> myPathToChangeMapping;
     private List<Change> myDetailedList;
     private final List<Pair<Integer, Boolean>> myWithoutDirStatus;
-    private SVNRepository myRepository;
 
     private ChangesListCreationHelper() {
       myList = new ArrayList<Change>();
@@ -334,8 +324,8 @@ public class SvnChangeList implements CommittedChangeList {
       final SvnFileUrlMapping urlMapping = myVcs.getSvnFileUrlMapping();
       final String path = urlMapping.getLocalPath(fullPath);
       if (path != null) {
-        final File file = new File(path);
-        return FilePathImpl.createForDeletedFile(file, isDir || file.isDirectory());
+        File file = new File(path);
+        return VcsUtil.getFilePathForDeletedFile(path, isDir || file.isDirectory());
       }
 
       return null;
@@ -345,7 +335,7 @@ public class SvnChangeList implements CommittedChangeList {
       final boolean knownAsDirectory = myKnownAsDirectories.contains(path);
       final String fullPath = myRepositoryRoot + path;
       if (! knownAsDirectory) {
-        myWithoutDirStatus.add(new Pair<Integer, Boolean>(myList.size(), isBeforeRevision));
+        myWithoutDirStatus.add(Pair.create(myList.size(), isBeforeRevision));
       }
       return SvnRepositoryContentRevision.create(myVcs, myRepositoryRoot, path, localDeletedPath(fullPath, knownAsDirectory),
                                                  getRevision(isBeforeRevision));
@@ -379,28 +369,21 @@ public class SvnChangeList implements CommittedChangeList {
         myDetailedList = new ArrayList<Change>(myList);
 
         try {
-          myRepository = myVcs.createRepository(myRepositoryRoot);
-
           doRemoteDetails();
           uploadDeletedRenamedChildren();
-          // remove duplicates
-          final HashSet<Change> set = new HashSet<Change>(myDetailedList);
-          myDetailedList.clear();
-          myDetailedList.addAll(set);
+          ContainerUtil.removeDuplicates(myDetailedList);
         }
         catch (SVNException e) {
           LOG.info(e);
-        } finally {
-          if (myRepository != null) {
-            myRepository.closeSession();
-            myRepository = null;
-          }
+        }
+        catch (VcsException e) {
+          LOG.info(e);
         }
       }
       return myDetailedList;
     }
 
-    private void doRemoteDetails() throws SVNException {
+    private void doRemoteDetails() throws SVNException, SvnBindException {
       for (Pair<Integer, Boolean> idxData : myWithoutDirStatus) {
         final Change sourceChange = myDetailedList.get(idxData.first.intValue());
         final SvnRepositoryContentRevision revision = (SvnRepositoryContentRevision)
@@ -408,9 +391,13 @@ public class SvnChangeList implements CommittedChangeList {
         if (revision == null) {
           continue;
         }
-        final boolean status = SVNNodeKind.DIR.equals(myRepository.checkPath(revision.getPath(), getRevision(idxData.second.booleanValue())));
-        final Change replacingChange = new Change(createRevision((SvnRepositoryContentRevision) sourceChange.getBeforeRevision(), status),
-                                                  createRevision((SvnRepositoryContentRevision) sourceChange.getAfterRevision(), status));
+        // TODO: Logic with detecting "isDirectory" status is not clear enough. Why we can't just collect this info from logEntry and
+        // TODO: if loading from disk - use cached values? Not to invoke separate call here.
+        SVNRevision beforeRevision = SVNRevision.create(getRevision(idxData.second.booleanValue()));
+        SVNInfo info = myVcs.getInfo(SvnUtil.createUrl(revision.getFullPath()), beforeRevision, beforeRevision);
+        boolean isDirectory = info != null && SVNNodeKind.DIR.equals(info.getKind());
+        Change replacingChange = new Change(createRevision((SvnRepositoryContentRevision)sourceChange.getBeforeRevision(), isDirectory),
+                                            createRevision((SvnRepositoryContentRevision)sourceChange.getAfterRevision(), isDirectory));
         replacingChange.setIsReplaced(sourceChange.isIsReplaced());
         myDetailedList.set(idxData.first.intValue(), replacingChange);
       }
@@ -421,64 +408,81 @@ public class SvnChangeList implements CommittedChangeList {
     @Nullable
     private SvnRepositoryContentRevision createRevision(final SvnRepositoryContentRevision previousRevision, final boolean isDir) {
       return previousRevision == null ? null :
-             SvnRepositoryContentRevision.create(myVcs, myRepositoryRoot, previousRevision.getPath(),
-             new FilePathImpl(previousRevision.getFile().getIOFile(), isDir),
-             ((SvnRevisionNumber) previousRevision.getRevisionNumber()).getRevision().getNumber());
+             SvnRepositoryContentRevision.create(myVcs, previousRevision.getFullPath(),
+                                                 new FilePathImpl(previousRevision.getFile().getIOFile(), isDir),
+                                                 ((SvnRevisionNumber)previousRevision.getRevisionNumber()).getRevision().getNumber());
     }
 
-    private void uploadDeletedRenamedChildren() throws SVNException {
-      // cannot insert when iterate
-      final List<Change> detailsOnly = new ArrayList<Change>();
+    private void uploadDeletedRenamedChildren() throws VcsException {
+      Set<Pair<Boolean, String>> duplicates = collectDuplicates();
+      List<Change> preprocessed = ChangesPreprocess.preprocessChangesRemoveDeletedForDuplicateMoved(myDetailedList);
 
-      final Set<Pair<Boolean, String>> duplicateControl = new HashSet<Pair<Boolean, String>>();
-      for (Change change : myDetailedList) {
-        if (change.getBeforeRevision() != null) {
-          duplicateControl.add(new Pair<Boolean, String>(Boolean.TRUE, ((SvnRepositoryContentRevision) change.getBeforeRevision()).getPath()));
-        }
-        if (change.getAfterRevision() != null) {
-          duplicateControl.add(new Pair<Boolean, String>(Boolean.FALSE, ((SvnRepositoryContentRevision) change.getAfterRevision()).getPath()));
-        }
-      }
+      myDetailedList.addAll(collectDetails(preprocessed, duplicates));
+    }
 
-      final List<Change> preprocessed = ChangesPreprocess.preprocessChangesRemoveDeletedForDuplicateMoved(myDetailedList);
+    private List<Change> collectDetails(@NotNull List<Change> changes, @NotNull Set<Pair<Boolean, String>> duplicates)
+      throws VcsException {
+      List<Change> result = ContainerUtil.newArrayList();
 
-      for (Change change : preprocessed) {
+      for (Change change : changes) {
         // directory statuses are already uploaded
         if ((change.getAfterRevision() == null) && (change.getBeforeRevision().getFile().isDirectory())) {
-          final SvnRepositoryContentRevision revision = (SvnRepositoryContentRevision) change.getBeforeRevision();
-          detailsOnly.addAll(getChildrenAsChanges(revision.getPath(), true, duplicateControl));
+          result.addAll(getChildrenAsChanges(change.getBeforeRevision(), true, duplicates));
         } else if ((change.getBeforeRevision() == null) && (change.getAfterRevision().getFile().isDirectory())) {
           // look for renamed folders contents
-          final SvnRepositoryContentRevision revision = (SvnRepositoryContentRevision) change.getAfterRevision();
-          if (myCopiedAddedPaths.containsKey(revision.getPath())) {
-            detailsOnly.addAll(getChildrenAsChanges(revision.getPath(), false, duplicateControl));
+          if (myCopiedAddedPaths.containsKey(getRelativePath(change.getAfterRevision()))) {
+            result.addAll(getChildrenAsChanges(change.getAfterRevision(), false, duplicates));
           }
         } else if ((change.isIsReplaced() || change.isMoved() || change.isRenamed()) && change.getAfterRevision().getFile().isDirectory()) {
-          final SvnRepositoryContentRevision beforeRevision = (SvnRepositoryContentRevision) change.getBeforeRevision();
-          detailsOnly.addAll(getChildrenAsChanges(beforeRevision.getPath(), true, duplicateControl));
-
-          final SvnRepositoryContentRevision revision = (SvnRepositoryContentRevision) change.getAfterRevision();
-          detailsOnly.addAll(getChildrenAsChanges(revision.getPath(), false, duplicateControl));
+          result.addAll(getChildrenAsChanges(change.getBeforeRevision(), true, duplicates));
+          result.addAll(getChildrenAsChanges(change.getAfterRevision(), false, duplicates));
         }
       }
 
-      myDetailedList.addAll(detailsOnly);
+      return result;
+    }
+
+    private Set<Pair<Boolean, String>> collectDuplicates() {
+      Set<Pair<Boolean, String>> result = ContainerUtil.newHashSet();
+
+      for (Change change : myDetailedList) {
+        addDuplicate(result, true, change.getBeforeRevision());
+        addDuplicate(result, false, change.getAfterRevision());
+      }
+
+      return result;
+    }
+
+    private void addDuplicate(@NotNull Set<Pair<Boolean, String>> duplicates,
+                              boolean isBefore,
+                              @Nullable ContentRevision revision) {
+      if (revision != null) {
+        duplicates.add(Pair.create(isBefore, getRelativePath(revision)));
+      }
+    }
+
+    @NotNull
+    private String getRelativePath(@NotNull ContentRevision revision) {
+      return ((SvnRepositoryContentRevision)revision).getRelativePath(myRepositoryRoot);
     }
 
     @NotNull
-    private Collection<Change> getChildrenAsChanges(final String path, final boolean isBefore, final Set<Pair<Boolean, String>> duplicateControl)
-        throws SVNException {
+    private Collection<Change> getChildrenAsChanges(@NotNull ContentRevision contentRevision,
+                                                    final boolean isBefore,
+                                                    @NotNull final Set<Pair<Boolean, String>> duplicates)
+      throws VcsException {
       final List<Change> result = new ArrayList<Change>();
 
-      final SVNLogClient client = myVcs.createLogClient();
+      final String path = getRelativePath(contentRevision);
+      SVNURL fullPath = SvnUtil.createUrl(((SvnRepositoryContentRevision)contentRevision).getFullPath());
+      SVNRevision revisionNumber = SVNRevision.create(getRevision(isBefore));
+      SvnTarget target = SvnTarget.fromURL(fullPath, revisionNumber);
 
-      final long revision = getRevision(isBefore);
-      client.doList(myRepository.getLocation().appendPath(path, true), SVNRevision.create(revision), SVNRevision.create(revision),
-                    true, new ISVNDirEntryHandler() {
+      myVcs.getFactory(target).createBrowseClient().list(target, revisionNumber, SVNDepth.INFINITY, new ISVNDirEntryHandler() {
         public void handleDirEntry(final SVNDirEntry dirEntry) throws SVNException {
           final String childPath = path + '/' + dirEntry.getRelativePath();
 
-          if (! duplicateControl.contains(new Pair<Boolean, String>(isBefore, childPath))) {
+          if (!duplicates.contains(Pair.create(isBefore, childPath))) {
             final ContentRevision contentRevision = createRevision(childPath, isBefore, SVNNodeKind.DIR.equals(dirEntry.getKind()));
             result.add(new Change(isBefore ? contentRevision : null, isBefore ? null : contentRevision));
           }
@@ -495,18 +499,6 @@ public class SvnChangeList implements CommittedChangeList {
   }
 
   private static class RenameHelper {
-    /*private final TreeMap<String, String> myRenamesMap;
-
-    private RenameHelper(final List<Change> svnRepositoryChanges) {
-      myRenamesMap = new TreeMap<String, String>();
-      for (Change change : svnRepositoryChanges) {
-        if (change.isMoved() || change.isRenamed()) {
-          final SvnRepositoryContentRevision before = (SvnRepositoryContentRevision) change.getBeforeRevision();
-          final SvnRepositoryContentRevision after = (SvnRepositoryContentRevision) change.getAfterRevision();
-          myRenamesMap.put(after.getPath(), before.getPath());
-        }
-      }
-    } */
 
     public String convertBeforePath(final String path, final TreeMap<String, String> after2before) {
       String current = path;
@@ -529,8 +521,8 @@ public class SvnChangeList implements CommittedChangeList {
       wasUrl = becameUrl;
 
       if (change instanceof ExternallyRenamedChange && change.getBeforeRevision() != null) {
-        final ExternallyRenamedChange renamedChange = (ExternallyRenamedChange)change;
-        final String originUrl = renamedChange.getOriginUrl();
+        String originUrl = ((ExternallyRenamedChange)change).getOriginUrl();
+
         if (originUrl != null) {
           // use another url for origin
           wasUrl = SVNURL.parseURIEncoded(SVNPathUtil.append(myRepositoryRoot, originUrl));
@@ -544,15 +536,18 @@ public class SvnChangeList implements CommittedChangeList {
     }
 
     final FilePath filePath = ChangesUtil.getFilePath(change);
-    final Change additional = new Change(change.getBeforeRevision() == null ? null :
-                                         new SvnLazyPropertyContentRevision(filePath, change.getBeforeRevision().getRevisionNumber(),
-                                                                            myVcs.getProject(), wasUrl),
-                                         change.getAfterRevision() == null ? null :
-                                         new SvnLazyPropertyContentRevision(filePath, change.getAfterRevision().getRevisionNumber(),
-                                                                            myVcs.getProject(), becameUrl));
+    final Change additional = new Change(createPropertyRevision(filePath, change.getBeforeRevision(), wasUrl),
+                                         createPropertyRevision(filePath, change.getAfterRevision(), becameUrl));
     change.addAdditionalLayerElement(SvnChangeProvider.PROPERTY_LAYER, additional);
   }
 
+  @Nullable
+  private SvnLazyPropertyContentRevision createPropertyRevision(@NotNull FilePath filePath,
+                                                                @Nullable ContentRevision revision,
+                                                                @NotNull SVNURL url) {
+    return revision == null ? null : new SvnLazyPropertyContentRevision(filePath, revision.getRevisionNumber(), myVcs.getProject(), url);
+  }
+
   @NotNull
   public String getName() {
     return myMessage;
@@ -704,38 +699,46 @@ public class SvnChangeList implements CommittedChangeList {
   }
 
   public SVNURL getBranchUrl() {
-    if (!myCachedInfoLoaded) {
-      updateCachedInfo();
-    }
+    ensureCacheUpdated();
+
     return myBranchUrl;
   }
 
   @Nullable
   public VirtualFile getVcsRoot() {
-    if (!myCachedInfoLoaded) {
-      updateCachedInfo();
-    }
-    return (myWcRoot == null) ? null : myWcRoot.getRoot();
+    ensureCacheUpdated();
+
+    return myWcRoot == null ? null : myWcRoot.getRoot();
   }
 
   @Nullable
   public VirtualFile getRoot() {
-    if (!myCachedInfoLoaded) {
-      updateCachedInfo();
-    }
-    return (myWcRoot == null) ? null : myWcRoot.getVirtualFile();
+    ensureCacheUpdated();
+
+    return myWcRoot == null ? null : myWcRoot.getVirtualFile();
   }
 
   public RootUrlInfo getWcRootInfo() {
+    ensureCacheUpdated();
+
+    return myWcRoot;
+  }
+
+  private void ensureCacheUpdated() {
     if (!myCachedInfoLoaded) {
       updateCachedInfo();
     }
-    return myWcRoot;
   }
 
   private static class CommonPathSearcher {
     private String myCommon;
 
+    public void next(Iterable<String> values) {
+      for (String value : values) {
+        next(value);
+      }
+    }
+
     public void next(final String value) {
       if (value == null) {
         return;
@@ -799,17 +802,13 @@ public class SvnChangeList implements CommittedChangeList {
   @Nullable
   public String getWcPath() {
     final RootUrlInfo rootInfo = getWcRootInfo();
-    if (rootInfo == null) {
-      return null;
-    }
-    return rootInfo.getIoFile().getAbsolutePath();
+
+    return rootInfo == null ? null : rootInfo.getIoFile().getAbsolutePath();
   }
 
   public boolean allPathsUnder(final String path) {
     final String commonRelative = myCommonPathSearcher.getCommon();
-    if (commonRelative != null) {
-      return SVNPathUtil.isAncestor(path, SVNPathUtil.append(myRepositoryRoot, commonRelative));
-    }
-    return false;
+
+    return commonRelative != null && SVNPathUtil.isAncestor(path, SVNPathUtil.append(myRepositoryRoot, commonRelative));
   }
 }
index 36c80b1caaae3f10ac6101acce08a05a438255a8..721c89d597bb8dd16909369091eb2dcfcbf7d688 100644 (file)
@@ -108,10 +108,20 @@ public class SvnRepositoryContentRevision implements ContentRevision, MarkerVcsC
     return new SvnRevisionNumber(SVNRevision.create(myRevision));
   }
 
-  public static SvnRepositoryContentRevision create(final SvnVcs vcs, final String repositoryRoot, final String path,
-                                                    @Nullable final FilePath localPath, final long revision) {
+  public static SvnRepositoryContentRevision create(@NotNull SvnVcs vcs,
+                                                    @NotNull String repositoryRoot,
+                                                    @NotNull String path,
+                                                    @Nullable FilePath localPath,
+                                                    long revision) {
+    return create(vcs, SvnUtil.appendMultiParts(repositoryRoot, path), localPath, revision);
+  }
+
+  public static SvnRepositoryContentRevision create(@NotNull SvnVcs vcs,
+                                                    @NotNull String fullPath,
+                                                    @Nullable FilePath localPath,
+                                                    long revision) {
     // TODO: Check if isDirectory = false always true for this method calls
-    FilePath remotePath = VcsUtil.getFilePathOnNonLocal(SvnUtil.appendMultiParts(repositoryRoot, path), false);
+    FilePath remotePath = VcsUtil.getFilePathOnNonLocal(fullPath, false);
 
     return create(vcs, remotePath, localPath, revision);
   }
@@ -172,8 +182,8 @@ public class SvnRepositoryContentRevision implements ContentRevision, MarkerVcsC
     return myPath;
   }
 
-  public String getPath() {
-    return myPath;
+  public String getRelativePath(@NotNull String repositoryUrl) {
+    return SvnUtil.getRelativePath(repositoryUrl, myPath);
   }
 
   @Override
index 5dc605b8ed57680d6c58f6a758d97b629dc0f3ff..2e497ca12bda000a78155bf7d10e5ef5e95c7265 100644 (file)
@@ -25,7 +25,6 @@ import org.jetbrains.idea.svn.RootUrlInfo;
 import org.jetbrains.idea.svn.SvnUtil;
 import org.jetbrains.idea.svn.SvnVcs;
 import org.jetbrains.idea.svn.commandLine.SvnBindException;
-import org.tmatesoft.svn.core.SVNException;
 import org.tmatesoft.svn.core.SVNURL;
 
 import java.io.File;
@@ -80,12 +79,7 @@ public class SvnRepositoryLocation implements RepositoryLocation {
     return result;
   }
 
-  public SVNURL toSvnUrl() throws VcsException {
-    try {
-      return SvnUtil.createUrl(myURL);
-    }
-    catch (SVNException e) {
-      throw new SvnBindException(e);
-    }
+  public SVNURL toSvnUrl() throws SvnBindException {
+    return SvnUtil.createUrl(myURL);
   }
 }
index f93b0c095d200c593fb6d8aac23396da5185ea79..b6228fca921d3e18cda364f4738970b0fe04d0c7 100644 (file)
  */
 package org.jetbrains.idea.svn.integrate;
 
-import com.intellij.openapi.project.Project;
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Factory;
 import com.intellij.openapi.vcs.FilePath;
+import com.intellij.openapi.vcs.VcsException;
 import com.intellij.openapi.vcs.VcsKey;
 import com.intellij.openapi.vcs.changes.*;
 import com.intellij.openapi.vcs.update.UpdatedFilesReverseSide;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.SvnPropertyKeys;
 import org.jetbrains.idea.svn.SvnVcs;
-import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.SVNPropertyValue;
 import org.tmatesoft.svn.core.wc.SVNPropertyData;
 import org.tmatesoft.svn.core.wc.SVNRevision;
-import org.tmatesoft.svn.core.wc.SVNWCClient;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
 
-import javax.swing.*;
 import java.io.File;
 import java.util.*;
 
-public class GatheringChangelistBuilder implements ChangelistBuilder {
-  private final Set<VirtualFile> myCheckSet;
-  private final List<Change> myChanges;
-  private final UpdatedFilesReverseSide myFiles;
-  private final VirtualFile myMergeRoot;
-  private final SvnVcs myVcs;
+public class GatheringChangelistBuilder extends EmptyChangelistBuilder {
 
-  public GatheringChangelistBuilder(final Project project, final UpdatedFilesReverseSide files, final VirtualFile mergeRoot) {
-    myVcs = SvnVcs.getInstance(project);
+  private static final Logger LOG = Logger.getInstance(GatheringChangelistBuilder.class);
+
+  @NotNull private final Set<VirtualFile> myCheckSet;
+  @NotNull private final List<Change> myChanges;
+  @NotNull private final UpdatedFilesReverseSide myFiles;
+  @NotNull private final SvnVcs myVcs;
+
+  public GatheringChangelistBuilder(@NotNull SvnVcs vcs, @NotNull UpdatedFilesReverseSide files) {
+    myVcs = vcs;
     myFiles = files;
-    myMergeRoot = mergeRoot;
-    myChanges = new ArrayList<Change>();
-    myCheckSet = new HashSet<VirtualFile>();
+    myChanges = ContainerUtil.newArrayList();
+    myCheckSet = ContainerUtil.newHashSet();
   }
 
   public void processChange(final Change change, VcsKey vcsKey) {
@@ -81,82 +82,36 @@ public class GatheringChangelistBuilder implements ChangelistBuilder {
   private void addChange(final Change change) {
     final FilePath path = ChangesUtil.getFilePath(change);
     final VirtualFile vf = path.getVirtualFile();
-    if ((mergeinfoChanged(path.getIOFile()) || ((vf != null) && myFiles.containsFile(vf))) && (! myCheckSet.contains(vf))) {
+    if ((mergeInfoChanged(path.getIOFile()) || (vf != null && myFiles.containsFile(vf))) && !myCheckSet.contains(vf)) {
       myCheckSet.add(vf);
       myChanges.add(change);
     }
   }
 
-  private boolean mergeinfoChanged(final File file) {
-    final SVNWCClient client = myVcs.createWCClient();
+  private boolean mergeInfoChanged(final File file) {
+    SvnTarget target = SvnTarget.fromFile(file);
+
     try {
-      final SVNPropertyData current = client.doGetProperty(file, "svn:mergeinfo", SVNRevision.UNDEFINED, SVNRevision.WORKING);
-      final SVNPropertyData base = client.doGetProperty(file, "svn:mergeinfo", SVNRevision.UNDEFINED, SVNRevision.BASE);
+      SVNPropertyData current =
+        myVcs.getFactory(target).createPropertyClient().getProperty(target, SvnPropertyKeys.MERGE_INFO, false, SVNRevision.WORKING);
+      SVNPropertyData base =
+        myVcs.getFactory(target).createPropertyClient().getProperty(target, SvnPropertyKeys.MERGE_INFO, false, SVNRevision.BASE);
+
       if (current != null) {
-        if (base == null) {
-          return true;
-        } else {
-          final SVNPropertyValue currentValue = current.getValue();
-          final SVNPropertyValue baseValue = base.getValue();
-          return ! Comparing.equal(currentValue, baseValue);
-        }
+        return base == null || !Comparing.equal(current.getValue(), base.getValue());
       }
     }
-    catch (SVNException e) {
-      //
+    catch (VcsException e) {
+      LOG.info(e);
     }
     return false;
   }
 
-  public void processUnversionedFile(final VirtualFile file) {
-
-  }
-
-  public void processLocallyDeletedFile(final FilePath file) {
-
-  }
-
-  public void processLocallyDeletedFile(LocallyDeletedChange locallyDeletedChange) {
-    
-  }
-
-  public void processModifiedWithoutCheckout(final VirtualFile file) {
-
-  }
-
-  public void processIgnoredFile(final VirtualFile file) {
-
-  }
-
-  public void processLockedFolder(final VirtualFile file) {
-  }
-
-  public void processLogicallyLockedFolder(VirtualFile file, LogicalLock logicalLock) {
-  }
-
-  public void processSwitchedFile(final VirtualFile file, final String branch, final boolean recursive) {
-
-  }
-
-  public void processRootSwitch(VirtualFile file, String branch) {
-  }
-
   public boolean reportChangesOutsideProject() {
     return true;
   }
 
-  @Override
-  public void reportAdditionalInfo(String text) {
-  }
-
-  @Override
-  public void reportAdditionalInfo(Factory<JComponent> infoComponent) {
-  }
-
-  public void reportWarningMessage(final String message) {
-    // todo maybe, use further
-  }
-
+  @NotNull
   public List<Change> getChanges() {
     return myChanges;
   }
index 92447f87793f00d30a80932e65508b6fb9781992..b4e544ba1e3da44a146fd7513b063324fb916e25 100644 (file)
@@ -331,7 +331,7 @@ public class SvnIntegrateChangesTask extends Task.Backgroundable {
     }
 
     final SvnChangeProvider provider = new SvnChangeProvider(myVcs);
-    final GatheringChangelistBuilder clb = new GatheringChangelistBuilder(myProject, myAccomulatedFiles, myMergeTarget == null ? null : myMergeTarget.getVirtualFile());
+    final GatheringChangelistBuilder clb = new GatheringChangelistBuilder(myVcs, myAccomulatedFiles);
     try {
       provider.getChanges(dirtyScope, clb, ProgressManager.getInstance().getProgressIndicator(), null);
     } catch (VcsException e) {
index f0de01f1e9b99f5dc01d171314541dc145b1230e..47b15802287bb6f023f440f96abc42c9364a643f 100644 (file)
@@ -25,7 +25,6 @@ import org.jetbrains.idea.svn.SvnWCRootCrawler;
 import org.tmatesoft.svn.core.SVNErrorCode;
 import org.tmatesoft.svn.core.SVNErrorMessage;
 import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.wc.SVNUpdateClient;
 
 import java.io.File;
 import java.util.Collection;
@@ -56,9 +55,6 @@ public abstract class AbstractUpdateIntegrateCrawler implements SvnWCRootCrawler
       showProgressMessage(progress, root);
     }
     try {
-      SVNUpdateClient client = myVcs.createUpdateClient();
-      client.setEventHandler(myHandler);
-
       long rev = doUpdate(root);
 
       if (rev < 0 && !isMerge()) {