From b1fc355f7183de90eb0d5d8dcb108d0d1f32ad5a Mon Sep 17 00:00:00 2001 From: irengrig Date: Tue, 27 Nov 2012 17:48:24 +0400 Subject: [PATCH] IDEA-95960 Subversion: Browse Repository -> Show History *for repository root* produces no history [r=kirill.l] --- .../idea/svn/history/SvnHistoryProvider.java | 20 +-- .../SvnPathThroughHistoryCorrection.java | 10 ++ .../jetbrains/idea/svn/SvnHistoryTest.java | 130 ++++++++++++++++++ 3 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnHistoryTest.java diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java index 47ed8d1785e4..f695a0908d55 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java @@ -522,15 +522,19 @@ public class SvnHistoryProvider } myIndicator.setText2(SvnBundle.message("progress.text2.revision.processed", logEntry.getRevision())); } - myLastPathCorrector.handleLogEntry(logEntry); - SVNLogEntryPath entryPath = myLastPathCorrector.getDirectlyMentioned(); + SVNLogEntryPath entryPath = null; String copyPath = null; - if (entryPath != null) { - copyPath = entryPath.getCopyPath(); - } else { - // if there are no path with exact match, check whether parent or child paths had changed - // "entry path" is allowed to be null now; if it is null, last path would be taken for revision construction - if (! checkForChildChanges(logEntry) && ! checkForParentChanges(logEntry)) return; + if (! myLastPathCorrector.isRoot()) { + myLastPathCorrector.handleLogEntry(logEntry); + entryPath = myLastPathCorrector.getDirectlyMentioned(); + copyPath = null; + if (entryPath != null) { + copyPath = entryPath.getCopyPath(); + } else { + // if there are no path with exact match, check whether parent or child paths had changed + // "entry path" is allowed to be null now; if it is null, last path would be taken for revision construction + if (! checkForChildChanges(logEntry) && ! checkForParentChanges(logEntry)) return; + } } final int mergeLevel = svnLogEntryIntegerPair.getSecond(); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnPathThroughHistoryCorrection.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnPathThroughHistoryCorrection.java index 84e64910e6a8..35b7b4dbc075 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnPathThroughHistoryCorrection.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnPathThroughHistoryCorrection.java @@ -15,6 +15,7 @@ */ package org.jetbrains.idea.svn.history; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.idea.svn.SvnUtil; import org.tmatesoft.svn.core.ISVNLogEntryHandler; import org.tmatesoft.svn.core.SVNException; @@ -36,14 +37,19 @@ public class SvnPathThroughHistoryCorrection implements ISVNLogEntryHandler { private String myBefore; private String myPath; private SVNLogEntryPath myDirectlyMentioned; + private boolean myRoot; public SvnPathThroughHistoryCorrection(String path) { myPath = path; myBefore = path; + myRoot = StringUtil.isEmpty(path); } @Override public void handleLogEntry(SVNLogEntry logEntry) throws SVNException { + if (myRoot) { + return; + } myBefore = myPath; myDirectlyMentioned = null; final Map paths = logEntry.getChangedPaths(); @@ -88,4 +94,8 @@ public class SvnPathThroughHistoryCorrection implements ISVNLogEntryHandler { public String getCurrentPath() { return myPath; } + + public boolean isRoot() { + return myRoot; + } } diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnHistoryTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnHistoryTest.java new file mode 100644 index 000000000000..37bd2601e221 --- /dev/null +++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnHistoryTest.java @@ -0,0 +1,130 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.svn; + +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.VcsConfiguration; +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.actions.VcsContextFactory; +import com.intellij.openapi.vcs.history.VcsAbstractHistorySession; +import com.intellij.openapi.vcs.history.VcsAppendableHistorySessionPartner; +import com.intellij.openapi.vcs.history.VcsFileRevision; +import com.intellij.openapi.vcs.history.VcsHistoryProvider; +import com.intellij.util.concurrency.Semaphore; +import junit.framework.Assert; +import org.junit.Test; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 11/27/12 + * Time: 5:15 PM + */ +public class SvnHistoryTest extends Svn17TestCase { + private volatile int myCnt; + + @Test + public void testRepositoryRootHistory() throws Exception { + enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); + enableSilentOperation(VcsConfiguration.StandardConfirmation.REMOVE); + myCnt = 0; + final VcsHistoryProvider provider = SvnVcs.getInstance(myProject).getVcsHistoryProvider(); + final SubTree tree = new SubTree(myWorkingCopyDir); + checkin(); + + for (int i = 0; i < 10; i++) { + editFileInCommand(myProject, tree.myS1File, "1\n2\n3\n4\n" + i); + checkin(); + } + + final Semaphore semaphore = new Semaphore(); + semaphore.down(); + final FilePath rootPath = VcsContextFactory.SERVICE.getInstance().createFilePathOnNonLocal(myRepoUrl, true); + provider.reportAppendableHistory(rootPath, new VcsAppendableHistorySessionPartner() { + @Override + public void reportCreatedEmptySession(VcsAbstractHistorySession session) { + } + + @Override + public void acceptRevision(VcsFileRevision revision) { + ++ myCnt; + semaphore.up(); + } + + @Override + public void reportException(VcsException exception) { + throw new RuntimeException(exception); + } + + @Override + public void finished() { + } + + @Override + public void forceRefresh() { + } + }); + semaphore.waitFor(1000); + + Assert.assertTrue(myCnt > 0); + } + + @Test + public void testSimpleHistory() throws Exception { + enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); + enableSilentOperation(VcsConfiguration.StandardConfirmation.REMOVE); + myCnt = 0; + final VcsHistoryProvider provider = SvnVcs.getInstance(myProject).getVcsHistoryProvider(); + final SubTree tree = new SubTree(myWorkingCopyDir); + checkin(); + + for (int i = 0; i < 10; i++) { + editFileInCommand(myProject, tree.myS1File, "1\n2\n3\n4\n" + i); + checkin(); + } + + final Semaphore semaphore = new Semaphore(); + semaphore.down(); + final FilePath rootPath = VcsContextFactory.SERVICE.getInstance().createFilePathOnNonLocal(myRepoUrl + "/root/source/s1.txt", true); + provider.reportAppendableHistory(rootPath, new VcsAppendableHistorySessionPartner() { + @Override + public void reportCreatedEmptySession(VcsAbstractHistorySession session) { + } + + @Override + public void acceptRevision(VcsFileRevision revision) { + ++ myCnt; + } + + @Override + public void reportException(VcsException exception) { + throw new RuntimeException(exception); + } + + @Override + public void finished() { + semaphore.up(); + } + + @Override + public void forceRefresh() { + } + }); + semaphore.waitFor(1000); + + Assert.assertEquals(11, myCnt); + } +}