From 87bcdbd77cf85b8c7f222ca3195e1280033b5f75 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Tue, 11 Feb 2014 20:05:56 +0400 Subject: [PATCH 01/18] svn: Refactored SvnChangeList - removed duplication, simplified code flow --- .../idea/svn/history/SvnChangeList.java | 82 +++++++++---------- 1 file changed, 37 insertions(+), 45 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java index 2af8f3c6d626..0dc7cb1c3740 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java @@ -24,6 +24,7 @@ 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; @@ -32,6 +33,7 @@ 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 org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.*; @@ -100,19 +102,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(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 +144,9 @@ public class SvnChangeList implements CommittedChangeList { myKnownAsDirectories = new HashSet(); 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 +236,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; @@ -345,7 +333,7 @@ public class SvnChangeList implements CommittedChangeList { final boolean knownAsDirectory = myKnownAsDirectories.contains(path); final String fullPath = myRepositoryRoot + path; if (! knownAsDirectory) { - myWithoutDirStatus.add(new Pair(myList.size(), isBeforeRevision)); + myWithoutDirStatus.add(Pair.create(myList.size(), isBeforeRevision)); } return SvnRepositoryContentRevision.create(myVcs, myRepositoryRoot, path, localDeletedPath(fullPath, knownAsDirectory), getRevision(isBeforeRevision)); @@ -433,10 +421,10 @@ public class SvnChangeList implements CommittedChangeList { final Set> duplicateControl = new HashSet>(); for (Change change : myDetailedList) { if (change.getBeforeRevision() != null) { - duplicateControl.add(new Pair(Boolean.TRUE, ((SvnRepositoryContentRevision) change.getBeforeRevision()).getPath())); + duplicateControl.add(Pair.create(Boolean.TRUE, ((SvnRepositoryContentRevision)change.getBeforeRevision()).getPath())); } if (change.getAfterRevision() != null) { - duplicateControl.add(new Pair(Boolean.FALSE, ((SvnRepositoryContentRevision) change.getAfterRevision()).getPath())); + duplicateControl.add(Pair.create(Boolean.FALSE, ((SvnRepositoryContentRevision) change.getAfterRevision()).getPath())); } } @@ -704,38 +692,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 values) { + for (String value : values) { + next(value); + } + } + public void next(final String value) { if (value == null) { return; @@ -799,17 +795,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)); } } From 24e95a4cb80f2d6bbdf106f12807f918ab2e89bf Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Tue, 11 Feb 2014 23:09:29 +0400 Subject: [PATCH 02/18] svn: Refactored SvnCommandLineInfoClient - code simplifications, warnings fixes --- .../idea/svn/commandLine/SvnCommandLineInfoClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java index ef4822607e37..8bbb58242e05 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java @@ -195,7 +195,7 @@ public class SvnCommandLineInfoClient extends SvnkitSvnWcClient { } } - private void fillParameters(String path, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, List parameters) { + private static void fillParameters(String path, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, List 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 From 58f70a1fb9b488b33d394f936e7e68a250c6c55d Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Tue, 11 Feb 2014 23:18:51 +0400 Subject: [PATCH 03/18] svn: Refactored RemoteRevisionsNumberCache - code simplifications, warnings fixes --- .../changes/RemoteRevisionsNumbersCache.java | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsNumbersCache.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsNumbersCache.java index 30d8f5ef88c0..03788f196192 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsNumbersCache.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsNumbersCache.java @@ -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 oldQueue = getQueue(oldVcsRoot); final LazyRefreshingSelfQueue newQueue = getQueue(newVcsRoot); - myData.put(key, new Pair(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 value = myData.get(key); if (value == null) { final LazyRefreshingSelfQueue queue = getQueue(vcsRoot); - myData.put(key, new Pair(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 queue = getQueue(vcsRoot); queue.forceRemove(path); queue.addRequest(path); - myData.put(path, new Pair(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(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; } From 56ca50de36e4b09988fad016deca8c4ef11a50fd Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 12 Feb 2014 00:15:42 +0400 Subject: [PATCH 04/18] svn: Ensure repository relative path is used in SvnChangeList logic (logic was broken and full path was returned after changes in commit 42c824) --- .../idea/svn/history/SvnChangeList.java | 25 +++++++++++-------- .../history/SvnRepositoryContentRevision.java | 20 +++++++++++---- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java index 0dc7cb1c3740..0fdb43b2acff 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java @@ -396,7 +396,8 @@ public class SvnChangeList implements CommittedChangeList { if (revision == null) { continue; } - final boolean status = SVNNodeKind.DIR.equals(myRepository.checkPath(revision.getPath(), getRevision(idxData.second.booleanValue()))); + final boolean status = SVNNodeKind.DIR + .equals(myRepository.checkPath(revision.getRelativePath(myRepositoryRoot), getRevision(idxData.second.booleanValue()))); final Change replacingChange = new Change(createRevision((SvnRepositoryContentRevision) sourceChange.getBeforeRevision(), status), createRevision((SvnRepositoryContentRevision) sourceChange.getAfterRevision(), status)); replacingChange.setIsReplaced(sourceChange.isIsReplaced()); @@ -409,9 +410,9 @@ 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 { @@ -421,10 +422,12 @@ public class SvnChangeList implements CommittedChangeList { final Set> duplicateControl = new HashSet>(); for (Change change : myDetailedList) { if (change.getBeforeRevision() != null) { - duplicateControl.add(Pair.create(Boolean.TRUE, ((SvnRepositoryContentRevision)change.getBeforeRevision()).getPath())); + duplicateControl.add(Pair.create(Boolean.TRUE, ((SvnRepositoryContentRevision)change.getBeforeRevision()).getRelativePath( + myRepositoryRoot))); } if (change.getAfterRevision() != null) { - duplicateControl.add(Pair.create(Boolean.FALSE, ((SvnRepositoryContentRevision) change.getAfterRevision()).getPath())); + duplicateControl.add(Pair.create(Boolean.FALSE, ((SvnRepositoryContentRevision) change.getAfterRevision()).getRelativePath( + myRepositoryRoot))); } } @@ -434,19 +437,19 @@ public class SvnChangeList implements CommittedChangeList { // 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)); + detailsOnly.addAll(getChildrenAsChanges(revision.getRelativePath(myRepositoryRoot), true, duplicateControl)); } 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(revision.getRelativePath(myRepositoryRoot))) { + detailsOnly.addAll(getChildrenAsChanges(revision.getRelativePath(myRepositoryRoot), false, duplicateControl)); } } 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)); + detailsOnly.addAll(getChildrenAsChanges(beforeRevision.getRelativePath(myRepositoryRoot), true, duplicateControl)); final SvnRepositoryContentRevision revision = (SvnRepositoryContentRevision) change.getAfterRevision(); - detailsOnly.addAll(getChildrenAsChanges(revision.getPath(), false, duplicateControl)); + detailsOnly.addAll(getChildrenAsChanges(revision.getRelativePath(myRepositoryRoot), false, duplicateControl)); } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java index 36c80b1caaae..721c89d597bb 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java @@ -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 From a66c80b16acb5d9b2d5003e7fd0970a0e04c671e Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 12 Feb 2014 15:42:25 +0400 Subject: [PATCH 05/18] svn: Refactored SvnChangeList - method extractions, code simplifications --- .../idea/svn/history/SvnChangeList.java | 124 +++++++++--------- 1 file changed, 63 insertions(+), 61 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java index 0fdb43b2acff..4d296e47ffe7 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java @@ -34,6 +34,8 @@ 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.*; @@ -280,8 +282,7 @@ public class SvnChangeList implements CommittedChangeList { @Nullable private FilePath getLocalPath(final String path, final NotNullFunction 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) { @@ -322,8 +323,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; @@ -371,10 +372,7 @@ public class SvnChangeList implements CommittedChangeList { doRemoteDetails(); uploadDeletedRenamedChildren(); - // remove duplicates - final HashSet set = new HashSet(myDetailedList); - myDetailedList.clear(); - myDetailedList.addAll(set); + ContainerUtil.removeDuplicates(myDetailedList); } catch (SVNException e) { LOG.info(e); @@ -416,60 +414,73 @@ public class SvnChangeList implements CommittedChangeList { } private void uploadDeletedRenamedChildren() throws SVNException { - // cannot insert when iterate - final List detailsOnly = new ArrayList(); + Set> duplicates = collectDuplicates(); + List preprocessed = ChangesPreprocess.preprocessChangesRemoveDeletedForDuplicateMoved(myDetailedList); - final Set> duplicateControl = new HashSet>(); - for (Change change : myDetailedList) { - if (change.getBeforeRevision() != null) { - duplicateControl.add(Pair.create(Boolean.TRUE, ((SvnRepositoryContentRevision)change.getBeforeRevision()).getRelativePath( - myRepositoryRoot))); - } - if (change.getAfterRevision() != null) { - duplicateControl.add(Pair.create(Boolean.FALSE, ((SvnRepositoryContentRevision) change.getAfterRevision()).getRelativePath( - myRepositoryRoot))); - } - } + myDetailedList.addAll(collectDetails(preprocessed, duplicates)); + } - final List preprocessed = ChangesPreprocess.preprocessChangesRemoveDeletedForDuplicateMoved(myDetailedList); + private List collectDetails(@NotNull List changes, @NotNull Set> duplicates) throws SVNException { + List 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.getRelativePath(myRepositoryRoot), 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.getRelativePath(myRepositoryRoot))) { - detailsOnly.addAll(getChildrenAsChanges(revision.getRelativePath(myRepositoryRoot), 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.getRelativePath(myRepositoryRoot), true, duplicateControl)); - - final SvnRepositoryContentRevision revision = (SvnRepositoryContentRevision) change.getAfterRevision(); - detailsOnly.addAll(getChildrenAsChanges(revision.getRelativePath(myRepositoryRoot), false, duplicateControl)); + result.addAll(getChildrenAsChanges(change.getBeforeRevision(), true, duplicates)); + result.addAll(getChildrenAsChanges(change.getAfterRevision(), false, duplicates)); } } - myDetailedList.addAll(detailsOnly); + return result; + } + + private Set> collectDuplicates() { + Set> result = ContainerUtil.newHashSet(); + + for (Change change : myDetailedList) { + addDuplicate(result, true, change.getBeforeRevision()); + addDuplicate(result, false, change.getAfterRevision()); + } + + return result; + } + + private void addDuplicate(@NotNull Set> duplicates, + boolean isBefore, + @Nullable ContentRevision revision) { + if (revision != null) { + duplicates.add(Pair.create(isBefore, getRelativePath(revision))); + } } @NotNull - private Collection getChildrenAsChanges(final String path, final boolean isBefore, final Set> duplicateControl) - throws SVNException { + private String getRelativePath(@NotNull ContentRevision revision) { + return ((SvnRepositoryContentRevision)revision).getRelativePath(myRepositoryRoot); + } + + @NotNull + private Collection getChildrenAsChanges(@NotNull ContentRevision contentRevision, + final boolean isBefore, + @NotNull final Set> duplicates) + throws SVNException { final List result = new ArrayList(); - final SVNLogClient client = myVcs.createLogClient(); + final String path = getRelativePath(contentRevision); + SVNRevision revisionNumber = SVNRevision.create(getRevision(isBefore)); - final long revision = getRevision(isBefore); - client.doList(myRepository.getLocation().appendPath(path, true), SVNRevision.create(revision), SVNRevision.create(revision), - true, new ISVNDirEntryHandler() { + final SVNLogClient client = myVcs.createLogClient(); + client.doList(myRepository.getLocation().appendPath(path, true), revisionNumber, revisionNumber, true, new ISVNDirEntryHandler() { public void handleDirEntry(final SVNDirEntry dirEntry) throws SVNException { final String childPath = path + '/' + dirEntry.getRelativePath(); - if (! duplicateControl.contains(new Pair(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)); } @@ -486,18 +497,6 @@ public class SvnChangeList implements CommittedChangeList { } private static class RenameHelper { - /*private final TreeMap myRenamesMap; - - private RenameHelper(final List svnRepositoryChanges) { - myRenamesMap = new TreeMap(); - 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 after2before) { String current = path; @@ -520,8 +519,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)); @@ -535,15 +534,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; From 8a44f019e16a6af681cf46eee3a25178450418df Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 12 Feb 2014 16:24:45 +0400 Subject: [PATCH 06/18] svn: Refactored SvnChangeList - SVNRepository usages replaced with "svn info" command --- .../idea/svn/history/SvnChangeList.java | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java index 4d296e47ffe7..629f7baf37b7 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java @@ -41,7 +41,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.*; 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.SVNInfo; import org.tmatesoft.svn.core.wc.SVNLogClient; import org.tmatesoft.svn.core.wc.SVNRevision; @@ -301,7 +301,6 @@ public class SvnChangeList implements CommittedChangeList { private final Map myPathToChangeMapping; private List myDetailedList; private final List> myWithoutDirStatus; - private SVNRepository myRepository; private ChangesListCreationHelper() { myList = new ArrayList(); @@ -368,19 +367,12 @@ public class SvnChangeList implements CommittedChangeList { myDetailedList = new ArrayList(myList); try { - myRepository = myVcs.createRepository(myRepositoryRoot); - doRemoteDetails(); uploadDeletedRenamedChildren(); ContainerUtil.removeDuplicates(myDetailedList); } catch (SVNException e) { LOG.info(e); - } finally { - if (myRepository != null) { - myRepository.closeSession(); - myRepository = null; - } } } return myDetailedList; @@ -394,10 +386,11 @@ public class SvnChangeList implements CommittedChangeList { if (revision == null) { continue; } - final boolean status = SVNNodeKind.DIR - .equals(myRepository.checkPath(revision.getRelativePath(myRepositoryRoot), getRevision(idxData.second.booleanValue()))); - final Change replacingChange = new Change(createRevision((SvnRepositoryContentRevision) sourceChange.getBeforeRevision(), status), - createRevision((SvnRepositoryContentRevision) sourceChange.getAfterRevision(), status)); + 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); } @@ -473,10 +466,11 @@ public class SvnChangeList implements CommittedChangeList { final List result = new ArrayList(); final String path = getRelativePath(contentRevision); + SVNURL fullPath = SvnUtil.createUrl(((SvnRepositoryContentRevision)contentRevision).getFullPath()); SVNRevision revisionNumber = SVNRevision.create(getRevision(isBefore)); final SVNLogClient client = myVcs.createLogClient(); - client.doList(myRepository.getLocation().appendPath(path, true), revisionNumber, revisionNumber, true, new ISVNDirEntryHandler() { + client.doList(fullPath, revisionNumber, revisionNumber, true, new ISVNDirEntryHandler() { public void handleDirEntry(final SVNDirEntry dirEntry) throws SVNException { final String childPath = path + '/' + dirEntry.getRelativePath(); From 05913e6be74975e12df29bbfdb6b849bb1f86b24 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 12 Feb 2014 19:19:38 +0400 Subject: [PATCH 07/18] svn: Refactored SvnUtil.createUrl - make it throw SvnBindException (instead of SVNException) --- .../src/org/jetbrains/idea/svn/SvnUtil.java | 23 +++++++++++-------- .../dialogs/BranchConfigurationDialog.java | 4 ++-- .../idea/svn/dialogs/QuickMerge.java | 3 ++- .../idea/svn/history/SvnChangeList.java | 13 +++++++---- .../svn/history/SvnRepositoryLocation.java | 10 ++------ 5 files changed, 29 insertions(+), 24 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java index 1e3fd7b1fb18..acb910880c61 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java @@ -44,8 +44,8 @@ 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; @@ -763,16 +763,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; + } + catch (SVNException e) { + throw new SvnBindException(e); } - - return result; } public static SVNURL parseUrl(@NotNull String url) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java index 32b1dae809ed..6bd08c1089cb 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java @@ -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()); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/QuickMerge.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/QuickMerge.java index 20077fc42e34..2bf09e0b6dba 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/QuickMerge.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/QuickMerge.java @@ -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); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java index 629f7baf37b7..bf3cf7edafcd 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java @@ -39,6 +39,7 @@ 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.wc.SVNInfo; @@ -374,11 +375,14 @@ public class SvnChangeList implements CommittedChangeList { catch (SVNException e) { LOG.info(e); } + catch (SvnBindException e) { + LOG.info(e); + } } return myDetailedList; } - private void doRemoteDetails() throws SVNException { + private void doRemoteDetails() throws SVNException, SvnBindException { for (Pair idxData : myWithoutDirStatus) { final Change sourceChange = myDetailedList.get(idxData.first.intValue()); final SvnRepositoryContentRevision revision = (SvnRepositoryContentRevision) @@ -406,14 +410,15 @@ public class SvnChangeList implements CommittedChangeList { ((SvnRevisionNumber)previousRevision.getRevisionNumber()).getRevision().getNumber()); } - private void uploadDeletedRenamedChildren() throws SVNException { + private void uploadDeletedRenamedChildren() throws SVNException, SvnBindException { Set> duplicates = collectDuplicates(); List preprocessed = ChangesPreprocess.preprocessChangesRemoveDeletedForDuplicateMoved(myDetailedList); myDetailedList.addAll(collectDetails(preprocessed, duplicates)); } - private List collectDetails(@NotNull List changes, @NotNull Set> duplicates) throws SVNException { + private List collectDetails(@NotNull List changes, @NotNull Set> duplicates) + throws SVNException, SvnBindException { List result = ContainerUtil.newArrayList(); for (Change change : changes) { @@ -462,7 +467,7 @@ public class SvnChangeList implements CommittedChangeList { private Collection getChildrenAsChanges(@NotNull ContentRevision contentRevision, final boolean isBefore, @NotNull final Set> duplicates) - throws SVNException { + throws SVNException, SvnBindException { final List result = new ArrayList(); final String path = getRelativePath(contentRevision); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryLocation.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryLocation.java index 5dc605b8ed57..2e497ca12bda 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryLocation.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryLocation.java @@ -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); } } From 4d8ae0890fabbe7951a4e9dcaac7f574910f910d Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 12 Feb 2014 19:27:33 +0400 Subject: [PATCH 08/18] svn: Refactored SvnChangeList - use common client factory model (instead of direct SVNLogClient usage) --- .../idea/svn/history/SvnChangeList.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java index bf3cf7edafcd..f894bb3f423e 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnChangeList.java @@ -28,6 +28,7 @@ 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; @@ -43,8 +44,8 @@ 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.wc.SVNInfo; -import org.tmatesoft.svn.core.wc.SVNLogClient; import org.tmatesoft.svn.core.wc.SVNRevision; +import org.tmatesoft.svn.core.wc2.SvnTarget; import java.io.DataInput; import java.io.DataOutput; @@ -375,7 +376,7 @@ public class SvnChangeList implements CommittedChangeList { catch (SVNException e) { LOG.info(e); } - catch (SvnBindException e) { + catch (VcsException e) { LOG.info(e); } } @@ -390,6 +391,8 @@ public class SvnChangeList implements CommittedChangeList { if (revision == null) { continue; } + // 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()); @@ -410,7 +413,7 @@ public class SvnChangeList implements CommittedChangeList { ((SvnRevisionNumber)previousRevision.getRevisionNumber()).getRevision().getNumber()); } - private void uploadDeletedRenamedChildren() throws SVNException, SvnBindException { + private void uploadDeletedRenamedChildren() throws VcsException { Set> duplicates = collectDuplicates(); List preprocessed = ChangesPreprocess.preprocessChangesRemoveDeletedForDuplicateMoved(myDetailedList); @@ -418,7 +421,7 @@ public class SvnChangeList implements CommittedChangeList { } private List collectDetails(@NotNull List changes, @NotNull Set> duplicates) - throws SVNException, SvnBindException { + throws VcsException { List result = ContainerUtil.newArrayList(); for (Change change : changes) { @@ -467,15 +470,15 @@ public class SvnChangeList implements CommittedChangeList { private Collection getChildrenAsChanges(@NotNull ContentRevision contentRevision, final boolean isBefore, @NotNull final Set> duplicates) - throws SVNException, SvnBindException { + throws VcsException { final List result = new ArrayList(); 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 SVNLogClient client = myVcs.createLogClient(); - client.doList(fullPath, revisionNumber, revisionNumber, 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(); From c4e1a04fb68980048ab76ed25aa8a71f9841a34e Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 12 Feb 2014 19:59:46 +0400 Subject: [PATCH 09/18] svn: Implemented correct element name and relative path calculation for CmdBrowseClient --- .../org/jetbrains/idea/svn/browse/CmdBrowseClient.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/browse/CmdBrowseClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/browse/CmdBrowseClient.java index b8fba0c6e6bf..782d521dc5c0 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/browse/CmdBrowseClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/browse/CmdBrowseClient.java @@ -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; From 17b7bfaddd472d7624e91e5ecbc41d9a5d8c0680 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 12 Feb 2014 20:23:27 +0400 Subject: [PATCH 10/18] svn: Make SvnKitBrowseClient not pass to handler separate entry for root folder (at which list() method was executed) - to have consistent behaviour for both CmdBrowseClient and SvnKitBrowseClient --- .../idea/svn/branchConfig/BranchesLoader.java | 2 +- .../idea/svn/browse/SvnKitBrowseClient.java | 38 +++++++++++++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java index 2cbbc1c9024b..5e1bba8ddccb 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/BranchesLoader.java @@ -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 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())); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/browse/SvnKitBrowseClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/browse/SvnKitBrowseClient.java index 29531ab7c8fa..95388a12a8ec 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/browse/SvnKitBrowseClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/browse/SvnKitBrowseClient.java @@ -15,15 +15,13 @@ */ 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 From 300839eb8011a1f6de8d1bc3460cd8ca29429755 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 12 Feb 2014 20:50:53 +0400 Subject: [PATCH 11/18] svn: Refactored GatheringChangelistBuilder - code simplifications, notnull, removed unused code --- .../jetbrains/idea/svn/SvnPropertyKeys.java | 1 + .../integrate/GatheringChangelistBuilder.java | 42 ++++++++----------- .../integrate/SvnIntegrateChangesTask.java | 2 +- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java index 1b0792a51c22..39835e6488ad 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java @@ -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"; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java index f93b0c095d20..f1106f7f643f 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java @@ -15,7 +15,7 @@ */ 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; @@ -23,10 +23,11 @@ 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 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; @@ -36,16 +37,17 @@ import java.io.File; import java.util.*; public class GatheringChangelistBuilder implements ChangelistBuilder { - private final Set myCheckSet; - private final List myChanges; - private final UpdatedFilesReverseSide myFiles; - private final VirtualFile myMergeRoot; - private final SvnVcs myVcs; - 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 myCheckSet; + @NotNull private final List 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(); myCheckSet = new HashSet(); } @@ -90,20 +92,15 @@ public class GatheringChangelistBuilder implements ChangelistBuilder { private boolean mergeinfoChanged(final File file) { final SVNWCClient client = myVcs.createWCClient(); 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 = client.doGetProperty(file, SvnPropertyKeys.MERGE_INFO, SVNRevision.UNDEFINED, SVNRevision.WORKING); + SVNPropertyData base = client.doGetProperty(file, SvnPropertyKeys.MERGE_INFO, SVNRevision.UNDEFINED, 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) { - // + LOG.info(e); } return false; } @@ -153,10 +150,7 @@ public class GatheringChangelistBuilder implements ChangelistBuilder { public void reportAdditionalInfo(Factory infoComponent) { } - public void reportWarningMessage(final String message) { - // todo maybe, use further - } - + @NotNull public List getChanges() { return myChanges; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesTask.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesTask.java index 92447f87793f..b4e544ba1e3d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesTask.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnIntegrateChangesTask.java @@ -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) { From f042e762cf76c549b0964137f5963511ad5f0430 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 12 Feb 2014 21:04:43 +0400 Subject: [PATCH 12/18] svn: Refactored GatheringChangelistBuilder - use common client factory model to get svn properties (instead of direct SVNWCClient usage) --- .../svn/integrate/GatheringChangelistBuilder.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java index f1106f7f643f..a86fd2ef1141 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java @@ -19,6 +19,7 @@ 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; @@ -27,10 +28,9 @@ 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.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; @@ -90,16 +90,19 @@ public class GatheringChangelistBuilder implements ChangelistBuilder { } private boolean mergeinfoChanged(final File file) { - final SVNWCClient client = myVcs.createWCClient(); + SvnTarget target = SvnTarget.fromFile(file); + try { - SVNPropertyData current = client.doGetProperty(file, SvnPropertyKeys.MERGE_INFO, SVNRevision.UNDEFINED, SVNRevision.WORKING); - SVNPropertyData base = client.doGetProperty(file, SvnPropertyKeys.MERGE_INFO, 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) { return base == null || !Comparing.equal(current.getValue(), base.getValue()); } } - catch (SVNException e) { + catch (VcsException e) { LOG.info(e); } return false; From e266021633a6a72342dcb5e1b9d90459aa12704e Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 12 Feb 2014 21:08:44 +0400 Subject: [PATCH 13/18] svn: Refactored GatheringChangelistBuilder - make inherit EmptyChangelistBuilder, renames, optimizations --- .../integrate/GatheringChangelistBuilder.java | 54 +++---------------- 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java index a86fd2ef1141..b6228fca921d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/GatheringChangelistBuilder.java @@ -17,13 +17,13 @@ package org.jetbrains.idea.svn.integrate; 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; @@ -32,11 +32,10 @@ import org.tmatesoft.svn.core.wc.SVNPropertyData; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; -import javax.swing.*; import java.io.File; import java.util.*; -public class GatheringChangelistBuilder implements ChangelistBuilder { +public class GatheringChangelistBuilder extends EmptyChangelistBuilder { private static final Logger LOG = Logger.getInstance(GatheringChangelistBuilder.class); @@ -48,8 +47,8 @@ public class GatheringChangelistBuilder implements ChangelistBuilder { public GatheringChangelistBuilder(@NotNull SvnVcs vcs, @NotNull UpdatedFilesReverseSide files) { myVcs = vcs; myFiles = files; - myChanges = new ArrayList(); - myCheckSet = new HashSet(); + myChanges = ContainerUtil.newArrayList(); + myCheckSet = ContainerUtil.newHashSet(); } public void processChange(final Change change, VcsKey vcsKey) { @@ -83,13 +82,13 @@ 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) { + private boolean mergeInfoChanged(final File file) { SvnTarget target = SvnTarget.fromFile(file); try { @@ -108,51 +107,10 @@ public class GatheringChangelistBuilder implements ChangelistBuilder { 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 infoComponent) { - } - @NotNull public List getChanges() { return myChanges; From b2d5f76224168463cc7923b7049c831db58a820e Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 12 Feb 2014 21:18:19 +0400 Subject: [PATCH 14/18] svn: Refactored AbstractUpdateIntegrateCrawler - remove unnecessary SVNUpdateClient creation --- .../idea/svn/update/AbstractUpdateIntegrateCrawler.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java index f0de01f1e9b9..47b15802287b 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java @@ -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()) { From 4af031a4c423dcc2c9dbce427a5de489229d95ce Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Tue, 18 Feb 2014 18:09:54 +0400 Subject: [PATCH 15/18] svn: Refactored SvnCheckinEnvironment - not null, code simplifications, methods extracted, warnings fixes --- .../src/org/jetbrains/idea/svn/SvnUtil.java | 11 ++ .../svn/checkin/SvnCheckinEnvironment.java | 101 ++++++++---------- 2 files changed, 54 insertions(+), 58 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java index acb910880c61..3b8bb4ac57cf 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java @@ -39,6 +39,7 @@ 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; @@ -105,6 +106,16 @@ public class SvnUtil { return info != null; } + public static List toFiles(Iterable paths) { + List result = ContainerUtil.newArrayList(); + + for (String path : paths) { + result.add(new File(path)); + } + + return result; + } + public static Collection crawlWCRoots(final Project project, File path, SvnWCRootCrawler callback, ProgressIndicator progress) { final LocalFileSystem lfs = LocalFileSystem.getInstance(); VirtualFile vf = lfs.findFileByIoFile(path); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java index c296cb25b8b7..6e5f5e2938c9 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java @@ -33,15 +33,13 @@ 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.*; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.Convertor; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NonNls; @@ -60,16 +58,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 additionalDataConsumer) { - return new KeepLocksComponent(panel); + return new KeepLocksComponent(); } @Nullable @@ -83,8 +82,7 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { } - private List commitInt(List paths, final String comment, final boolean force, final boolean recursive, - final Set feedback) { + private List commitInt(List paths, final String comment, final boolean force, final Set feedback) { final List exception = new ArrayList(); final List committables = getCommitables(paths); @@ -143,7 +141,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()); @@ -163,6 +160,7 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { String comment, boolean force, List exception, final Set feedback) { + //noinspection unchecked final MultiMap,File> map = SvnUtil.splitIntoRepositoriesMap(mySvnVcs, committables, Convertor.SELF); for (Map.Entry, Collection> entry : map.entrySet()) { doCommitOneRepo(entry.getValue(), committer, comment, force, exception, feedback, entry.getKey().getSecond(), entry.getKey().getFirst()); @@ -209,18 +207,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,7 +363,8 @@ 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); @@ -388,26 +386,22 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { return new SvnCommandLineStatusClient(mySvnVcs).doStatus(file, false); } - private static List collectPaths(final List changes) { + private static List collectPaths(@NotNull List changes) { // case sensitive.. - ArrayList result = new ArrayList(); + Set paths = ContainerUtil.newHashSet(); - final Set pathesSet = new HashSet(); 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 paths, @Nullable ContentRevision revision) { + if (revision != null) { + paths.add(revision.getFile().getIOFile().getAbsolutePath()); } - return result; } public String getCheckinOperationName() { @@ -418,11 +412,11 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { String preparedComment, @NotNull NullableFunction parametersHolder, Set feedback) { - return commitInt(collectPaths(changes), preparedComment, true, false, feedback); + return commitInt(collectPaths(changes), preparedComment, true, feedback); } public List commit(List changes, String preparedComment) { - return commit(changes, preparedComment, FunctionUtil.nullConstant(), null); + return commit(changes, preparedComment, FunctionUtil.nullConstant(), null); } public List scheduleMissingFileForDeletion(List filePaths) { @@ -452,34 +446,25 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { public static List scheduleUnversionedFilesForAddition(@NotNull SvnVcs vcs, List 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 exceptions = new ArrayList(); + 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 +486,13 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { } private class KeepLocksComponent implements RefreshableOnComponent { - private final JCheckBox myKeepLocksBox; - private boolean myIsKeepLocks; - private final JPanel myPanel; - private final JCheckBox myAutoUpdate; - public KeepLocksComponent(final Refreshable panel) { + @NotNull private final JCheckBox myKeepLocksBox; + private boolean myIsKeepLocks; + @NotNull private final JPanel myPanel; + @NotNull private final JCheckBox myAutoUpdate; + + public KeepLocksComponent() { myPanel = new JPanel(new BorderLayout()); myKeepLocksBox = new JCheckBox(SvnBundle.message("checkbox.chckin.keep.files.locked")); @@ -522,11 +508,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 +530,4 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { myAutoUpdate.setSelected(configuration.isAutoUpdateAfterCommit()); } } - } From effd7741d71f0122700a26929543cd95da4d7d1d Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Tue, 18 Feb 2014 18:19:31 +0400 Subject: [PATCH 16/18] svn: Refactored SvnCheckinEnvironment - use common client factory model for file status detection --- .../idea/svn/checkin/SvnCheckinEnvironment.java | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java index 6e5f5e2938c9..07504dacb93f 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java @@ -366,26 +366,17 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { @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 collectPaths(@NotNull List changes) { // case sensitive.. Set paths = ContainerUtil.newHashSet(); From 93b33a355fb2b45d49626e78d4eb0e92ae206f14 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Tue, 18 Feb 2014 19:22:11 +0400 Subject: [PATCH 17/18] svn: Refactored SvnCheckinEnvironment - utilize IdeaCommitHandler as event handler for SVNKit commit flow --- .../idea/svn/checkin/IdeaCommitHandler.java | 67 ++++++++++++++++--- .../svn/checkin/SvnCheckinEnvironment.java | 66 +++++------------- 2 files changed, 74 insertions(+), 59 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java index 8a4b2031c8ce..96c96161c898 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java @@ -15,17 +15,27 @@ */ 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 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 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() { + @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; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java index 07504dacb93f..fd5197c49040 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java @@ -18,16 +18,17 @@ 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; @@ -37,18 +38,22 @@ 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.*; +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.*; @@ -89,50 +94,9 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { final SVNCommitClient committer = mySvnVcs.createCommitClient(); final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); - final Collection deletedFiles = new ArrayList(); + 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() { - @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) { @@ -149,7 +113,7 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { doCommit(committables, committer, comment, force, exception, feedback); } - for(VirtualFile f : deletedFiles) { + for(VirtualFile f : handler.getDeletedFiles()) { f.putUserData(VirtualFile.REQUESTOR_MARKER, this); } return exception; From cf9ace318187791551ac9269fd795f9f66260a66 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Tue, 18 Feb 2014 20:11:55 +0400 Subject: [PATCH 18/18] svn: Do not check repository protocol (just working copy format) when determining which implementation (SVNKit or command line) should be used for commit operation --- .../svn/checkin/SvnCheckinEnvironment.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java index fd5197c49040..8c9756ba8a1d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java @@ -113,6 +113,8 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { doCommit(committables, committer, comment, force, exception, feedback); } + // 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); } @@ -127,7 +129,7 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { //noinspection unchecked final MultiMap,File> map = SvnUtil.splitIntoRepositoriesMap(mySvnVcs, committables, Convertor.SELF); for (Map.Entry, Collection> 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()); } } @@ -135,18 +137,18 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { SVNCommitClient committer, String comment, boolean force, - List exception, final Set feedback, final WorkingCopyFormat format, SVNURL url) { + List exception, final Set 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 committables,