| /* |
| * 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.execution.process.ProcessOutput; |
| import com.intellij.openapi.command.WriteCommandAction; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.openapi.vcs.FileStatus; |
| import com.intellij.openapi.vcs.VcsConfiguration; |
| import com.intellij.openapi.vcs.VcsException; |
| import com.intellij.openapi.vcs.changes.Change; |
| import com.intellij.openapi.vcs.changes.ChangeListManager; |
| import com.intellij.openapi.vcs.changes.ChangeListManagerImpl; |
| import com.intellij.openapi.vcs.rollback.RollbackProgressListener; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import org.jetbrains.annotations.NonNls; |
| import org.junit.Assert; |
| import org.junit.Test; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| /** |
| * @author yole |
| */ |
| public class SvnRenameTest extends Svn17TestCase { |
| @NonNls private static final String LOG_SEPARATOR = "------------------------------------------------------------------------\n"; |
| @NonNls private static final String LOG_SEPARATOR_START = "-------------"; |
| |
| public SvnRenameTest() { |
| myInitChangeListManager = false; |
| } |
| |
| @Test |
| public void testSimpleRename() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile a = createFileInCommand("a.txt", "test"); |
| checkin(); |
| |
| renameFileInCommand(a, "b.txt"); |
| verifySorted(runSvn("status"), "A + b.txt", "D a.txt"); |
| } |
| |
| // IDEADEV-18844 |
| @Test |
| public void testRenameReplace() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile a = createFileInCommand("a.txt", "old"); |
| final VirtualFile aNew = createFileInCommand("aNew.txt", "new"); |
| checkin(); |
| |
| renameFileInCommand(a, "aOld.txt"); |
| renameFileInCommand(aNew, "a.txt"); |
| final ProcessOutput result = runSvn("status"); |
| verifySorted(result, "A + aOld.txt", "D aNew.txt", "R + a.txt"); |
| } |
| |
| // IDEADEV-16251 |
| @Test |
| public void testRenameAddedPackage() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile dir = createDirInCommand(myWorkingCopyDir, "child"); |
| createFileInCommand(dir, "a.txt", "content"); |
| renameFileInCommand(dir, "newchild"); |
| verifySorted(runSvn("status"), "A newchild", "A newchild" + File.separatorChar + "a.txt"); |
| } |
| |
| // IDEADEV-8091 |
| @Test |
| public void testDoubleRename() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile a = createFileInCommand("a.txt", "test"); |
| checkin(); |
| |
| renameFileInCommand(a, "b.txt"); |
| renameFileInCommand(a, "c.txt"); |
| verifySorted(runSvn("status"), "A + c.txt", "D a.txt"); |
| } |
| |
| // IDEADEV-15876 |
| @Test |
| public void testRenamePackageWithChildren() throws Exception { |
| final VirtualFile child = prepareDirectoriesForRename(); |
| |
| renameFileInCommand(child, "childnew"); |
| final ProcessOutput result = runSvn("status"); |
| verifySorted(result, "A + childnew", |
| "D child", |
| "D child" + File.separatorChar + "a.txt", |
| "D child" + File.separatorChar + "grandChild", |
| "D child" + File.separatorChar + "grandChild" + File.separatorChar + "b.txt"); |
| |
| refreshVfs(); // wait for end of refresh operations initiated from SvnFileSystemListener |
| final ChangeListManager changeListManager = ChangeListManager.getInstance(myProject); |
| insideInitializedChangeListManager(changeListManager, new Runnable() { |
| @Override |
| public void run() { |
| changeListManager.ensureUpToDate(false); |
| List<Change> changes = new ArrayList<Change>(changeListManager.getDefaultChangeList().getChanges()); |
| Assert.assertEquals(4, changes.size()); |
| sortChanges(changes); |
| verifyChange(changes.get(0), "child", "childnew"); |
| verifyChange(changes.get(1), "child" + File.separatorChar + "a.txt", "childnew" + File.separatorChar + "a.txt"); |
| verifyChange(changes.get(2), "child" + File.separatorChar + "grandChild", "childnew" + File.separatorChar + "grandChild"); |
| verifyChange(changes.get(3), "child" + File.separatorChar + "grandChild" + File.separatorChar + "b.txt", "childnew" + File.separatorChar + "grandChild" + File.separatorChar + "b.txt"); |
| } |
| }); |
| |
| // there is no such directory any more |
| /*VirtualFile oldChild = myWorkingCopyDir.findChild("child"); |
| if (oldChild == null) { |
| myWorkingCopyDir.refresh(false, true); |
| oldChild = myWorkingCopyDir.findChild("child"); |
| } |
| Assert.assertEquals(FileStatus.DELETED, changeListManager.getStatus(oldChild));*/ |
| } |
| |
| private void insideInitializedChangeListManager(final ChangeListManager changeListManager, final Runnable runnable) { |
| ((ChangeListManagerImpl) changeListManager).projectOpened(); |
| try { |
| runnable.run(); |
| } finally { |
| ((ChangeListManagerImpl) changeListManager).projectClosed(); |
| ((ChangeListManagerImpl) changeListManager).stopEveryThingIfInTestMode(); |
| } |
| } |
| |
| private VirtualFile prepareDirectoriesForRename() throws IOException { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile child = createDirInCommand(myWorkingCopyDir, "child"); |
| final VirtualFile grandChild = createDirInCommand(child, "grandChild"); |
| createFileInCommand(child, "a.txt", "a"); |
| createFileInCommand(grandChild, "b.txt", "b"); |
| checkin(); |
| return child; |
| } |
| |
| // IDEADEV-19065 |
| @Test |
| public void testCommitAfterRenameDir() throws Exception { |
| final VirtualFile child = prepareDirectoriesForRename(); |
| |
| renameFileInCommand(child, "newchild"); |
| checkin(); |
| |
| final ProcessOutput runResult = runSvn("log", "-q", "newchild/a.txt"); |
| verify(runResult); |
| final List<String> lines = StringUtil.split(runResult.getStdout(), "\n"); |
| for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) { |
| final String next = iterator.next(); |
| if (next.startsWith(LOG_SEPARATOR_START)) { |
| iterator.remove(); |
| } |
| } |
| Assert.assertEquals(2, lines.size()); |
| Assert.assertTrue(lines.get(0).startsWith("r2 |")); |
| Assert.assertTrue(lines.get(1).startsWith("r1 |")); |
| } |
| |
| // todo - undo; undo after commit |
| // IDEADEV-9755 |
| @Test |
| public void testRollbackRenameDir() throws Exception { |
| final VirtualFile child = prepareDirectoriesForRename(); |
| renameFileInCommand(child, "newchild"); |
| |
| final ChangeListManager changeListManager = ChangeListManager.getInstance(myProject); |
| insideInitializedChangeListManager(changeListManager, new Runnable() { |
| @Override |
| public void run() { |
| changeListManager.ensureUpToDate(false); |
| final Change change = changeListManager.getChange(myWorkingCopyDir.findChild("newchild")); |
| Assert.assertNotNull(change); |
| |
| final List<VcsException> exceptions = new ArrayList<VcsException>(); |
| SvnVcs.getInstance(myProject).getRollbackEnvironment().rollbackChanges(Collections.singletonList(change), exceptions, |
| RollbackProgressListener.EMPTY); |
| Assert.assertTrue(exceptions.isEmpty()); |
| Assert.assertFalse(new File(myWorkingCopyDir.getPath(), "newchild").exists()); |
| Assert.assertTrue(new File(myWorkingCopyDir.getPath(), "child").exists()); |
| } |
| }); |
| } |
| |
| // todo undo; undo after commit |
| // IDEADEV-7697 |
| @Test |
| public void testMovePackageToParent() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile child = createDirInCommand(myWorkingCopyDir, "child"); |
| final VirtualFile grandChild = createDirInCommand(child, "grandChild"); |
| createFileInCommand(grandChild, "a.txt", "a"); |
| checkin(); |
| final ChangeListManager changeListManager = ChangeListManager.getInstance(myProject); |
| insideInitializedChangeListManager(changeListManager, new Runnable() { |
| @Override |
| public void run() { |
| moveFileInCommand(grandChild, myWorkingCopyDir); |
| refreshVfs(); // wait for end of refresh operations initiated from SvnFileSystemListener |
| changeListManager.ensureUpToDate(false); |
| final List<Change> changes = new ArrayList<Change>(changeListManager.getDefaultChangeList().getChanges()); |
| Assert.assertEquals(listToString(changes), 2, changes.size()); |
| sortChanges(changes); |
| verifyChange(changes.get(0), "child" + File.separatorChar + "grandChild", "grandChild"); |
| verifyChange(changes.get(1), "child" + File.separatorChar + "grandChild" + File.separatorChar + "a.txt", |
| "grandChild" + File.separatorChar + "a.txt"); |
| } |
| }); |
| } |
| |
| private String listToString(final List<Change> changes) { |
| return "{" + StringUtil.join(changes, StringUtil.createToStringFunction(Change.class), ",") + "}"; |
| } |
| |
| // IDEADEV-19223 |
| @Test |
| public void testRollbackRenameWithUnversioned() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile child = createDirInCommand(myWorkingCopyDir, "child"); |
| createFileInCommand(child, "a.txt", "a"); |
| checkin(); |
| disableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile unversioned = createFileInCommand(child, "u.txt", "u"); |
| final VirtualFile unversionedDir = createDirInCommand(child, "uc"); |
| createFileInCommand(unversionedDir, "c.txt", "c"); |
| |
| final ChangeListManager changeListManager = ChangeListManager.getInstance(myProject); |
| insideInitializedChangeListManager(changeListManager, new Runnable() { |
| @Override |
| public void run() { |
| changeListManager.ensureUpToDate(false); |
| Assert.assertEquals(FileStatus.UNKNOWN, changeListManager.getStatus(unversioned)); |
| |
| renameFileInCommand(child, "newchild"); |
| File childPath = new File(myWorkingCopyDir.getPath(), "child"); |
| File newChildPath = new File(myWorkingCopyDir.getPath(), "newchild"); |
| Assert.assertTrue(new File(newChildPath, "a.txt").exists()); |
| Assert.assertTrue(new File(newChildPath, "u.txt").exists()); |
| Assert.assertFalse(new File(childPath, "u.txt").exists()); |
| |
| refreshVfs(); |
| changeListManager.ensureUpToDate(false); |
| final List<Change> changes = new ArrayList<Change>(); |
| changes.add(ChangeListManager.getInstance(myProject).getChange(myWorkingCopyDir.findChild("newchild").findChild("a.txt"))); |
| changes.add(ChangeListManager.getInstance(myProject).getChange(myWorkingCopyDir.findChild("newchild"))); |
| |
| final List<VcsException> exceptions = new ArrayList<VcsException>(); |
| SvnVcs.getInstance(myProject).getRollbackEnvironment().rollbackChanges(changes, exceptions, RollbackProgressListener.EMPTY); |
| try { |
| Thread.sleep(300); |
| } |
| catch (InterruptedException e) { |
| // |
| } |
| Assert.assertTrue(exceptions.isEmpty()); |
| final File fileA = new File(childPath, "a.txt"); |
| Assert.assertTrue(fileA.getAbsolutePath(), fileA.exists()); |
| final File fileU = new File(childPath, "u.txt"); |
| Assert.assertTrue(fileU.getAbsolutePath(), fileU.exists()); |
| final File unversionedDirFile = new File(childPath, "uc"); |
| Assert.assertTrue(unversionedDirFile.exists()); |
| Assert.assertTrue(new File(unversionedDirFile, "c.txt").exists()); |
| } |
| }); |
| } |
| |
| // IDEA-13824 |
| @Test |
| public void testRenameFileRenameDir() throws Exception { |
| setNativeAcceleration(true); //todo debug |
| final VirtualFile child = prepareDirectoriesForRename(); |
| final VirtualFile f = child.findChild("a.txt"); |
| renameFileInCommand(f, "anew.txt"); |
| renameFileInCommand(child, "newchild"); |
| |
| verifySorted(runSvn("status"), "A + newchild", "A + newchild" + File.separatorChar + "anew.txt", |
| "D child", "D child" + File.separatorChar + "a.txt", "D child" + File.separatorChar + "grandChild", "D child" + File.separatorChar + "grandChild" + File.separatorChar + "b.txt", "D + newchild" + File.separatorChar + "a.txt"); |
| |
| final ChangeListManager changeListManager = ChangeListManager.getInstance(myProject); |
| insideInitializedChangeListManager(changeListManager, new Runnable() { |
| @Override |
| public void run() { |
| refreshVfs(); // wait for end of refresh operations initiated from SvnFileSystemListener |
| changeListManager.ensureUpToDate(false); |
| final List<Change> changes = new ArrayList<Change>(changeListManager.getDefaultChangeList().getChanges()); |
| final List<VcsException> list = SvnVcs.getInstance(myProject).getCheckinEnvironment().commit(changes, "test"); |
| Assert.assertEquals(0, list.size()); |
| } |
| }); |
| } |
| |
| // IDEADEV-19364 |
| @Test |
| public void testUndoMovePackage() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile parent1 = createDirInCommand(myWorkingCopyDir, "parent1"); |
| final VirtualFile parent2 = createDirInCommand(myWorkingCopyDir, "parent2"); |
| final VirtualFile child = createDirInCommand(parent1, "child"); |
| createFileInCommand(child, "a.txt", "a"); |
| checkin(); |
| |
| moveFileInCommand(child, parent2); |
| undo(); |
| final File childPath = new File(parent1.getPath(), "child"); |
| Assert.assertTrue(childPath.exists()); |
| Assert.assertTrue(new File(childPath, "a.txt").exists()); |
| } |
| |
| // IDEADEV-19552 |
| @Test |
| public void testUndoRename() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A"); |
| checkin(); |
| |
| renameFileInCommand(file, "b.txt"); |
| undo(); |
| Assert.assertTrue(new File(myWorkingCopyDir.getPath(), "a.txt").exists()); |
| Assert.assertFalse(new File(myWorkingCopyDir.getPath(), "b.txt").exists()); |
| } |
| |
| @Test |
| public void testUndoCommittedRenameFile() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A"); |
| checkin(); |
| |
| renameFileInCommand(file, "b.txt"); |
| checkin(); |
| undo(); |
| verifySorted(runSvn("status"), "A + a.txt", "D b.txt"); |
| } |
| |
| // IDEADEV-19336 |
| @Test |
| public void testUndoMoveCommittedPackage() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.REMOVE); |
| final VirtualFile parent1 = createDirInCommand(myWorkingCopyDir, "parent1"); |
| final VirtualFile parent2 = createDirInCommand(myWorkingCopyDir, "parent2"); |
| final VirtualFile child = createDirInCommand(parent1, "child"); |
| createFileInCommand(child, "a.txt", "a"); |
| checkin(); |
| |
| moveFileInCommand(child, parent2); |
| checkin(); |
| |
| undo(); |
| verifySorted(runSvn("status"), "A + parent1" + File.separatorChar + "child", |
| "D parent2" + File.separatorChar + "child", |
| "D parent2" + File.separatorChar + "child" + File.separatorChar + "a.txt"); |
| } |
| |
| @Test |
| public void testMoveToUnversioned() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A"); |
| final VirtualFile child = moveToNewPackage(file, "child"); |
| verifySorted(runSvn("status"), "A child", "A child" + File.separatorChar + "a.txt"); |
| checkin(); |
| disableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile unversioned = createDirInCommand(myWorkingCopyDir, "unversioned"); |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| verifySorted(runSvn("status"), "? unversioned"); |
| |
| moveFileInCommand(child, unversioned); |
| verifySorted(runSvn("status"), "? unversioned", "D child", "D child" + File.separator + "a.txt"); |
| } |
| |
| @Test |
| public void testUndoMoveToUnversioned() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A"); |
| final VirtualFile child = moveToNewPackage(file, "child"); |
| verifySorted(runSvn("status"), "A child", "A child" + File.separatorChar + "a.txt"); |
| checkin(); |
| disableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile unversioned = createDirInCommand(myWorkingCopyDir, "unversioned"); |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| verifySorted(runSvn("status"), "? unversioned"); |
| |
| moveFileInCommand(child, unversioned); |
| verifySorted(runSvn("status"), "? unversioned", "D child", "D child" + File.separator + "a.txt"); |
| |
| undo(); |
| verifySorted(runSvn("status"), "? unversioned"); |
| } |
| |
| @Test |
| public void testUndoMoveUnversionedToUnversioned() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| |
| disableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A"); |
| verifySorted(runSvn("status"), "? a.txt"); |
| final VirtualFile unversioned = createDirInCommand(myWorkingCopyDir, "unversioned"); |
| moveFileInCommand(file, unversioned); |
| verifySorted(runSvn("status"), "? unversioned"); |
| undo(); |
| verifySorted(runSvn("status"), "? a.txt", "? unversioned"); |
| } |
| |
| @Test |
| public void testUndoMoveAddedToUnversioned() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| |
| final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A"); |
| verifySorted(runSvn("status"), "A a.txt"); |
| disableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile unversioned = createDirInCommand(myWorkingCopyDir, "unversioned"); |
| moveFileInCommand(file, unversioned); |
| verifySorted(runSvn("status"), "? unversioned"); |
| undo(); |
| verifySorted(runSvn("status"), "? a.txt", "? unversioned"); |
| } |
| |
| @Test |
| public void testUndoMoveToUnversionedCommitted() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A"); |
| final VirtualFile child = moveToNewPackage(file, "child"); |
| verifySorted(runSvn("status"), "A child", "A child" + File.separatorChar + "a.txt"); |
| checkin(); |
| disableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile unversioned = createDirInCommand(myWorkingCopyDir, "unversioned"); |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| verifySorted(runSvn("status"), "? unversioned"); |
| |
| moveFileInCommand(child, unversioned); |
| verifySorted(runSvn("status"), "? unversioned", "D child", "D child" + File.separator + "a.txt"); |
| checkin(); |
| |
| undo(); |
| verifySorted(runSvn("status"), "? child", "? unversioned"); |
| } |
| |
| // IDEA-92941 |
| @Test |
| public void testUndoNewMove() throws Exception { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile sink = createDirInCommand(myWorkingCopyDir, "sink"); |
| final VirtualFile child = createDirInCommand(myWorkingCopyDir, "child"); |
| verifySorted(runSvn("status"), "A child", "A sink"); |
| checkin(); |
| final VirtualFile file = createFileInCommand(child, "a.txt", "A"); |
| verifySorted(runSvn("status"), "A child" + File.separatorChar + "a.txt"); |
| moveFileInCommand(file, sink); |
| verifySorted(runSvn("status"), "A sink" + File.separatorChar + "a.txt"); |
| undo(); |
| verifySorted(runSvn("status"), "A child" + File.separatorChar + "a.txt"); |
| } |
| |
| // todo undo, undo committed? |
| @Test |
| public void testMoveToNewPackage() throws Throwable { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A"); |
| moveToNewPackage(file, "child"); |
| verifySorted(runSvn("status"), "A child", "A child" + File.separatorChar + "a.txt"); |
| } |
| |
| @Test |
| public void testMoveToNewPackageCommitted() throws Throwable { |
| enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD); |
| final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A"); |
| checkin(); |
| moveToNewPackage(file, "child"); |
| verifySorted(runSvn("status"), "A child", "A + child" + File.separatorChar + "a.txt", "D a.txt"); |
| } |
| |
| private VirtualFile moveToNewPackage(final VirtualFile file, final String packageName) throws Exception { |
| final VirtualFile[] dir = new VirtualFile[1]; |
| new WriteCommandAction.Simple(myProject) { |
| @Override |
| public void run() { |
| try { |
| dir[0] = myWorkingCopyDir.createChildDirectory(this, packageName); |
| file.move(this, dir[0]); |
| } |
| catch (IOException e) { |
| throw new RuntimeException(e); |
| } |
| |
| } |
| }.execute().throwException(); |
| return dir[0]; |
| } |
| } |