| /******************************************************************************* |
| * Copyright (C) 2015 Obeo and others. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| *******************************************************************************/ |
| package org.eclipse.emf.compare.ide.ui.tests.merge; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertSame; |
| import static org.junit.Assert.assertTrue; |
| |
| import java.io.File; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IStorage; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.emf.compare.egit.internal.merge.GitResourceVariantTreeProvider; |
| import org.eclipse.emf.compare.egit.internal.merge.GitResourceVariantTreeSubscriber; |
| import org.eclipse.emf.compare.egit.internal.merge.TreeWalkResourceVariantTreeProvider; |
| import org.eclipse.jgit.revwalk.RevTree; |
| import org.eclipse.jgit.revwalk.RevWalk; |
| import org.eclipse.jgit.treewalk.NameConflictTreeWalk; |
| import org.eclipse.jgit.treewalk.TreeWalk; |
| import org.eclipse.team.core.diff.IDiff; |
| import org.eclipse.team.core.diff.IThreeWayDiff; |
| import org.eclipse.team.core.history.IFileRevision; |
| import org.eclipse.team.core.mapping.provider.ResourceDiff; |
| import org.eclipse.team.core.synchronize.SyncInfo; |
| import org.eclipse.team.core.variants.IResourceVariant; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| public class GitResourceVariantTreeSubscriberTest extends VariantsTestCase { |
| private static final String BRANCH_CHANGES = "branch changes\n"; |
| |
| private static final String MASTER_CHANGES = "\nsome changes"; |
| |
| private static final String BASE = "base"; |
| |
| private File file1; |
| |
| private File file2; |
| |
| private IFile iFile1; |
| |
| private IFile iFile2; |
| |
| @Override |
| @Before |
| public void setUp() throws Exception { |
| super.setUp(); |
| |
| file1 = repository.createFile(iProject, "file1"); |
| file2 = repository.createFile(iProject, "file2"); |
| |
| iFile1 = repository.getIFile(iProject, file1); |
| iFile2 = repository.getIFile(iProject, file2); |
| } |
| |
| @Test |
| public void testSubscriber() throws Exception { |
| GitResourceVariantTreeProvider provider = createTreeProvider(); |
| GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(provider); |
| |
| assertTrue(subscriber.isSupervised(iProject)); |
| assertTrue(subscriber.isSupervised(iFile1)); |
| assertTrue(subscriber.isSupervised(iFile2)); |
| |
| assertSame(provider.getBaseTree(), subscriber.getBaseTree()); |
| assertSame(provider.getRemoteTree(), subscriber.getRemoteTree()); |
| assertSame(provider.getSourceTree(), subscriber.getSourceTree()); |
| |
| assertNotNull(subscriber.getDiff(iProject)); |
| assertNotNull(subscriber.getDiff(iFile1)); |
| assertNotNull(subscriber.getDiff(iFile2)); |
| |
| assertNotNull(subscriber.getSyncInfo(iProject)); |
| assertNotNull(subscriber.getSyncInfo(iFile1)); |
| assertNotNull(subscriber.getSyncInfo(iFile2)); |
| |
| } |
| |
| @Test |
| public void testSyncInfo() throws Exception { |
| GitResourceVariantTreeProvider provider = createTreeProvider(); |
| GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(provider); |
| |
| final SyncInfo projectInfo = subscriber.getSyncInfo(iProject); |
| assertNotNull(projectInfo); |
| assertEquals(SyncInfo.CONFLICTING | SyncInfo.CHANGE, projectInfo.getKind()); |
| |
| final SyncInfo syncInfo1 = subscriber.getSyncInfo(iFile1); |
| assertNotNull(syncInfo1); |
| assertEquals(SyncInfo.OUTGOING | SyncInfo.CHANGE, syncInfo1.getKind()); |
| IResourceVariant baseVariant1 = syncInfo1.getBase(); |
| IResourceVariant remoteVariant1 = syncInfo1.getRemote(); |
| assertContentEquals(baseVariant1, INITIAL_CONTENT_1); |
| assertContentEquals(remoteVariant1, INITIAL_CONTENT_1); |
| |
| final SyncInfo syncInfo2 = subscriber.getSyncInfo(iFile2); |
| assertNotNull(syncInfo2); |
| assertEquals(SyncInfo.INCOMING | SyncInfo.CHANGE, syncInfo2.getKind()); |
| IResourceVariant baseVariant2 = syncInfo2.getBase(); |
| IResourceVariant remoteVariant2 = syncInfo2.getRemote(); |
| assertContentEquals(baseVariant2, INITIAL_CONTENT_2); |
| assertContentEquals(remoteVariant2, BRANCH_CHANGES + INITIAL_CONTENT_2); |
| } |
| |
| @Test |
| public void testDiff() throws Exception { |
| GitResourceVariantTreeProvider provider = createTreeProvider(); |
| GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(provider); |
| |
| final IDiff diff1 = subscriber.getDiff(iFile1); |
| assertTrue(diff1 instanceof IThreeWayDiff); |
| assertEquals(IDiff.CHANGE, diff1.getKind()); |
| assertEquals(IThreeWayDiff.OUTGOING, ((IThreeWayDiff)diff1).getDirection()); |
| final IDiff localDiff1 = ((IThreeWayDiff)diff1).getLocalChange(); |
| final IDiff remoteDiff1 = ((IThreeWayDiff)diff1).getRemoteChange(); |
| assertNull(remoteDiff1); |
| assertTrue(localDiff1 instanceof ResourceDiff); |
| final IFileRevision localState1 = ((ResourceDiff)localDiff1).getAfterState(); |
| final IFileRevision baseState1 = ((ResourceDiff)localDiff1).getBeforeState(); |
| assertNotNull(localState1); |
| assertNotNull(baseState1); |
| assertTrue(iFile1.getName().equals(localState1.getName())); |
| assertTrue(iFile1.getName().equals(baseState1.getName())); |
| final IStorage localStorage1 = localState1.getStorage(new NullProgressMonitor()); |
| final IStorage baseStorage1 = baseState1.getStorage(new NullProgressMonitor()); |
| assertContentEquals(localStorage1, INITIAL_CONTENT_1 + MASTER_CHANGES); |
| assertContentEquals(baseStorage1, INITIAL_CONTENT_1); |
| |
| final IDiff diff2 = subscriber.getDiff(iFile2); |
| assertTrue(diff2 instanceof IThreeWayDiff); |
| assertEquals(IDiff.CHANGE, diff2.getKind()); |
| assertEquals(IThreeWayDiff.INCOMING, ((IThreeWayDiff)diff2).getDirection()); |
| final IDiff localDiff2 = ((IThreeWayDiff)diff2).getLocalChange(); |
| final IDiff remoteDiff2 = ((IThreeWayDiff)diff2).getRemoteChange(); |
| assertTrue(remoteDiff2 instanceof ResourceDiff); |
| assertNull(localDiff2); |
| final IFileRevision remoteState2 = ((ResourceDiff)remoteDiff2).getAfterState(); |
| final IFileRevision ancestorState2 = ((ResourceDiff)remoteDiff2).getBeforeState(); |
| assertTrue(iFile2.getName().equals(ancestorState2.getName())); |
| assertTrue(iFile2.getName().equals(remoteState2.getName())); |
| final IStorage ancestorStorage2 = ancestorState2.getStorage(new NullProgressMonitor()); |
| final IStorage remoteStorage2 = remoteState2.getStorage(new NullProgressMonitor()); |
| assertContentEquals(ancestorStorage2, INITIAL_CONTENT_2); |
| assertContentEquals(remoteStorage2, BRANCH_CHANGES + INITIAL_CONTENT_2); |
| } |
| |
| @Test |
| public void testAddLocalAndRemote() throws Exception { |
| GitResourceVariantTreeProvider provider = createTreeProviderWithAdditions(); |
| GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(provider); |
| |
| final IDiff diff1 = subscriber.getDiff(iFile1); |
| assertTrue(diff1 instanceof IThreeWayDiff); |
| assertEquals(IDiff.ADD, diff1.getKind()); |
| assertEquals(IThreeWayDiff.OUTGOING, ((IThreeWayDiff)diff1).getDirection()); |
| final IDiff localDiff1 = ((IThreeWayDiff)diff1).getLocalChange(); |
| final IDiff remoteDiff1 = ((IThreeWayDiff)diff1).getRemoteChange(); |
| assertTrue(localDiff1 instanceof ResourceDiff); |
| assertNull(remoteDiff1); |
| final IFileRevision ancestorState1 = ((ResourceDiff)localDiff1).getBeforeState(); |
| final IFileRevision localState1 = ((ResourceDiff)localDiff1).getAfterState(); |
| assertTrue(iFile1.getName().equals(localState1.getName())); |
| assertNull(ancestorState1); |
| final IStorage localStorage1 = localState1.getStorage(new NullProgressMonitor()); |
| assertContentEquals(localStorage1, INITIAL_CONTENT_1); |
| |
| final IDiff diff2 = subscriber.getDiff(iFile2); |
| assertTrue(diff2 instanceof IThreeWayDiff); |
| assertEquals(IDiff.ADD, diff2.getKind()); |
| assertEquals(IThreeWayDiff.INCOMING, ((IThreeWayDiff)diff2).getDirection()); |
| final IDiff localDiff2 = ((IThreeWayDiff)diff2).getLocalChange(); |
| final IDiff remoteDiff2 = ((IThreeWayDiff)diff2).getRemoteChange(); |
| assertTrue(remoteDiff2 instanceof ResourceDiff); |
| assertNull(localDiff2); |
| final IFileRevision ancestorState2 = ((ResourceDiff)remoteDiff2).getBeforeState(); |
| final IFileRevision remoteState2 = ((ResourceDiff)remoteDiff2).getAfterState(); |
| assertNull(ancestorState2); |
| assertTrue(iFile2.getName().equals(remoteState2.getName())); |
| final IStorage remoteStorage2 = remoteState2.getStorage(new NullProgressMonitor()); |
| assertContentEquals(remoteStorage2, INITIAL_CONTENT_2); |
| } |
| |
| @Test |
| public void testRemoveLocalAndRemote() throws Exception { |
| GitResourceVariantTreeProvider provider = createTreeProviderWithDeletions(); |
| GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(provider); |
| |
| // file1 has been removed locally |
| final IDiff diff1 = subscriber.getDiff(iFile1); |
| assertTrue(diff1 instanceof IThreeWayDiff); |
| assertEquals(IDiff.REMOVE, diff1.getKind()); |
| assertEquals(IThreeWayDiff.OUTGOING, ((IThreeWayDiff)diff1).getDirection()); |
| final IDiff localDiff1 = ((IThreeWayDiff)diff1).getLocalChange(); |
| final IDiff remoteDiff1 = ((IThreeWayDiff)diff1).getRemoteChange(); |
| assertTrue(localDiff1 instanceof ResourceDiff); |
| assertNull(remoteDiff1); |
| final IFileRevision ancestorState1 = ((ResourceDiff)localDiff1).getBeforeState(); |
| final IFileRevision localState1 = ((ResourceDiff)localDiff1).getAfterState(); |
| assertTrue(iFile1.getName().equals(ancestorState1.getName())); |
| assertNull(localState1); |
| final IStorage ancestorStorage1 = ancestorState1.getStorage(new NullProgressMonitor()); |
| assertContentEquals(ancestorStorage1, INITIAL_CONTENT_1); |
| |
| // file2 has been removed remotely |
| final IDiff diff2 = subscriber.getDiff(iFile2); |
| assertTrue(diff2 instanceof IThreeWayDiff); |
| assertEquals(IDiff.REMOVE, diff2.getKind()); |
| assertEquals(IThreeWayDiff.INCOMING, ((IThreeWayDiff)diff2).getDirection()); |
| final IDiff localDiff2 = ((IThreeWayDiff)diff2).getLocalChange(); |
| final IDiff remoteDiff2 = ((IThreeWayDiff)diff2).getRemoteChange(); |
| assertTrue(remoteDiff2 instanceof ResourceDiff); |
| assertNull(localDiff2); |
| final IFileRevision ancestorState2 = ((ResourceDiff)remoteDiff2).getBeforeState(); |
| final IFileRevision remoteState2 = ((ResourceDiff)remoteDiff2).getAfterState(); |
| assertTrue(iFile2.getName().equals(ancestorState2.getName())); |
| assertNull(remoteState2); |
| final IStorage rancestorStorage2 = ancestorState2.getStorage(new NullProgressMonitor()); |
| assertContentEquals(rancestorStorage2, INITIAL_CONTENT_2); |
| } |
| |
| private GitResourceVariantTreeProvider createTreeProvider() throws Exception { |
| repository.appendContentAndCommit(iProject, file1, INITIAL_CONTENT_1, "first file - initial commit"); |
| repository.appendContentAndCommit(iProject, file2, INITIAL_CONTENT_2, "second file - initial commit"); |
| repository.createBranch(MASTER, BASE); |
| |
| repository.createAndCheckoutBranch(MASTER, BRANCH); |
| |
| setContentsAndCommit(repository, iFile2, BRANCH_CHANGES + INITIAL_CONTENT_2, "branch commit"); |
| |
| repository.checkoutBranch(MASTER); |
| |
| setContentsAndCommit(repository, iFile1, INITIAL_CONTENT_1 + MASTER_CHANGES, "master commit"); |
| iProject.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); |
| |
| // as if we tried to merge branch into master |
| RevWalk walk = new RevWalk(repo); |
| try { |
| RevTree baseTree = walk.parseTree(repo.resolve(BASE)); |
| RevTree sourceTree = walk.parseTree(repo.resolve(MASTER)); |
| RevTree remoteTree = walk.parseTree(repo.resolve(BRANCH)); |
| TreeWalk treeWalk = new NameConflictTreeWalk(repo); |
| treeWalk.addTree(baseTree); |
| treeWalk.addTree(sourceTree); |
| treeWalk.addTree(remoteTree); |
| return new TreeWalkResourceVariantTreeProvider(repo, treeWalk, 0, 1, 2); |
| } finally { |
| walk.close(); |
| } |
| } |
| |
| private GitResourceVariantTreeProvider createTreeProviderWithAdditions() throws Exception { |
| repository.createBranch(MASTER, BASE); |
| repository.createAndCheckoutBranch(MASTER, BRANCH); |
| file2 = repository.createFile(iProject, "file2"); |
| repository.appendContentAndCommit(iProject, file2, INITIAL_CONTENT_2, |
| "Creation of file2 in branch2."); |
| |
| repository.checkoutBranch(MASTER); |
| file1 = repository.createFile(iProject, "file1"); |
| repository.appendContentAndCommit(iProject, file1, INITIAL_CONTENT_1, |
| "Creation of file1 in branch1."); |
| |
| iProject.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); |
| |
| // as if we tried to merge branch3 into branch2 |
| RevWalk walk = new RevWalk(repo); |
| try { |
| RevTree baseTree = walk.parseTree(repo.resolve(BASE)); |
| RevTree sourceTree = walk.parseTree(repo.resolve(MASTER)); |
| RevTree remoteTree = walk.parseTree(repo.resolve(BRANCH)); |
| TreeWalk treeWalk = new NameConflictTreeWalk(repo); |
| treeWalk.addTree(baseTree); |
| treeWalk.addTree(sourceTree); |
| treeWalk.addTree(remoteTree); |
| return new TreeWalkResourceVariantTreeProvider(repo, treeWalk, 0, 1, 2); |
| } finally { |
| walk.close(); |
| } |
| } |
| |
| private GitResourceVariantTreeProvider createTreeProviderWithDeletions() throws Exception { |
| file1 = repository.createFile(iProject, "file1"); |
| repository.appendContentAndCommit(iProject, file1, INITIAL_CONTENT_1, |
| "Creation of file1 in branch1."); |
| file2 = repository.createFile(iProject, "file2"); |
| repository.appendContentAndCommit(iProject, file2, INITIAL_CONTENT_2, |
| "Creation of file2 in branch2."); |
| repository.createBranch(MASTER, BASE); |
| |
| repository.createAndCheckoutBranch(MASTER, BRANCH); |
| repository.untrack(file2); |
| repository.commit("Removed file2 in branch."); |
| |
| repository.checkoutBranch(MASTER); |
| repository.untrack(file1); |
| repository.commit("Removed file1 in master."); |
| |
| iProject.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); |
| |
| // as if we tried to merge branch3 into branch2 |
| RevWalk walk = new RevWalk(repo); |
| try { |
| RevTree baseTree = walk.parseTree(repo.resolve(BASE)); |
| RevTree sourceTree = walk.parseTree(repo.resolve(MASTER)); |
| RevTree remoteTree = walk.parseTree(repo.resolve(BRANCH)); |
| TreeWalk treeWalk = new NameConflictTreeWalk(repo); |
| treeWalk.addTree(baseTree); |
| treeWalk.addTree(sourceTree); |
| treeWalk.addTree(remoteTree); |
| return new TreeWalkResourceVariantTreeProvider(repo, treeWalk, 0, 1, 2); |
| } finally { |
| walk.close(); |
| } |
| } |
| } |