diff options
author | Thomas Wolf | 2018-02-12 08:40:41 +0000 |
---|---|---|
committer | Matthias Sohn | 2018-05-05 23:19:18 +0000 |
commit | 6209c97acc74faeae0f344af0ecf9e2922e63dbd (patch) | |
tree | ac9b535f43558702d17e2b7ab05ae25b25cca16f /org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal | |
parent | 788e4174e4d4e04707c3de8fcdead4a00ad35e89 (diff) | |
download | egit-6209c97acc74faeae0f344af0ecf9e2922e63dbd.tar.gz egit-6209c97acc74faeae0f344af0ecf9e2922e63dbd.tar.xz egit-6209c97acc74faeae0f344af0ecf9e2922e63dbd.zip |
Respect gitattributes in the compare editor
Apply smudge/clean filters. Store the filters to be applied when
we create the internal GitBlobStorage and apply them when the stream
is opened. Unfortunately this requires quite a few interface changes
to pass through CheckoutMetadata.
Adds tests for the new behavior, including index edits.
Bug: 520693
Change-Id: If7696501f3e1b8f6d99518915b7292e268d656bd
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal')
-rw-r--r-- | org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/CompareUtilsTest.java | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/CompareUtilsTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/CompareUtilsTest.java new file mode 100644 index 0000000000..1dc86cccd2 --- /dev/null +++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/CompareUtilsTest.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (C) 2017, Thomas Wolf <thomas.wolf@paranor.ch> + * + * 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.egit.ui.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + +import org.eclipse.compare.ITypedElement; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.egit.core.Activator; +import org.eclipse.egit.core.op.CommitOperation; +import org.eclipse.egit.core.op.ResetOperation; +import org.eclipse.egit.ui.common.LocalRepositoryTestCase; +import org.eclipse.egit.ui.internal.revision.EditableRevision; +import org.eclipse.egit.ui.test.TestUtil; +import org.eclipse.jgit.api.ResetCommand.ResetType; +import org.eclipse.jgit.attributes.FilterCommand; +import org.eclipse.jgit.attributes.FilterCommandFactory; +import org.eclipse.jgit.attributes.FilterCommandRegistry; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.StoredConfig; +import org.eclipse.jgit.util.IO; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests for CompareUtils; in particular editing index content as it can be done + * in the compare editor. + */ +public class CompareUtilsTest extends LocalRepositoryTestCase { + + private Repository repository; + + @Before + public void setup() throws Exception { + File repoFile = createProjectAndCommitToRepository(); + assertNotNull(repoFile); + repository = Activator.getDefault().getRepositoryCache() + .lookupRepository(repoFile); + assertNotNull(repository); + } + + private String get(InputStream in) throws IOException { + ByteBuffer buffer = IO.readWholeStream(in, 1); + return new String(buffer.array(), 0, buffer.limit(), + StandardCharsets.UTF_8); + } + + @Test + public void testIndexEdit() throws Exception { + IFile testFile = touch("a"); + stage(testFile); + // Get the index file revision. + ITypedElement element = CompareUtils.getIndexTypedElement(testFile); + assert (element instanceof EditableRevision); + EditableRevision revision = (EditableRevision) element; + // Check that its contents are 'a'. + try (InputStream in = revision.getContents()) { + assertEquals("a", get(in)); + } + // Change the contents to 'xx' + revision.setContent("xx".getBytes(StandardCharsets.UTF_8)); + // Commit the index + CommitOperation op = new CommitOperation(repository, + TestUtil.TESTAUTHOR, TestUtil.TESTCOMMITTER, + "Commit modified index"); + op.execute(null); + TestUtil.waitForJobs(50, 5000); + // Do a reset --hard + ResetOperation reset = new ResetOperation(repository, Constants.HEAD, + ResetType.HARD); + reset.execute(null); + TestUtil.waitForJobs(50, 5000); + // Should have 'xx' now + try (InputStream in = testFile.getContents()) { + assertEquals("xx", get(in)); + } + } + + @Test + public void testIndexEditWithAttributes() throws Exception { + IFile testFile = touch("a"); + stage(testFile); + // Set up .gitattributes such that 'a's are changed to 'x' on smudge + IFile gitAttributes = touch(PROJ1, FOLDER + "/.gitattributes", + FILE1 + " filter=test"); + try { + FilterCommandRegistry.register("egitui://builtin/test/smudge", + new TestCommandFactory('a', 'x')); + StoredConfig config = repository.getConfig(); + config.setString("filter", "test", "smudge", + "egitui://builtin/test/smudge"); + config.save(); + // Get the index file revision. + ITypedElement element = CompareUtils.getIndexTypedElement(testFile); + assert (element instanceof EditableRevision); + EditableRevision revision = (EditableRevision) element; + // Check that its contents are 'x'. + try (InputStream in = revision.getContents()) { + assertEquals("x", get(in)); + } + // Modify the filter to transform 'x' to 'a' on clean + FilterCommandRegistry.register("egitui://builtin/test/clean", + new TestCommandFactory('x', 'a')); + config.setString("filter", "test", "clean", + "egitui://builtin/test/clean"); + config.save(); + // Change the contents to 'xx'. This should apply the above clean + // filter. + revision.setContent("xx".getBytes(StandardCharsets.UTF_8)); + // Commit the index + CommitOperation op = new CommitOperation(repository, + TestUtil.TESTAUTHOR, TestUtil.TESTCOMMITTER, + "Commit modified index"); + op.execute(null); + TestUtil.waitForJobs(50, 5000); + // Remove filters + gitAttributes.delete(true, true, new NullProgressMonitor()); + config.unsetSection("filter", "test"); + config.save(); + // Do a reset --hard + ResetOperation reset = new ResetOperation(repository, + Constants.HEAD, ResetType.HARD); + reset.execute(null); + TestUtil.waitForJobs(50, 5000); + // Should have 'aa' now since we never committed the .gitattributes + try (InputStream in = testFile.getContents()) { + assertEquals("aa", get(in)); + } + } finally { + FilterCommandRegistry.unregister("egitui://builtin/test/smudge"); + FilterCommandRegistry.unregister("egitui://builtin/test/clean"); + } + } + + private static class TestCommandFactory implements FilterCommandFactory { + private final int toReplace; + + private final int replacement; + + public TestCommandFactory(int toReplace, int replacement) { + this.toReplace = toReplace; + this.replacement = replacement; + } + + @Override + public FilterCommand create(Repository repo, InputStream in, + final OutputStream out) { + FilterCommand cmd = new FilterCommand(in, out) { + + @Override + public int run() throws IOException { + int b = in.read(); + if (b == -1) { + return b; + } else if (b == toReplace) { + out.write(replacement); + } else { + out.write(b); + } + return 1; + } + }; + return cmd; + } + } +} |