diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/RootUrlInfo.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/RootUrlInfo.java index 55309962aeca..3262ac006fd4 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/RootUrlInfo.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/RootUrlInfo.java @@ -25,6 +25,7 @@ public class RootUrlInfo implements RootUrlPair { private final String myRepositoryUrl; private final SVNURL myAbsoluteUrlAsUrl; private final WorkingCopyFormat myFormat; + private final boolean myRepoSupportsMergeInfo; private final File myIoFile; private final VirtualFile myVfile; @@ -33,11 +34,12 @@ public class RootUrlInfo implements RootUrlPair { private NestedCopyType myType; public RootUrlInfo(final SVNURL repositoryUrl, final SVNURL absoluteUrlAsUrl, final WorkingCopyFormat format, final VirtualFile vfile, - final VirtualFile root) { + final VirtualFile root, boolean repoSupportsMergeInfo) { myRepositoryUrlUrl = repositoryUrl; myFormat = format; myVfile = vfile; myRoot = root; + myRepoSupportsMergeInfo = repoSupportsMergeInfo; myIoFile = new File(myVfile.getPath()); final String asString = repositoryUrl.toString(); myRepositoryUrl = asString.endsWith("/") ? asString.substring(0, asString.length() - 1) : asString; @@ -89,4 +91,8 @@ public class RootUrlInfo implements RootUrlPair { public void setType(NestedCopyType type) { myType = type; } + + public boolean isRepoSupportsMergeInfo() { + return myRepoSupportsMergeInfo; + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java index 17e730c6f1cf..de898af284a5 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java @@ -298,7 +298,8 @@ class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentStateCompone } else { myRepositoryRoots.register(repoRoot); myTopRoots.add(new RootUrlInfo(repoRoot, foundRoot.getInfo().getURL(), - SvnFormatSelector.getWorkingCopyFormat(foundRoot.getInfo().getFile()), foundRoot.getFile(), vcsRoot)); + SvnFormatSelector.getWorkingCopyFormat(foundRoot.getInfo().getFile()), foundRoot.getFile(), vcsRoot, + SvnUtil.doesRepositorySupportMergeinfo(myVcs, repoRoot))); } } } @@ -354,9 +355,10 @@ class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentStateCompone } for (RootUrlInfo topRoot : myTopRoots) { if (VfsUtil.isAncestor(topRoot.getVirtualFile(), info.getFile(), true)) { - final SVNURL repoRoot = myRepositoryRoots.ask(info.getUrl()); + final RepoInfo repoRoot = myRepositoryRoots.ask(info.getUrl()); if (repoRoot != null) { - final RootUrlInfo rootInfo = new RootUrlInfo(repoRoot, info.getUrl(), info.getFormat(), info.getFile(), topRoot.getRoot()); + final RootUrlInfo rootInfo = new RootUrlInfo(repoRoot.getUrl(), info.getUrl(), info.getFormat(), info.getFile(), topRoot.getRoot(), + repoRoot.isRepoSupportsMergeinfo()); rootInfo.setType(info.getType()); nestedRoots.add(rootInfo); } @@ -413,28 +415,48 @@ class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentStateCompone private static class RepositoryRoots { private final SvnVcs myVcs; - private final Set myRoots; + private final Set myRoots; private RepositoryRoots(final SvnVcs vcs) { myVcs = vcs; - myRoots = new HashSet(); + myRoots = new HashSet(); } public void register(final SVNURL url) { - myRoots.add(url); + myRoots.add(new RepoInfo(url, SvnUtil.doesRepositorySupportMergeinfo(myVcs, url))); } - public SVNURL ask(final SVNURL url) { - for (SVNURL root : myRoots) { - if (root.equals(SVNURLUtil.getCommonURLAncestor(root, url))) { + public RepoInfo ask(final SVNURL url) { + for (RepoInfo root : myRoots) { + if (root.getUrl().equals(SVNURLUtil.getCommonURLAncestor(root.getUrl(), url))) { return root; } } - final SVNURL newRoot = SvnUtil.getRepositoryRoot(myVcs, url); - if (newRoot != null) { + final SVNURL newUrl = SvnUtil.getRepositoryRoot(myVcs, url); + if (newUrl != null) { + final RepoInfo newRoot = new RepoInfo(newUrl, SvnUtil.doesRepositorySupportMergeinfo(myVcs, url)); myRoots.add(newRoot); + return newRoot; } - return newRoot; + return null; + } + } + + private static class RepoInfo { + private final SVNURL myUrl; + private final boolean myRepoSupportsMergeinfo; + + private RepoInfo(final SVNURL url, final boolean repoSupportsMergeinfo) { + myRepoSupportsMergeinfo = repoSupportsMergeinfo; + myUrl = url; + } + + public boolean isRepoSupportsMergeinfo() { + return myRepoSupportsMergeinfo; + } + + public SVNURL getUrl() { + return myUrl; } } @@ -537,7 +559,7 @@ class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentStateCompone if ((svnInfo == null) || (svnInfo.getRepositoryRootURL() == null)) continue; mapping.add(new RootUrlInfo(svnInfo.getRepositoryRootURL(), svnInfo.getURL(), - SvnFormatSelector.getWorkingCopyFormat(svnInfo.getFile()), copyRoot, vcsRoot)); + SvnFormatSelector.getWorkingCopyFormat(svnInfo.getFile()), copyRoot, vcsRoot, SvnUtil.doesRepositorySupportMergeinfo(vcs, svnInfo.getURL()))); } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java index 48cbec92eba8..5d2c0ae24082 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java @@ -614,4 +614,13 @@ public class SvnUtil { } return null; } + + public static boolean doesRepositorySupportMergeinfo(final SvnVcs vcs, final SVNURL url) { + try { + return vcs.createRepository(url).hasCapability(SVNCapability.MERGE_INFO); + } + catch (SVNException e) { + return false; + } + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java index 74205cb4a57c..791d2b89763b 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java @@ -896,7 +896,7 @@ public class SvnVcs extends AbstractVcs { final File file = info.getIoFile(); infos.add(new WCInfo(file.getAbsolutePath(), info.getAbsoluteUrlAsUrl(), SvnFormatSelector.getWorkingCopyFormat(file), info.getRepositoryUrl(), SvnUtil.isWorkingCopyRoot(file), info.getType(), - SvnUtil.getDepth(this, file))); + SvnUtil.getDepth(this, file), info.isRepoSupportsMergeInfo())); } return infos; } 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 54b70f62a2b0..e6d1c9a7f617 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/QuickMerge.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/QuickMerge.java @@ -141,7 +141,7 @@ public class QuickMerge { tasks.add(new MyInitChecks()); tasks.add(new SourceUrlCorrection()); - final boolean supportsMergeinfo = myWcInfo.getFormat().supportsMergeInfo(); + final boolean supportsMergeinfo = myWcInfo.getFormat().supportsMergeInfo() && myWcInfo.isRepoSupportsMergeInfo(); if (! supportsMergeinfo) { insertMergeAll(tasks); } else { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/WCInfo.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/WCInfo.java index b75f3926e31f..34efa4c48c86 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/WCInfo.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/WCInfo.java @@ -29,9 +29,10 @@ public class WCInfo implements WCPaths { private final boolean myIsWcRoot; private final NestedCopyType myType; private final SVNDepth myStickyDepth; + private final boolean myRepoSupportsMergeInfo; public WCInfo(final String path, final SVNURL url, final WorkingCopyFormat format, final String repositoryRoot, final boolean isWcRoot, - final NestedCopyType type, SVNDepth stickyDepth) { + final NestedCopyType type, SVNDepth stickyDepth, boolean repoSupportsMergeInfo) { myPath = path; myUrl = url; myFormat = format; @@ -39,6 +40,7 @@ public class WCInfo implements WCPaths { myIsWcRoot = isWcRoot; myType = type; myStickyDepth = stickyDepth; + myRepoSupportsMergeInfo = repoSupportsMergeInfo; } public SVNDepth getStickyDepth() { @@ -97,4 +99,8 @@ public class WCInfo implements WCPaths { public NestedCopyType getType() { return myType; } + + public boolean isRepoSupportsMergeInfo() { + return myRepoSupportsMergeInfo; + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/WCInfoWithBranches.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/WCInfoWithBranches.java index e1b5c8c8e646..4a18e1c8858a 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/WCInfoWithBranches.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/WCInfoWithBranches.java @@ -33,8 +33,8 @@ public class WCInfoWithBranches extends WCInfo { final List branches, final VirtualFile root, final String trunkToot, - final NestedCopyType type, final SVNDepth depth) { - super(path, url, format, repositoryRoot, isWcRoot, type, depth); + final NestedCopyType type, final SVNDepth depth, boolean repoSupportsMergeinfo) { + super(path, url, format, repositoryRoot, isWcRoot, type, depth, repoSupportsMergeinfo); myBranches = branches; myRoot = root; myTrunkRoot = trunkToot; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/WcInfoLoader.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/WcInfoLoader.java index d5985b7eef23..e03eaf06acd1 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/WcInfoLoader.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/WcInfoLoader.java @@ -80,7 +80,7 @@ public class WcInfoLoader { } final WCInfo wcInfo = new WCInfo(rootInfo.getIoFile().getAbsolutePath(), rootInfo.getAbsoluteUrlAsUrl(), SvnFormatSelector.getWorkingCopyFormat(file), rootInfo.getRepositoryUrl(), SvnUtil.isWorkingCopyRoot(file), - rootInfo.getType(), SvnUtil.getDepth(vcs, file)); + rootInfo.getType(), SvnUtil.getDepth(vcs, file), info.isRepoSupportsMergeInfo()); return createInfo(wcInfo, vcs, urlMapping); } @@ -125,7 +125,7 @@ public class WcInfoLoader { final String branchRoot = createBranchesList(url, configuration, items); return new WCInfoWithBranches(info.getPath(), info.getUrl(), info.getFormat(), info.getRepositoryRoot(), info.isIsWcRoot(), items, root, - branchRoot, info.getType(), info.getStickyDepth()); + branchRoot, info.getType(), info.getStickyDepth(), info.isRepoSupportsMergeInfo()); } private static String createBranchesList(final String url, final SvnBranchConfigurationNew configuration, diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnMergeInfoTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnMergeInfoTest.java index 8f2211c5fb54..14a668b3ca71 100644 --- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnMergeInfoTest.java +++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnMergeInfoTest.java @@ -43,7 +43,7 @@ public class SvnMergeInfoTest extends SvnTestCase { myProjectLevelVcsManager.setDirectoryMapping(myBranchVcsRoot.getAbsolutePath(), SvnVcs.VCS_NAME); myWCInfo = new WCInfo(myBranchVcsRoot.getAbsolutePath(), SVNURL.parseURIEncoded(myRepoUrl + "/branch"), WorkingCopyFormat.ONE_DOT_SIX, - myRepoUrl, true, null, SVNDepth.INFINITY); + myRepoUrl, true, null, SVNDepth.INFINITY, true); myOneShotMergeInfoHelper = new OneShotMergeInfoHelper(myProject, myWCInfo, myRepoUrl + "/trunk"); SvnConfiguration.getInstance(myProject).CHECK_NESTED_FOR_QUICK_MERGE = true;